Sync with my local tree.

Changes to current operation:
-Elts are no longer converted to 16-bit format
-Cube maps
This commit is contained in:
Aapo Tahkola 2005-10-26 16:42:06 +00:00
parent 23f076ca67
commit 4dc3249f0d
16 changed files with 1897 additions and 155 deletions

View file

@ -25,6 +25,8 @@ DRIVER_SOURCES = \
radeon_lock.c \
radeon_span.c \
radeon_state.c \
radeon_mm.c \
radeon_vtxfmt_a.c \
\
r300_context.c \
r300_ioctl.c \

View file

@ -128,9 +128,10 @@ int r300FlushCmdBuf(r300ContextPtr r300, const char* caller)
}
static void print_state_atom(struct r300_state_atom *state, int dwords)
void r300_print_state_atom(r300ContextPtr r300, struct r300_state_atom *state)
{
int i;
int dwords = (*state->check)(r300, state);
fprintf(stderr, " emit %s/%d/%d\n", state->name, dwords, state->cmd_size);
@ -159,7 +160,7 @@ static __inline__ void r300DoEmitState(r300ContextPtr r300, GLboolean dirty)
int dwords = (*atom->check)(r300, atom);
if (dwords)
print_state_atom(atom, dwords);
r300_print_state_atom(r300, atom);
else
fprintf(stderr, " skip state %s\n",
atom->name);
@ -567,7 +568,7 @@ void r300EmitBlit(r300ContextPtr rmesa,
GLint srcx, GLint srcy,
GLint dstx, GLint dsty, GLuint w, GLuint h)
{
drm_radeon_cmd_header_t *cmd;
drm_r300_cmd_header_t *cmd;
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr,
@ -582,14 +583,13 @@ void r300EmitBlit(r300ContextPtr rmesa,
assert(w < (1 << 16));
assert(h < (1 << 16));
cmd =
(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 8,
cmd = (drm_r300_cmd_header_t *) r300AllocCmdBuf(rmesa, 8,
__FUNCTION__);
cmd[0].header.cmd_type = R300_CMD_PACKET3;
cmd[0].header.pad0 = R300_CMD_PACKET3_RAW;
cmd[1].i = R200_CP_CMD_BITBLT_MULTI | (5 << 16);
cmd[2].i = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
cmd[1].u = R200_CP_CMD_BITBLT_MULTI | (5 << 16);
cmd[2].u = (RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
RADEON_GMC_BRUSH_NONE |
(color_fmt << 8) |
@ -598,28 +598,24 @@ void r300EmitBlit(r300ContextPtr rmesa,
RADEON_DP_SRC_SOURCE_MEMORY |
RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
cmd[3].i = ((src_pitch / 64) << 22) | (src_offset >> 10);
cmd[4].i = ((dst_pitch / 64) << 22) | (dst_offset >> 10);
cmd[5].i = (srcx << 16) | srcy;
cmd[6].i = (dstx << 16) | dsty; /* dst */
cmd[7].i = (w << 16) | h;
cmd[3].u = ((src_pitch / 64) << 22) | (src_offset >> 10);
cmd[4].u = ((dst_pitch / 64) << 22) | (dst_offset >> 10);
cmd[5].u = (srcx << 16) | srcy;
cmd[6].u = (dstx << 16) | dsty; /* dst */
cmd[7].u = (w << 16) | h;
}
void r300EmitWait(r300ContextPtr rmesa, GLuint flags)
{
if (rmesa->radeon.dri.drmMinor >= 6) {
drm_radeon_cmd_header_t *cmd;
drm_r300_cmd_header_t *cmd;
assert(!(flags & ~(R300_WAIT_2D | R300_WAIT_3D)));
assert(!(flags & ~(R300_WAIT_2D | R300_WAIT_3D)));
cmd =
(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
1,
__FUNCTION__);
cmd[0].i = 0;
cmd[0].wait.cmd_type = R300_CMD_WAIT;
cmd[0].wait.flags = flags;
}
cmd = (drm_r300_cmd_header_t *) r300AllocCmdBuf(rmesa, 1,
__FUNCTION__);
cmd[0].u = 0;
cmd[0].wait.cmd_type = R300_CMD_WAIT;
cmd[0].wait.flags = flags;
}
void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)

View file

@ -59,6 +59,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_ioctl.h"
#include "r300_tex.h"
#ifdef USER_BUFFERS
#include "radeon_mm.h"
#endif
#include "vblank.h"
#include "utils.h"
#include "xmlpool.h" /* for symbolic values of enum-type options */
@ -83,8 +87,7 @@ const struct dri_extension card_extensions[] = {
{"GL_ARB_multitexture", NULL},
{"GL_ARB_texture_border_clamp", NULL},
{"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
/* disable until we support it, fixes a few things in ut2004 */
/* {"GL_ARB_texture_cube_map", NULL}, */
{"GL_ARB_texture_cube_map", NULL},
{"GL_ARB_texture_env_add", NULL},
{"GL_ARB_texture_env_combine", NULL},
{"GL_ARB_texture_env_crossbar", NULL},
@ -155,75 +158,6 @@ static const struct tnl_pipeline_stage *r300_pipeline[] = {
0,
};
static void r300BufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
const GLvoid *data, GLenum usage, struct gl_buffer_object *obj)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
drm_radeon_mem_alloc_t alloc;
int offset, ret;
/* Free previous buffer */
if (obj->OnCard) {
drm_radeon_mem_free_t memfree;
memfree.region = RADEON_MEM_REGION_GART;
memfree.region_offset = (char *)obj->Data - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
ret = drmCommandWrite(rmesa->radeon.radeonScreen->driScreen->fd,
DRM_RADEON_FREE, &memfree, sizeof(memfree));
if (ret) {
WARN_ONCE("Failed to free GART memroy!\n");
}
obj->OnCard = GL_FALSE;
}
alloc.region = RADEON_MEM_REGION_GART;
alloc.alignment = 4;
alloc.size = size;
alloc.region_offset = &offset;
ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_ALLOC, &alloc, sizeof(alloc));
if (ret) {
WARN_ONCE("Ran out of GART memory!\n");
obj->Data = NULL;
_mesa_buffer_data(ctx, target, size, data, usage, obj);
return ;
}
obj->Data = ((GLubyte *)rmesa->radeon.radeonScreen->gartTextures.map) + offset;
if (data)
memcpy(obj->Data, data, size);
obj->Size = size;
obj->Usage = usage;
obj->OnCard = GL_TRUE;
#if 0
fprintf(stderr, "allocated %d bytes at %p, offset=%d\n", size, obj->Data, offset);
#endif
}
static void r300DeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
if(r300IsGartMemory(rmesa, obj->Data, obj->Size)){
drm_radeon_mem_free_t memfree;
int ret;
memfree.region = RADEON_MEM_REGION_GART;
memfree.region_offset = (char *)obj->Data - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
ret = drmCommandWrite(rmesa->radeon.radeonScreen->driScreen->fd,
DRM_RADEON_FREE, &memfree, sizeof(memfree));
if(ret){
WARN_ONCE("Failed to free GART memroy!\n");
}
obj->Data = NULL;
}
_mesa_delete_buffer_object(ctx, obj);
}
/* Create the device specific rendering context.
*/
@ -263,13 +197,14 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
r300InitTextureFuncs(&functions);
r300InitShaderFuncs(&functions);
#if 0 /* Needs various Mesa changes... */
if (hw_tcl_on) {
functions.BufferData = r300BufferData;
functions.DeleteBuffer = r300DeleteBuffer;
}
#ifdef USER_BUFFERS
radeon_mm_init(r300);
#endif
#ifdef HW_VBOS
if (hw_tcl_on) {
r300_init_vbo_funcs(&functions);
}
#endif
if (!radeonInitContext(&r300->radeon, &functions,
glVisual, driContextPriv, sharedContextPrivate)) {
FREE(r300);
@ -331,6 +266,11 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
ctx->Const.MinLineWidthAA = 1.0;
ctx->Const.MaxLineWidth = R300_LINESIZE_MAX;
ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX;
#ifdef USER_BUFFERS
/* Needs further modifications */
//ctx->Const.MaxArrayLockSize = (/*512*/RADEON_BUFFER_SIZE*16*1024) / (4*4);
#endif
/* Initialize the software rasterizer and helper modules.
*/
@ -391,6 +331,10 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
radeonInitSpanFuncs(ctx);
r300InitCmdBuf(r300);
r300InitState(r300);
#ifdef RADEON_VTXFMT_A
radeon_init_vtxfmt_a(r300);
#endif
#if 0
/* plug in a few more device driver functions */

View file

@ -48,6 +48,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_context.h"
#define USE_ARB_F_P 1
//#define USER_BUFFERS
//#define RADEON_VTXFMT_A
//#define HW_VBOS
//#define OPTIMIZE_ELTS
struct r300_context;
typedef struct r300_context r300ContextRec;
@ -109,12 +113,15 @@ static __inline__ uint32_t r300PackFloat32(float fl)
struct r300_dma_buffer {
int refcount; /* the number of retained regions in buf */
drmBufPtr buf;
int id;
};
#ifdef USER_BUFFERS
#define GET_START(rvb) (r300GartOffsetFromVirtual(rmesa, (rvb)->address+(rvb)->start))
#else
#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset + \
(rvb)->address - rmesa->dma.buf0_address + \
(rvb)->start)
#endif
/* A retained region, eg vertices for indexed vertices.
*/
struct r300_dma_region {
@ -738,6 +745,30 @@ struct r300_pixel_shader_state {
#define REG_COLOR0 1
#define REG_TEX0 2
#ifdef USER_BUFFERS
struct dt {
GLint size;
GLenum type;
GLsizei stride;
void *data;
};
struct radeon_vertex_buffer {
int Count;
void *Elts;
int elt_size;
int elt_min, elt_max; /* debug */
struct dt AttribPtr[VERT_ATTRIB_MAX];
struct tnl_prim *Primitive;
GLuint PrimitiveCount;
GLint LockFirst;
GLsizei LockCount;
int lock_uptodate;
};
#endif
struct r300_aos_rec {
GLuint offset;
int element_size; /* in dwords */
@ -761,6 +792,9 @@ struct r300_state {
#endif
struct r300_dma_region aos[R300_MAX_AOS_ARRAYS];
int aos_count;
#ifdef USER_BUFFERS
struct radeon_vertex_buffer VB;
#endif
GLuint *Elts;
struct r300_dma_region elt_dma;
@ -815,8 +849,19 @@ struct r300_context {
GLuint TexGenInputs;
GLuint TexGenCompSel;
GLmatrix tmpmat;
#ifdef USER_BUFFERS
key_t mm_ipc_key;
int mm_shm_id;
int mm_sem_id;
struct radeon_memory_manager *rmm;
#endif
};
struct r300_buffer_object {
struct gl_buffer_object mesa_obj;
int id;
};
#define R300_CONTEXT(ctx) ((r300ContextPtr)(ctx->DriverCtx))
static __inline GLuint r300PackColor( GLuint cpp,
@ -841,4 +886,12 @@ void translate_vertex_shader(struct r300_vertex_program *vp);
extern void r300InitShaderFuncs(struct dd_function_table *functions);
extern void r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program *vp);
#ifdef RADEON_VTXFMT_A
extern void radeon_init_vtxfmt_a(r300ContextPtr rmesa);
#endif
#ifdef HW_VBOS
extern void r300_init_vbo_funcs(struct dd_function_table *functions);
#endif
#endif /* __R300_CONTEXT_H__ */

View file

@ -71,6 +71,8 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
r300ContextPtr rmesa=r300;
LOCAL_VARS;
#else
r300ContextPtr rmesa=r300;
LOCAL_VARS;
int i;
#endif
@ -261,6 +263,11 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
r300EmitState(r300);
#else
#if 1
cp_wait(r300, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
end_3d(PASS_PREFIX_VOID);
#endif
R300_STATECHANGE(r300, cb);
reg_start(R300_RB3D_COLOROFFSET0, 0);
e32(cboffset);
@ -270,6 +277,9 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
else
cbpitch |= R300_COLOR_FORMAT_RGB565;
if (r300->radeon.sarea->tiling_enabled)
cbpitch |= R300_COLOR_TILE_ENABLE;
reg_start(R300_RB3D_COLORPITCH0, 0);
e32(cbpitch);
@ -352,6 +362,15 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
cmd2[7].u = r300PackFloat32(ctx->Color.ClearColor[2]);
cmd2[8].u = r300PackFloat32(ctx->Color.ClearColor[3]);
#if 1
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
e32(0x0000000a);
reg_start(0x4f18,0);
e32(0x00000003);
cp_wait(rmesa, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
#endif
}
#ifdef CB_DPATH
@ -422,7 +441,7 @@ static void r300EmitClearState(GLcontext * ctx)
R300_STATECHANGE(r300, rc);
/* The second constant is needed to get glxgears display anything .. */
reg_start(R300_RS_CNTL_0, 1);
e32(R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18);
e32((1 << R300_RS_CNTL_CI_CNT_SHIFT) | R300_RS_CNTL_0_UNKNOWN_18);
e32(0);
R300_STATECHANGE(r300, rr);
@ -477,6 +496,8 @@ static void r300EmitClearState(GLcontext * ctx)
e32(VP_ZERO());
e32(0);
/*reg_start(0x4500,0);
e32(2560-1);*/
}
#endif
@ -561,6 +582,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean all,
#endif
}
void r300Flush(GLcontext * ctx)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
@ -572,6 +594,104 @@ void r300Flush(GLcontext * ctx)
r300FlushCmdBuf(r300, __FUNCTION__);
}
#ifdef USER_BUFFERS
#include "radeon_mm.h"
void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
{
struct r300_dma_buffer *dmabuf;
int fd = rmesa->radeon.dri.fd;
int index = 0;
int size = 0;
drmDMAReq dma;
int ret;
if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
fprintf(stderr, "%s\n", __FUNCTION__);
if (rmesa->dma.flush) {
rmesa->dma.flush(rmesa);
}
if (rmesa->dma.current.buf)
r300ReleaseDmaRegion(rmesa, &rmesa->dma.current, __FUNCTION__);
if (rmesa->dma.nr_released_bufs > 4)
r300FlushCmdBuf(rmesa, __FUNCTION__);
dmabuf = CALLOC_STRUCT(r300_dma_buffer);
dmabuf->buf = (void *)1; /* hack */
dmabuf->refcount = 1;
dmabuf->id = radeon_mm_alloc(rmesa, 4, RADEON_BUFFER_SIZE*16);
rmesa->dma.current.buf = dmabuf;
rmesa->dma.current.address = radeon_mm_ptr(rmesa, dmabuf->id);
rmesa->dma.current.end = RADEON_BUFFER_SIZE*16;
rmesa->dma.current.start = 0;
rmesa->dma.current.ptr = 0;
}
void r300ReleaseDmaRegion(r300ContextPtr rmesa,
struct r300_dma_region *region, const char *caller)
{
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
if (!region->buf)
return;
if (rmesa->dma.flush)
rmesa->dma.flush(rmesa);
if (--region->buf->refcount == 0) {
radeon_mm_free(rmesa, region->buf->id);
FREE(region->buf);
rmesa->dma.nr_released_bufs++;
}
region->buf = 0;
region->start = 0;
}
/* Allocates a region from rmesa->dma.current. If there isn't enough
* space in current, grab a new buffer (and discard what was left of current)
*/
void r300AllocDmaRegion(r300ContextPtr rmesa,
struct r300_dma_region *region,
int bytes, int alignment)
{
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
if (rmesa->dma.flush)
rmesa->dma.flush(rmesa);
if (region->buf)
r300ReleaseDmaRegion(rmesa, region, __FUNCTION__);
alignment--;
rmesa->dma.current.start = rmesa->dma.current.ptr =
(rmesa->dma.current.ptr + alignment) & ~alignment;
if (rmesa->dma.current.ptr + bytes > rmesa->dma.current.end)
r300RefillCurrentDmaRegion(rmesa);
region->start = rmesa->dma.current.start;
region->ptr = rmesa->dma.current.start;
region->end = rmesa->dma.current.start + bytes;
region->address = rmesa->dma.current.address;
region->buf = rmesa->dma.current.buf;
region->buf->refcount++;
rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
rmesa->dma.current.start =
rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;
assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
}
#else
void r300RefillCurrentDmaRegion(r300ContextPtr rmesa)
{
struct r300_dma_buffer *dmabuf;
@ -714,6 +834,8 @@ void r300AllocDmaRegion(r300ContextPtr rmesa,
assert(rmesa->dma.current.ptr <= rmesa->dma.current.end);
}
#endif
/* Called via glXGetMemoryOffsetMESA() */
GLuint r300GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn,
const GLvoid * pointer)

View file

@ -50,6 +50,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_maos.h"
#include "r300_ioctl.h"
#ifdef USER_BUFFERS
#include "radeon_mm.h"
#endif
#define DEBUG_ALL DEBUG_VERTS
@ -173,15 +177,11 @@ static void emit_vector(GLcontext * ctx,
fprintf(stderr, "%s count %d size %d stride %d\n",
__FUNCTION__, count, size, stride);
if(r300IsGartMemory(rmesa, data, size*stride)){
rvb->address = rmesa->radeon.radeonScreen->gartTextures.map;
rvb->start = (char *)data - rvb->address;
if(r300IsGartMemory(rmesa, data, /*(count-1)*stride */ 4)){
rvb->address = data;
rvb->start = 0;
rvb->aos_offset = r300GartOffsetFromVirtual(rmesa, data);
if(stride == 0)
rvb->aos_stride = 0;
else
rvb->aos_stride = stride / 4;
rvb->aos_stride = stride / 4 ;
rvb->aos_size = size;
return;
@ -226,26 +226,30 @@ static void emit_vector(GLcontext * ctx,
}
void r300EmitElts(GLcontext * ctx, GLuint *elts, unsigned long n_elts)
void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts, int elt_size)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_dma_region *rvb=&rmesa->state.elt_dma;
unsigned short int *out;
int i;
void *out;
if(r300IsGartMemory(rmesa, elts, n_elts*sizeof(unsigned short int))){
assert(elt_size == 2 || elt_size == 4);
if(r300IsGartMemory(rmesa, elts, n_elts * elt_size)){
rvb->address = rmesa->radeon.radeonScreen->gartTextures.map;
rvb->start = (char *)elts - rvb->address;
rvb->start = ((char *)elts) - rvb->address;
rvb->aos_offset = rmesa->radeon.radeonScreen->gart_texture_offset + rvb->start;
return ;
}else if(r300IsGartMemory(rmesa, elts, 1)){
WARN_ONCE("Pointer not within GART memory!\n");
exit(1);
}
r300AllocDmaRegion(rmesa, rvb, n_elts*sizeof(unsigned short int), 2);
r300AllocDmaRegion(rmesa, rvb, n_elts * elt_size, elt_size);
rvb->aos_offset = GET_START(rvb);
out = (unsigned short int *)(rvb->address + rvb->start);
for(i=0; i < n_elts; i++)
out[i]=(unsigned short int)elts[i];
out = rvb->address + rvb->start;
memcpy(out, elts, n_elts * elt_size);
}
/* Emit vertex data to GART memory (unless immediate mode)
@ -549,6 +553,362 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
rmesa->state.aos_count = nr;
}
#ifdef RADEON_VTXFMT_A
void r300EmitArraysVtx(GLcontext * ctx, GLboolean immd)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
r300ContextPtr r300 = rmesa;
struct radeon_vertex_buffer *VB = &rmesa->state.VB;
//struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLuint nr = 0;
GLuint count = VB->Count;
GLuint dw,mask;
GLuint vic_1 = 0; /* R300_VAP_INPUT_CNTL_1 */
GLuint aa_vap_reg = 0; /* VAP register assignment */
GLuint i;
GLuint inputs = 0;
#define CONFIGURE_AOS(r, f, v, sz, cn) { \
if (RADEON_DEBUG & DEBUG_STATE) \
fprintf(stderr, "Enabling "#v "\n"); \
if (++nr >= R300_MAX_AOS_ARRAYS) { \
fprintf(stderr, "Aieee! AOS array count exceeded!\n"); \
exit(-1); \
} \
\
if (hw_tcl_on == GL_FALSE) \
rmesa->state.aos[nr-1].aos_reg = aa_vap_reg++; \
rmesa->state.aos[nr-1].aos_format = f; \
if (immd) { \
rmesa->state.aos[nr-1].aos_size = 4; \
rmesa->state.aos[nr-1].aos_stride = 4; \
rmesa->state.aos[nr-1].aos_offset = 0; \
} else { \
emit_vector(ctx, \
&rmesa->state.aos[nr-1], \
v.data, \
sz, \
v.stride, \
cn); \
rmesa->state.vap_reg.r=rmesa->state.aos[nr-1].aos_reg; \
} \
}
if (hw_tcl_on) {
GLuint InputsRead = CURRENT_VERTEX_SHADER(ctx)->InputsRead;
struct r300_vertex_program *prog=(struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
if (InputsRead & (1<<VERT_ATTRIB_POS)) {
inputs |= _TNL_BIT_POS;
rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_POS];
}
if (InputsRead & (1<<VERT_ATTRIB_NORMAL)) {
inputs |= _TNL_BIT_NORMAL;
rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_NORMAL];
}
if (InputsRead & (1<<VERT_ATTRIB_COLOR0)) {
inputs |= _TNL_BIT_COLOR0;
rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_COLOR0];
}
if (InputsRead & (1<<VERT_ATTRIB_COLOR1)) {
inputs |= _TNL_BIT_COLOR1;
rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_COLOR1];
}
if (InputsRead & (1<<VERT_ATTRIB_FOG)) {
inputs |= _TNL_BIT_FOG;
rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_FOG];
}
if(ctx->Const.MaxTextureUnits > 8) { /* Not sure if this can even happen... */
fprintf(stderr, "%s: Cant handle that many inputs\n", __FUNCTION__);
exit(-1);
}
for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
if (InputsRead & (1<<(VERT_ATTRIB_TEX0+i))) {
inputs |= _TNL_BIT_TEX0<<i;
rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_TEX0+i];
}
}
nr = 0;
} else {
inputs = TNL_CONTEXT(ctx)->render_inputs;
}
rmesa->state.render_inputs = inputs;
if (inputs & _TNL_BIT_POS) {
CONFIGURE_AOS(i_coords, AOS_FORMAT_FLOAT,
VB->AttribPtr[VERT_ATTRIB_POS],
immd ? 4 : VB->AttribPtr[VERT_ATTRIB_POS].size,
count);
vic_1 |= R300_INPUT_CNTL_POS;
}
if (inputs & _TNL_BIT_NORMAL) {
CONFIGURE_AOS(i_normal, AOS_FORMAT_FLOAT,
VB->AttribPtr[VERT_ATTRIB_NORMAL],
immd ? 4 : VB->AttribPtr[VERT_ATTRIB_NORMAL].size,
count);
vic_1 |= R300_INPUT_CNTL_NORMAL;
}
if (inputs & _TNL_BIT_COLOR0) {
int emitsize=4;
if (!immd) {
if (VB->AttribPtr[VERT_ATTRIB_COLOR0].size == 4 &&
(VB->AttribPtr[VERT_ATTRIB_COLOR0].stride != 0 ||
((float*)VB->AttribPtr[VERT_ATTRIB_COLOR0].data)[3] != 1.0)) {
emitsize = 4;
} else {
emitsize = 3;
}//emitsize = VB->AttribPtr[VERT_ATTRIB_COLOR0].size;
}
if(VB->AttribPtr[VERT_ATTRIB_COLOR0].type == GL_UNSIGNED_BYTE)
emitsize = 1;
CONFIGURE_AOS(i_color[0], VB->AttribPtr[VERT_ATTRIB_COLOR0].type == GL_UNSIGNED_BYTE ? AOS_FORMAT_UBYTE : AOS_FORMAT_FLOAT_COLOR,
VB->AttribPtr[VERT_ATTRIB_COLOR0],
immd ? 4 : emitsize,
count);
vic_1 |= R300_INPUT_CNTL_COLOR;
}
if (inputs & _TNL_BIT_COLOR1) {
CONFIGURE_AOS(i_color[1], AOS_FORMAT_FLOAT_COLOR,
VB->AttribPtr[VERT_ATTRIB_COLOR1],
immd ? 4 : VB->AttribPtr[VERT_ATTRIB_COLOR1].size,
count);
}
#if 0
if (inputs & _TNL_BIT_FOG) {
CONFIGURE_AOS( AOS_FORMAT_FLOAT,
VB->FogCoordPtr,
immd ? 4 : VB->FogCoordPtr->size,
count);
}
#endif
r300->state.texture.tc_count = 0;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
if (inputs & (_TNL_BIT_TEX0 << i)) {
CONFIGURE_AOS(i_tex[i], AOS_FORMAT_FLOAT,
VB->AttribPtr[VERT_ATTRIB_TEX0+i],
immd ? 4 : VB->AttribPtr[VERT_ATTRIB_TEX0+i].size,
count);
vic_1 |= R300_INPUT_CNTL_TC0 << i;
r300->state.texture.tc_count++;
}
}
for(i=0; i < nr; i++)
if(r300->state.aos[i].aos_format == 2){
assert(r300->state.aos[i].aos_size == 1);
r300->state.aos[i].aos_size=5;
}
#define SHOW_INFO(n) do { \
if (RADEON_DEBUG & DEBUG_ALL) { \
fprintf(stderr, "RR[%d] - sz=%d, reg=%d, fmt=%d -- st=%d, of=0x%08x\n", \
n, \
r300->state.aos[n].aos_size, \
r300->state.aos[n].aos_reg, \
r300->state.aos[n].aos_format, \
r300->state.aos[n].aos_stride, \
r300->state.aos[n].aos_offset); \
} \
} while(0);
/* setup INPUT_ROUTE */
R300_STATECHANGE(r300, vir[0]);
for(i=0;i+1<nr;i+=2){
SHOW_INFO(i)
SHOW_INFO(i+1)
dw=(r300->state.aos[i].aos_size-1)
| ((r300->state.aos[i].aos_reg)<<8)
| (r300->state.aos[i].aos_format<<14)
| (((r300->state.aos[i+1].aos_size-1)
| ((r300->state.aos[i+1].aos_reg)<<8)
| (r300->state.aos[i+1].aos_format<<14))<<16);
if(i+2==nr){
dw|=(1<<(13+16));
}
r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
}
if(nr & 1){
SHOW_INFO(nr-1)
dw=(r300->state.aos[nr-1].aos_size-1)
| (r300->state.aos[nr-1].aos_format<<14)
| ((r300->state.aos[nr-1].aos_reg)<<8)
| (1<<13);
r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(nr>>1)]=dw;
//fprintf(stderr, "vir0 dw=%08x\n", dw);
}
/* Set the rest of INPUT_ROUTE_0 to 0 */
//for(i=((count+1)>>1); i<8; i++)r300->hw.vir[0].cmd[R300_VIR_CNTL_0+i]=(0x0);
((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->packet0.count = (nr+1)>>1;
/* Mesa assumes that all missing components are from (0, 0, 0, 1) */
#define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<<R300_INPUT_ROUTE_X_SHIFT) \
| (R300_INPUT_ROUTE_SELECT_Y<<R300_INPUT_ROUTE_Y_SHIFT) \
| (R300_INPUT_ROUTE_SELECT_Z<<R300_INPUT_ROUTE_Z_SHIFT) \
| (R300_INPUT_ROUTE_SELECT_W<<R300_INPUT_ROUTE_W_SHIFT))
#define ALL_DEFAULT ((R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_X_SHIFT) \
| (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Y_SHIFT) \
| (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Z_SHIFT) \
| (R300_INPUT_ROUTE_SELECT_ONE<<R300_INPUT_ROUTE_W_SHIFT))
R300_STATECHANGE(r300, vir[1]);
for(i=0; i < nr; i++)
if(r300->state.aos[i].aos_format == 2){
assert(r300->state.aos[i].aos_size == 5);
r300->state.aos[i].aos_size=/*3*/4; /* XXX */
}
for(i=0;i+1<nr;i+=2){
/* do i first.. */
mask=(1<<(r300->state.aos[i].aos_size*3))-1;
dw=(ALL_COMPONENTS & mask)
| (ALL_DEFAULT & ~mask)
| R300_INPUT_ROUTE_ENABLE;
/* i+1 */
mask=(1<<(r300->state.aos[i+1].aos_size*3))-1;
dw|=(
(ALL_COMPONENTS & mask)
| (ALL_DEFAULT & ~mask)
| R300_INPUT_ROUTE_ENABLE
)<<16;
//fprintf(stderr, "vir1 dw=%08x\n", dw);
r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
}
if(nr & 1){
mask=(1<<(r300->state.aos[nr-1].aos_size*3))-1;
dw=(ALL_COMPONENTS & mask)
| (ALL_DEFAULT & ~mask)
| R300_INPUT_ROUTE_ENABLE;
r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(nr>>1)]=dw;
//fprintf(stderr, "vir1 dw=%08x\n", dw);
}
/* Set the rest of INPUT_ROUTE_1 to 0 */
//for(i=((count+1)>>1); i<8; i++)r300->hw.vir[1].cmd[R300_VIR_CNTL_0+i]=0x0;
((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->packet0.count = (nr+1)>>1;
/* Set up input_cntl */
/* I don't think this is needed for vertex buffers, but it doesn't hurt anything */
R300_STATECHANGE(r300, vic);
r300->hw.vic.cmd[R300_VIC_CNTL_0]=0x5555; /* Hard coded value, no idea what it means */
r300->hw.vic.cmd[R300_VIC_CNTL_1]=vic_1;
for(i=0; i < nr; i++)
if(r300->state.aos[i].aos_format == 2){
assert(r300->state.aos[i].aos_size == /*3*/4); /* XXX */
r300->state.aos[i].aos_size=1;
}
#if 0
r300->hw.vic.cmd[R300_VIC_CNTL_1]=0;
if(r300->state.render_inputs & _TNL_BIT_POS)
r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_POS;
if(r300->state.render_inputs & _TNL_BIT_NORMAL)
r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_NORMAL;
if(r300->state.render_inputs & _TNL_BIT_COLOR0)
r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_COLOR;
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
if(r300->state.render_inputs & (_TNL_BIT_TEX0<<i))
r300->hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<<i);
#endif
/* Stage 3: VAP output */
R300_STATECHANGE(r300, vof);
r300->hw.vof.cmd[R300_VOF_CNTL_0]=0;
r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
if (hw_tcl_on){
GLuint OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->OutputsWritten;
if(OutputsWritten & (1<<VERT_RESULT_HPOS))
r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
if(OutputsWritten & (1<<VERT_RESULT_COL0))
r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
/*if(OutputsWritten & (1<<VERT_RESULT_COL1))
r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
if(OutputsWritten & (1<<VERT_RESULT_BFC0))
r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT;
if(OutputsWritten & (1<<VERT_RESULT_BFC1))
r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;*/
//if(OutputsWritten & (1<<VERT_RESULT_FOGC))
if(OutputsWritten & (1<<VERT_RESULT_PSIZ))
r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
if(OutputsWritten & (1<<(VERT_RESULT_TEX0+i)))
r300->hw.vof.cmd[R300_VOF_CNTL_1] |= (4<<(3*i));
} else {
if(inputs & _TNL_BIT_POS)
r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
if(inputs & _TNL_BIT_COLOR0)
r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
if(inputs & _TNL_BIT_COLOR1)
r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
if(inputs & (_TNL_BIT_TEX0<<i))
r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
}
rmesa->state.aos_count = nr;
}
#endif
#ifdef USER_BUFFERS
void r300UseArrays(GLcontext * ctx)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
int i;
if(rmesa->state.elt_dma.buf)
radeon_mm_use(rmesa, rmesa->state.elt_dma.buf->id);
for (i=0; i < rmesa->state.aos_count;i++) {
if (rmesa->state.aos[i].buf)
radeon_mm_use(rmesa, rmesa->state.aos[i].buf->id);
}
#ifdef HW_VBOS
#define USE_VBO(a) if (ctx->Array.a.BufferObj->Name && ctx->Array.a.Enabled) \
radeon_mm_use(rmesa, ((struct r300_buffer_object *)ctx->Array.a.BufferObj)->id)
if (ctx->Array.ElementArrayBufferObj->Name && ctx->Array.ElementArrayBufferObj->OnCard)
radeon_mm_use(rmesa, ((struct r300_buffer_object *)ctx->Array.ElementArrayBufferObj)->id);
USE_VBO(Vertex);
USE_VBO(Normal);
USE_VBO(Color);
USE_VBO(SecondaryColor);
USE_VBO(FogCoord);
for (i=0; i < MAX_TEXTURE_COORD_UNITS; i++)
USE_VBO(TexCoord[i]);
#endif
}
#endif
void r300ReleaseArrays(GLcontext * ctx)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);

View file

@ -40,8 +40,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_context.h"
extern void r300EmitElts(GLcontext * ctx, GLuint *elts, unsigned long n_elts);
extern void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts, int elt_size);
extern void r300EmitArrays(GLcontext * ctx, GLboolean immd);
#ifdef RADEON_VTXFMT_A
extern void r300EmitArraysVtx(GLcontext * ctx, GLboolean immd);
#endif
#ifdef USER_BUFFERS
void r300UseArrays(GLcontext * ctx);
#endif
extern void r300ReleaseArrays(GLcontext * ctx);
#endif

View file

@ -728,6 +728,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */
/* 0x16 - some 16 bit green format.. ?? */
# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */
# define R300_TX_FORMAT_CUBIC_MAP (1 << 26)
/* gap */
/* Floating point formats */

View file

@ -417,27 +417,81 @@ static GLboolean r300_run_immediate_render(GLcontext *ctx,
/* vertex buffer implementation */
static void inline fire_EB(PREFIX unsigned long addr, int vertex_count, int type)
static void inline fire_EB(PREFIX unsigned long addr, int vertex_count, int type, int elt_size)
{
LOCAL_VARS
unsigned long addr_a;
unsigned long t_addr;
unsigned long magic_1, magic_2;
GLcontext *ctx;
ctx = rmesa->radeon.glCtx;
if(addr & 1){
assert(elt_size == 2 || elt_size == 4);
if(addr & (elt_size-1)){
WARN_ONCE("Badly aligned buffer\n");
return ;
}
addr_a = 0; /*addr & 0x1c;*/
#ifdef OPTIMIZE_ELTS
addr_a = 0;
magic_1 = (addr % 32) / 4;
t_addr = addr & (~0x1d);
magic_2 = (vertex_count + 1 + (t_addr & 0x2)) / 2 + magic_1;
check_space(6);
start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
/* TODO: R300_VAP_VF_CNTL__INDEX_SIZE_32bit . */
e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type);
if(elt_size == 4){
e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
} else {
e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type);
}
start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2);
e32(R300_EB_UNK1 | (addr_a << 16) | R300_EB_UNK2);
if(elt_size == 4){
e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
e32(addr /*& 0xffffffe3*/);
} else {
e32(R300_EB_UNK1 | (magic_1 << 16) | R300_EB_UNK2);
e32(t_addr);
}
if(elt_size == 4){
e32(vertex_count /*+ addr_a/4*/); /* Total number of dwords needed? */
} else {
e32(magic_2); /* Total number of dwords needed? */
}
//cp_delay(PASS_PREFIX 1);
#if 0
fprintf(stderr, "magic_1 %d\n", magic_1);
fprintf(stderr, "t_addr %x\n", t_addr);
fprintf(stderr, "magic_2 %d\n", magic_2);
exit(1);
#endif
#else
addr_a = 0;
check_space(6);
start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
if(elt_size == 4){
e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
} else {
e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type);
}
start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2);
e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
e32(addr /*& 0xffffffe3*/);
e32((vertex_count+1)/2 /*+ addr_a/4*/); /* Total number of dwords needed? */
if(elt_size == 4){
e32(vertex_count /*+ addr_a/4*/); /* Total number of dwords needed? */
} else {
e32((vertex_count+1)/2 /*+ addr_a/4*/); /* Total number of dwords needed? */
}
//cp_delay(PASS_PREFIX 1);
#endif
}
static void r300_render_vb_primitive(r300ContextPtr rmesa,
@ -476,8 +530,8 @@ static void r300_render_vb_primitive(r300ContextPtr rmesa,
WARN_ONCE("Too many elts\n");
return;
}
r300EmitElts(ctx, rmesa->state.Elts+start, num_verts);
fire_EB(PASS_PREFIX GET_START(&(rmesa->state.elt_dma)), num_verts, type);
r300EmitElts(ctx, rmesa->state.Elts+start, num_verts, 4);
fire_EB(PASS_PREFIX GET_START(&(rmesa->state.elt_dma)), num_verts, type, 4);
#endif
}else{
r300EmitAOS(rmesa, rmesa->state.aos_count, start);
@ -500,7 +554,7 @@ static GLboolean r300_run_vb_render(GLcontext *ctx,
r300ReleaseArrays(ctx);
r300EmitArrays(ctx, GL_FALSE);
// LOCK_HARDWARE(&(rmesa->radeon));
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
@ -526,6 +580,9 @@ static GLboolean r300_run_vb_render(GLcontext *ctx,
reg_start(0x4f18,0);
e32(0x00000003);
#ifdef USER_BUFFERS
r300UseArrays(ctx);
#endif
// end_3d(PASS_PREFIX_VOID);
/* Flush state - we are done drawing.. */
@ -536,6 +593,186 @@ static GLboolean r300_run_vb_render(GLcontext *ctx,
return GL_FALSE;
}
#ifdef RADEON_VTXFMT_A
static void r300_render_vb_primitive_vtxfmt_a(r300ContextPtr rmesa,
GLcontext *ctx,
int start,
int end,
int prim)
{
int type, num_verts;
radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
LOCAL_VARS
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
int i;
type=r300_get_primitive_type(rmesa, ctx, prim);
num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
if(type<0 || num_verts <= 0)return;
if(rmesa->state.VB.Elts){
r300EmitAOS(rmesa, rmesa->state.aos_count, /*0*/start);
#if 0
start_index32_packet(num_verts, type);
for(i=0; i < num_verts; i++)
e32(((unsigned long *)rmesa->state.VB.Elts)[i]/*rmesa->state.Elts[start+i]*/); /* start ? */
#else
WARN_ONCE("Rendering with elt buffers\n");
if(num_verts == 1){
//start_index32_packet(num_verts, type);
//e32(rmesa->state.Elts[start]);
return;
}
if(num_verts > 65535){ /* not implemented yet */
WARN_ONCE("Too many elts\n");
return;
}
r300EmitElts(ctx, rmesa->state.VB.Elts, num_verts, rmesa->state.VB.elt_size);
fire_EB(PASS_PREFIX rmesa->state.elt_dma.aos_offset, num_verts, type, rmesa->state.VB.elt_size);
#endif
}else{
r300EmitAOS(rmesa, rmesa->state.aos_count, start);
fire_AOS(PASS_PREFIX num_verts, type);
}
}
void dump_array(struct r300_dma_region *rvb, int count)
{
int *out = (int *)(rvb->address + rvb->start);
int i, ci;
for (i=0; i < count; i++) {
fprintf(stderr, "{");
if (rvb->aos_format == AOS_FORMAT_FLOAT)
for (ci=0; ci < rvb->aos_size; ci++)
fprintf(stderr, "%f ", ((float *)out)[ci]);
else
for (ci=0; ci < rvb->aos_size; ci++)
fprintf(stderr, "%d ", ((unsigned char *)out)[ci]);
fprintf(stderr, "}");
out += rvb->aos_stride;
}
fprintf(stderr, "\n");
}
void dump_dt(struct dt *dt, int count)
{
int *out = dt->data;
int i, ci;
fprintf(stderr, "base at %p ", out);
for (i=0; i < count; i++){
fprintf(stderr, "{");
if (dt->type == GL_FLOAT)
for (ci=0; ci < dt->size; ci++)
fprintf(stderr, "%f ", ((float *)out)[ci]);
else
for (ci=0; ci < dt->size; ci++)
fprintf(stderr, "%d ", ((unsigned char *)out)[ci]);
fprintf(stderr, "}");
out = (char *)out + dt->stride;
}
fprintf(stderr, "\n");
}
/*static */GLboolean r300_run_vb_render_vtxfmt_a(GLcontext *ctx,
struct tnl_pipeline_stage *stage)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
//TNLcontext *tnl = TNL_CONTEXT(ctx);
struct radeon_vertex_buffer *VB = &rmesa->state.VB; //&tnl->vb;
int i, j;
LOCAL_VARS
if (RADEON_DEBUG & DEBUG_PRIMS)
fprintf(stderr, "%s\n", __FUNCTION__);
if (rmesa->state.VB.LockCount == 0) {
r300ReleaseArrays(ctx);
r300EmitArraysVtx(ctx, GL_FALSE);
} else {
/* TODO: Figure out why do we need these. */
R300_STATECHANGE(rmesa, vir[0]);
R300_STATECHANGE(rmesa, vir[1]);
R300_STATECHANGE(rmesa, vic);
R300_STATECHANGE(rmesa, vof);
#if 0
fprintf(stderr, "dt:\n");
for(i=0; i < VERT_ATTRIB_MAX; i++){
fprintf(stderr, "dt %d:", i);
dump_dt(&rmesa->state.VB.AttribPtr[i], VB->Count);
}
fprintf(stderr, "before:\n");
for(i=0; i < rmesa->state.aos_count; i++){
fprintf(stderr, "aos %d:", i);
dump_array(&rmesa->state.aos[i], VB->Count);
}
#endif
#if 0
r300ReleaseArrays(ctx);
r300EmitArraysVtx(ctx, GL_FALSE);
fprintf(stderr, "after:\n");
for(i=0; i < rmesa->state.aos_count; i++){
fprintf(stderr, "aos %d:", i);
dump_array(&rmesa->state.aos[i], VB->Count);
}
#endif
}
// LOCK_HARDWARE(&(rmesa->radeon));
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
e32(0x0000000a);
reg_start(0x4f18,0);
e32(0x00000003);
#if 0
reg_start(R300_VAP_PVS_WAITIDLE,0);
e32(0x00000000);
#endif
r300EmitState(rmesa);
for(i=0; i < VB->PrimitiveCount; i++){
GLuint prim = VB->Primitive[i].mode;
GLuint start = VB->Primitive[i].start;
GLuint length = VB->Primitive[i].count;
r300_render_vb_primitive_vtxfmt_a(rmesa, ctx, start, start + length, prim);
}
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
e32(0x0000000a/*0x2*/);
reg_start(0x4f18,0);
e32(0x00000003/*0x1*/);
#ifdef USER_BUFFERS
r300UseArrays(ctx);
#endif
// end_3d(PASS_PREFIX_VOID);
/* Flush state - we are done drawing.. */
// r300FlushCmdBufLocked(rmesa, __FUNCTION__);
// radeonWaitForIdleLocked(&(rmesa->radeon));
// UNLOCK_HARDWARE(&(rmesa->radeon));
return GL_FALSE;
}
#endif
/**
* Called by the pipeline manager to render a batch of primitives.
* We can return true to pass on to the next stage (i.e. software
@ -678,26 +915,9 @@ static GLboolean r300_run_tcl_render(GLcontext *ctx,
fprintf(stderr, "%s\n", __FUNCTION__);
if(hw_tcl_on == GL_FALSE)
return GL_TRUE;
if(ctx->VertexProgram._Enabled == GL_FALSE){
_tnl_UpdateFixedFunctionProgram(ctx);
}
vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
if(vp->translated == GL_FALSE)
translate_vertex_shader(vp);
if(vp->translated == GL_FALSE){
fprintf(stderr, "Failing back to sw-tcl\n");
debug_vp(ctx, &vp->mesa_program);
hw_tcl_on=future_hw_tcl_on=0;
r300ResetHwState(rmesa);
return GL_TRUE;
}
r300_setup_textures(ctx);
r300_setup_rs_unit(ctx);
r300SetupVertexShader(rmesa);
r300SetupPixelShader(rmesa);
r300UpdateShaderStates(rmesa);
return r300_run_vb_render(ctx, stage);
}

View file

@ -1553,6 +1553,36 @@ void r300SetupVertexProgram(r300ContextPtr rmesa)
#endif
}
extern int future_hw_tcl_on;
void r300UpdateShaderStates(r300ContextPtr rmesa)
{
GLcontext *ctx;
struct r300_vertex_program *vp;
ctx = rmesa->radeon.glCtx;
if(ctx->VertexProgram._Enabled == GL_FALSE){
_tnl_UpdateFixedFunctionProgram(ctx);
}
vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
if(vp->translated == GL_FALSE)
translate_vertex_shader(vp);
if(vp->translated == GL_FALSE){
fprintf(stderr, "Failing back to sw-tcl\n");
debug_vp(ctx, &vp->mesa_program);
hw_tcl_on=future_hw_tcl_on=0;
r300ResetHwState(rmesa);
return ;
}
r300_setup_textures(ctx);
r300_setup_rs_unit(ctx);
r300SetupVertexShader(rmesa);
r300SetupPixelShader(rmesa);
}
/* This is probably wrong for some values, I need to test this
* some more. Range checking would be a good idea also..
*

View file

@ -43,6 +43,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
r300->hw.is_dirty = GL_TRUE; \
} while(0)
#define R300_PRINT_STATE(r300, atom) \
r300_print_state_atom(r300, &r300->hw.atom)
/* Fire the buffered vertices no matter what.
TODO: This has not been implemented yet
*/
@ -65,5 +68,6 @@ extern void r300SetupPixelShader(r300ContextPtr rmesa);
extern void r300_setup_textures(GLcontext *ctx);
extern void r300_setup_rs_unit(GLcontext *ctx);
extern void r300UpdateShaderStates(r300ContextPtr rmesa);
#endif /* __R300_STATE_H__ */

View file

@ -341,9 +341,8 @@ static void r300SetTexImages(r300ContextPtr rmesa,
t->format_x |= R200_TEXCOORD_VOLUME;
} else if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
ASSERT(log2Width == log2Height);
t->format |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) |
(log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT)
| (R200_TXFORMAT_CUBIC_MAP_ENABLE));
t->format |= R300_TX_FORMAT_CUBIC_MAP;
t->format_x |= R200_TEXCOORD_CUBIC_ENV;
t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
(log2Height << R200_FACE_HEIGHT_1_SHIFT) |

View file

@ -597,6 +597,7 @@ void translate_vertex_shader(struct r300_vertex_program *vp)
Ops that need temp vars should probably be given reg indexes starting at the end of tmp area. */
switch(vpi->Opcode){
case VP_OPCODE_MOV://ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}
#if 1
o_inst->op=MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, t_dst_index(vp, &vpi->DstReg),
t_dst_mask(vpi->DstReg.WriteMask), t_dst_class(vpi->DstReg.File));
o_inst->src1=t_src(vp, &src[0]);
@ -606,6 +607,23 @@ void translate_vertex_shader(struct r300_vertex_program *vp)
t_src_class(src[0].File), VSF_FLAG_NONE);
o_inst->src3=0;
#else
hw_op=(src[0].File == PROGRAM_TEMPORARY) ? R300_VPI_OUT_OP_MAD_2 : R300_VPI_OUT_OP_MAD;
o_inst->op=MAKE_VSF_OP(hw_op, t_dst_index(vp, &vpi->DstReg),
t_dst_mask(vpi->DstReg.WriteMask), t_dst_class(vpi->DstReg.File));
o_inst->src1=t_src(vp, &src[0]);
o_inst->src2=MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
SWIZZLE_ONE, SWIZZLE_ONE,
SWIZZLE_ONE, SWIZZLE_ONE,
t_src_class(src[0].File), VSF_FLAG_NONE);
o_inst->src3=MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
SWIZZLE_ZERO, SWIZZLE_ZERO,
SWIZZLE_ZERO, SWIZZLE_ZERO,
t_src_class(src[0].File), VSF_FLAG_NONE);
#endif
goto next;

View file

@ -0,0 +1,339 @@
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/sem.h>
#include "r300_context.h"
#include "r300_cmdbuf.h"
#include "radeon_mm.h"
#ifdef USER_BUFFERS
void radeon_mm_reset(r300ContextPtr rmesa)
{
drm_r300_cmd_header_t *cmd;
int ret;
memset(rmesa->rmm, 0, sizeof(struct radeon_memory_manager));
rmesa->rmm->u_size = 1024; //2048;
//rmesa->radeon.radeonScreen->scratch[2] = rmesa->rmm->vb_age;
#if 0 /* FIXME */
cmd = r300AllocCmdBuf(rmesa, 4, __FUNCTION__);
cmd[0].scratch.cmd_type = R300_CMD_SCRATCH;
cmd[0].scratch.reg = 2;
cmd[0].scratch.n_bufs = 1;
cmd[0].scratch.flags = 0;
cmd[1].u = (unsigned long)(&rmesa->rmm->vb_age);
cmd[2].u = (unsigned long)(&rmesa->rmm->u_list[0].age);
cmd[3].u = /*id*/0;
/* Protect from DRM. */
LOCK_HARDWARE(&rmesa->radeon);
rmesa->rmm->u_list[0].h_pending ++;
ret = r300FlushCmdBufLocked(rmesa, __FUNCTION__);
UNLOCK_HARDWARE(&rmesa->radeon);
if (ret) {
WARN_ONCE("r300FlushCmdBufLocked\n");
exit(1);
}
#endif
}
void radeon_mm_init(r300ContextPtr rmesa)
{
rmesa->mm_ipc_key = 0xdeadbeed; //ftok("/tmp/.r300.mm_lock", "x");
if(rmesa->mm_ipc_key == -1){
perror("ftok");
exit(1);
}
rmesa->mm_shm_id = shmget(rmesa->mm_ipc_key, sizeof(struct radeon_memory_manager), 0644);
if (rmesa->mm_shm_id == -1) {
rmesa->mm_shm_id = shmget(rmesa->mm_ipc_key, sizeof(struct radeon_memory_manager), 0644 | IPC_CREAT);
rmesa->rmm = shmat(rmesa->mm_shm_id, (void *)0, 0);
if (rmesa->rmm == (char *)(-1)) {
perror("shmat");
exit(1);
}
radeon_mm_reset(rmesa);
rmesa->mm_sem_id = semget(rmesa->mm_ipc_key, 2, 0666 | IPC_CREAT);
if (rmesa->mm_sem_id == -1) {
perror("semget");
exit(1);
}
return ;
}
rmesa->rmm = shmat(rmesa->mm_shm_id, (void *)0, 0);
if (rmesa->rmm == (char *)(-1)) {
perror("shmat");
exit(1);
}
/* FIXME */
radeon_mm_reset(rmesa);
rmesa->mm_sem_id = semget(rmesa->mm_ipc_key, 2, 0666);
if (rmesa->mm_sem_id == -1) {
perror("semget");
exit(1);
}
}
static void radeon_mm_lock(r300ContextPtr rmesa, int sem)
{
struct sembuf sb = { 0, 1, 0 };
sb.sem_num = sem;
if (semop(rmesa->mm_sem_id, &sb, 1) == -1) {
perror("semop");
exit(1);
}
}
static void radeon_mm_unlock(r300ContextPtr rmesa, int sem)
{
struct sembuf sb = { 0, -1, 0 };
sb.sem_num = sem;
if (semop(rmesa->mm_sem_id, &sb, 1) == -1) {
perror("semop");
exit(1);
}
}
void *radeon_mm_ptr(r300ContextPtr rmesa, int id)
{
return rmesa->rmm->u_list[id].ptr;
}
//#define MM_DEBUG
int radeon_mm_alloc(r300ContextPtr rmesa, int alignment, int size)
{
drm_radeon_mem_alloc_t alloc;
int offset, ret;
int i, end, free=-1;
int done_age;
drm_radeon_mem_free_t memfree;
int tries=0, tries2=0;
memfree.region = RADEON_MEM_REGION_GART;
radeon_mm_lock(rmesa, RADEON_MM_UL);
again:
done_age = rmesa->radeon.radeonScreen->scratch[2];
i = 1; //rmesa->rmm->u_head + 1;
//i &= rmesa->rmm->u_size - 1;
end = i + rmesa->rmm->u_size;
//end &= rmesa->rmm->u_size - 1;
for (; i != end; i ++/*, i &= rmesa->rmm->u_size-1*/) {
if (rmesa->rmm->u_list[i].ptr == NULL){
free = i;
continue;
}
if (rmesa->rmm->u_list[i].h_pending == 0 &&
rmesa->rmm->u_list[i].pending && rmesa->rmm->u_list[i].age <= done_age) {
memfree.region_offset = (char *)rmesa->rmm->u_list[i].ptr -
(char *)rmesa->radeon.radeonScreen->gartTextures.map;
ret = drmCommandWrite(rmesa->radeon.radeonScreen->driScreen->fd,
DRM_RADEON_FREE, &memfree, sizeof(memfree));
if (ret) {
//fprintf(stderr, "Failed to free at %p\n", rmesa->rmm->u_list[i].ptr);
//fprintf(stderr, "ret = %s\n", strerror(-ret));
//radeon_mm_unlock(rmesa, RADEON_MM_UL);
//exit(1);
} else {
#ifdef MM_DEBUG
fprintf(stderr, "really freed %d at age %x\n", i, rmesa->radeon.radeonScreen->scratch[2]);
#endif
rmesa->rmm->u_list[i].pending = 0;
rmesa->rmm->u_list[i].ptr = NULL;
free = i;
}
}
}
done:
rmesa->rmm->u_head = i;
if (free == -1) {
//usleep(100);
r300FlushCmdBuf(rmesa, __FUNCTION__);
tries++;
if(tries>100){
WARN_ONCE("Ran out of slots!\n");
exit(1);
}
goto again;
}
alloc.region = RADEON_MEM_REGION_GART;
alloc.alignment = alignment;
alloc.size = size;
alloc.region_offset = &offset;
ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_ALLOC, &alloc, sizeof(alloc));
if (ret) {
r300FlushCmdBuf(rmesa, __FUNCTION__);
//usleep(100);
tries2++;
tries = 0;
if(tries2>100){
WARN_ONCE("Ran out of GART memory!\n");
exit(1);
}
goto again;
}
i = free;
rmesa->rmm->u_list[i].ptr = ((GLubyte *)rmesa->radeon.radeonScreen->gartTextures.map) + offset;
rmesa->rmm->u_list[i].size = size;
rmesa->rmm->u_list[i].age = 0;
#ifdef MM_DEBUG
fprintf(stderr, "allocated %d at age %x\n", i, rmesa->radeon.radeonScreen->scratch[2]);
#endif
radeon_mm_unlock(rmesa, RADEON_MM_UL);
return i;
}
void radeon_mm_use(r300ContextPtr rmesa, int id)
{
#ifdef MM_DEBUG
fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, rmesa->radeon.radeonScreen->scratch[2]);
#endif
drm_r300_cmd_header_t *cmd;
if(id == 0)
return;
radeon_mm_lock(rmesa, RADEON_MM_UL);
cmd = r300AllocCmdBuf(rmesa, 4, __FUNCTION__);
cmd[0].scratch.cmd_type = R300_CMD_SCRATCH;
cmd[0].scratch.reg = 2;
cmd[0].scratch.n_bufs = 1;
cmd[0].scratch.flags = 0;
cmd[1].u = (unsigned long)(&rmesa->rmm->vb_age);
cmd[2].u = (unsigned long)(&rmesa->rmm->u_list[id].age);
cmd[3].u = /*id*/0;
LOCK_HARDWARE(&rmesa->radeon); /* Protect from DRM. */
rmesa->rmm->u_list[id].h_pending ++;
UNLOCK_HARDWARE(&rmesa->radeon);
radeon_mm_unlock(rmesa, RADEON_MM_UL);
}
void *radeon_mm_map(r300ContextPtr rmesa, int id, int access)
{
#ifdef MM_DEBUG
fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, rmesa->radeon.radeonScreen->scratch[2]);
#endif
void *ptr;
int tries = 0;
if (access == RADEON_MM_R) {
radeon_mm_lock(rmesa, RADEON_MM_UL);
if(rmesa->rmm->u_list[id].mapped == 1)
WARN_ONCE("buffer %d already mapped\n", id);
rmesa->rmm->u_list[id].mapped = 1;
ptr = radeon_mm_ptr(rmesa, id);
radeon_mm_unlock(rmesa, RADEON_MM_UL);
return ptr;
}
radeon_mm_lock(rmesa, RADEON_MM_UL);
if (rmesa->rmm->u_list[id].h_pending)
r300FlushCmdBuf(rmesa, __FUNCTION__);
if (rmesa->rmm->u_list[id].h_pending) {
radeon_mm_unlock(rmesa, RADEON_MM_UL);
return NULL;
}
while(rmesa->rmm->u_list[id].age > rmesa->radeon.radeonScreen->scratch[2] && tries++ < 1000)
usleep(10);
if (tries >= 1000) {
fprintf(stderr, "Idling failed (%x vs %x)\n",
rmesa->rmm->u_list[id].age, rmesa->radeon.radeonScreen->scratch[2]);
radeon_mm_unlock(rmesa, RADEON_MM_UL);
return NULL;
}
if(rmesa->rmm->u_list[id].mapped == 1)
WARN_ONCE("buffer %d already mapped\n", id);
rmesa->rmm->u_list[id].mapped = 1;
ptr = radeon_mm_ptr(rmesa, id);
radeon_mm_unlock(rmesa, RADEON_MM_UL);
return ptr;
}
void radeon_mm_unmap(r300ContextPtr rmesa, int id)
{
#ifdef MM_DEBUG
fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, rmesa->radeon.radeonScreen->scratch[2]);
#endif
radeon_mm_lock(rmesa, RADEON_MM_UL);
if(rmesa->rmm->u_list[id].mapped == 0)
WARN_ONCE("buffer %d not mapped\n", id);
rmesa->rmm->u_list[id].mapped = 0;
radeon_mm_unlock(rmesa, RADEON_MM_UL);
}
void radeon_mm_free(r300ContextPtr rmesa, int id)
{
#ifdef MM_DEBUG
fprintf(stderr, "%s: %d at age %x\n", __FUNCTION__, id, rmesa->radeon.radeonScreen->scratch[2]);
#endif
if(id == 0)
return;
radeon_mm_lock(rmesa, RADEON_MM_UL);
if(rmesa->rmm->u_list[id].ptr == NULL){
radeon_mm_unlock(rmesa, RADEON_MM_UL);
WARN_ONCE("Not allocated!\n");
return ;
}
if(rmesa->rmm->u_list[id].pending){
radeon_mm_unlock(rmesa, RADEON_MM_UL);
WARN_ONCE("%p already pended!\n", rmesa->rmm->u_list[id].ptr);
return ;
}
rmesa->rmm->u_list[id].pending = 1;
radeon_mm_unlock(rmesa, RADEON_MM_UL);
}
#endif

View file

@ -0,0 +1,35 @@
#ifndef __RADEON_MM_H__
#define __RADEON_MM_H__
//#define RADEON_MM_PDL 0
#define RADEON_MM_UL 1
#define RADEON_MM_R 1
#define RADEON_MM_W 2
#define RADEON_MM_RW (RADEON_MM_R | RADEON_MM_W)
struct radeon_memory_manager {
uint32_t vb_age;
/*uint32_t ages[1024];*/
struct {
void *ptr;
uint32_t size;
uint32_t age;
uint32_t h_pending;
int pending;
int mapped;
} u_list[/*4096*/2048];
int u_head, u_tail, u_size;
};
extern void radeon_mm_init(r300ContextPtr rmesa);
extern void *radeon_mm_ptr(r300ContextPtr rmesa, int id);
extern int radeon_mm_alloc(r300ContextPtr rmesa, int alignment, int size);
extern void radeon_mm_use(r300ContextPtr rmesa, int id);
extern void *radeon_mm_map(r300ContextPtr rmesa, int id, int access);
extern void radeon_mm_unmap(r300ContextPtr rmesa, int id);
extern void radeon_mm_free(r300ContextPtr rmesa, int id);
#endif

View file

@ -0,0 +1,610 @@
#include "context.h"
#include "r300_context.h"
#include "r300_cmdbuf.h"
#include "radeon_mm.h"
#ifdef RADEON_VTXFMT_A
#define CONV(a, b) rmesa->state.VB.AttribPtr[(a)].size = ctx->Array.b.Size, \
rmesa->state.VB.AttribPtr[(a)].data = ctx->Array.b.BufferObj->Name ? \
ADD_POINTERS(ctx->Array.b.Ptr, ctx->Array.b.BufferObj->Data) : ctx->Array.b.Ptr, \
rmesa->state.VB.AttribPtr[(a)].stride = ctx->Array.b.StrideB, \
rmesa->state.VB.AttribPtr[(a)].type = ctx->Array.b.Type
static int setup_arrays(r300ContextPtr rmesa, GLint start)
{
int i;
struct dt def = { 4, GL_FLOAT, 0, NULL };
GLcontext *ctx;
GLuint enabled = 0;
ctx = rmesa->radeon.glCtx;
memset(rmesa->state.VB.AttribPtr, 0, VERT_ATTRIB_MAX*sizeof(struct dt));
CONV(VERT_ATTRIB_POS, Vertex);
if (ctx->Array.Vertex.Enabled)
enabled |= 1 << VERT_ATTRIB_POS;
CONV(VERT_ATTRIB_NORMAL, Normal);
if (ctx->Array.Normal.Enabled)
enabled |= 1 << VERT_ATTRIB_NORMAL;
CONV(VERT_ATTRIB_COLOR0, Color);
if (ctx->Array.Color.Enabled)
enabled |= 1 << VERT_ATTRIB_COLOR0;
CONV(VERT_ATTRIB_COLOR1, SecondaryColor);
if (ctx->Array.SecondaryColor.Enabled)
enabled |= 1 << VERT_ATTRIB_COLOR1;
CONV(VERT_ATTRIB_FOG, FogCoord);
if (ctx->Array.FogCoord.Enabled)
enabled |= 1 << VERT_ATTRIB_FOG;
for (i=0; i < MAX_TEXTURE_COORD_UNITS; i++) {
CONV(VERT_ATTRIB_TEX0 + i, TexCoord[i]);
if(ctx->Array.TexCoord[i].Enabled) {
enabled |= 1 << (VERT_ATTRIB_TEX0+i);
}
}
for (i=0; i < VERT_ATTRIB_MAX; i++) {
if (enabled & (1 << i)) {
rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start;
} else {
def.data = ctx->Current.Attrib[i];
memcpy(&rmesa->state.VB.AttribPtr[i], &def, sizeof(struct dt));
}
/*if(rmesa->state.VB.AttribPtr[i].data == ctx->Current.Attrib[i])
fprintf(stderr, "%d is default coord\n", i);*/
}
for(i=0; i < VERT_ATTRIB_MAX; i++){
if(rmesa->state.VB.AttribPtr[i].type != GL_UNSIGNED_BYTE &&
rmesa->state.VB.AttribPtr[i].type != GL_FLOAT){
WARN_ONCE("Unsupported format %d at index %d\n", rmesa->state.VB.AttribPtr[i].type, i);
return -1;
}
if(rmesa->state.VB.AttribPtr[i].type == GL_UNSIGNED_BYTE &&
rmesa->state.VB.AttribPtr[i].size != 4){
WARN_ONCE("Unsupported component count for ub colors\n");
return -1;
}
/*fprintf(stderr, "%d: ", i);
switch(rmesa->state.VB.AttribPtr[i].type){
case GL_BYTE: fprintf(stderr, "byte "); break;
case GL_UNSIGNED_BYTE: fprintf(stderr, "u byte "); break;
case GL_SHORT: fprintf(stderr, "short "); break;
case GL_UNSIGNED_SHORT: fprintf(stderr, "u short "); break;
case GL_INT: fprintf(stderr, "int "); break;
case GL_UNSIGNED_INT: fprintf(stderr, "u int "); break;
case GL_FLOAT: fprintf(stderr, "float "); break;
case GL_2_BYTES: fprintf(stderr, "2 bytes "); break;
case GL_3_BYTES: fprintf(stderr, "3 bytes "); break;
case GL_4_BYTES: fprintf(stderr, "4 bytes "); break;
case GL_DOUBLE: fprintf(stderr, "double "); break;
default: fprintf(stderr, "unknown "); break;
}
fprintf(stderr, "Size %d ", rmesa->state.VB.AttribPtr[i].size);
fprintf(stderr, "Ptr %p ", rmesa->state.VB.AttribPtr[i].data);
fprintf(stderr, "Stride %d ", rmesa->state.VB.AttribPtr[i].stride);
fprintf(stderr, "\n");*/
}
return 0;
}
void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices )
{
GET_CURRENT_CONTEXT(ctx);
r300ContextPtr rmesa = R300_CONTEXT(ctx);
int elt_size;
int i;
unsigned int min = ~0, max = 0;
struct tnl_prim prim;
static void *ptr = NULL;
static struct r300_dma_region rvb;
if (ctx->Array.ElementArrayBufferObj->Name) {
/* use indices in the buffer object */
if (!ctx->Array.ElementArrayBufferObj->Data) {
_mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!");
return;
}
/* actual address is the sum of pointers */
indices = (const GLvoid *)
ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) indices);
}
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
return;
FLUSH_CURRENT( ctx, 0 );
/*
fprintf(stderr, "dt at %s:\n", __FUNCTION__);
for(i=0; i < VERT_ATTRIB_MAX; i++){
fprintf(stderr, "dt %d:", i);
dump_dt(&rmesa->state.VB.AttribPtr[i], rmesa->state.VB.Count);
}*/
r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
switch (type) {
case GL_UNSIGNED_BYTE:
elt_size = 2;
r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
rvb.aos_offset = GET_START(&rvb);
ptr = rvb.address + rvb.start;
for (i=0; i < count; i++) {
if(((unsigned char *)indices)[i] < min)
min = ((unsigned char *)indices)[i];
if(((unsigned char *)indices)[i] > max)
max = ((unsigned char *)indices)[i];
}
for (i=0; i < count; i++)
((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - min;
break;
case GL_UNSIGNED_SHORT:
elt_size = 2;
r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
rvb.aos_offset = GET_START(&rvb);
ptr = rvb.address + rvb.start;
for (i=0; i < count; i++) {
if(((unsigned short int *)indices)[i] < min)
min = ((unsigned short int *)indices)[i];
if(((unsigned short int *)indices)[i] > max)
max = ((unsigned short int *)indices)[i];
}
for (i=0; i < count; i++)
((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - min;
break;
case GL_UNSIGNED_INT:
elt_size = 4;
r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
rvb.aos_offset = GET_START(&rvb);
ptr = rvb.address + rvb.start;
for (i=0; i < count; i++) {
if(((unsigned int *)indices)[i] < min)
min = ((unsigned int *)indices)[i];
if(((unsigned int *)indices)[i] > max)
max = ((unsigned int *)indices)[i];
}
for (i=0; i < count; i++)
((unsigned int *)ptr)[i] = ((unsigned int *)indices)[i] - min;
break;
default:
fprintf(stderr, "Unknown elt type!\n");
return;
}
if (ctx->NewState)
_mesa_update_state( ctx );
r300UpdateShaderStates(rmesa);
if (rmesa->state.VB.LockCount) {
if (rmesa->state.VB.lock_uptodate == GL_FALSE) {
if (setup_arrays(rmesa, rmesa->state.VB.LockFirst))
return;
rmesa->state.VB.Count = rmesa->state.VB.LockCount;
r300ReleaseArrays(ctx);
r300EmitArraysVtx(ctx, GL_FALSE);
rmesa->state.VB.lock_uptodate = GL_TRUE;
}
if (min < rmesa->state.VB.LockFirst) {
WARN_ONCE("Out of range min %d vs %d!\n", min, rmesa->state.VB.LockFirst);
return;
}
if (max >= rmesa->state.VB.LockFirst + rmesa->state.VB.LockCount) {
WARN_ONCE("Out of range max %d vs %d!\n", max, rmesa->state.VB.LockFirst +
rmesa->state.VB.LockCount);
return;
}
} else {
if (setup_arrays(rmesa, min))
return;
rmesa->state.VB.Count = max - min + 1;
}
rmesa->state.VB.Primitive = &prim;
rmesa->state.VB.PrimitiveCount = 1;
prim.mode = mode | PRIM_BEGIN | PRIM_END;
if (rmesa->state.VB.LockCount)
prim.start = min - rmesa->state.VB.LockFirst;
else
prim.start = 0;
prim.count = count;
rmesa->state.VB.Elts = ptr;
rmesa->state.VB.elt_size = elt_size;
r300_run_vb_render_vtxfmt_a(ctx, NULL);
if(rvb.buf)
radeon_mm_use(rmesa, rvb.buf->id);
}
void radeonDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
GET_CURRENT_CONTEXT(ctx);
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct tnl_prim prim;
int elt_size;
int i;
static void *ptr = NULL;
static struct r300_dma_region rvb;
if (ctx->Array.ElementArrayBufferObj->Name) {
/* use indices in the buffer object */
if (!ctx->Array.ElementArrayBufferObj->Data) {
_mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!");
return;
}
/* actual address is the sum of pointers */
indices = (const GLvoid *)
ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) indices);
}
if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, type, indices ))
return;
FLUSH_CURRENT( ctx, 0 );
#ifdef OPTIMIZE_ELTS
start = 0;
#endif
r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__);
switch(type){
case GL_UNSIGNED_BYTE:
elt_size = 2;
r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
rvb.aos_offset = GET_START(&rvb);
ptr = rvb.address + rvb.start;
for(i=0; i < count; i++)
((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - start;
break;
case GL_UNSIGNED_SHORT:
elt_size = 2;
#ifdef OPTIMIZE_ELTS
if (start == 0 && ctx->Array.ElementArrayBufferObj->Name){
ptr = indices;
break;
}
#endif
r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
rvb.aos_offset = GET_START(&rvb);
ptr = rvb.address + rvb.start;
for(i=0; i < count; i++)
((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - start;
break;
case GL_UNSIGNED_INT:
elt_size = 4;
r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size);
rvb.aos_offset = GET_START(&rvb);
ptr = rvb.address + rvb.start;
for(i=0; i < count; i++)
((unsigned int *)ptr)[i] = ((unsigned int *)indices)[i] - start;
break;
default:
fprintf(stderr, "Unknown elt type!\n");
return;
}
if(setup_arrays(rmesa, start))
return;
if (ctx->NewState)
_mesa_update_state( ctx );
r300UpdateShaderStates(rmesa);
rmesa->state.VB.Count = (end - start) + 1;
rmesa->state.VB.Primitive = &prim;
rmesa->state.VB.PrimitiveCount = 1;
prim.mode = mode | PRIM_BEGIN | PRIM_END;
prim.start = 0;
prim.count = count;
rmesa->state.VB.Elts = ptr;
rmesa->state.VB.elt_size = elt_size;
rmesa->state.VB.elt_min = start;
rmesa->state.VB.elt_max = end;
r300_run_vb_render_vtxfmt_a(ctx, NULL);
if(rvb.buf)
radeon_mm_use(rmesa, rvb.buf->id);
}
void radeonDrawArrays( GLenum mode, GLint start, GLsizei count )
{
GET_CURRENT_CONTEXT(ctx);
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct tnl_prim prim;
if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
return;
FLUSH_CURRENT( ctx, 0 );
if (ctx->NewState)
_mesa_update_state( ctx );
if (rmesa->state.VB.LockCount == 0)
if (setup_arrays(rmesa, start))
return;
r300UpdateShaderStates(rmesa);
if (rmesa->state.VB.LockCount) {
start -= rmesa->state.VB.LockFirst;
if (start < 0) { /* Generate error */
WARN_ONCE("Out of range!\n");
return;
}
}
if (rmesa->state.VB.LockCount == 0)
rmesa->state.VB.Count = count;
rmesa->state.VB.Primitive = &prim;
rmesa->state.VB.PrimitiveCount = 1;
prim.mode = mode | PRIM_BEGIN | PRIM_END;
if (ctx->Array.LockCount == 0)
prim.start = 0;
else
prim.start = start;
prim.count = count;
rmesa->state.VB.Elts = NULL;
rmesa->state.VB.elt_size = 0;
rmesa->state.VB.elt_min = 0;
rmesa->state.VB.elt_max = 0;
r300_run_vb_render_vtxfmt_a(ctx, NULL);
}
void radeon_init_vtxfmt_a(r300ContextPtr rmesa)
{
GLcontext *ctx;
GLvertexformat *vfmt;
ctx = rmesa->radeon.glCtx;
vfmt = ctx->TnlModule.Current;
vfmt->DrawElements = radeonDrawElements;
vfmt->DrawArrays = radeonDrawArrays;
vfmt->DrawRangeElements = radeonDrawRangeElements;
}
#endif
#ifdef HW_VBOS
void radeonLockArraysEXT(GLcontext *ctx, GLint first, GLsizei count)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
int i;
/* Disabled as array changes arent properly handled yet. */
first = 0; count = 0;
if (first < 0 || count <= 0) {
rmesa->state.VB.LockFirst = 0;
rmesa->state.VB.LockCount = 0;
return ;
}
rmesa->state.VB.LockFirst = first;
rmesa->state.VB.LockCount = count;
rmesa->state.VB.lock_uptodate = GL_FALSE;
}
void radeonUnlockArraysEXT(GLcontext *ctx)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
rmesa->state.VB.LockFirst = 0;
rmesa->state.VB.LockCount = 0;
}
struct gl_buffer_object *
r300NewBufferObject(GLcontext *ctx, GLuint name, GLenum target )
{
struct r300_buffer_object *obj;
(void) ctx;
obj = MALLOC_STRUCT(r300_buffer_object);
_mesa_initialize_buffer_object(&obj->mesa_obj, name, target);
return &obj->mesa_obj;
}
void r300BufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
const GLvoid *data, GLenum usage, struct gl_buffer_object *obj)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)obj;
drm_radeon_mem_alloc_t alloc;
int offset, ret;
/* Free previous buffer */
if (obj->OnCard) {
radeon_mm_free(rmesa, r300_obj->id);
obj->OnCard = GL_FALSE;
} else {
if (obj->Data)
free(obj->Data);
}
#ifdef OPTIMIZE_ELTS
if (0) {
#else
if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
#endif
obj->Data = malloc(size);
if (data)
memcpy(obj->Data, data, size);
obj->OnCard = GL_FALSE;
} else {
r300_obj->id = radeon_mm_alloc(rmesa, 4, size);
obj->Data = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_W);
if (data)
memcpy(obj->Data, data, size);
radeon_mm_unmap(rmesa, r300_obj->id);
obj->OnCard = GL_TRUE;
}
obj->Size = size;
obj->Usage = usage;
}
void r300BufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
GLsizeiptrARB size, const GLvoid * data, struct gl_buffer_object * bufObj)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)bufObj;
(void) ctx; (void) target;
void *ptr;
if (bufObj->Data && ((GLuint) (size + offset) <= bufObj->Size)) {
if (bufObj->OnCard){
ptr = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_W);
_mesa_memcpy( (GLubyte *) ptr + offset, data, size );
radeon_mm_unmap(rmesa, r300_obj->id);
} else {
_mesa_memcpy( (GLubyte *) bufObj->Data + offset, data, size );
}
}
}
void *r300MapBuffer(GLcontext *ctx, GLenum target, GLenum access,
struct gl_buffer_object *bufObj)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)bufObj;
(void) ctx;
(void) target;
(void) access;
//ASSERT(!bufObj->OnCard);
/* Just return a direct pointer to the data */
if (bufObj->Pointer) {
/* already mapped! */
return NULL;
}
if (!bufObj->OnCard) {
bufObj->Pointer = bufObj->Data;
return bufObj->Pointer;
}
switch (access) {
case GL_READ_ONLY:
bufObj->Pointer = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_R);
break;
case GL_WRITE_ONLY:
bufObj->Pointer = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_W);
break;
case GL_READ_WRITE:
bufObj->Pointer = radeon_mm_map(rmesa, r300_obj->id, RADEON_MM_RW);
break;
default:
WARN_ONCE("Unknown access type\n");
bufObj->Pointer = NULL;
break;
}
return bufObj->Pointer;
}
GLboolean r300UnmapBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *bufObj)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)bufObj;
(void) ctx;
(void) target;
//ASSERT(!bufObj->OnCard);
/* XXX we might assert here that bufObj->Pointer is non-null */
if (!bufObj->OnCard) {
bufObj->Pointer = NULL;
return GL_TRUE;
}
radeon_mm_unmap(rmesa, r300_obj->id);
bufObj->Pointer = NULL;
return GL_TRUE;
}
void r300DeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_buffer_object *r300_obj = (struct r300_buffer_object *)obj;
if (obj->OnCard) {
radeon_mm_free(rmesa, r300_obj->id);
obj->Data = NULL;
}
_mesa_delete_buffer_object(ctx, obj);
}
void r300_init_vbo_funcs(struct dd_function_table *functions)
{
functions->NewBufferObject = r300NewBufferObject;
functions->BufferData = r300BufferData;
functions->BufferSubData = r300BufferSubData;
functions->MapBuffer = r300MapBuffer;
functions->UnmapBuffer = r300UnmapBuffer;
functions->DeleteBuffer = r300DeleteBuffer;
functions->LockArraysEXT = radeonLockArraysEXT;
functions->UnlockArraysEXT = radeonUnlockArraysEXT;
}
#endif