r600 : add draw_prim support.
[mesa.git] / src / mesa / drivers / dri / r600 / r700_vertprog.c
index 9ee26286d9b390b7a80efc232fee592c8bd85036..e7a209be9d8fe6fefbd8ee38f6acf70dbf75e697 100644 (file)
@@ -159,7 +159,35 @@ GLboolean Process_Vertex_Program_Vfetch_Instructions(
        return GL_TRUE;
 }
 
-void Map_Vertex_Program(struct r700_vertex_program *vp,
+GLboolean Process_Vertex_Program_Vfetch_Instructions2(
+    GLcontext *ctx,
+       struct r700_vertex_program *vp,
+       struct gl_vertex_program   *mesa_vp)
+{
+    int i;
+    context_t *context = R700_CONTEXT(ctx);
+
+    VTX_FETCH_METHOD vtxFetchMethod;
+       vtxFetchMethod.bEnableMini          = GL_FALSE;
+       vtxFetchMethod.mega_fetch_remainder = 0;
+
+    for(i=0; i<context->nNumActiveAos; i++)
+    {
+        assemble_vfetch_instruction2(&vp->r700AsmCode,
+                                      vp->r700AsmCode.ucVP_AttributeMap[context->stream_desc[i].element],
+                                      context->stream_desc[i].type,
+                                      context->stream_desc[i].size,
+                                      context->stream_desc[i].element,
+                                      context->stream_desc[i]._signed,
+                                      context->stream_desc[i].normalize,                                                           
+                                     &vtxFetchMethod);
+    }
+
+    return GL_TRUE;
+}
+
+void Map_Vertex_Program(GLcontext *ctx,
+                        struct r700_vertex_program *vp,
                                                struct gl_vertex_program   *mesa_vp)
 {
     GLuint ui;
@@ -175,11 +203,22 @@ void Map_Vertex_Program(struct r700_vertex_program *vp,
        pAsm->number_used_registers += num_inputs;
 
        // Create VFETCH instructions for inputs
-       if (GL_TRUE != Process_Vertex_Program_Vfetch_Instructions(vp, mesa_vp) ) 
-       {
-               radeon_error("Calling Process_Vertex_Program_Vfetch_Instructions return error. \n");
-               return; //error
-       }
+       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; 
+           }
+    }
 
        // Map Outputs
        pAsm->number_of_exports = Map_Vertex_Output(pAsm, mesa_vp, pAsm->number_used_registers);
@@ -261,7 +300,8 @@ GLboolean Find_Instruction_Dependencies_vp(struct r700_vertex_program *vp,
 }
 
 struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
-                                               struct gl_vertex_program *mesa_vp)
+                                               struct gl_vertex_program *mesa_vp,
+                        GLint nVer)
 {
        context_t *context = R700_CONTEXT(ctx);
        struct r700_vertex_program *vp;
@@ -271,6 +311,7 @@ struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
        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);
 
        if (mesa_vp->IsPositionInvariant)
@@ -296,7 +337,7 @@ struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
 
        //Init_Program
        Init_r700_AssemblerBase(SPT_VP, &(vp->r700AsmCode), &(vp->r700Shader) );
-       Map_Vertex_Program( vp, vp->mesa_program );
+       Map_Vertex_Program(ctx, vp, vp->mesa_program );
 
        if(GL_FALSE == Find_Instruction_Dependencies_vp(vp, vp->mesa_program))
        {
@@ -325,7 +366,7 @@ struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
        return vp;
 }
 
-void r700SelectVertexShader(GLcontext *ctx)
+void r700SelectVertexShader(GLcontext *ctx, GLint nVersion)
 {
     context_t *context = R700_CONTEXT(ctx);
     struct r700_vertex_program_cont *vpc;
@@ -365,7 +406,7 @@ void r700SelectVertexShader(GLcontext *ctx)
        }
     }
 
-    vp = r700TranslateVertexShader(ctx, &(vpc->mesa_program) );
+    vp = r700TranslateVertexShader(ctx, &(vpc->mesa_program), nVersion);
     if(!vp)
     {
        radeon_error("Failed to translate vertex shader. \n");
@@ -377,6 +418,140 @@ void r700SelectVertexShader(GLcontext *ctx)
     return;
 }
 
+int getTypeSize(GLenum type)
+{
+    switch (type) 
+    {
+    case GL_DOUBLE:
+        return sizeof(GLdouble);
+    case GL_FLOAT:
+        return sizeof(GLfloat);
+    case GL_INT:
+        return sizeof(GLint);
+    case GL_UNSIGNED_INT:
+        return sizeof(GLuint);
+    case GL_SHORT:
+        return sizeof(GLshort);
+    case GL_UNSIGNED_SHORT:
+        return sizeof(GLushort);
+    case GL_BYTE:
+        return sizeof(GLbyte);
+    case GL_UNSIGNED_BYTE:
+        return sizeof(GLubyte);
+    default:
+        assert(0);
+        return 0;
+    }
+}
+
+static void r700TranslateAttrib(GLcontext *ctx, GLuint unLoc, int count, const struct gl_client_array *input)
+{
+    context_t *context = R700_CONTEXT(ctx);
+    
+    StreamDesc * pStreamDesc = &(context->stream_desc[context->nNumActiveAos]);
+
+       GLuint stride;
+
+       stride = (input->StrideB == 0) ? getTypeSize(input->Type) * input->Size 
+                                   : input->StrideB;
+
+    if (input->Type == GL_DOUBLE || input->Type == GL_UNSIGNED_INT || input->Type == GL_INT ||
+#if MESA_BIG_ENDIAN
+        getTypeSize(input->Type) != 4 ||
+#endif
+        stride < 4) 
+    {
+        pStreamDesc->type = GL_FLOAT;
+
+        if (input->StrideB == 0) 
+        {
+               pStreamDesc->stride = 0;
+        } 
+        else 
+        {
+               pStreamDesc->stride = sizeof(GLfloat) * input->Size;
+        }
+        pStreamDesc->dwords = input->Size;
+        pStreamDesc->is_named_bo = GL_FALSE;
+    } 
+    else 
+    {
+        pStreamDesc->type = input->Type;
+        pStreamDesc->dwords = (getTypeSize(input->Type) * input->Size + 3)/ 4;
+        if (!input->BufferObj->Name) 
+        {
+            if (input->StrideB == 0) 
+            {
+                pStreamDesc->stride = 0;
+            } 
+            else 
+            {
+                pStreamDesc->stride = (getTypeSize(pStreamDesc->type) * input->Size + 3) & ~3;
+            }
+
+            pStreamDesc->is_named_bo = GL_FALSE;
+        }
+    }
+
+       pStreamDesc->size = input->Size;
+       pStreamDesc->dst_loc = context->nNumActiveAos;
+       pStreamDesc->element = unLoc;
+
+       switch (pStreamDesc->type) 
+       { //GetSurfaceFormat
+       case GL_FLOAT:
+               pStreamDesc->_signed = 0;
+               pStreamDesc->normalize = GL_FALSE;
+               break;
+       case GL_SHORT:
+               pStreamDesc->_signed = 1;
+               pStreamDesc->normalize = input->Normalized;
+               break;
+       case GL_BYTE:
+               pStreamDesc->_signed = 1;
+               pStreamDesc->normalize = input->Normalized;
+               break;
+       case GL_UNSIGNED_SHORT:
+               pStreamDesc->_signed = 0;
+               pStreamDesc->normalize = input->Normalized;
+               break;
+       case GL_UNSIGNED_BYTE:
+               pStreamDesc->_signed = 0;
+               pStreamDesc->normalize = input->Normalized;
+               break;
+       default:
+       case GL_INT:
+       case GL_UNSIGNED_INT:
+       case GL_DOUBLE: 
+               assert(0);
+               break;
+       }
+       context->nNumActiveAos++;
+}
+
+void r700SetVertexFormat(GLcontext *ctx, const struct gl_client_array *arrays[], int count)
+{
+    context_t *context = R700_CONTEXT(ctx);
+    struct r700_vertex_program *vpc
+           = (struct r700_vertex_program *)ctx->VertexProgram._Current;
+
+    struct gl_vertex_program * mesa_vp = (struct gl_vertex_program *)&(vpc->mesa_program);
+    unsigned int unLoc = 0;
+    unsigned int unBit = mesa_vp->Base.InputsRead;
+    context->nNumActiveAos = 0;
+
+    while(unBit) 
+    {
+        if(unBit & 1)
+        {
+            r700TranslateAttrib(ctx, unLoc, count, arrays[unLoc]);
+        }
+
+        unBit >>= 1;
+        ++unLoc;
+    }
+}
+
 void * r700GetActiveVpShaderBo(GLcontext * ctx)
 {
     context_t *context = R700_CONTEXT(ctx);