From: Andre Maasikas Date: Fri, 11 Sep 2009 14:59:05 +0000 (-0400) Subject: r600: enable caching of vertex programs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9edd1a441c3c0c3f018ae561cd5711398ca56f95;p=mesa.git r600: enable caching of vertex programs --- diff --git a/src/mesa/drivers/dri/r600/r600_context.h b/src/mesa/drivers/dri/r600/r600_context.h index 8ae05a301c7..c59df7505af 100644 --- a/src/mesa/drivers/dri/r600/r600_context.h +++ b/src/mesa/drivers/dri/r600/r600_context.h @@ -51,6 +51,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r700_chip.h" #include "r600_tex.h" #include "r700_oglprog.h" +#include "r700_vertprog.h" struct r600_context; typedef struct r600_context context_t; @@ -155,6 +156,8 @@ struct r600_context { struct r600_hw_state atoms; + struct r700_vertex_program *selected_vp; + /* Vertex buffers */ GLvector4f dummy_attrib[_TNL_ATTRIB_MAX]; diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c index 312cacffda3..1b560591974 100644 --- a/src/mesa/drivers/dri/r600/r700_chip.c +++ b/src/mesa/drivers/dri/r600/r700_chip.c @@ -211,8 +211,7 @@ static void r700SetupVTXConstants(GLcontext * ctx, void r700SetupStreams(GLcontext *ctx) { context_t *context = R700_CONTEXT(ctx); - struct r700_vertex_program *vpc - = (struct r700_vertex_program *)ctx->VertexProgram._Current; + struct r700_vertex_program *vp = context->selected_vp; TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *vb = &tnl->vb; unsigned int i, j = 0; @@ -221,7 +220,7 @@ void r700SetupStreams(GLcontext *ctx) R600_STATECHANGE(context, vtx); for(i=0; imesa_program.Base.InputsRead & (1 << i)) { + if(vp->mesa_program->Base.InputsRead & (1 << i)) { rcommon_emit_vector(ctx, &context->radeon.tcl.aos[j], vb->AttribPtr[i]->data, @@ -237,8 +236,7 @@ void r700SetupStreams(GLcontext *ctx) static void r700SendVTXState(GLcontext *ctx, struct radeon_state_atom *atom) { context_t *context = R700_CONTEXT(ctx); - struct r700_vertex_program *vpc - = (struct r700_vertex_program *)ctx->VertexProgram._Current; + struct r700_vertex_program *vp = context->selected_vp; unsigned int i, j = 0; BATCH_LOCALS(&context->radeon); radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__); @@ -258,7 +256,7 @@ static void r700SendVTXState(GLcontext *ctx, struct radeon_state_atom *atom) COMMIT_BATCH(); for(i=0; imesa_program.Base.InputsRead & (1 << i)) { + if(vp->mesa_program->Base.InputsRead & (1 << i)) { /* currently aos are packed */ r700SetupVTXConstants(ctx, i, diff --git a/src/mesa/drivers/dri/r600/r700_oglprog.c b/src/mesa/drivers/dri/r600/r700_oglprog.c index 3c8c1fd7a34..5290ef31be3 100644 --- a/src/mesa/drivers/dri/r600/r700_oglprog.c +++ b/src/mesa/drivers/dri/r600/r700_oglprog.c @@ -46,7 +46,7 @@ static struct gl_program *r700NewProgram(GLcontext * ctx, { struct gl_program *pProgram = NULL; - struct r700_vertex_program *vp; + struct r700_vertex_program_cont *vpc; struct r700_fragment_program *fp; radeon_print(RADEON_SHADER, RADEON_VERBOSE, @@ -56,16 +56,11 @@ static struct gl_program *r700NewProgram(GLcontext * ctx, { case GL_VERTEX_STATE_PROGRAM_NV: case GL_VERTEX_PROGRAM_ARB: - vp = CALLOC_STRUCT(r700_vertex_program); + vpc = CALLOC_STRUCT(r700_vertex_program_cont); pProgram = _mesa_init_vertex_program(ctx, - &vp->mesa_program, + &vpc->mesa_program, target, id); - vp->translated = GL_FALSE; - vp->loaded = GL_FALSE; - - vp->shaderbo = NULL; - break; case GL_FRAGMENT_PROGRAM_NV: case GL_FRAGMENT_PROGRAM_ARB: @@ -89,7 +84,8 @@ static struct gl_program *r700NewProgram(GLcontext * ctx, static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog) { - struct r700_vertex_program * vp; + struct r700_vertex_program_cont * vpc; + struct r700_vertex_program *vp, *tmp; struct r700_fragment_program * fp; radeon_print(RADEON_SHADER, RADEON_VERBOSE, @@ -99,14 +95,20 @@ static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog) { case GL_VERTEX_STATE_PROGRAM_NV: case GL_VERTEX_PROGRAM_ARB: - vp = (struct r700_vertex_program*)prog; - /* Release DMA region */ - - r600DeleteShader(ctx, vp->shaderbo); - - /* Clean up */ - Clean_Up_Assembler(&(vp->r700AsmCode)); - Clean_Up_Shader(&(vp->r700Shader)); + vpc = (struct r700_vertex_program_cont*)prog; + vp = vpc->progs; + while (vp) { + tmp = vp->next; + /* Release DMA region */ + + r600DeleteShader(ctx, vp->shaderbo); + + /* Clean up */ + Clean_Up_Assembler(&(vp->r700AsmCode)); + Clean_Up_Shader(&(vp->r700Shader)); + _mesa_free(vp); + vp = tmp; + } break; case GL_FRAGMENT_PROGRAM_NV: case GL_FRAGMENT_PROGRAM_ARB: diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c index 3566bf3ca78..b1c3648ca56 100644 --- a/src/mesa/drivers/dri/r600/r700_render.c +++ b/src/mesa/drivers/dri/r600/r700_render.c @@ -319,14 +319,13 @@ static GLuint r700PredictRenderSize(GLcontext* ctx) { context_t *context = R700_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); - struct r700_vertex_program *vpc - = (struct r700_vertex_program *)ctx->VertexProgram._Current; + struct r700_vertex_program *vp = context->selected_vp; struct vertex_buffer *vb = &tnl->vb; GLboolean flushed; GLuint dwords, i; GLuint state_size; /* pre calculate aos count so state prediction works */ - context->radeon.tcl.aos_count = _mesa_bitcount(vpc->mesa_program.Base.InputsRead); + context->radeon.tcl.aos_count = _mesa_bitcount(vp->mesa_program->Base.InputsRead); dwords = PRE_EMIT_STATE_BUFSZ; for (i = 0; i < vb->PrimitiveCount; i++) @@ -365,7 +364,6 @@ static GLboolean r700RunRender(GLcontext * ctx, /* mark vtx as dirty since it changes per-draw */ R600_STATECHANGE(context, vtx); - r700UpdateShaders(ctx); r700SetScissor(context); r700SetupVertexProgram(ctx); r700SetupFragmentProgram(ctx); @@ -427,7 +425,10 @@ static GLboolean r700RunTCLRender(GLcontext * ctx, /*----------------------*/ /* TODO : sw fallback */ + /* Need shader bo's setup before bo check */ + r700UpdateShaders(ctx); /** + * Ensure all enabled and complete textures are uploaded along with any buffers being used. */ if(!r600ValidateBuffers(ctx)) diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c index d107f99e7ba..8c2b0071df9 100644 --- a/src/mesa/drivers/dri/r600/r700_vertprog.c +++ b/src/mesa/drivers/dri/r600/r700_vertprog.c @@ -35,6 +35,7 @@ #include "main/mtypes.h" #include "tnl/t_context.h" +#include "shader/program.h" #include "shader/prog_parameter.h" #include "shader/prog_statevars.h" @@ -258,28 +259,54 @@ GLboolean Find_Instruction_Dependencies_vp(struct r700_vertex_program *vp, return GL_TRUE; } -GLboolean r700TranslateVertexShader(struct r700_vertex_program *vp, - struct gl_vertex_program *mesa_vp) +struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx, + struct gl_vertex_program *mesa_vp) { + context_t *context = R700_CONTEXT(ctx); + struct r700_vertex_program *vp; + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *vb = &tnl->vb; + unsigned int unBit; + unsigned int i; + + vp = _mesa_calloc(sizeof(*vp)); + vp->mesa_program = (struct gl_vertex_program *)_mesa_clone_program(ctx, &mesa_vp->Base); + + for(i=0; imesa_program->Base.InputsRead & unBit) /* ctx->Array.ArrayObj->xxxxxxx */ + { + vp->aos_desc[i].size = vb->AttribPtr[i]->size; + vp->aos_desc[i].stride = vb->AttribPtr[i]->size * sizeof(GL_FLOAT);/* when emit array, data is packed. vb->AttribPtr[i]->stride;*/ + vp->aos_desc[i].type = GL_FLOAT; + } + } + + if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) + { + vp->r700AsmCode.bR6xx = 1; + } + //Init_Program Init_r700_AssemblerBase(SPT_VP, &(vp->r700AsmCode), &(vp->r700Shader) ); Map_Vertex_Program( vp, mesa_vp ); if(GL_FALSE == Find_Instruction_Dependencies_vp(vp, mesa_vp)) { - return GL_FALSE; + return NULL; } if(GL_FALSE == AssembleInstr(mesa_vp->Base.NumInstructions, &(mesa_vp->Base.Instructions[0]), &(vp->r700AsmCode)) ) { - return GL_FALSE; + return NULL; } if(GL_FALSE == Process_Vertex_Exports(&(vp->r700AsmCode), mesa_vp->Base.OutputsWritten) ) { - return GL_FALSE; + return NULL; } vp->r700Shader.nRegs = (vp->r700AsmCode.number_used_registers == 0) ? 0 @@ -289,72 +316,82 @@ GLboolean r700TranslateVertexShader(struct r700_vertex_program *vp, vp->translated = GL_TRUE; - return GL_TRUE; + return vp; } void r700SelectVertexShader(GLcontext *ctx) { context_t *context = R700_CONTEXT(ctx); - struct r700_vertex_program *vpc - = (struct r700_vertex_program *)ctx->VertexProgram._Current; + struct r700_vertex_program_cont *vpc; + struct r700_vertex_program *vp; TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *vb = &tnl->vb; unsigned int unBit; unsigned int i; + GLboolean match; + vpc = (struct r700_vertex_program_cont *)ctx->VertexProgram._Current; + +#if 0 if (context->radeon.NewGLState & (_NEW_PROGRAM_CONSTANTS|_NEW_PROGRAM)) { vpc->needUpdateVF = 1; } +#endif - if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) + for (vp = vpc->progs; vp; vp = vp->next) { - vpc->r700AsmCode.bR6xx = 1; - } - + match = GL_TRUE; for(i=0; imesa_program.Base.InputsRead & unBit) /* ctx->Array.ArrayObj->xxxxxxx */ + if(vpc->mesa_program.Base.InputsRead & unBit) { - vpc->aos_desc[i].size = vb->AttribPtr[i]->size; - vpc->aos_desc[i].stride = vb->AttribPtr[i]->size * sizeof(GL_FLOAT);/* when emit array, data is packed. vb->AttribPtr[i]->stride;*/ - vpc->aos_desc[i].type = GL_FLOAT; + if (vp->aos_desc[i].size != vb->AttribPtr[i]->size) + match = GL_FALSE; + break; } } - - if(GL_FALSE == vpc->translated) { - r700TranslateVertexShader(vpc, &(vpc->mesa_program) ); + if (match) + { + context->selected_vp = vp; + return; } + } + + vp = r700TranslateVertexShader(ctx, &(vpc->mesa_program) ); + if(!vp) + { + radeon_error("Failed to translate vertex shader. \n"); + return; + } + vp->next = vpc->progs; + vpc->progs = vp; + context->selected_vp = vp; + return; } void * r700GetActiveVpShaderBo(GLcontext * ctx) { - struct r700_vertex_program *vp - = (struct r700_vertex_program *)ctx->VertexProgram._Current; + context_t *context = R700_CONTEXT(ctx); + struct r700_vertex_program *vp = context->selected_vp;; - return vp->shaderbo; + if (vp) + return vp->shaderbo; + else + return NULL; } GLboolean r700SetupVertexProgram(GLcontext * ctx) { context_t *context = R700_CONTEXT(ctx); R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw); - struct r700_vertex_program *vp - = (struct r700_vertex_program *)ctx->VertexProgram._Current; + struct r700_vertex_program *vp = context->selected_vp; struct gl_program_parameter_list *paramList; unsigned int unNumParamData; unsigned int ui; - if (vp->needUpdateVF) - { - vp->loaded = GL_FALSE; - vp->r700Shader.bNeedsAssembly = GL_TRUE; - Process_Vertex_Program_Vfetch_Instructions(vp, &(vp->mesa_program)); - r600DeleteShader(ctx, vp->shaderbo); - } - if(GL_FALSE == vp->loaded) { if(vp->r700Shader.bNeedsAssembly == GL_TRUE) @@ -410,7 +447,7 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx) */ /* sent out shader constants. */ - paramList = vp->mesa_program.Base.Parameters; + paramList = vp->mesa_program->Base.Parameters; if(NULL != paramList) { _mesa_load_state_parameters(ctx, paramList); diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.h b/src/mesa/drivers/dri/r600/r700_vertprog.h index e2e65021fd3..c48764c43ba 100644 --- a/src/mesa/drivers/dri/r600/r700_vertprog.h +++ b/src/mesa/drivers/dri/r600/r700_vertprog.h @@ -43,7 +43,7 @@ typedef struct ArrayDesc //TEMP struct r700_vertex_program { - struct gl_vertex_program mesa_program; /* Must be first */ + struct gl_vertex_program *mesa_program; /* Must be first */ struct r700_vertex_program *next; @@ -59,6 +59,13 @@ struct r700_vertex_program ArrayDesc aos_desc[VERT_ATTRIB_MAX]; }; +struct r700_vertex_program_cont +{ + struct gl_vertex_program mesa_program; + + struct r700_vertex_program *progs; +}; + //Internal unsigned int Map_Vertex_Output(r700_AssemblerBase *pAsm, struct gl_vertex_program *mesa_vp, @@ -74,7 +81,7 @@ void Map_Vertex_Program(struct r700_vertex_program *vp, GLboolean Find_Instruction_Dependencies_vp(struct r700_vertex_program *vp, struct gl_vertex_program *mesa_vp); -GLboolean r700TranslateVertexShader(struct r700_vertex_program *vp, +struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx, struct gl_vertex_program *mesa_vp); /* Interface */