Major code restructuring:

* move proven code into the r300_state.c
  * update ClearBuffer to cope with more dynamic state
  * cleanup !
This commit is contained in:
Vladimir Dergachev 2005-01-04 18:59:47 +00:00
parent 85edffd5ff
commit 638faa92fc
8 changed files with 411 additions and 295 deletions

View file

@ -416,26 +416,26 @@ void r300InitCmdBuf(r300ContextPtr r300)
r300->hw.vps.cmd[R300_VPS_CMD_0] = cmdvpu(R300_PVS_UPLOAD_POINTSIZE, 1);
/* Textures */
ALLOC_STATE( tex.filter, always, mtu, "tex_filter", 0 );
r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_FILTER_0, mtu-1);
ALLOC_STATE( tex.filter, variable, mtu+1, "tex_filter", 0 );
r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_FILTER_0, 0);
ALLOC_STATE( tex.unknown1, always, mtu, "tex_unknown1", 0 );
r300->hw.tex.unknown1.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK1_0, mtu-1);
ALLOC_STATE( tex.unknown1, variable, mtu+1, "tex_unknown1", 0 );
r300->hw.tex.unknown1.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK1_0, 0);
ALLOC_STATE( tex.size, always, mtu, "tex_size", 0 );
r300->hw.tex.size.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_SIZE_0, mtu-1);
ALLOC_STATE( tex.size, variable, mtu+1, "tex_size", 0 );
r300->hw.tex.size.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_SIZE_0, 0);
ALLOC_STATE( tex.format, always, mtu, "tex_format", 0 );
r300->hw.tex.format.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_FORMAT_0, mtu-1);
ALLOC_STATE( tex.format, variable, mtu+1, "tex_format", 0 );
r300->hw.tex.format.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_FORMAT_0, 0);
ALLOC_STATE( tex.offset, always, mtu, "tex_offset", 0 );
r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_OFFSET_0, mtu-1);
ALLOC_STATE( tex.offset, variable, mtu+1, "tex_offset", 0 );
r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_OFFSET_0, 0);
ALLOC_STATE( tex.unknown4, always, mtu, "tex_unknown4", 0 );
r300->hw.tex.unknown4.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK4_0, mtu-1);
ALLOC_STATE( tex.unknown4, variable, mtu+1, "tex_unknown4", 0 );
r300->hw.tex.unknown4.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK4_0, 0);
ALLOC_STATE( tex.unknown5, always, mtu, "tex_unknown5", 0 );
r300->hw.tex.unknown5.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK5_0, mtu-1);
ALLOC_STATE( tex.unknown5, variable, mtu+1, "tex_unknown5", 0 );
r300->hw.tex.unknown5.cmd[R300_TEX_CMD_0] = cmducs(R300_TX_UNK5_0, 0);
/* Setup the atom linked list */
@ -574,7 +574,7 @@ void r300EmitBlit(r300ContextPtr rmesa,
assert(h < (1 << 16));
cmd =
(drm_radeon_cmd_header_t *) r200AllocCmdBuf(rmesa, 8 * sizeof(int),
(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 8 * sizeof(int),
__FUNCTION__);
cmd[0].header.cmd_type = RADEON_CMD_PACKET3;
@ -603,7 +603,7 @@ void r300EmitWait(r300ContextPtr rmesa, GLuint flags)
assert(!(flags & ~(RADEON_WAIT_2D | RADEON_WAIT_3D)));
cmd =
(drm_radeon_cmd_header_t *) r200AllocCmdBuf(rmesa,
(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
1 * sizeof(int),
__FUNCTION__);
cmd[0].i = 0;

View file

@ -98,5 +98,18 @@ static __inline__ uint32_t* r300AllocCmdBuf(r300ContextPtr r300,
return ptr;
}
extern void r300EmitBlit(r300ContextPtr rmesa,
GLuint color_fmt,
GLuint src_pitch,
GLuint src_offset,
GLuint dst_pitch,
GLuint dst_offset,
GLint srcx, GLint srcy,
GLint dstx, GLint dsty, GLuint w, GLuint h);
extern void r300EmitWait(r300ContextPtr rmesa, GLuint flags);
extern void r300EmitLOAD_VBPNTR(r300ContextPtr rmesa, int start);
extern void r300EmitVertexShader(r300ContextPtr rmesa);
extern void r300EmitPixelShader(r300ContextPtr rmesa);
#endif /* __R300_CMDBUF_H__ */

View file

@ -174,10 +174,11 @@ struct r300_texture_env_state {
GLenum envMode;
};
#define R300_MAX_TEXTURE_UNITS 6
#define R300_MAX_TEXTURE_UNITS 8
struct r300_texture_state {
struct r300_texture_env_state unit[R300_MAX_TEXTURE_UNITS];
int tc_count; /* number of incoming texture coordinates from VAP */
};
/**

View file

@ -81,6 +81,26 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
cboffset += r300->radeon.radeonScreen->fbLocation;
R300_STATECHANGE(r300, vir[0]);
((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
r300->hw.vir[0].cmd[1] = 0x21030003;
R300_STATECHANGE(r300, vir[1]);
((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = 1;
r300->hw.vir[1].cmd[1] = 0xF688F688;
R300_STATECHANGE(r300, vic);
r300->hw.vic.cmd[R300_VIR_CNTL_0] = 0x00000001;
r300->hw.vic.cmd[R300_VIR_CNTL_1] = 0x00000405;
R300_STATECHANGE(r300, vof);
r300->hw.vof.cmd[R300_VOF_CNTL_0] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
| R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0; /* no textures */
R300_STATECHANGE(r300, txe);
r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
R300_STATECHANGE(r300, vpt);
r300->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(1.0);
r300->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(dPriv->x);
@ -105,6 +125,11 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
for(i = 1; i <= 8; ++i)
r300->hw.ri.cmd[i] = R300_RS_INTERP_USED;
R300_STATECHANGE(r300, rc);
/* The second constant is needed to get glxgears display anything .. */
r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18;
r300->hw.rc.cmd[2] = 0;
R300_STATECHANGE(r300, rr);
((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
r300->hw.rr.cmd[1] = 0x00004000;

View file

@ -49,6 +49,14 @@ extern GLuint r300GartOffsetFromVirtual(r300ContextPtr rmesa,
const GLvoid * pointer);
extern void r300Flush(GLcontext * ctx);
extern void r300RefillCurrentDmaRegion(r300ContextPtr rmesa);
extern void r300ReleaseDmaRegion(r300ContextPtr rmesa,
struct r300_dma_region *region, const char *caller);
extern void r300AllocDmaRegion(r300ContextPtr rmesa,
struct r300_dma_region *region,
int bytes, int alignment);
extern void r300InitIoctlFuncs(struct dd_function_table *functions);
#endif /* __R300_IOCTL_H__ */

View file

@ -45,6 +45,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "array_cache/acache.h"
#include "tnl/tnl.h"
#include "radeon_reg.h"
#include "radeon_macros.h"
#include "radeon_ioctl.h"
#include "radeon_state.h"
#include "r300_context.h"
@ -52,6 +54,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_state.h"
#include "r300_reg.h"
#include "r300_program.h"
#include "r300_tex.h"
#include "r300_lib.h"
@ -149,180 +152,6 @@ static int r300_get_primitive_type(r300ContextPtr rmesa,
static void inline r300_setup_routing(r300ContextPtr r300, GLcontext *ctx, GLboolean immediate)
{
int i, count=0,reg=0;
GLuint dw, mask;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
/* Stage 1 - input to VAP */
/* Assign register number automatically, retaining it in rmesa->state.reg */
/* Note: immediate vertex data includes all coordinates.
To save bandwidth use either VBUF or state-based vertex generation */
#define CONFIGURE_AOS(v, o, r, f) \
{\
if(immediate){ \
r300->state.aos[count].element_size=4; \
r300->state.aos[count].stride=4; \
r300->state.aos[count].ncomponents=4; \
} else { \
r300->state.aos[count].element_size=v->size; \
r300->state.aos[count].stride=v->size; \
r300->state.aos[count].ncomponents=v->size; \
} \
r300->state.aos[count].offset=o; \
r300->state.aos[count].reg=reg; \
r300->state.aos[count].format=(f); \
r300->state.vap_reg.r=reg; \
count++; \
reg++; \
}
/* All offsets are 0 - for use by immediate mode.
Should change later to handle vertex buffers */
CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT);
CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR);
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
if(ctx->Texture.Unit[i].Enabled)
CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT);
r300->state.aos_count=count;
if(count>R300_MAX_AOS_ARRAYS){
fprintf(stderr, "Aieee ! AOS array count exceeded !\n");
exit(-1);
}
/* Implement AOS */
/* setup INPUT_ROUTE */
R300_STATECHANGE(r300, vir[0]);
for(i=0;i+1<count;i+=2){
dw=(r300->state.aos[i].ncomponents-1)
| ((r300->state.aos[i].reg)<<8)
| (r300->state.aos[i].format<<14)
| (((r300->state.aos[i+1].ncomponents-1)
| ((r300->state.aos[i+1].reg)<<8)
| (r300->state.aos[i+1].format<<14))<<16);
if(i+2==count){
dw|=(1<<(13+16));
}
r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
}
if(count & 1){
dw=(r300->state.aos[count-1].ncomponents-1)
| (r300->state.aos[count-1].format<<14)
| ((r300->state.aos[count-1].reg)<<8)
| (1<<13);
r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(count>>1)]=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);
/* 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+1<count;i+=2){
/* do i first.. */
mask=(1<<(r300->state.aos[i].ncomponents*3))-1;
dw=(ALL_COMPONENTS & mask)
| (ALL_DEFAULT & ~mask)
| R300_INPUT_ROUTE_ENABLE;
/* i+1 */
mask=(1<<(r300->state.aos[i+1].ncomponents*3))-1;
dw|=(
(ALL_COMPONENTS & mask)
| (ALL_DEFAULT & ~mask)
| R300_INPUT_ROUTE_ENABLE
)<<16;
r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
}
if(count & 1){
mask=(1<<(r300->state.aos[count-1].ncomponents*3))-1;
dw=(ALL_COMPONENTS & mask)
| (ALL_DEFAULT & ~mask)
| R300_INPUT_ROUTE_ENABLE;
r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(count>>1)]=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);
/* Set up input_cntl */
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]=R300_INPUT_CNTL_POS
| R300_INPUT_CNTL_COLOR;
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
if(ctx->Texture.Unit[i].Enabled)
r300->hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<<i);
/* Stage 3: VAP output */
R300_STATECHANGE(r300, vof);
r300->hw.vof.cmd[R300_VOF_CNTL_0]=R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
| R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
if(ctx->Texture.Unit[i].Enabled)
r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
}
static inline void r300_setup_textures(r300ContextPtr r300, GLcontext *ctx)
{
int i;
struct r300_tex_obj *t;
R300_STATECHANGE(r300, txe);
R300_STATECHANGE(r300, tex.filter);
R300_STATECHANGE(r300, tex.unknown1);
R300_STATECHANGE(r300, tex.size);
R300_STATECHANGE(r300, tex.format);
R300_STATECHANGE(r300, tex.offset);
R300_STATECHANGE(r300, tex.unknown4);
R300_STATECHANGE(r300, tex.unknown5);
r300->hw.txe.cmd[R300_TXE_ENABLE]=0x0;
for(i=0;i<R300_MAX_TEXTURE_UNITS;i++){
if((t=r300->state.texture.unit[i].texobj)!=NULL){
r300->hw.txe.cmd[R300_TXE_ENABLE]|=(1<<i);
r300->hw.tex.filter.cmd[R300_TEX_CMD_0+i]=t->filter;
r300->hw.tex.unknown1.cmd[R300_TEX_CMD_0+i]=t->pitch;
r300->hw.tex.size.cmd[R300_TEX_CMD_0+i]=t->size;
r300->hw.tex.format.cmd[R300_TEX_CMD_0+i]=t->format;
r300->hw.tex.offset.cmd[R300_TEX_CMD_0+i]=r300->radeon.radeonScreen->fbLocation+t->offset;
r300->hw.tex.unknown4.cmd[R300_TEX_CMD_0+i]=0x0;
r300->hw.tex.unknown5.cmd[R300_TEX_CMD_0+i]=0x0;
/* We don't know how to set this yet */
r300->hw.tex.format.cmd[R300_TEX_CMD_0+i]=0x88a0c;
}
}
}
/* Immediate implementation - vertex data is sent via command stream */
@ -431,8 +260,8 @@ static GLboolean r300_run_flat_render(GLcontext *ctx,
| R300_VTX_W0_FMT;
R300_STATECHANGE(rmesa, vte);
r300_setup_routing(rmesa, ctx, GL_TRUE);
r300_setup_textures(rmesa, ctx);
// r300_setup_routing(rmesa, ctx, GL_TRUE);
// r300_setup_textures(rmesa, ctx);
r300EmitState(rmesa);
@ -544,13 +373,6 @@ static void r300_render_vb_flat_primitive(r300ContextPtr rmesa,
fire_AOS(PASS_PREFIX end-start, type);
}
static VERTEX_SHADER_FRAGMENT default_vector_vsf={
length: 4,
body: {
f: {0.0, 0.0, 0.0, 1.0}
}
};
static GLboolean r300_run_vb_flat_render(GLcontext *ctx,
struct tnl_pipeline_stage *stage)
{
@ -645,7 +467,7 @@ static void r300_render_tex_primitive(r300ContextPtr rmesa,
type=r300_get_primitive_type(rmesa, ctx, start, end, prim);
#if 1
#if 0
fprintf(stderr,"ObjPtr: size=%d stride=%d\n",
VB->ObjPtr->size, VB->ObjPtr->stride);
fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n",
@ -702,17 +524,8 @@ static GLboolean r300_run_tex_render(GLcontext *ctx,
/* Update texture state - needs to be done only when actually changed..
All the time for now.. */
r300UpdateTextureState(ctx);
r300_setup_routing(rmesa, ctx, GL_TRUE);
r300_setup_textures(rmesa, ctx);
exit(-1);
/* Flush state - make sure command buffer is nice and large */
r300Flush(ctx);
//fprintf(stderr, "You can enable texture drawing in %s:%s \n", __FILE__, __FUNCTION__);
//return GL_TRUE;
if (RADEON_DEBUG == DEBUG_PRIMS)
@ -735,69 +548,29 @@ static GLboolean r300_run_tex_render(GLcontext *ctx,
R300_STATECHANGE(rmesa, vte);
r300EmitState(rmesa);
// r300Flush(ctx);
assign_pipeline(rmesa, &SINGLE_TEXTURE_PIPELINE);
SINGLE_TEXTURE_PIPELINE.vertex_shader.matrix[0].length=16;
memcpy(SINGLE_TEXTURE_PIPELINE.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
SINGLE_TEXTURE_PIPELINE.vertex_shader.unknown2.length=4;
SINGLE_TEXTURE_PIPELINE.vertex_shader.unknown2.body.f[0]=0.0;
SINGLE_TEXTURE_PIPELINE.vertex_shader.unknown2.body.f[1]=0.0;
SINGLE_TEXTURE_PIPELINE.vertex_shader.unknown2.body.f[2]=1.0;
SINGLE_TEXTURE_PIPELINE.vertex_shader.unknown2.body.f[3]=0.0;
/* Use actual texture offset */
fprintf(stderr,"pp_border_color=%08x pp_cubic_faces=%08x format=%08x size=%08x format_x=%08x\n",
t->pp_border_color, t->pp_cubic_faces, t->format, t->size, t->format_x);
SINGLE_TEXTURE_PIPELINE.texture_unit[0].offset=rmesa->radeon.radeonScreen->fbLocation+t->offset;
#if 0
SINGLE_TEXTURE_PIPELINE.texture_unit[0].format=t->format;
#endif
SINGLE_TEXTURE_PIPELINE.texture_unit[0].size=t->size;
SINGLE_TEXTURE_PIPELINE.texture_unit[0].filter=t->filter;
SINGLE_TEXTURE_PIPELINE.texture_unit[0].unknown1=t->pitch; /* Unknown 1 is pitch ! */
SINGLE_TEXTURE_PIPELINE.texture_unit[0].filter=t->filter;
/* Program RS unit. This needs to be moved into R300 pipeline */
reg_start(R300_RS_CNTL_0,1);
/* R300_RS_CNTL_0(4300) */
e32(0x00040084);
/* RS_INST_COUNT(4304) */
e32(0x000000c0);
reg_start(R300_RS_ROUTE_0,0);
e32(0x00024008);
reg_start(R300_RS_INTERP_0,7);
/* X_MEM0_0(4310) */
e32(0x00d10000);
/* X_MEM0_1(4314) */
e32(0x00d10044);
/* X_MEM0_2(4318) */
e32(0x00d10084);
/* X_MEM0_3(431c) */
e32(0x00d100c4);
/* X_MEM0_4(4320) */
e32(0x00d10004);
/* X_MEM0_5(4324) */
e32(0x00d10004);
/* X_MEM0_6(4328) */
e32(0x00d10004);
/* X_MEM0_7(432c) */
e32(0x00d10004);
reg_start(R300_RS_CNTL_0,0);
e32(0x00040084);
rmesa->state.vertex_shader.matrix[0].length=16;
memcpy(rmesa->state.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
rmesa->state.vertex_shader.unknown2.length=4;
rmesa->state.vertex_shader.unknown2.body.f[0]=0.0;
rmesa->state.vertex_shader.unknown2.body.f[1]=0.0;
rmesa->state.vertex_shader.unknown2.body.f[2]=1.0;
rmesa->state.vertex_shader.unknown2.body.f[3]=0.0;
/* Magic register - note it is right after 20b0 */
reg_start(0x20b4,0);
e32(0x0000000c);
program_pipeline(PASS_PREFIX &SINGLE_TEXTURE_PIPELINE);
// program_pipeline(PASS_PREFIX &SINGLE_TEXTURE_PIPELINE);
r300EmitVertexShader(rmesa);
r300EmitPixelShader(rmesa);
/* We need LOAD_VBPNTR to setup AOS_ATTR fields.. the offsets are irrelevant */
r300EmitLOAD_VBPNTR(rmesa, 0);
@ -817,8 +590,8 @@ reg_start(R300_RS_INTERP_0,7);
reg_start(0x4f18,0);
e32(0x00000003);
// exit(-1);
fprintf(stderr, "\n");
//exit(-1);
return GL_FALSE;
}

View file

@ -331,6 +331,294 @@ static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
r300UpdateWindow(ctx);
}
/* Routing and texture-related */
void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
{
int i, count=0,reg=0;
GLuint dw, mask;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
r300ContextPtr r300 = R300_CONTEXT(ctx);
/* Stage 1 - input to VAP */
/* Assign register number automatically, retaining it in rmesa->state.reg */
/* Note: immediate vertex data includes all coordinates.
To save bandwidth use either VBUF or state-based vertex generation */
#define CONFIGURE_AOS(v, o, r, f) \
{\
if(immediate){ \
r300->state.aos[count].element_size=4; \
r300->state.aos[count].stride=4; \
r300->state.aos[count].ncomponents=4; \
} else { \
r300->state.aos[count].element_size=v->size; \
r300->state.aos[count].stride=v->size; \
r300->state.aos[count].ncomponents=v->size; \
} \
r300->state.aos[count].offset=o; \
r300->state.aos[count].reg=reg; \
r300->state.aos[count].format=(f); \
r300->state.vap_reg.r=reg; \
count++; \
reg++; \
}
/* All offsets are 0 - for use by immediate mode.
Should change later to handle vertex buffers */
CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT);
CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR);
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
if(ctx->Texture.Unit[i].Enabled)
CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT);
r300->state.aos_count=count;
if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "aos_count=%d\n", count);
if(count>R300_MAX_AOS_ARRAYS){
fprintf(stderr, "Aieee ! AOS array count exceeded !\n");
exit(-1);
}
/* Implement AOS */
/* setup INPUT_ROUTE */
R300_STATECHANGE(r300, vir[0]);
for(i=0;i+1<count;i+=2){
dw=(r300->state.aos[i].ncomponents-1)
| ((r300->state.aos[i].reg)<<8)
| (r300->state.aos[i].format<<14)
| (((r300->state.aos[i+1].ncomponents-1)
| ((r300->state.aos[i+1].reg)<<8)
| (r300->state.aos[i+1].format<<14))<<16);
if(i+2==count){
dw|=(1<<(13+16));
}
r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
}
if(count & 1){
dw=(r300->state.aos[count-1].ncomponents-1)
| (r300->state.aos[count-1].format<<14)
| ((r300->state.aos[count-1].reg)<<8)
| (1<<13);
r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(count>>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)->unchecked_state.count = (count+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+1<count;i+=2){
/* do i first.. */
mask=(1<<(r300->state.aos[i].ncomponents*3))-1;
dw=(ALL_COMPONENTS & mask)
| (ALL_DEFAULT & ~mask)
| R300_INPUT_ROUTE_ENABLE;
/* i+1 */
mask=(1<<(r300->state.aos[i+1].ncomponents*3))-1;
dw|=(
(ALL_COMPONENTS & mask)
| (ALL_DEFAULT & ~mask)
| R300_INPUT_ROUTE_ENABLE
)<<16;
r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
}
if(count & 1){
mask=(1<<(r300->state.aos[count-1].ncomponents*3))-1;
dw=(ALL_COMPONENTS & mask)
| (ALL_DEFAULT & ~mask)
| R300_INPUT_ROUTE_ENABLE;
r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(count>>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)->unchecked_state.count = (count+1)>>1;
/* Set up input_cntl */
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]=R300_INPUT_CNTL_POS
| R300_INPUT_CNTL_COLOR;
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
if(ctx->Texture.Unit[i].Enabled)
r300->hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<<i);
/* Stage 3: VAP output */
R300_STATECHANGE(r300, vof);
r300->hw.vof.cmd[R300_VOF_CNTL_0]=R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
| R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
if(ctx->Texture.Unit[i].Enabled)
r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
}
static r300TexObj default_tex_obj={
filter:R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR,
pitch: 0x8000,
size: (0xff << R300_TX_WIDTHMASK_SHIFT)
| (0xff << R300_TX_HEIGHTMASK_SHIFT)
| (0x8 << R300_TX_SIZE_SHIFT),
format: 0x88a0c,
offset: 0x0,
unknown4: 0x0,
unknown5: 0x0
};
void r300_setup_textures(GLcontext *ctx)
{
int i, mtu;
struct r300_tex_obj *t;
r300ContextPtr r300 = R300_CONTEXT(ctx);
int max_texture_unit=-1; /* -1 translates into no setup costs for fields */
R300_STATECHANGE(r300, txe);
R300_STATECHANGE(r300, tex.filter);
R300_STATECHANGE(r300, tex.unknown1);
R300_STATECHANGE(r300, tex.size);
R300_STATECHANGE(r300, tex.format);
R300_STATECHANGE(r300, tex.offset);
R300_STATECHANGE(r300, tex.unknown4);
R300_STATECHANGE(r300, tex.unknown5);
r300->state.texture.tc_count=0;
r300->hw.txe.cmd[R300_TXE_ENABLE]=0x0;
mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "mtu=%d\n", mtu);
if(mtu>R300_MAX_TEXTURE_UNITS){
fprintf(stderr, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
mtu, R300_MAX_TEXTURE_UNITS);
exit(-1);
}
for(i=0;i<mtu;i++){
if(ctx->Texture.Unit[i].Enabled!=NULL){
t=r300->state.texture.unit[i].texobj;
r300->state.texture.tc_count++;
if(t==NULL){
fprintf(stderr, "Texture unit %d enabled, but corresponding texobj is NULL, using default object.\n", i);
//exit(-1);
t=&default_tex_obj;
}
if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "Activating texture unit %d\n", i);
max_texture_unit=i;
r300->hw.txe.cmd[R300_TXE_ENABLE]|=(1<<i);
r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=t->filter;
r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=t->pitch;
r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=t->size;
r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=t->format;
r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation+t->offset;
r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
/* We don't know how to set this yet */
r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x88a0c;
} else {
/* Fill in with 0's */
#if 0 /* No need.. */
r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=0x0;
r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=0x0;
r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=0x0;
r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x0;
r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation;
r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
#endif
}
}
((drm_r300_cmd_header_t*)r300->hw.tex.filter.cmd)->unchecked_state.count = max_texture_unit+1;
((drm_r300_cmd_header_t*)r300->hw.tex.unknown1.cmd)->unchecked_state.count = max_texture_unit+1;
((drm_r300_cmd_header_t*)r300->hw.tex.size.cmd)->unchecked_state.count = max_texture_unit+1;
((drm_r300_cmd_header_t*)r300->hw.tex.format.cmd)->unchecked_state.count = max_texture_unit+1;
((drm_r300_cmd_header_t*)r300->hw.tex.offset.cmd)->unchecked_state.count = max_texture_unit+1;
((drm_r300_cmd_header_t*)r300->hw.tex.unknown4.cmd)->unchecked_state.count = max_texture_unit+1;
((drm_r300_cmd_header_t*)r300->hw.tex.unknown5.cmd)->unchecked_state.count = max_texture_unit+1;
if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "TX_ENABLE: %08x max_texture_unit=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], max_texture_unit);
}
void r300_setup_rs_unit(GLcontext *ctx)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
int i;
/* This needs to be rewritten - it is a hack at best */
R300_STATECHANGE(r300, ri);
R300_STATECHANGE(r300, rc);
R300_STATECHANGE(r300, rr);
for(i = 1; i <= 8; ++i)
r300->hw.ri.cmd[i] = 0x00d10000;
r300->hw.ri.cmd[R300_RI_INTERP_1] |= R300_RS_INTERP_1_UNKNOWN;
r300->hw.ri.cmd[R300_RI_INTERP_2] |= R300_RS_INTERP_2_UNKNOWN;
r300->hw.ri.cmd[R300_RI_INTERP_3] |= R300_RS_INTERP_3_UNKNOWN;
for(i = 1; i <= 8; ++i)
r300->hw.rr.cmd[i] = 0;
/* textures enabled ? */
if(r300->state.texture.tc_count>0){
/* This code only really works with one set of texture coordinates */
/* The second constant is needed to get glxgears display anything .. */
r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7
| R300_RS_CNTL_0_UNKNOWN_18
| (r300->state.texture.tc_count<<R300_RS_CNTL_TC_CNT_SHIFT);
r300->hw.rc.cmd[2] = 0xc0;
((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x24008;
} else {
/* The second constant is needed to get glxgears display anything .. */
r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18;
r300->hw.rc.cmd[2] = 0;
((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x4000;
}
}
/**
* Called by Mesa after an internal state update.
@ -374,6 +662,12 @@ void r300ResetHwState(r300ContextPtr r300)
r300DepthFunc(ctx, ctx->Depth.Func);
r300UpdateCulling(ctx);
r300_setup_routing(ctx, GL_TRUE);
r300UpdateTextureState(ctx);
r300_setup_textures(ctx);
r300_setup_rs_unit(ctx);
//BEGIN: TODO
r300->hw.unk2080.cmd[1] = 0x0030045A;
@ -395,6 +689,7 @@ void r300ResetHwState(r300ContextPtr r300)
r300->hw.unk2140.cmd[1] = 0x00000000;
#if 0 /* Done in setup routing */
((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
r300->hw.vir[0].cmd[1] = 0x21030003;
@ -403,7 +698,8 @@ void r300ResetHwState(r300ContextPtr r300)
r300->hw.vic.cmd[R300_VIR_CNTL_0] = 0x00000001;
r300->hw.vic.cmd[R300_VIR_CNTL_1] = 0x00000405;
#endif
r300->hw.unk21DC.cmd[1] = 0xAAAAAAAA;
r300->hw.unk221C.cmd[1] = R300_221C_NORMAL;
@ -418,10 +714,12 @@ void r300ResetHwState(r300ContextPtr r300)
else
r300->hw.unk2288.cmd[1] = R300_2288_RV350;
#if 0
r300->hw.vof.cmd[R300_VOF_CNTL_0] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
| R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0; /* no textures */
#endif
r300->hw.pvs.cmd[R300_PVS_CNTL_1] = 0;
r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0;
r300->hw.pvs.cmd[R300_PVS_CNTL_3] = 0;
@ -443,7 +741,7 @@ void r300ResetHwState(r300ContextPtr r300)
r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = 0x00000000;
r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = 0x00000000; /* No antialiasing */
r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
//r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
r300->hw.unk4200.cmd[1] = r300PackFloat32(0.0);
r300->hw.unk4200.cmd[2] = r300PackFloat32(0.0);
@ -481,20 +779,6 @@ void r300ResetHwState(r300ContextPtr r300)
r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
r300->hw.unk42C0.cmd[2] = 0x00000000;
/* The second constant is needed to get glxgears display anything .. */
r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18;
r300->hw.rc.cmd[2] = 0;
for(i = 1; i <= 8; ++i)
r300->hw.ri.cmd[i] = 0x00d10000;
r300->hw.ri.cmd[R300_RI_INTERP_1] |= R300_RS_INTERP_1_UNKNOWN;
r300->hw.ri.cmd[R300_RI_INTERP_2] |= R300_RS_INTERP_2_UNKNOWN;
r300->hw.ri.cmd[R300_RI_INTERP_3] |= R300_RS_INTERP_3_UNKNOWN;
((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
for(i = 1; i <= 8; ++i)
r300->hw.rr.cmd[i] = 0;
r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x4000;
r300->hw.unk43A4.cmd[1] = 0x0000001C;
r300->hw.unk43A4.cmd[2] = 0x2DA49525;
@ -602,16 +886,6 @@ void r300ResetHwState(r300ContextPtr r300)
r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0;
/* Initialize texture units */
for(i=0;i<r300->radeon.glCtx->Const.MaxTextureUnits;i++){
r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=0x0;
r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=0x0;
r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=0x0;
r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x0;
r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=0x0;
r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
}
//END: TODO
r300->hw.all_dirty = GL_TRUE;
@ -626,9 +900,29 @@ void r300ResetHwState(r300ContextPtr r300)
*/
void r300InitState(r300ContextPtr r300)
{
GLcontext *ctx = r300->radeon.glCtx;
GLuint depth_fmt;
radeonInitState(&r300->radeon);
r300->state.depth.scale = 1.0 / (GLfloat) 0xffff;
switch (ctx->Visual.depthBits) {
case 16:
r300->state.depth.scale = 1.0 / (GLfloat) 0xffff;
depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z;
//r300->state.stencil.clear = 0x00000000;
break;
case 24:
r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff;
depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z;
//r300->state.stencil.clear = 0xff000000;
break;
default:
fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
ctx->Visual.depthBits);
exit(-1);
}
memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
r300ResetHwState(r300);
}

View file

@ -47,5 +47,7 @@ extern void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t);
extern void r300InitTextureFuncs(struct dd_function_table *functions);
extern void r300UpdateTextureState(GLcontext * ctx);
#endif
#endif /* __r300_TEX_H__ */