radeon_hd: More initial ring queue work

* Rename RenderQueue to RingQueue to be more generic
* We will need two Ring Buffer types, one for
  host -> gpu (render/cp data) and one gpu -> host (irq)
* Add header guard to ringqueue.h
* Things still may change as I work up to a bigger picture.
This commit is contained in:
Alexander von Gluck IV 2012-04-11 13:33:58 -05:00
parent f454574fca
commit 745450ade8
7 changed files with 59 additions and 24 deletions

View File

@ -23,6 +23,6 @@ Addon radeon_hd.accelerant :
hooks.cpp
mode.cpp
pll.cpp
renderqueue.cpp
: be libaccelerantscommon.a
ringqueue.cpp
: be libaccelerantscommon.a $(TARGET_LIBSUPC++)
;

View File

@ -297,6 +297,9 @@ radeon_init_accelerant(int device)
radeon_gpu_mc_setup();
// Set up data crunching + irq rings
radeon_gpu_ring_setup();
TRACE("%s done\n", __func__);
return B_OK;
}

View File

@ -19,6 +19,7 @@
#include "mode.h"
#include "pll.h"
#include "radeon_hd.h"
#include "ringqueue.h"
#define MAX_DISPLAY 2
@ -70,6 +71,8 @@ struct accelerant_info {
struct fb_info fb; // used for frame buffer info within MC
volatile uint32 dpms_mode; // current driver dpms mode
RingQueue* ringQueue[RADEON_QUEUE_MAX]; // Ring buffer command processor
};

View File

@ -501,19 +501,22 @@ radeon_gpu_mc_setup()
status_t
radeon_gpu_irq_setup()
radeon_gpu_ring_setup()
{
// TODO: Stub for IRQ setup
TRACE("%s called\n", __func__);
// allocate rings via r600_ih_ring_alloc
// init GFX ring queue
gInfo->ringQueue[RADEON_QUEUE_TYPE_GFX_INDEX]
= new RingQueue(1024 * 1024, RADEON_QUEUE_TYPE_GFX_INDEX);
// disable irq's via r600_disable_interrupts
#if 0
// init IRQ ring queue (reverse of rendering/cp ring queue)
gInfo->irqRingQueue
= new IRQRingQueue(64 * 1024)
#endif
// r600_rlc_init
// setup interrupt control
return B_ERROR;
return B_OK;
}

View File

@ -175,7 +175,7 @@ void radeon_gpu_mc_halt(struct gpu_state *gpuState);
void radeon_gpu_mc_resume(struct gpu_state *gpuState);
status_t radeon_gpu_mc_idlewait();
status_t radeon_gpu_mc_setup();
status_t radeon_gpu_irq_setup();
status_t radeon_gpu_ring_setup();
status_t radeon_gpu_ss_disable();

View File

@ -7,7 +7,7 @@
*/
#include "renderqueue.h"
#include "ringqueue.h"
#include <stdlib.h>
#include <string.h>
@ -24,6 +24,13 @@ extern "C" void _sPrintf(const char* format, ...);
#define ERROR(x...) _sPrintf("radeon_hd: " x)
static const char* queueName[RADEON_QUEUE_MAX] = {
"GFX",
"CP1",
"CP2"
};
static int
compute_order(unsigned long size)
{
@ -36,19 +43,22 @@ compute_order(unsigned long size)
}
RenderQueue::RenderQueue(size_t sizeBytes)
RingQueue::RingQueue(size_t sizeBytes, uint32 queueType)
:
_queueType(queueType),
_readPtr(0),
_writePtr(0)
{
TRACE("%s: Requested %d bytes for RenderQueue.\n", __func__, sizeBytes);
TRACE("%s: Requested %d bytes for %s RingQueue.\n", __func__, sizeBytes,
queueName[_queueType]);
size_t renderQueueSize = compute_order(sizeBytes / 8);
_size = (1 << (renderQueueSize + 1)) * 4;
_writeBytesAvail = _size;
_alignMask = 16 - 1;
TRACE("%s: Allocating %d bytes for RenderQueue.\n", __func__, _size);
TRACE("%s: Allocating %d bytes for %s RingQueue.\n", __func__, _size,
queueName[_queueType]);
// Allocate buffer memory
_data = (unsigned char*)malloc(_size);
@ -57,17 +67,17 @@ RenderQueue::RenderQueue(size_t sizeBytes)
}
RenderQueue::~RenderQueue()
RingQueue::~RingQueue()
{
TRACE("%s: Closing RenderQueue.\n", __func__);
TRACE("%s: Closing %s RingQueue.\n", __func__, queueName[_queueType]);
free(_data);
}
status_t
RenderQueue::Empty()
RingQueue::Empty()
{
TRACE("%s: Clearing RenderQueue\n", __func__);
TRACE("%s: Clearing %s RingQueue\n", __func__, queueName[_queueType]);
// Clear buffer
memset(_data, 0, _size);
@ -80,7 +90,7 @@ RenderQueue::Empty()
size_t
RenderQueue::Read(unsigned char* dataPtr, size_t bytes)
RingQueue::Read(unsigned char* dataPtr, size_t bytes)
{
// If there is no data or nothing to read, return 0 bytes
if (dataPtr == 0 || bytes <= 0 || _writeBytesAvail == _size)
@ -109,7 +119,7 @@ RenderQueue::Read(unsigned char* dataPtr, size_t bytes)
size_t
RenderQueue::Write(unsigned char* dataPtr, size_t bytes)
RingQueue::Write(unsigned char* dataPtr, size_t bytes)
{
// If there is no data, or no room available, 0 bytes written.
if (dataPtr == 0 || bytes <= 0 || _writeBytesAvail == 0)

View File

@ -5,16 +5,27 @@
* Authors:
* Alexander von Gluck, kallisti5@unixzen.com
*/
#ifndef _RADEON_HD_RINGQUEUE_H
#define _RADEON_HD_RINGQUEUE_H
#include "Accelerant.h"
#define RADEON_QUEUE_MAX 3
// Basic r100+ graphic data ring
#define RADEON_QUEUE_TYPE_GFX_INDEX 0
// Cayman+ have two compute command processor rings
#define CAYMAN_QUEUE_TYPE_CP1_INDEX 1
#define CAYMAN_QUEUE_TYPE_CP2_INDEX 2
// A basic ring buffer for passing render data into card.
class RenderQueue {
// Data flows from the host to the GPU
class RingQueue {
public:
RenderQueue(size_t bytes);
~RenderQueue();
RingQueue(size_t bytes, uint32 queueType);
~RingQueue();
size_t Read(unsigned char* data, size_t bytes);
size_t Write(unsigned char* data, size_t bytes);
status_t Empty();
@ -23,6 +34,8 @@ public:
size_t GetWriteAvail() {return _writeBytesAvail;}
size_t GetReadAvail() {return _size - _writeBytesAvail;}
private:
uint32 _queueType;
unsigned char* _data;
size_t _size;
size_t _writeBytesAvail;
@ -31,3 +44,6 @@ private:
uint32 _alignMask;
};
#endif /* _RADEON_HD_RINGQUEUE_H */