Compare commits

...

7 Commits

Author SHA1 Message Date
Vladimir Dergachev
e443d1ec47 Qualify the magic 20B0 register as SE_VTE_CNTL similar to R200. Looks like disabling Z offset and scaling displays gears properly, not sure why. Perhaps the meaning of the bits has changed ?
Cleanup code a bit.
2004-12-31 21:28:36 +00:00
Vladimir Dergachev
92d47e79f1 Sync with master copy. 2004-12-31 20:57:48 +00:00
Vladimir Dergachev
11374bdb86 Add texture drawing code. Note: it is broken at the moment and is disabled in CVS. However, all hooks are there.
Fix vertex buffer drawing code.
2004-12-31 19:39:03 +00:00
Vladimir Dergachev
24b5e49141 Rework slightly r300_get_primitive_type - make it clearer and more compact.. 2004-12-30 20:24:30 +00:00
Keith Whitwell
179cc373f1 Get scissor test working again. Passes glean scissor test. 2004-12-30 17:47:08 +00:00
Keith Whitwell
c664f0c515 Calculate DEPTH_SCALE correctly for polygon offset. 2004-12-30 16:30:26 +00:00
Keith Whitwell
8be4747fd6 Simplify viaBlit a bit more.
Implement masked clears.
2004-12-30 16:13:35 +00:00
10 changed files with 444 additions and 174 deletions

View File

@@ -284,8 +284,8 @@ void r300InitCmdBuf(r300ContextPtr r300)
r300->hw.unk2080.cmd[0] = cmducs(0x2080, 1);
ALLOC_STATE( ovf, always, R300_OVF_CMDSIZE, "ovf", 0 );
r300->hw.ovf.cmd[R300_OVF_CMD_0] = cmducs(R300_VAP_OUTPUT_VTX_FMT_0, 2);
ALLOC_STATE( unk20B0, always, 3, "unk20B0", 0 );
r300->hw.unk20B0.cmd[0] = cmducs(0x20B0, 2);
ALLOC_STATE( vte, always, 3, "vte", 0 );
r300->hw.vte.cmd[0] = cmducs(R300_SE_VTE_CNTL, 2);
ALLOC_STATE( unk2134, always, 3, "unk2134", 0 );
r300->hw.unk2134.cmd[0] = cmducs(0x2134, 2);
ALLOC_STATE( unk2140, always, 2, "unk2140", 0 );
@@ -415,7 +415,7 @@ void r300InitCmdBuf(r300ContextPtr r300)
insert_at_tail(&r300->hw.atomlist, &r300->hw.vpt);
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2080);
insert_at_tail(&r300->hw.atomlist, &r300->hw.ovf);
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk20B0);
insert_at_tail(&r300->hw.atomlist, &r300->hw.vte);
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2134);
insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2140);
insert_at_tail(&r300->hw.atomlist, &r300->hw.vir[0]);

View File

@@ -246,7 +246,7 @@ struct r300_hw_state {
struct r300_state_atom vpt; /* viewport (1D98) */
struct r300_state_atom unk2080; /* (2080) */
struct r300_state_atom ovf; /* output vertex format (2090) */
struct r300_state_atom unk20B0; /* (20B0) */
struct r300_state_atom vte; /* (20B0) */
struct r300_state_atom unk2134; /* (2134) */
struct r300_state_atom unk2140; /* (2140) */
struct r300_state_atom vir[2]; /* vap input route (2150/21E0) */

View File

@@ -70,6 +70,19 @@ I am fairly certain that they are correct unless stated otherwise in comments.
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21
/* END */
#define R300_SE_VTE_CNTL 0x20b0
# define R300_VPORT_X_SCALE_ENA 0x00000001
# define R300_VPORT_X_OFFSET_ENA 0x00000002
# define R300_VPORT_Y_SCALE_ENA 0x00000004
# define R300_VPORT_Y_OFFSET_ENA 0x00000008
# define R300_VPORT_Z_SCALE_ENA 0x00000010
# define R300_VPORT_Z_OFFSET_ENA 0x00000020
# define R300_VTX_XY_FMT 0x00000100
# define R300_VTX_Z_FMT 0x00000200
# define R300_VTX_W0_FMT 0x00000400
# define R300_VTX_W0_NORMALIZE 0x00000800
# define R300_VTX_ST_DENORMALIZED 0x00001000
/* BEGIN: Vertex data assembly - lots of uncertainties */
/* gap */
/* Where do we get our vertex data?

View File

@@ -72,81 +72,69 @@ static int r300_get_primitive_type(r300ContextPtr rmesa,
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i;
int type=-1;
int type=-1, min_vertices=0;
char *name="UNKNOWN";
if(end<=start)return -1; /* do we need to watch for this ? */
fprintf(stderr, "[%d-%d]", start, end);
switch (prim & PRIM_MODE_MASK) {
case GL_LINES:
fprintf(stderr, "L ");
case GL_POINTS:
name="P";
type=R300_VAP_VF_CNTL__PRIM_POINTS;
min_vertices=1;
break;
case GL_LINES:
name="L";
type=R300_VAP_VF_CNTL__PRIM_LINES;
if(end<start+2){
fprintf(stderr, "Not enough vertices\n");
return -1; /* need enough vertices for Q */
}
break;
case GL_LINE_STRIP:
fprintf(stderr, "LS ");
min_vertices=2;
break;
case GL_LINE_STRIP:
name="LS";
type=R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
if(end<start+2){
fprintf(stderr, "Not enough vertices\n");
return -1; /* need enough vertices for Q */
}
min_vertices=2;
break;
case GL_LINE_LOOP:
fprintf(stderr, "LL ");
case GL_LINE_LOOP:
name="LL";
min_vertices=2;
return -1;
if(end<start+2){
fprintf(stderr, "Not enough vertices\n");
return -1; /* need enough vertices for Q */
}
break;
case GL_TRIANGLES:
fprintf(stderr, "T ");
case GL_TRIANGLES:
name="T";
type=R300_VAP_VF_CNTL__PRIM_TRIANGLES;
if(end<start+3){
fprintf(stderr, "Not enough vertices\n");
return -1; /* need enough vertices for Q */
}
min_vertices=3;
break;
case GL_TRIANGLE_STRIP:
fprintf(stderr, "TS ");
case GL_TRIANGLE_STRIP:
name="TS";
type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
if(end<start+3){
fprintf(stderr, "Not enough vertices\n");
return -1; /* need enough vertices for Q */
}
min_vertices=3;
break;
case GL_TRIANGLE_FAN:
fprintf(stderr, "TF ");
case GL_TRIANGLE_FAN:
name="TF";
type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
if(end<start+3){
fprintf(stderr, "Not enough vertices\n");
return -1; /* need enough vertices for Q */
}
min_vertices=3;
break;
case GL_QUADS:
fprintf(stderr, "Q ");
case GL_QUADS:
name="Q";
type=R300_VAP_VF_CNTL__PRIM_QUADS;
if(end<start+4){
fprintf(stderr, "Not enough vertices\n");
return -1; /* need enough vertices for Q */
}
min_vertices=4;
break;
case GL_QUAD_STRIP:
fprintf(stderr, "QS ");
case GL_QUAD_STRIP:
name="QS";
type=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
if(end<start+4){
fprintf(stderr, "Not enough vertices\n");
return -1; /* need enough vertices for Q */
}
min_vertices=4;
break;
default:
default:
fprintf(stderr, "Cannot handle primitive %02x ", prim & PRIM_MODE_MASK);
return -1;
break;
}
}
#if 1
fprintf(stderr, "[%d-%d]%s ", start, end, name);
#endif
if(start+min_vertices>=end){
fprintf(stderr, "Not enough vertices\n");
return -1;
}
return type;
}
@@ -180,6 +168,12 @@ static void r300_render_flat_primitive(r300ContextPtr rmesa,
LOCAL_VARS
type=r300_get_primitive_type(rmesa, ctx, start, end, prim);
fprintf(stderr,"ObjPtr: size=%d stride=%d\n",
VB->ObjPtr->size, VB->ObjPtr->stride);
fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n",
VB->ColorPtr[0]->size, VB->ColorPtr[0]->stride);
if(type<0)return;
@@ -251,10 +245,14 @@ static GLboolean r300_run_flat_render(GLcontext *ctx,
reg_start(0x4f18,0);
e32(0x00000003);
r300EmitState(rmesa);
rmesa->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
| R300_VPORT_X_OFFSET_ENA
| R300_VPORT_Y_SCALE_ENA
| R300_VPORT_Y_OFFSET_ENA
| R300_VTX_W0_FMT;
R300_STATECHANGE(rmesa, vte);
reg_start(0x20b0,0);
e32(0x0000043f);
r300EmitState(rmesa);
FLAT_COLOR_PIPELINE.vertex_shader.matrix[0].length=16;
memcpy(FLAT_COLOR_PIPELINE.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
@@ -287,7 +285,8 @@ static GLboolean r300_run_flat_render(GLcontext *ctx,
/* We use the start part of GART texture buffer for vertices */
#define R300_MAX_AOS_ARRAYS 16
/* 8 is somewhat bogus... it is probably something like 24 */
#define R300_MAX_AOS_ARRAYS 8
static void upload_vertex_buffer(r300ContextPtr rmesa,
GLcontext *ctx, AOS_DATA *array, int *n_arrays)
@@ -312,7 +311,7 @@ static void upload_vertex_buffer(r300ContextPtr rmesa,
} else { \
for(i=0;i<VB->Count;i++){ \
/* copy one vertex at a time*/ \
memcpy(rsp->gartTextures.map+offset, VEC_ELT(v, GLfloat, i), v->size*4); \
memcpy(rsp->gartTextures.map+offset+i*v->size*4, VEC_ELT(v, GLfloat, i), v->size*4); \
} \
} \
/* v->flags &= ~((1<<v->size)-1);*/ \
@@ -325,24 +324,8 @@ static void upload_vertex_buffer(r300ContextPtr rmesa,
array[idx].reg=r; \
offset+=v->size*4*VB->Count; \
idx++; \
/* Fill in the rest with the components of default_vector */\
/* \
if(v->size<4){ \
array[idx].element_size=4-v->size; \
array[idx].stride=0; \
array[idx].format=(f); \
array[idx].ncomponents=4-v->size; \
array[idx].offset=rsp->gartTextures.handle+v->size*4;\
array[idx].reg=r; \
idx++; \
} \
*/\
}
/* Put a copy of default vector */
memcpy(rsp->gartTextures.map, default_vector, 16);
offset+=16;
UPLOAD_VECTOR(VB->ObjPtr, REG_COORDS, AOS_FORMAT_FLOAT);
UPLOAD_VECTOR(VB->ColorPtr[0], REG_COLOR0, AOS_FORMAT_FLOAT_COLOR);
@@ -407,9 +390,6 @@ static GLboolean r300_run_vb_flat_render(GLcontext *ctx,
r300EmitState(rmesa);
reg_start(0x20b0,0);
e32(0x0000043f);
FLAT_COLOR_PIPELINE.vertex_shader.matrix[0].length=16;
memcpy(FLAT_COLOR_PIPELINE.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
@@ -418,12 +398,9 @@ static GLboolean r300_run_vb_flat_render(GLcontext *ctx,
FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[1]=0.0;
FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[2]=1.0;
FLAT_COLOR_PIPELINE.vertex_shader.unknown2.body.f[3]=0.0;
program_pipeline(PASS_PREFIX &FLAT_COLOR_PIPELINE);
reg_start(R300_RE_OCCLUSION_CNTL, 0);
e32(R300_OCCLUSION_ON);
set_quad0(PASS_PREFIX 1.0,1.0,1.0,1.0);
set_init21(PASS_PREFIX 0.0,1.0);
@@ -435,7 +412,7 @@ static GLboolean r300_run_vb_flat_render(GLcontext *ctx,
/* copy arrays */
memcpy(vb_arrays2, vb_arrays, sizeof(AOS_DATA)*n_arrays);
for(j=0;j<n_arrays;j++){
vb_arrays2[j].offset+=vb_arrays2[j].stride*start;
vb_arrays2[j].offset+=vb_arrays2[j].stride*start*4;
}
setup_AOS(PASS_PREFIX vb_arrays2, n_arrays);
@@ -451,6 +428,221 @@ static GLboolean r300_run_vb_flat_render(GLcontext *ctx,
return GL_FALSE;
}
/* Textures... */
/* Immediate implementation - vertex data is sent via command stream */
static void r300_render_tex_primitive(r300ContextPtr rmesa,
GLcontext *ctx,
int start,
int end,
int prim)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i;
int k, type;
LOCAL_VARS
type=r300_get_primitive_type(rmesa, ctx, start, end, prim);
fprintf(stderr,"ObjPtr: size=%d stride=%d\n",
VB->ObjPtr->size, VB->ObjPtr->stride);
fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n",
VB->ColorPtr[0]->size, VB->ColorPtr[0]->stride);
if(type<0)return;
start_immediate_packet(end-start, type, 8);
for(i=start;i<end;i++){
#if 0
fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n",
VEC_ELT(VB->ObjPtr, GLfloat, i)[0],
VEC_ELT(VB->ObjPtr, GLfloat, i)[1],
VEC_ELT(VB->ObjPtr, GLfloat, i)[2],
VEC_ELT(VB->ObjPtr, GLfloat, i)[3],
VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0],
VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1],
VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2],
VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]
);
#endif
/* coordinates */
output_vector(VB->ObjPtr, i);
/* color components */
output_vector(VB->TexCoordPtr[0], i);
}
}
static GLboolean r300_run_tex_render(GLcontext *ctx,
struct tnl_pipeline_stage *stage)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i;
AOS_DATA vb_arrays[2];
/* Only do 2d textures */
struct gl_texture_object *to=ctx->Texture.Unit[0].Current2D;
radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
LOCAL_VARS
fprintf(stderr, "%s Fixme ! I am broken\n", __FUNCTION__);
return GL_TRUE;
if (RADEON_DEBUG == DEBUG_PRIMS)
fprintf(stderr, "%s\n", __FUNCTION__);
/* setup array of structures data */
/* Note: immediate vertex data includes all coordinates.
To save bandwidth use either VBUF or state-based vertex generation */
/* xyz */
vb_arrays[0].element_size=4;
vb_arrays[0].stride=4;
vb_arrays[0].offset=0; /* Not used */
vb_arrays[0].format=AOS_FORMAT_FLOAT;
vb_arrays[0].ncomponents=4;
vb_arrays[0].reg=REG_COORDS;
/* color */
vb_arrays[1].element_size=4;
vb_arrays[1].stride=4;
vb_arrays[1].offset=0; /* Not used */
vb_arrays[1].format=AOS_FORMAT_FLOAT;
vb_arrays[1].ncomponents=4;
vb_arrays[1].reg=REG_TEX0;
/* needed before starting 3d operation .. */
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
e32(0x0000000a);
reg_start(0x4f18,0);
e32(0x00000003);
r300EmitState(rmesa);
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;
/* Put it in the beginning of texture memory */
SINGLE_TEXTURE_PIPELINE.texture_unit[0].offset=rsp->gartTextures.handle;
/* Upload texture, a hack, really we can do a lot better */
#if 0
memcpy(rsp->gartTextures.map, to->Image[0][0]->Data, to->Image[0][0]->RowStride*to->Image[0][0]->Height*4);
#endif
reg_start(0x4e0c,0);
e32(0x0000000f);
reg_start(0x427c,1);
/* XG_427c(427c) */
e32(0x00000000);
/* XG_4280(4280) */
e32(0x00000000);
reg_start(0x4e04,1);
/* XG_4e04(4e04) */
e32(0x20220000);
/* XG_4e08(4e08) */
e32(0x00000000);
reg_start(0x4f14,0);
e32(0x00000001);
reg_start(0x4f1c,0);
e32(0x00000000);
/* gap */
sync_VAP(PASS_PREFIX_VOID);
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(0x221c,0);
e32(0x00000000);
reg_start(0x20b0,0);
e32(0x0000043f);
reg_start(0x4bd8,0);
e32(0x00000000);
reg_start(0x4e04,0);
e32(0x20220000);
reg_start(0x20b4,0);
e32(0x0000000c);
reg_start(0x4288,0);
e32(0x00000000);
reg_start(0x4e0c,0);
e32(0x0000000f);
reg_start(R300_RS_CNTL_0,0);
e32(0x00040084);
program_pipeline(PASS_PREFIX &SINGLE_TEXTURE_PIPELINE);
/* We need LOAD_VBPNTR to setup AOS_ATTR fields.. the offsets are irrelevant */
setup_AOS(PASS_PREFIX vb_arrays, 2);
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_tex_primitive(rmesa, ctx, start, start + length, prim);
}
end_3d(PASS_PREFIX_VOID);
fprintf(stderr, "\n");
return GL_FALSE;
}
/**
* 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
@@ -469,7 +661,11 @@ static GLboolean r300_run_render(GLcontext *ctx,
fprintf(stderr, "%s\n", __FUNCTION__);
#if 1
return r300_run_flat_render(ctx, stage);
/* Just switch between pipelines.. We could possibly do better.. (?) */
if(ctx->Texture.Unit[0].Enabled)
return r300_run_tex_render(ctx, stage);
else
return r300_run_flat_render(ctx, stage);
#else
return GL_TRUE;
#endif
@@ -562,7 +758,8 @@ static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
/* One step at a time - let one texture pass.. */
for (i = 1; i < ctx->Const.MaxTextureUnits; i++)
FALLBACK_IF(ctx->Texture.Unit[i].Enabled);

View File

@@ -327,8 +327,14 @@ void r300ResetHwState(r300ContextPtr r300)
r300->hw.ovf.cmd[R300_OVF_FMT_0] = 0x00000003;
r300->hw.ovf.cmd[R300_OVF_FMT_1] = 0x00000000;
r300->hw.unk20B0.cmd[1] = 0x0000040A;
r300->hw.unk20B0.cmd[2] = 0x00000008;
r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
| R300_VPORT_X_OFFSET_ENA
| R300_VPORT_Y_SCALE_ENA
| R300_VPORT_Y_OFFSET_ENA
| R300_VPORT_Z_SCALE_ENA
| R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT;
r300->hw.vte.cmd[2] = 0x00000008;
r300->hw.unk2134.cmd[1] = 0x00FFFFFF;
r300->hw.unk2134.cmd[2] = 0x00000000;

View File

@@ -356,6 +356,7 @@ viaCreateContext(const __GLcontextModes *mesaVis,
vmesa->depth_max = (GLfloat)0xffff;
vmesa->depth_clear_mask = 0xf << 28;
vmesa->ClearDepth = 0xffff;
vmesa->polygon_offset_scale = 1.0 / vmesa->depth_max;
break;
case 24:
vmesa->hasDepth = GL_TRUE;
@@ -370,6 +371,7 @@ viaCreateContext(const __GLcontextModes *mesaVis,
vmesa->have_hw_stencil = GL_TRUE;
vmesa->stencilBits = mesaVis->stencilBits;
vmesa->stencil_clear_mask = 0x1 << 28;
vmesa->polygon_offset_scale = 2.0 / vmesa->depth_max;
break;
case 32:
vmesa->hasDepth = GL_TRUE;
@@ -380,6 +382,7 @@ viaCreateContext(const __GLcontextModes *mesaVis,
vmesa->depth_clear_mask = 0;
vmesa->ClearDepth = 0xffffffff;
vmesa->depth_clear_mask = 0xf << 28;
vmesa->polygon_offset_scale = 2.0 / vmesa->depth_max;
break;
default:
assert(0);
@@ -658,8 +661,16 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
(GLframebuffer *)driDrawPriv->driverPrivate,
(GLframebuffer *)driReadPriv->driverPrivate);
if (VIA_DEBUG) fprintf(stderr, "Context %d MakeCurrent\n", vmesa->hHWContext);
viaXMesaWindowMoved(vmesa);
/* These are probably needed only the first time a context is
* made current:
*/
viaXMesaWindowMoved(vmesa);
ctx->Driver.Scissor(ctx,
ctx->Scissor.X,
ctx->Scissor.Y,
ctx->Scissor.Width,
ctx->Scissor.Height);
}
else {

View File

@@ -103,6 +103,7 @@ struct via_context_t {
GLuint depth_clear_mask;
GLuint stencil_clear_mask;
GLfloat depth_max;
GLfloat polygon_offset_scale;
GLubyte *dma;
viaRegion tex;
@@ -212,6 +213,8 @@ struct via_context_t {
GLenum TexEnvImageFmt[2];
GLuint ClearColor;
GLuint ClearMask;
/* DRI stuff
*/
GLuint needClip;

View File

@@ -90,77 +90,61 @@ void viaCheckDma(viaContextPtr vmesa, GLuint bytes)
} while (0)
static void viaBlit(viaContextPtr vmesa, GLuint bpp,GLuint srcBase,
GLuint srcPitch,GLuint dstBase,GLuint dstPitch,
GLuint w,GLuint h,int xdir,int ydir, GLuint blitMode,
static void viaBlit(viaContextPtr vmesa, GLuint bpp,
GLuint srcBase, GLuint srcPitch,
GLuint dstBase, GLuint dstPitch,
GLuint w, GLuint h,
GLuint blitMode,
GLuint color, GLuint nMask )
{
GLuint dwGEMode = 0, srcY=0, srcX, dstY=0, dstX;
GLuint cmd;
GLuint dwGEMode, srcX, dstX, cmd;
RING_VARS;
if (VIA_DEBUG)
fprintf(stderr, "%s bpp %d src %x/%x dst %x/%x w %d h %d dir %d,%d mode: %x color: 0x%08x mask 0x%08x\n",
__FUNCTION__, bpp, srcBase, srcPitch, dstBase, dstPitch, w,h, xdir, ydir, blitMode, color, nMask);
fprintf(stderr, "%s bpp %d src %x/%x dst %x/%x w %d h %d mode: %x color: 0x%08x mask 0x%08x\n",
__FUNCTION__, bpp, srcBase, srcPitch, dstBase, dstPitch, w,h, blitMode, color, nMask);
if (!w || !h)
return;
srcX = srcBase & 31;
dstX = dstBase & 31;
switch (bpp) {
case 16:
dwGEMode |= VIA_GEM_16bpp;
srcX >>= 1;
dstX >>= 1;
dwGEMode = VIA_GEM_16bpp;
srcX = (srcBase & 0x1f) >> 1;
dstX = (dstBase & 0x1f) >> 1;
break;
case 32:
dwGEMode |= VIA_GEM_32bpp;
srcX >>= 2;
dstX >>= 2;
dwGEMode = VIA_GEM_32bpp;
srcX = (srcBase & 0x1f) >> 2;
dstX = (dstBase & 0x1f) >> 2;
break;
default:
dwGEMode |= VIA_GEM_8bpp;
break;
}
cmd = 0;
if (xdir < 0) {
cmd |= VIA_GEC_DECX;
srcX += (w - 1);
dstX += (w - 1);
}
if (ydir < 0) {
cmd |= VIA_GEC_DECY;
srcY += (h - 1);
dstY += (h - 1);
return;
}
switch(blitMode) {
case VIA_BLIT_FILL:
BEGIN_RING((2 + 9) * 2);
SetReg2DAGP(VIA_REG_GEMODE, dwGEMode);
SetReg2DAGP( VIA_REG_FGCOLOR, color);
cmd |= VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24);
cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (VIA_BLIT_FILL << 24);
break;
case VIA_BLIT_COPY:
BEGIN_RING((2 + 9) * 2);
SetReg2DAGP(VIA_REG_GEMODE, dwGEMode);
SetReg2DAGP( VIA_REG_KEYCONTROL, 0x0);
cmd |= VIA_GEC_BLT | (VIA_BLIT_COPY << 24);
cmd = VIA_GEC_BLT | (VIA_BLIT_COPY << 24);
break;
default:
return;
}
BEGIN_RING(22);
SetReg2DAGP( VIA_REG_GEMODE, dwGEMode);
SetReg2DAGP( VIA_REG_FGCOLOR, color);
SetReg2DAGP( 0x2C, nMask);
SetReg2DAGP( VIA_REG_SRCBASE, (srcBase & ~31) >> 3);
SetReg2DAGP( VIA_REG_DSTBASE, (dstBase & ~31) >> 3);
SetReg2DAGP( VIA_REG_SRCBASE, (srcBase & ~0x1f) >> 3);
SetReg2DAGP( VIA_REG_DSTBASE, (dstBase & ~0x1f) >> 3);
SetReg2DAGP( VIA_REG_PITCH, VIA_PITCH_ENABLE |
(srcPitch >> 3) | (((dstPitch) >> 3) << 16));
SetReg2DAGP( VIA_REG_SRCPOS, ((srcY << 16) | srcX));
SetReg2DAGP( VIA_REG_DSTPOS, ((dstY << 16) | dstX));
(srcPitch >> 3) | ((dstPitch >> 3) << 16));
SetReg2DAGP( VIA_REG_SRCPOS, srcX);
SetReg2DAGP( VIA_REG_DSTPOS, dstX);
SetReg2DAGP( VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
SetReg2DAGP( VIA_REG_GECMD, cmd);
SetReg2DAGP( 0x2C, 0x00000000);
@@ -192,7 +176,6 @@ static void viaFillBuffer(viaContextPtr vmesa,
offset, buffer->pitch,
offset, buffer->pitch,
w, h,
0, 0,
VIA_BLIT_FILL, pixel, mask);
}
}
@@ -204,7 +187,6 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
const GLuint colorMask = *((GLuint *)&ctx->Color.ColorMask);
int flag = 0;
GLuint i = 0;
GLuint clear_depth_mask = 0xf << 28;
@@ -212,12 +194,12 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
VIA_FLUSH_DMA(vmesa);
if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) {
if (mask & DD_FRONT_LEFT_BIT) {
flag |= VIA_FRONT;
mask &= ~DD_FRONT_LEFT_BIT;
}
if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) {
if (mask & DD_BACK_LEFT_BIT) {
flag |= VIA_BACK;
mask &= ~DD_BACK_LEFT_BIT;
}
@@ -239,9 +221,9 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
mask &= ~DD_STENCIL_BIT;
}
else {
fprintf(stderr, "XXX: Clear stencil writemask %x -- need triangles (or a ROP?)\n",
ctx->Stencil.WriteMask[0]);
/* Fixme - clear with triangles */
if (VIA_DEBUG)
fprintf(stderr, "XXX: Clear stencil writemask %x -- need triangles (or a ROP?)\n",
ctx->Stencil.WriteMask[0]);
}
}
}
@@ -293,11 +275,11 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
}
if (flag & VIA_FRONT) {
viaFillBuffer(vmesa, &vmesa->front, boxes, nr, vmesa->ClearColor, 0);
viaFillBuffer(vmesa, &vmesa->front, boxes, nr, vmesa->ClearColor, vmesa->ClearMask);
}
if (flag & VIA_BACK) {
viaFillBuffer(vmesa, &vmesa->back, boxes, nr, vmesa->ClearColor, 0); /* FIXME: masks */
viaFillBuffer(vmesa, &vmesa->back, boxes, nr, vmesa->ClearColor, vmesa->ClearMask);
}
if (flag & VIA_DEPTH) {
@@ -341,7 +323,7 @@ static void viaDoSwapBuffers(viaContextPtr vmesa,
src, back->pitch,
dest, front->pitch,
w, h,
0,0,VIA_BLIT_COPY, 0, 0);
VIA_BLIT_COPY, 0, 0);
}
}
@@ -513,11 +495,9 @@ static void via_emit_cliprect(viaContextPtr vmesa,
GLuint pitch = buffer->pitch;
GLuint offset = buffer->orig;
GLuint clipL = b->x1 - vmesa->drawX;
GLuint clipR = b->x2 - vmesa->drawX;
GLuint clipT = b->y1 - vmesa->drawY;
GLuint clipB = b->y2 - vmesa->drawY;
if (0)
fprintf(stderr, "emit cliprect for box %d,%d %d,%d\n", b->x1, b->y1, b->x2, b->y2);
vb[0] = HC_HEADER2;
vb[1] = (HC_ParaType_NotTex << 16);
@@ -526,8 +506,8 @@ static void via_emit_cliprect(viaContextPtr vmesa,
vb[3] = (HC_SubA_HClipLR << 24) | 0x0;
}
else {
vb[2] = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB;
vb[3] = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR;
vb[2] = (HC_SubA_HClipTB << 24) | (b->y1 << 12) | b->y2;
vb[3] = (HC_SubA_HClipLR << 24) | (b->x1 << 12) | b->x2;
}
vb[4] = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
@@ -543,6 +523,11 @@ static int intersect_rect(drm_clip_rect_t *out,
drm_clip_rect_t *b)
{
*out = *a;
if (0)
fprintf(stderr, "intersect %d,%d %d,%d and %d,%d %d,%d\n",
a->x1, a->y1, a->x2, a->y2,
b->x1, b->y1, b->x2, b->y2);
if (b->x1 > out->x1) out->x1 = b->x1;
if (b->x2 < out->x2) out->x2 = b->x2;
@@ -575,6 +560,9 @@ void viaFlushDmaLocked(viaContextPtr vmesa, GLuint flags)
int i;
RING_VARS;
if (VIA_DEBUG)
fprintf(stderr, "%s\n", __FUNCTION__);
if (*(GLuint *)vmesa->driHwLock != (DRM_LOCK_HELD|vmesa->hHWContext) &&
*(GLuint *)vmesa->driHwLock != (DRM_LOCK_HELD|DRM_LOCK_CONT|vmesa->hHWContext)) {
fprintf(stderr, "%s called without lock held\n", __FUNCTION__);
@@ -640,35 +628,42 @@ void viaFlushDmaLocked(viaContextPtr vmesa, GLuint flags)
dump_dma( vmesa );
if (flags & VIA_NO_CLIPRECTS) {
if (0) fprintf(stderr, "%s VIA_NO_CLIPRECTS\n", __FUNCTION__);
assert(vmesa->dmaCliprectAddr == 0);
fire_buffer( vmesa );
}
else if (!vmesa->dmaCliprectAddr) {
/* Contains only state. Could just dump the packet?
*/
if (0) fprintf(stderr, "no dmaCliprectAddr\n");
if (0) fprintf(stderr, "%s: no dmaCliprectAddr\n", __FUNCTION__);
if (0) fire_buffer( vmesa );
}
else if (vmesa->numClipRects) {
int ret;
drm_clip_rect_t *pbox = vmesa->pClipRects;
if (0) fprintf(stderr, "%s: %d cliprects\n", __FUNCTION__, vmesa->numClipRects);
for (i = 0; i < vmesa->numClipRects; i++) {
if (vmesa->glCtx->Scissor.Enabled) {
drm_clip_rect_t b;
if (!intersect_rect(&b, &pbox[i], &vmesa->scissorRect))
continue;
via_emit_cliprect(vmesa, &b);
}
else {
via_emit_cliprect(vmesa, &pbox[i]);
}
ret = fire_buffer(vmesa);
if (ret)
drm_clip_rect_t b;
b.x1 = pbox[i].x1 - (vmesa->drawX + vmesa->drawXoff);
b.x2 = pbox[i].x2 - (vmesa->drawX + vmesa->drawXoff);
b.y1 = pbox[i].y1 - vmesa->drawY;
b.y2 = pbox[i].y2 - vmesa->drawY;
if (vmesa->glCtx->Scissor.Enabled &&
!intersect_rect(&b, &b, &vmesa->scissorRect))
continue;
b.x1 += vmesa->drawXoff;
b.x2 += vmesa->drawXoff;
via_emit_cliprect(vmesa, &b);
if (fire_buffer(vmesa) != 0)
goto done;
}
} else {
if (0) fprintf(stderr, "%s: no cliprects\n", __FUNCTION__);
UNLOCK_HARDWARE(vmesa);
sched_yield();
LOCK_HARDWARE(vmesa);
@@ -760,6 +755,9 @@ GLuint *viaAllocDmaFunc(viaContextPtr vmesa, int bytes, const char *func, int li
GLuint *viaExtendPrimitive(viaContextPtr vmesa, int bytes)
{
if (0)
fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
assert(vmesa->dmaLastPrim);
if (vmesa->dmaLow + bytes > VIA_DMA_HIGHWATER) {
viaWrapPrimitive(vmesa);

View File

@@ -615,7 +615,8 @@ static void viaScissor(GLcontext *ctx, GLint x, GLint y,
if (!vmesa->driDrawable)
return;
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
if (VIA_DEBUG)
fprintf(stderr, "%s %d,%d %dx%d, drawH %d\n", __FUNCTION__, x,y,w,h, vmesa->driDrawable->h);
if (ctx->Scissor.Enabled) {
VIA_FLUSH_DMA(vmesa); /* don't pipeline cliprect changes */
@@ -628,6 +629,19 @@ static void viaScissor(GLcontext *ctx, GLint x, GLint y,
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
}
static void viaEnable(GLcontext *ctx, GLenum cap, GLboolean state)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
switch (cap) {
case GL_SCISSOR_TEST:
VIA_FLUSH_DMA(vmesa);
break;
default:
break;
}
}
/* Fallback to swrast for select and feedback.
@@ -684,6 +698,26 @@ static void viaClearColor(GLcontext *ctx, const GLfloat color[4])
}
#define WRITEMASK_ALPHA_SHIFT 31
#define WRITEMASK_RED_SHIFT 30
#define WRITEMASK_GREEN_SHIFT 29
#define WRITEMASK_BLUE_SHIFT 28
static void viaColorMask(GLcontext *ctx,
GLboolean r, GLboolean g,
GLboolean b, GLboolean a)
{
viaContextPtr vmesa = VIA_CONTEXT( ctx );
if (VIA_DEBUG)
fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a);
vmesa->ClearMask = (((!r) << WRITEMASK_RED_SHIFT) |
((!g) << WRITEMASK_GREEN_SHIFT) |
((!b) << WRITEMASK_BLUE_SHIFT) |
((!a) << WRITEMASK_ALPHA_SHIFT));
}
/* =============================================================
*/
@@ -1256,12 +1290,13 @@ static void viaChooseColorState(GLcontext *ctx)
vmesa->regHROP = HC_HROP_P;
vmesa->regHFBBMSKL = (*(GLuint *)&ctx->Color.ColorMask[0]) & 0xFFFFFF;
vmesa->regHROP |= ((*(GLuint *)&ctx->Color.ColorMask[0]) >> 24) & 0xFF;
vmesa->regHROP |= ctx->Color.ColorMask[3];
if ((GLuint)((GLuint *)&ctx->Color.ColorMask[0]) & 0xFF000000)
if (ctx->Color.ColorMask[3])
vmesa->regEnable |= HC_HenAW_MASK;
else
vmesa->regEnable &= (~HC_HenAW_MASK);
vmesa->regEnable &= ~HC_HenAW_MASK;
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
@@ -1585,11 +1620,13 @@ void viaInitStateFuncs(GLcontext *ctx)
ctx->Driver.BlendEquationSeparate = viaBlendEquationSeparate;
ctx->Driver.BlendFuncSeparate = viaBlendFuncSeparate;
ctx->Driver.ClearColor = viaClearColor;
ctx->Driver.ColorMask = viaColorMask;
ctx->Driver.DrawBuffer = viaDrawBuffer;
ctx->Driver.RenderMode = viaRenderMode;
ctx->Driver.Scissor = viaScissor;
ctx->Driver.DepthRange = viaDepthRange;
ctx->Driver.Viewport = viaViewport;
ctx->Driver.Enable = viaEnable;
/* Pixel path fallbacks.
*/

View File

@@ -222,7 +222,7 @@ static struct {
} while (0)
#define DEPTH_SCALE (1.0 / 0xffff)
#define DEPTH_SCALE vmesa->polygon_offset_scale
#define UNFILLED_TRI unfilled_tri
#define UNFILLED_QUAD unfilled_quad
#define VERT_X(_v) _v->v.x
@@ -790,9 +790,11 @@ static void viaRenderPrimitive( GLcontext *ctx, GLuint prim )
void viaFinishPrimitive(viaContextPtr vmesa)
{
if (VIA_DEBUG) fprintf(stderr, "%s\n", __FUNCTION__);
if (VIA_DEBUG)
fprintf(stderr, "%s\n", __FUNCTION__);
if (!vmesa->dmaLastPrim) {
if (!vmesa->dmaLastPrim || !vmesa->dmaCliprectAddr) {
assert(0);
}
else if (vmesa->dmaLow != vmesa->dmaLastPrim) {
GLuint cmdA = vmesa->regCmdA_End | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK;
@@ -818,6 +820,9 @@ void viaFinishPrimitive(viaContextPtr vmesa)
viaFlushDma( vmesa );
}
else {
if (VIA_DEBUG)
fprintf(stderr, "remove empty primitive\n");
/* Remove the primitive header:
*/
vmesa->dmaLastPrim = 0;