gallium/draw: initial code to properly support llvm in the draw module
[mesa.git] / src / mesa / drivers / dri / r600 / r700_vertprog.c
index d12c39c9f73eafed3ae4f48c7addfa77e8128a3d..07e0adc89056b498c3c2ed8f5396917c276b96e0 100644 (file)
@@ -111,6 +111,15 @@ unsigned int Map_Vertex_Output(r700_AssemblerBase       *pAsm,
                }
        }
 
+    for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++)
+       {
+               unBit = 1 << i;
+               if(mesa_vp->Base.OutputsWritten & unBit)
+               {
+                       pAsm->ucVP_OutputMap[i] = unTotal++;
+               }
+       }
+
        return (unTotal - unStart);
 }
 
@@ -179,7 +188,8 @@ GLboolean Process_Vertex_Program_Vfetch_Instructions2(
                                       context->stream_desc[i].size,
                                       context->stream_desc[i].element,
                                       context->stream_desc[i]._signed,
-                                      context->stream_desc[i].normalize,                                                           
+                                      context->stream_desc[i].normalize,
+                                      context->stream_desc[i].format,
                                      &vtxFetchMethod);
     }
 
@@ -203,22 +213,11 @@ void Map_Vertex_Program(GLcontext *ctx,
        pAsm->number_used_registers += num_inputs;
 
        // Create VFETCH instructions for inputs
-       if(1 == vp->uiVersion) 
-    {
-           if (GL_TRUE != Process_Vertex_Program_Vfetch_Instructions(vp, mesa_vp) ) 
-           {
-                   radeon_error("Calling Process_Vertex_Program_Vfetch_Instructions return error. \n");
-                   return; 
-           }
-    }
-    else
-    {
-        if (GL_TRUE != Process_Vertex_Program_Vfetch_Instructions2(ctx, vp, mesa_vp) ) 
-           {
-                   radeon_error("Calling Process_Vertex_Program_Vfetch_Instructions2 return error. \n");
-                   return; 
-           }
-    }
+        if (GL_TRUE != Process_Vertex_Program_Vfetch_Instructions2(ctx, vp, mesa_vp) )
+       {
+               radeon_error("Calling Process_Vertex_Program_Vfetch_Instructions2 return error. \n");
+               return;
+       }
 
        // Map Outputs
        pAsm->number_of_exports = Map_Vertex_Output(pAsm, mesa_vp, pAsm->number_used_registers);
@@ -228,7 +227,7 @@ void Map_Vertex_Program(GLcontext *ctx,
        pAsm->number_used_registers += pAsm->number_of_exports;
 
     pAsm->pucOutMask = (unsigned char*) MALLOC(pAsm->number_of_exports);
-    
+
     for(ui=0; ui<pAsm->number_of_exports; ui++)
     {
         pAsm->pucOutMask[ui] = 0x0;
@@ -245,7 +244,9 @@ void Map_Vertex_Program(GLcontext *ctx,
     {   /* fix func t_vp uses NumTemporaries */
         pAsm->number_used_registers += mesa_vp->Base.NumTemporaries;
     }
-       
+
+    pAsm->flag_reg_index = pAsm->number_used_registers++;
+
     pAsm->uFirstHelpReg = pAsm->number_used_registers;
 }
 
@@ -300,48 +301,28 @@ GLboolean Find_Instruction_Dependencies_vp(struct r700_vertex_program *vp,
 }
 
 struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
-                                               struct gl_vertex_program *mesa_vp,
-                        GLint nVer)
+                                                     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->uiVersion = nVer;
-       vp->mesa_program = (struct gl_vertex_program *)_mesa_clone_program(ctx, &mesa_vp->Base);
+       vp = calloc(1, sizeof(*vp));
+       vp->mesa_program = _mesa_clone_vertex_program(ctx, mesa_vp);
 
        if (mesa_vp->IsPositionInvariant)
        {
                 _mesa_insert_mvp_code(ctx, vp->mesa_program);
         }
 
-       if( 1 == nVer )
+       for(i=0; i<context->nNumActiveAos; i++)
        {
-           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;
-               }
-           }
+               vp->aos_desc[i].size   = context->stream_desc[i].size;
+               vp->aos_desc[i].stride = context->stream_desc[i].stride;
+               vp->aos_desc[i].type   = context->stream_desc[i].type;
+               vp->aos_desc[i].format = context->stream_desc[i].format;
        }
-       else
-       {
-               for(i=0; i<context->nNumActiveAos; i++)
-               {
-                       vp->aos_desc[i].size   = context->stream_desc[i].size;
-                       vp->aos_desc[i].stride = context->stream_desc[i].stride;
-                       vp->aos_desc[i].type   = context->stream_desc[i].type;
-               }
-       }       
-       
+
        if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
        {
                vp->r700AsmCode.bR6xx = 1;
@@ -354,20 +335,36 @@ struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
        if(GL_FALSE == Find_Instruction_Dependencies_vp(vp, vp->mesa_program))
        {
                return NULL;
+       }
+
+    InitShaderProgram(&(vp->r700AsmCode));
+
+    for(i=0; i < MAX_SAMPLERS; i++)
+    {
+        vp->r700AsmCode.SamplerUnits[i] = vp->mesa_program->Base.SamplerUnits[i];
     }
 
-       if(GL_FALSE == AssembleInstr(vp->mesa_program->Base.NumInstructions,
-                                 &(vp->mesa_program->Base.Instructions[0]), 
+    vp->r700AsmCode.unCurNumILInsts = vp->mesa_program->Base.NumInstructions;
+
+       if(GL_FALSE == AssembleInstr(0,
+                                 0,
+                                 vp->mesa_program->Base.NumInstructions,
+                                 &(vp->mesa_program->Base.Instructions[0]),
                                  &(vp->r700AsmCode)) )
        {
                return NULL;
-       } 
+       }
 
     if(GL_FALSE == Process_Vertex_Exports(&(vp->r700AsmCode), vp->mesa_program->Base.OutputsWritten) )
     {
         return NULL;
     }
 
+    if( GL_FALSE == RelocProgram(&(vp->r700AsmCode), &(vp->mesa_program->Base)) )
+    {
+        return GL_FALSE;
+    }
+
     vp->r700Shader.nRegs = (vp->r700AsmCode.number_used_registers == 0) ? 0 
                          : (vp->r700AsmCode.number_used_registers - 1);
 
@@ -378,14 +375,11 @@ struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
        return vp;
 }
 
-void r700SelectVertexShader(GLcontext *ctx, GLint nVersion)
+void r700SelectVertexShader(GLcontext *ctx)
 {
     context_t *context = R700_CONTEXT(ctx);
     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;
     GLbitfield InputsRead;
@@ -396,47 +390,28 @@ void r700SelectVertexShader(GLcontext *ctx, GLint nVersion)
     if (vpc->mesa_program.IsPositionInvariant)
     {
        InputsRead |= VERT_BIT_POS;
-    } 
-    
+    }
+
     for (vp = vpc->progs; vp; vp = vp->next)
     {
-       if (vp->uiVersion != nVersion ) 
-           continue;
-       match = GL_TRUE;        
-       if ( 1 == nVersion ) 
+       match = GL_TRUE;
+       for(i=0; i<context->nNumActiveAos; i++)
        {
-           for(i=0; i<VERT_ATTRIB_MAX; i++)
-           {
-               unBit = 1 << i;
-               if(InputsRead & unBit)
+               if (vp->aos_desc[i].size != context->stream_desc[i].size ||
+                   vp->aos_desc[i].format != context->stream_desc[i].format)
                {
-                   if (vp->aos_desc[i].size != vb->AttribPtr[i]->size)
-                   {
                        match = GL_FALSE;
                        break;
-                   }
                }
-           }
        }
-       else
-       {
-           for(i=0; i<context->nNumActiveAos; i++)
-           {
-               if (vp->aos_desc[i].size != context->stream_desc[i].size)
-               {
-                   match = GL_FALSE;
-                   break;
-               }
-           }
-       }       
-       if (match) 
+       if (match)
        {
                context->selected_vp = vp;
                return;
        }
     }
 
-    vp = r700TranslateVertexShader(ctx, &(vpc->mesa_program), nVersion);
+    vp = r700TranslateVertexShader(ctx, &(vpc->mesa_program));
     if(!vp)
     {
        radeon_error("Failed to translate vertex shader. \n");
@@ -526,6 +501,7 @@ static void r700TranslateAttrib(GLcontext *ctx, GLuint unLoc, int count, const s
        pStreamDesc->size = input->Size;
        pStreamDesc->dst_loc = context->nNumActiveAos;
        pStreamDesc->element = unLoc;
+       pStreamDesc->format = input->Format;
 
        switch (pStreamDesc->type) 
        { //GetSurfaceFormat
@@ -570,6 +546,11 @@ void r700SetVertexFormat(GLcontext *ctx, const struct gl_client_array *arrays[],
     unsigned int unBit = mesa_vp->Base.InputsRead;
     context->nNumActiveAos = 0;
 
+    if (mesa_vp->IsPositionInvariant)
+    {
+        unBit |= VERT_BIT_POS;
+    }
+
     while(unBit) 
     {
         if(unBit & 1)
@@ -580,6 +561,7 @@ void r700SetVertexFormat(GLcontext *ctx, const struct gl_client_array *arrays[],
         unBit >>= 1;
         ++unLoc;
     }
+    context->radeon.tcl.aos_count = context->nNumActiveAos;
 }
 
 void * r700GetActiveVpShaderBo(GLcontext * ctx)
@@ -661,6 +643,12 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
     paramList = vp->mesa_program->Base.Parameters;
 
     if(NULL != paramList) {
+        /* vp->mesa_program was cloned, not updated by glsl shader api. */
+        /* _mesa_reference_program has already checked glsl shProg is ok and set ctx->VertexProgem._Current */
+        /* so, use ctx->VertexProgem._Current */       
+        struct gl_program_parameter_list *paramListOrginal = 
+                         ctx->VertexProgram._Current->Base.Parameters;
+         
            _mesa_load_state_parameters(ctx, paramList);
 
            if (paramList->NumParameters > R700_MAX_DX9_CONSTS)
@@ -673,13 +661,42 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
            unNumParamData = paramList->NumParameters;
 
            for(ui=0; ui<unNumParamData; ui++) {
-                   r700->vs.consts[ui][0].f32All = paramList->ParameterValues[ui][0];
-                   r700->vs.consts[ui][1].f32All = paramList->ParameterValues[ui][1];
-                   r700->vs.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
-                   r700->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
+            if(paramList->Parameters[ui].Type == PROGRAM_UNIFORM) 
+            {
+                r700->vs.consts[ui][0].f32All = paramListOrginal->ParameterValues[ui][0];
+                       r700->vs.consts[ui][1].f32All = paramListOrginal->ParameterValues[ui][1];
+                       r700->vs.consts[ui][2].f32All = paramListOrginal->ParameterValues[ui][2];
+                       r700->vs.consts[ui][3].f32All = paramListOrginal->ParameterValues[ui][3];
+            }
+            else
+            {
+                       r700->vs.consts[ui][0].f32All = paramList->ParameterValues[ui][0];
+                       r700->vs.consts[ui][1].f32All = paramList->ParameterValues[ui][1];
+                       r700->vs.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
+                       r700->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
+            }
            }
     } else
            r700->vs.num_consts = 0;
 
+    COMPILED_SUB * pCompiledSub;
+    GLuint uj;
+    GLuint unConstOffset = r700->vs.num_consts;
+    for(ui=0; ui<vp->r700AsmCode.unNumPresub; ui++)
+    {
+        pCompiledSub = vp->r700AsmCode.presubs[ui].pCompiledSub;
+
+        r700->vs.num_consts += pCompiledSub->NumParameters;
+
+        for(uj=0; uj<pCompiledSub->NumParameters; uj++)
+        {
+            r700->vs.consts[uj + unConstOffset][0].f32All = pCompiledSub->ParameterValues[uj][0];
+                   r700->vs.consts[uj + unConstOffset][1].f32All = pCompiledSub->ParameterValues[uj][1];
+                   r700->vs.consts[uj + unConstOffset][2].f32All = pCompiledSub->ParameterValues[uj][2];
+                   r700->vs.consts[uj + unConstOffset][3].f32All = pCompiledSub->ParameterValues[uj][3];
+        }
+        unConstOffset += pCompiledSub->NumParameters;
+    }
+
     return GL_TRUE;
 }