Skip to content
Snippets Groups Projects
Commit a656dc25 authored by Vladimir Dergachev's avatar Vladimir Dergachev
Browse files

Restructure code.

Add drawing code that uses vertex buffers - does not lockup, but does not draw correctly either.. Perhaps something to do with vertices being overwritten ?
Start using hardware state retained by the driver and cut back on direct register writes significantly.
parent 51050efe
No related branches found
No related tags found
No related merge requests found
......@@ -63,63 +63,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* rasterization hardware for rendering.
**********************************************************************/
static void r300_render_flat_primitive(r300ContextPtr rmesa,
GLcontext *ctx,
int start,
int end,
int type)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i;
int k;
LOCAL_VARS
if(end<=start)return; /* do we need to watch for this ? */
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 */
efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[0]);
efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[1]);
efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[2]);
#if 0
efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[3]);
#else
efloat(2.0);
#endif
/* color components */
efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0]);
efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1]);
efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2]);
#if 0
efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]);
#else
efloat(0.0);
#endif
}
}
static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,
static int r300_get_primitive_type(r300ContextPtr rmesa,
GLcontext *ctx,
int start,
int end,
......@@ -130,7 +74,7 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,
GLuint i;
int type=-1;
if(end<=start)return; /* do we need to watch for this ? */
if(end<=start)return -1; /* do we need to watch for this ? */
fprintf(stderr, "[%d-%d]", start, end);
switch (prim & PRIM_MODE_MASK) {
......@@ -139,7 +83,7 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,
type=R300_VAP_VF_CNTL__PRIM_LINES;
if(end<start+2){
fprintf(stderr, "Not enough vertices\n");
return; /* need enough vertices for Q */
return -1; /* need enough vertices for Q */
}
break;
case GL_LINE_STRIP:
......@@ -147,15 +91,15 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,
type=R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
if(end<start+2){
fprintf(stderr, "Not enough vertices\n");
return; /* need enough vertices for Q */
return -1; /* need enough vertices for Q */
}
break;
case GL_LINE_LOOP:
fprintf(stderr, "LL ");
return;
return -1;
if(end<start+2){
fprintf(stderr, "Not enough vertices\n");
return; /* need enough vertices for Q */
return -1; /* need enough vertices for Q */
}
break;
case GL_TRIANGLES:
......@@ -163,7 +107,7 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,
type=R300_VAP_VF_CNTL__PRIM_TRIANGLES;
if(end<start+3){
fprintf(stderr, "Not enough vertices\n");
return; /* need enough vertices for Q */
return -1; /* need enough vertices for Q */
}
break;
case GL_TRIANGLE_STRIP:
......@@ -171,7 +115,7 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,
type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
if(end<start+3){
fprintf(stderr, "Not enough vertices\n");
return; /* need enough vertices for Q */
return -1; /* need enough vertices for Q */
}
break;
case GL_TRIANGLE_FAN:
......@@ -179,7 +123,7 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,
type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
if(end<start+3){
fprintf(stderr, "Not enough vertices\n");
return; /* need enough vertices for Q */
return -1; /* need enough vertices for Q */
}
break;
case GL_QUADS:
......@@ -187,7 +131,7 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,
type=R300_VAP_VF_CNTL__PRIM_QUADS;
if(end<start+4){
fprintf(stderr, "Not enough vertices\n");
return; /* need enough vertices for Q */
return -1; /* need enough vertices for Q */
}
break;
case GL_QUAD_STRIP:
......@@ -195,16 +139,97 @@ static void r300_dispatch_flat_primitive(r300ContextPtr rmesa,
type=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
if(end<start+4){
fprintf(stderr, "Not enough vertices\n");
return; /* need enough vertices for Q */
return -1; /* need enough vertices for Q */
}
break;
default:
fprintf(stderr, "Cannot handle primitive %02x ", prim & PRIM_MODE_MASK);
return;
return -1;
break;
}
r300_render_flat_primitive(rmesa, ctx, start, end, type);
return type;
}
/* Immediate implementation - vertex data is sent via command stream */
static GLfloat default_vector[4]={0.0, 0.0, 0.0, 1.0};
#define output_vector(v, i) \
{ \
int _i; \
for(_i=0;_i<v->size;_i++){ \
efloat(VEC_ELT(v, GLfloat, i)[_i]); \
} \
for(_i=v->size;_i<4;_i++){ \
efloat(default_vector[_i]); \
} \
}
static void r300_render_flat_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);
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 */
#if 1
output_vector(VB->ObjPtr, i);
#else
efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[0]);
efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[1]);
efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[2]);
#if 0
efloat(VEC_ELT(VB->ObjPtr, GLfloat, i)[3]);
#else
efloat(2.0);
#endif
#endif
/* color components */
#if 1
output_vector(VB->ColorPtr[0], i);
#else
efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0]);
efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1]);
efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2]);
#if 0
efloat(VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]);
#else
efloat(0.0);
#endif
#endif
}
}
static GLboolean r300_run_flat_render(GLcontext *ctx,
......@@ -214,7 +239,6 @@ static GLboolean r300_run_flat_render(GLcontext *ctx,
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i;
ADAPTOR adaptor;
AOS_DATA vb_arrays[2];
LOCAL_VARS
......@@ -231,6 +255,7 @@ static GLboolean r300_run_flat_render(GLcontext *ctx,
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;
......@@ -238,46 +263,205 @@ static GLboolean r300_run_flat_render(GLcontext *ctx,
vb_arrays[1].offset=0; /* Not used */
vb_arrays[1].format=AOS_FORMAT_FLOAT_COLOR;
vb_arrays[1].ncomponents=4;
vb_arrays[1].reg=REG_COLOR0;
adaptor=TWO_PIPE_ADAPTOR;
r300EmitState(rmesa);
adaptor.color_offset[0]=rmesa->radeon.radeonScreen->backOffset+rmesa->radeon.radeonScreen->fbLocation;
adaptor.color_pitch[0]=(rmesa->radeon.radeonScreen->backPitch) | (0xc0<<16);
/* needed before starting 3d operation .. */
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
e32(0x0000000a);
reg_start(0x4f18,0);
e32(0x00000003);
reg_start(0x20b0,0);
e32(0x0000043f);
program_pipeline(PASS_PREFIX &FLAT_COLOR_PIPELINE);
adaptor.depth_offset=rmesa->radeon.radeonScreen->depthOffset;
adaptor.depth_pitch=rmesa->radeon.radeonScreen->depthPitch | (0x2 << 16);
#if 0 /* Turn on for smooth color on teeth.. why ??.. */
set_cull_cntl(PASS_PREFIX 0);
#endif
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);
init_3d(PASS_PREFIX &adaptor);
init_flat_primitive(PASS_PREFIX &adaptor);
/* 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_flat_primitive(rmesa, ctx, start, start + length, prim);
}
end_3d(PASS_PREFIX_VOID);
set_scissors(PASS_PREFIX 0, 0, 2647, 1941);
fprintf(stderr, "\n");
return GL_FALSE;
}
/* vertex buffer implementation */
/* We use the start part of GART texture buffer for vertices */
set_cliprect(PASS_PREFIX 0, 0, 0, 2647,1941);
set_cliprect(PASS_PREFIX 1, 0, 0, 2647,1941);
set_cliprect(PASS_PREFIX 2, 0, 0, 2647,1941);
set_cliprect(PASS_PREFIX 3, 0, 0, 2647,1941);
#define R300_MAX_AOS_ARRAYS 16
static void upload_vertex_buffer(r300ContextPtr rmesa,
GLcontext *ctx, AOS_DATA *array, int *n_arrays)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
int offset=0, idx=0;
int i,j;
radeonScreenPtr rsp=rmesa->radeon.radeonScreen;
/* Not the most efficient implementation, but, for now, I just want something that
works */
/* to do - make single memcpy per column (is it possible ?) */
/* to do - use dirty flags to avoid redundant copies */
#define UPLOAD_VECTOR(v, r, f)\
{ \
/* Is the data dirty ? */ \
if (v->flags & ((1<<v->size)-1)) { \
fprintf(stderr, "size=%d vs stride=%d\n", v->size, v->stride); \
if(v->size*4==v->stride){\
/* fast path */ \
memcpy(rsp->gartTextures.map+offset, v->data, v->stride*VB->Count); \
} 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); \
} \
} \
/* v->flags &= ~((1<<v->size)-1);*/ \
} \
array[idx].element_size=v->size; \
array[idx].stride=v->size; \
array[idx].format=(f); \
array[idx].ncomponents=v->size; \
array[idx].offset=rsp->gartTextures.handle+offset; \
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);
*n_arrays=idx;
if(idx>=R300_MAX_AOS_ARRAYS){
fprintf(stderr, "Aieee ! Maximum AOS arrays count exceeded.. \n");
exit(-1);
}
}
static void r300_render_vb_flat_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, n_arrays;
LOCAL_VARS
if(end<=start)return; /* do we need to watch for this ? */
type=r300_get_primitive_type(rmesa, ctx, start, end, prim);
if(type<0)return;
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)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
int i, j, n_arrays;
AOS_DATA vb_arrays[R300_MAX_AOS_ARRAYS];
AOS_DATA vb_arrays2[R300_MAX_AOS_ARRAYS];
LOCAL_VARS
if (RADEON_DEBUG == DEBUG_PRIMS)
fprintf(stderr, "%s\n", __FUNCTION__);
/* setup array of structures data */
upload_vertex_buffer(rmesa, ctx, vb_arrays, &n_arrays);
fprintf(stderr, "Using %d AOS arrays\n", n_arrays);
r300EmitState(rmesa);
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
e32(0x0000000a);
reg_start(0x4f18,0);
e32(0x00000003);
reg_start(0x20b0,0);
e32(0x0000043f);
program_pipeline(PASS_PREFIX &FLAT_COLOR_PIPELINE);
//upload_vertex_shader_fragment(PASS_PREFIX VSF_DEST_UNKNOWN1, &default_vector_vsf);
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);
/* 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_dispatch_flat_primitive(rmesa, ctx, start, start + length, prim);
/* 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;
}
setup_AOS(PASS_PREFIX vb_arrays2, n_arrays);
r300_render_vb_flat_primitive(rmesa, ctx, start, start + length, prim);
}
end_3d(PASS_PREFIX_VOID);
start_packet3(RADEON_CP_PACKET3_NOP, 0);
e32(0x0);
/* Flush state - we are done drawing.. */
r300Flush(ctx);
fprintf(stderr, "\n");
return GL_FALSE;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment