Module: Mesa
Branch: mesa_7_6_branch
Commit: 9edd1a441c3c0c3f018ae561cd5711398ca56f95
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=9edd1a441c3c0c3f018ae561cd5711398ca56f95

Author: Andre Maasikas <amaasi...@gmail.com>
Date:   Fri Sep 11 10:59:05 2009 -0400

r600: enable caching of vertex programs

---

 src/mesa/drivers/dri/r600/r600_context.h  |    3 +
 src/mesa/drivers/dri/r600/r700_chip.c     |   10 +--
 src/mesa/drivers/dri/r600/r700_oglprog.c  |   36 +++++-----
 src/mesa/drivers/dri/r600/r700_render.c   |    9 ++-
 src/mesa/drivers/dri/r600/r700_vertprog.c |  103 +++++++++++++++++++---------
 src/mesa/drivers/dri/r600/r700_vertprog.h |   11 +++-
 6 files changed, 110 insertions(+), 62 deletions(-)

diff --git a/src/mesa/drivers/dri/r600/r600_context.h 
b/src/mesa/drivers/dri/r600/r600_context.h
index 8ae05a3..c59df75 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 312cacf..1b56059 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; i<VERT_ATTRIB_MAX; i++) {
-           if(vpc->mesa_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; i<VERT_ATTRIB_MAX; i++) {
-           if(vpc->mesa_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 3c8c1fd..5290ef3 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 3566bf3..b1c3648 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 d107f99..8c2b007 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; i<VERT_ATTRIB_MAX; i++)
+       {
+               unBit = 1 << i;
+               if(vp->mesa_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; i<VERT_ATTRIB_MAX; i++)
        {
                unBit = 1 << i;
-               if(vpc->mesa_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 e2e6502..c48764c 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 */

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to