r600 : add draw_prim support.
authorRichard Li <richardradeon@gmail.com>
Tue, 22 Sep 2009 20:39:11 +0000 (16:39 -0400)
committerRichard Li <richardradeon@gmail.com>
Tue, 22 Sep 2009 21:04:49 +0000 (17:04 -0400)
15 files changed:
src/mesa/drivers/dri/r600/Makefile
src/mesa/drivers/dri/r600/r600_context.c
src/mesa/drivers/dri/r600/r600_context.h
src/mesa/drivers/dri/r600/r700_assembler.c
src/mesa/drivers/dri/r600/r700_assembler.h
src/mesa/drivers/dri/r600/r700_chip.c
src/mesa/drivers/dri/r600/r700_render.c
src/mesa/drivers/dri/r600/r700_shader.c
src/mesa/drivers/dri/r600/r700_shader.h
src/mesa/drivers/dri/r600/r700_state.c
src/mesa/drivers/dri/r600/r700_state.h
src/mesa/drivers/dri/r600/r700_vertprog.c
src/mesa/drivers/dri/r600/r700_vertprog.h
src/mesa/drivers/dri/r600/radeon_buffer_objects.c [new symlink]
src/mesa/drivers/dri/r600/radeon_buffer_objects.h [new symlink]

index 36bf773c054b83ca810a4339f5e230f6e58aefc6..7d5a7b1ab6f9a3ec33cbbdbbe64387f52739f706 100644 (file)
@@ -29,6 +29,7 @@ COMMON_SOURCES = \
 RADEON_COMMON_SOURCES = \
        radeon_bo_legacy.c \
        radeon_common_context.c \
+       radeon_buffer_objects.c \
        radeon_common.c \
        radeon_cs_legacy.c \
        radeon_dma.c \
index 354b263f5cb0993700635470498717872c8ac3db..6fc6d9d7bfa17d98625e94c6f247004936ccd1ca 100644 (file)
@@ -257,6 +257,7 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
        r600InitTextureFuncs(&functions);
        r700InitShaderFuncs(&functions);
        r700InitIoctlFuncs(&functions);
+    radeonInitBufferObjectFuncs(&functions);
 
        if (!radeonInitContext(&r600->radeon, &functions,
                               glVisual, driContextPriv,
@@ -375,6 +376,8 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
                _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
        }
 
+    r700InitDraw(ctx);
+
        radeon_fbo_init(&r600->radeon);
        radeonInitSpanFuncs( ctx );
 
index 9397ecde81b281d31f65e13707b2b467562b86c9..a296ea23fa475a1b0c763dea7954486c043b2759 100644 (file)
@@ -126,6 +126,34 @@ struct r600_hw_state {
        struct radeon_state_atom tx_brdr_clr;
 };
 
+typedef struct StreamDesc 
+{
+       GLint   size;   //number of data element
+       GLenum  type;  //data element type
+       GLsizei stride;
+
+    struct radeon_bo *bo;
+    GLint  bo_offset;
+
+    GLuint    dwords;
+       GLuint    dst_loc;
+       GLuint    _signed;
+       GLboolean normalize;
+    GLboolean is_named_bo;
+    GLubyte   element;
+} StreamDesc;
+
+typedef struct r700_index_buffer 
+{
+    struct radeon_bo *bo;
+    int    bo_offset;
+
+    GLboolean is_32bit;
+    GLuint    count;
+
+    GLboolean bHostIb;
+} r700_index_buffer;
+
 /**
  * \brief R600 context structure.
  */
@@ -144,6 +172,9 @@ struct r600_context {
        GLvector4f dummy_attrib[_TNL_ATTRIB_MAX];
        GLvector4f *temp_attrib[_TNL_ATTRIB_MAX];
 
+    GLint      nNumActiveAos;
+       StreamDesc stream_desc[VERT_ATTRIB_MAX];
+    struct r700_index_buffer ind_buf;
 };
 
 #define R700_CONTEXT(ctx)              ((context_t *)(ctx->DriverCtx))
@@ -177,6 +208,7 @@ extern GLboolean r700SyncSurf(context_t *context,
 extern void r700SetupStreams(GLcontext * ctx);
 extern void r700Start3D(context_t *context);
 extern void r600InitAtoms(context_t *context);
+extern void r700InitDraw(GLcontext *ctx);
 
 #define RADEON_D_CAPTURE 0
 #define RADEON_D_PLAYBACK 1
index f46bc3220117007d3272ef18894a9492097b82f1..81269350e43cb288d8d5d1a43b8645496d976d8f 100644 (file)
@@ -786,6 +786,133 @@ GLboolean assemble_vfetch_instruction(r700_AssemblerBase* pAsm,
        return GL_TRUE;
 }
 
+GLboolean assemble_vfetch_instruction2(r700_AssemblerBase* pAsm,
+                                       GLuint              destination_register,                                                                      
+                                       GLenum              type,
+                                       GLint               size,
+                                       GLubyte             element,
+                                       GLuint              _signed,
+                                       GLboolean           normalize,
+                                       VTX_FETCH_METHOD  * pFetchMethod)
+{
+    GLuint client_size_inbyte;
+       GLuint data_format;
+    GLuint mega_fetch_count;
+       GLuint is_mega_fetch_flag;
+
+       R700VertexGenericFetch*   vfetch_instruction_ptr;
+       R700VertexGenericFetch*   assembled_vfetch_instruction_ptr 
+                                     = pAsm->vfetch_instruction_ptr_array[element];
+
+       if (assembled_vfetch_instruction_ptr == NULL) 
+       {
+               vfetch_instruction_ptr = (R700VertexGenericFetch*) CALLOC_STRUCT(R700VertexGenericFetch);
+               if (vfetch_instruction_ptr == NULL) 
+               {
+                       return GL_FALSE;
+               }
+        Init_R700VertexGenericFetch(vfetch_instruction_ptr);
+    }
+       else 
+       {
+               vfetch_instruction_ptr = assembled_vfetch_instruction_ptr;
+       }
+
+    data_format = GetSurfaceFormat(type, size, &client_size_inbyte);   
+
+       if(GL_TRUE == pFetchMethod->bEnableMini) //More conditions here
+       {
+               //TODO : mini fetch
+       }
+       else
+       {
+               mega_fetch_count = MEGA_FETCH_BYTES - 1;
+               is_mega_fetch_flag       = 0x1;
+               pFetchMethod->mega_fetch_remainder = MEGA_FETCH_BYTES - client_size_inbyte;
+       }
+
+       vfetch_instruction_ptr->m_Word0.f.vtx_inst         = SQ_VTX_INST_FETCH;
+       vfetch_instruction_ptr->m_Word0.f.fetch_type       = SQ_VTX_FETCH_VERTEX_DATA;
+       vfetch_instruction_ptr->m_Word0.f.fetch_whole_quad = 0x0;
+
+       vfetch_instruction_ptr->m_Word0.f.buffer_id        = element;
+       vfetch_instruction_ptr->m_Word0.f.src_gpr          = 0x0; 
+       vfetch_instruction_ptr->m_Word0.f.src_rel          = SQ_ABSOLUTE;
+       vfetch_instruction_ptr->m_Word0.f.src_sel_x        = SQ_SEL_X;
+       vfetch_instruction_ptr->m_Word0.f.mega_fetch_count = mega_fetch_count;
+
+       vfetch_instruction_ptr->m_Word1.f.dst_sel_x        = (size < 1) ? SQ_SEL_0 : SQ_SEL_X;
+       vfetch_instruction_ptr->m_Word1.f.dst_sel_y        = (size < 2) ? SQ_SEL_0 : SQ_SEL_Y;
+       vfetch_instruction_ptr->m_Word1.f.dst_sel_z        = (size < 3) ? SQ_SEL_0 : SQ_SEL_Z;
+       vfetch_instruction_ptr->m_Word1.f.dst_sel_w        = (size < 4) ? SQ_SEL_1 : SQ_SEL_W;
+
+       vfetch_instruction_ptr->m_Word1.f.use_const_fields = 1;
+    vfetch_instruction_ptr->m_Word1.f.data_format      = data_format;
+    vfetch_instruction_ptr->m_Word2.f.endian_swap      = SQ_ENDIAN_NONE;
+
+    if(1 == _signed)
+    {
+        vfetch_instruction_ptr->m_Word1.f.format_comp_all  = SQ_FORMAT_COMP_SIGNED;
+    }
+    else
+    {
+        vfetch_instruction_ptr->m_Word1.f.format_comp_all  = SQ_FORMAT_COMP_UNSIGNED;
+    }
+
+    if(GL_TRUE == normalize)
+    {
+        vfetch_instruction_ptr->m_Word1.f.num_format_all   = SQ_NUM_FORMAT_NORM;
+    }
+    else
+    {
+        vfetch_instruction_ptr->m_Word1.f.num_format_all   = SQ_NUM_FORMAT_INT;
+    }
+
+       // Destination register
+       vfetch_instruction_ptr->m_Word1_GPR.f.dst_gpr = destination_register; 
+       vfetch_instruction_ptr->m_Word1_GPR.f.dst_rel = SQ_ABSOLUTE;
+
+       vfetch_instruction_ptr->m_Word2.f.offset              = 0;
+       vfetch_instruction_ptr->m_Word2.f.const_buf_no_stride = 0x0;
+
+       vfetch_instruction_ptr->m_Word2.f.mega_fetch          = is_mega_fetch_flag;
+
+       if (assembled_vfetch_instruction_ptr == NULL) 
+       {
+               if ( GL_FALSE == add_vfetch_instruction(pAsm, (R700VertexInstruction *)vfetch_instruction_ptr) ) 
+        {   
+                       return GL_FALSE;
+               }
+
+               if (pAsm->vfetch_instruction_ptr_array[element] != NULL) 
+               {
+                       return GL_FALSE;
+               }
+               else 
+               {
+                       pAsm->vfetch_instruction_ptr_array[element] = vfetch_instruction_ptr;
+               }
+       }
+
+       return GL_TRUE;
+}
+
+GLboolean cleanup_vfetch_instructions(r700_AssemblerBase* pAsm)
+{
+    GLint i;
+    pAsm->cf_current_clause_type    = CF_EMPTY_CLAUSE;
+    pAsm->cf_current_vtx_clause_ptr = NULL;
+
+    for (i=0; i<VERT_ATTRIB_MAX; i++) 
+       {
+               pAsm->vfetch_instruction_ptr_array[ i ] = NULL;
+       }
+
+    cleanup_vfetch_shaderinst(pAsm->pR700Shader);
+    
+    return GL_TRUE;
+}
+
 GLuint gethelpr(r700_AssemblerBase* pAsm) 
 {
     GLuint r = pAsm->uHelpReg;
index f9c4d849c65a24e95329fcc82ddf27fa3aaf95bb..4e6e20011adf2309a8625968697622180696106f 100644 (file)
@@ -411,6 +411,14 @@ GLboolean assemble_vfetch_instruction(r700_AssemblerBase* pAsm,
                                                                GLuint number_of_elements,
                                 GLenum dataElementType,
                                                                VTX_FETCH_METHOD* pFetchMethod);
+GLboolean assemble_vfetch_instruction2(r700_AssemblerBase* pAsm,
+                                       GLuint              destination_register,                                                                      
+                                       GLenum              type,
+                                       GLint               size,
+                                       GLubyte             element,
+                                       GLuint              _signed,
+                                       GLboolean           normalize,
+                                       VTX_FETCH_METHOD  * pFetchMethod);
 GLuint gethelpr(r700_AssemblerBase* pAsm);
 void resethelpr(r700_AssemblerBase* pAsm);
 void checkop_init(r700_AssemblerBase* pAsm);
index 06d7e9c9ab14ff0fdea691b5583a4d9bc96bccbe..783427a94c9d82fb0fc0dab10fb7250d32a12b25 100644 (file)
@@ -208,6 +208,80 @@ static void r700SetupVTXConstants(GLcontext  * ctx,
 
 }
 
+extern int getTypeSize(GLenum type);
+static void r700SetupVTXConstants2(GLcontext  * ctx,
+                                                  void *       pAos,
+                                   StreamDesc * pStreamDesc)     
+{
+    context_t *context = R700_CONTEXT(ctx);
+    struct radeon_aos * paos = (struct radeon_aos *)pAos;
+    unsigned int nVBsize;
+    BATCH_LOCALS(&context->radeon);
+
+    unsigned int uSQ_VTX_CONSTANT_WORD0_0;
+    unsigned int uSQ_VTX_CONSTANT_WORD1_0;
+    unsigned int uSQ_VTX_CONSTANT_WORD2_0 = 0;
+    unsigned int uSQ_VTX_CONSTANT_WORD3_0 = 0;
+    unsigned int uSQ_VTX_CONSTANT_WORD6_0 = 0;
+
+    if (!paos->bo)
+           return;
+
+    if ((context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV610) ||
+       (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV620) ||
+       (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS780) ||
+       (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS880) ||
+       (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV710))
+           r700SyncSurf(context, paos->bo, RADEON_GEM_DOMAIN_GTT, 0, TC_ACTION_ENA_bit);
+    else
+           r700SyncSurf(context, paos->bo, RADEON_GEM_DOMAIN_GTT, 0, VC_ACTION_ENA_bit);
+
+    if(0 == pStreamDesc->stride)
+    {
+        nVBsize = paos->count * pStreamDesc->size * getTypeSize(pStreamDesc->type);
+    }
+    else
+    {
+        nVBsize = paos->count * pStreamDesc->stride;
+    }
+
+    uSQ_VTX_CONSTANT_WORD0_0 = paos->offset;
+    uSQ_VTX_CONSTANT_WORD1_0 = nVBsize - 1;
+
+    SETfield(uSQ_VTX_CONSTANT_WORD2_0, 0, BASE_ADDRESS_HI_shift, BASE_ADDRESS_HI_mask); /* TODO */
+    SETfield(uSQ_VTX_CONSTANT_WORD2_0, pStreamDesc->stride, SQ_VTX_CONSTANT_WORD2_0__STRIDE_shift,
+            SQ_VTX_CONSTANT_WORD2_0__STRIDE_mask);
+    SETfield(uSQ_VTX_CONSTANT_WORD2_0, GetSurfaceFormat(pStreamDesc->type, pStreamDesc->size, NULL),
+            SQ_VTX_CONSTANT_WORD2_0__DATA_FORMAT_shift,
+            SQ_VTX_CONSTANT_WORD2_0__DATA_FORMAT_mask); /* TODO : trace back api for initial data type, not only GL_FLOAT */
+    SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_SCALED,
+            SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask);
+    SETbit(uSQ_VTX_CONSTANT_WORD2_0, SQ_VTX_CONSTANT_WORD2_0__FORMAT_COMP_ALL_bit);
+
+    SETfield(uSQ_VTX_CONSTANT_WORD3_0, 1, MEM_REQUEST_SIZE_shift, MEM_REQUEST_SIZE_mask);
+    SETfield(uSQ_VTX_CONSTANT_WORD6_0, SQ_TEX_VTX_VALID_BUFFER,
+            SQ_TEX_RESOURCE_WORD6_0__TYPE_shift, SQ_TEX_RESOURCE_WORD6_0__TYPE_mask);
+
+    BEGIN_BATCH_NO_AUTOSTATE(9 + 2);
+
+    R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
+    R600_OUT_BATCH((pStreamDesc->element + SQ_FETCH_RESOURCE_VS_OFFSET) * FETCH_RESOURCE_STRIDE);
+    R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD0_0);
+    R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD1_0);
+    R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD2_0);
+    R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD3_0);
+    R600_OUT_BATCH(0);
+    R600_OUT_BATCH(0);
+    R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD6_0);
+    R600_OUT_BATCH_RELOC(uSQ_VTX_CONSTANT_WORD0_0,
+                         paos->bo,
+                         uSQ_VTX_CONSTANT_WORD0_0,
+                         RADEON_GEM_DOMAIN_GTT, 0, 0);
+    END_BATCH();
+    COMMIT_BATCH();
+
+}
+
 void r700SetupStreams(GLcontext *ctx)
 {
     context_t         *context = R700_CONTEXT(ctx);
@@ -256,14 +330,24 @@ static void r700SendVTXState(GLcontext *ctx, struct radeon_state_atom *atom)
     COMMIT_BATCH();
 
     for(i=0; i<VERT_ATTRIB_MAX; i++) {
-           if(vp->mesa_program->Base.InputsRead & (1 << i)) {
-                   /* currently aos are packed */
-                   r700SetupVTXConstants(ctx,
-                                         i,
-                                         (void*)(&context->radeon.tcl.aos[j]),
-                                         (unsigned int)context->radeon.tcl.aos[j].components,
-                                         (unsigned int)context->radeon.tcl.aos[j].stride * 4,
-                                         (unsigned int)context->radeon.tcl.aos[j].count);
+           if(vp->mesa_program->Base.InputsRead & (1 << i)) 
+        {
+                   if(1 == context->selected_vp->uiVersion)
+            {
+                       /* currently aos are packed */
+                       r700SetupVTXConstants(ctx,
+                                             i,
+                                             (void*)(&context->radeon.tcl.aos[j]),
+                                             (unsigned int)context->radeon.tcl.aos[j].components,
+                                             (unsigned int)context->radeon.tcl.aos[j].stride * 4,
+                                             (unsigned int)context->radeon.tcl.aos[j].count);
+            }
+            else
+            {   /* context->selected_vp->uiVersion == 2 : aos not always packed */                
+                r700SetupVTXConstants2(ctx,                                        
+                                             (void*)(&context->radeon.tcl.aos[j]),
+                                             &(context->stream_desc[j]));
+            }
                    j++;
            }
     }
index b1c3648ca568867685e29afac3fb875d97d4a4a8..b58859b6ba31f586cefda9620bfac306d22621ee 100644 (file)
@@ -43,6 +43,7 @@
 #include "tnl/t_context.h"
 #include "tnl/t_vertex.h"
 #include "tnl/t_pipeline.h"
+#include "vbo/vbo_context.h"
 
 #include "r600_context.h"
 #include "r600_cmdbuf.h"
@@ -53,6 +54,7 @@
 #include "r700_fragprog.h"
 #include "r700_state.h"
 
+#include "radeon_buffer_objects.h"
 #include "radeon_common_context.h"
 
 void r700WaitForIdle(context_t *context);
@@ -270,46 +272,82 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
        if (type < 0 || num_indices <= 0)
                return;
 
-        total_emit =   3 /* VGT_PRIMITIVE_TYPE */
-                    + 2 /* VGT_INDEX_TYPE */
-                    + 2 /* NUM_INSTANCES */
-                     + num_indices + 3; /* DRAW_INDEX_IMMD */
+    total_emit =   3 /* VGT_PRIMITIVE_TYPE */
+            + 2 /* VGT_INDEX_TYPE */
+            + 2 /* NUM_INSTANCES */
+                 + num_indices + 3; /* DRAW_INDEX_IMMD */
 
-        BEGIN_BATCH_NO_AUTOSTATE(total_emit);
+    BEGIN_BATCH_NO_AUTOSTATE(total_emit);
        // prim
-        SETfield(vgt_primitive_type, type,
-                VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift, VGT_PRIMITIVE_TYPE__PRIM_TYPE_mask);
-        R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
-        R600_OUT_BATCH(mmVGT_PRIMITIVE_TYPE - ASIC_CONFIG_BASE_INDEX);
-        R600_OUT_BATCH(vgt_primitive_type);
+    SETfield(vgt_primitive_type, type,
+       VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift, VGT_PRIMITIVE_TYPE__PRIM_TYPE_mask);
+    R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
+    R600_OUT_BATCH(mmVGT_PRIMITIVE_TYPE - ASIC_CONFIG_BASE_INDEX);
+    R600_OUT_BATCH(vgt_primitive_type);
 
        // index type
-        SETfield(vgt_index_type, DI_INDEX_SIZE_32_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
-        R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
-        R600_OUT_BATCH(vgt_index_type);
+    SETfield(vgt_index_type, DI_INDEX_SIZE_32_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
+    R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
+    R600_OUT_BATCH(vgt_index_type);
 
        // num instances
        R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
         R600_OUT_BATCH(1);
 
        // draw packet
-        vgt_num_indices = num_indices;
-        SETfield(vgt_draw_initiator, DI_SRC_SEL_IMMEDIATE, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
+    vgt_num_indices = num_indices;
+    SETfield(vgt_draw_initiator, DI_SRC_SEL_IMMEDIATE, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
        SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, MAJOR_MODE_mask);
 
-        R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (num_indices + 1)));
-        R600_OUT_BATCH(vgt_num_indices);
-        R600_OUT_BATCH(vgt_draw_initiator);
+    R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (num_indices + 1)));
+    R600_OUT_BATCH(vgt_num_indices);
+    R600_OUT_BATCH(vgt_draw_initiator);
 
+    if(NULL == context->ind_buf.bo)
+    {
         for (i = start; i < (start + num_indices); i++) {
-               if(vb->Elts)
-                       R600_OUT_BATCH(vb->Elts[i]);
-               else
-                       R600_OUT_BATCH(i);
+            if(vb->Elts)
+            {
+                R600_OUT_BATCH(vb->Elts[i]);
+            }
+            else
+                R600_OUT_BATCH(i);
         }
-        END_BATCH();
-        COMMIT_BATCH();
+    }
+    else
+    {        
+        if(GL_TRUE == context->ind_buf.bHostIb)
+        {
+            if(GL_TRUE != context->ind_buf.is_32bit)
+            {
+                GLushort * pIndex = (GLushort*)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+                pIndex += start;
+                for (i = 0; i < num_indices; i++) 
+                {           
+                    R600_OUT_BATCH(*pIndex);
+                    pIndex++;
+                }
+            }
+            else
+            {                
+                GLuint * pIndex = (GLuint*)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+                pIndex += start;                
+
+                for (i = 0; i < num_indices; i++) 
+                {                
+                    R600_OUT_BATCH(*pIndex);
+                    pIndex++;
+                }
+            }
+        }
+        else
+        {
+            /* TODO : hw ib draw */
+        }
+    }
 
+    END_BATCH();
+    COMMIT_BATCH();
 }
 
 /* start 3d, idle, cb/db flush */
@@ -477,4 +515,585 @@ const struct tnl_pipeline_stage *r700_pipeline[] =
     0,
 };
 
+#define CONVERT( TYPE, MACRO ) do {            \
+       GLuint i, j, sz;                                \
+       sz = input->Size;                               \
+       if (input->Normalized) {                        \
+               for (i = 0; i < count; i++) {           \
+                       const TYPE *in = (TYPE *)src_ptr;               \
+                       for (j = 0; j < sz; j++) {              \
+                               *dst_ptr++ = MACRO(*in);                \
+                               in++;                           \
+                       }                                       \
+                       src_ptr += stride;                      \
+               }                                               \
+       } else {                                        \
+               for (i = 0; i < count; i++) {           \
+                       const TYPE *in = (TYPE *)src_ptr;               \
+                       for (j = 0; j < sz; j++) {              \
+                               *dst_ptr++ = (GLfloat)(*in);            \
+                               in++;                           \
+                       }                                       \
+                       src_ptr += stride;                      \
+               }                                               \
+       }                                               \
+} while (0)
+
+/**
+ * Convert attribute data type to float
+ * If the attribute uses named buffer object replace the bo with newly allocated bo
+ */
+static void r700ConvertAttrib(GLcontext *ctx, int count, 
+                              const struct gl_client_array *input, 
+                              struct StreamDesc *attr)
+{
+    context_t *context = R700_CONTEXT(ctx);
+    const GLvoid *src_ptr;
+    GLboolean mapped_named_bo = GL_FALSE;
+    GLfloat *dst_ptr;
+    GLuint stride;
+
+    stride = (input->StrideB == 0) ? getTypeSize(input->Type) * input->Size : input->StrideB;
+
+    /* Convert value for first element only */
+    if (input->StrideB == 0)
+    {
+        count = 1;
+    }
+
+    if (input->BufferObj->Name) 
+    {
+        if (!input->BufferObj->Pointer) 
+        {
+            ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
+            mapped_named_bo = GL_TRUE;
+        }
+
+        src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
+    } 
+    else 
+    {
+        src_ptr = input->Ptr;
+    }
+
+    radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset, 
+                         sizeof(GLfloat) * input->Size * count, 32);
+    dst_ptr = (GLfloat *)ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
+
+    assert(src_ptr != NULL);
+
+    switch (input->Type) 
+    {
+        case GL_DOUBLE:
+            CONVERT(GLdouble, (GLfloat));
+            break;
+        case GL_UNSIGNED_INT:
+            CONVERT(GLuint, UINT_TO_FLOAT);
+            break;
+        case GL_INT:
+            CONVERT(GLint, INT_TO_FLOAT);
+            break;
+        case GL_UNSIGNED_SHORT:
+            CONVERT(GLushort, USHORT_TO_FLOAT);
+            break;
+        case GL_SHORT:
+            CONVERT(GLshort, SHORT_TO_FLOAT);
+            break;
+        case GL_UNSIGNED_BYTE:
+            assert(input->Format != GL_BGRA);
+            CONVERT(GLubyte, UBYTE_TO_FLOAT);
+            break;
+        case GL_BYTE:
+            CONVERT(GLbyte, BYTE_TO_FLOAT);
+            break;
+        default:
+            assert(0);
+            break;
+    }
+
+    if (mapped_named_bo) 
+    {
+        ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
+    }
+}
+
+static void r700AlignDataToDword(GLcontext *ctx, 
+                                 const struct gl_client_array *input, 
+                                 int count, 
+                                 struct StreamDesc *attr)
+{
+    context_t *context = R700_CONTEXT(ctx);
+    const int dst_stride = (input->StrideB + 3) & ~3;
+    const int size = getTypeSize(input->Type) * input->Size * count;
+    GLboolean mapped_named_bo = GL_FALSE;
+
+    radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset, size, 32);
+
+    if (!input->BufferObj->Pointer) 
+    {
+        ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
+        mapped_named_bo = GL_TRUE;
+    }
+
+    {
+        GLvoid *src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
+        GLvoid *dst_ptr = ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
+        int i;
+
+        for (i = 0; i < count; ++i) 
+        {
+            _mesa_memcpy(dst_ptr, src_ptr, input->StrideB);
+            src_ptr += input->StrideB;
+            dst_ptr += dst_stride;
+        }
+    }
+
+    if (mapped_named_bo) 
+    {
+        ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
+    }
+
+    attr->stride = dst_stride;
+}
+
+static void r700SetupStreams2(GLcontext *ctx, const struct gl_client_array *input[], int count)
+{
+       context_t *context = R700_CONTEXT(ctx);
+    GLuint stride;
+    int ret;
+    int i, index;
+
+    R600_STATECHANGE(context, vtx);
+
+    for(index = 0; index < context->nNumActiveAos; index++) 
+    {
+        struct radeon_aos *aos = &context->radeon.tcl.aos[index];
+        i = context->stream_desc[index].element;
+
+        stride = (input[i]->StrideB == 0) ? getTypeSize(input[i]->Type) * input[i]->Size : input[i]->StrideB;
+
+        if (input[i]->Type == GL_DOUBLE || input[i]->Type == GL_UNSIGNED_INT || input[i]->Type == GL_INT ||
+#if MESA_BIG_ENDIAN
+            getTypeSize(input[i]->Type) != 4 || 
+#endif
+            stride < 4) 
+        {
+            r700ConvertAttrib(ctx, count, input[i], &context->stream_desc[index]);
+        } 
+        else 
+        {
+            if (input[i]->BufferObj->Name) 
+            {
+                if (stride % 4 != 0) 
+                {
+                    assert(((intptr_t) input[i]->Ptr) % input[i]->StrideB == 0);
+                    r700AlignDataToDword(ctx, input[i], count, &context->stream_desc[index]);
+                    context->stream_desc[index].is_named_bo = GL_FALSE;
+                } 
+                else 
+                {
+                    context->stream_desc[index].stride = input[i]->StrideB;
+                    context->stream_desc[index].bo_offset = (intptr_t) input[i]->Ptr;
+                    context->stream_desc[index].bo = get_radeon_buffer_object(input[i]->BufferObj)->bo;
+                    context->stream_desc[index].is_named_bo = GL_TRUE;
+                }
+            } 
+            else 
+            {
+                int size;
+                int local_count = count;
+                uint32_t *dst;
+
+                if (input[i]->StrideB == 0) 
+                {
+                    size = getTypeSize(input[i]->Type) * input[i]->Size;
+                    local_count = 1;
+                } 
+                else 
+                {
+                    size = getTypeSize(input[i]->Type) * input[i]->Size * local_count;
+                }
+
+                radeonAllocDmaRegion(&context->radeon, &context->stream_desc[index].bo, 
+                                     &context->stream_desc[index].bo_offset, size, 32);
+                assert(context->stream_desc[index].bo->ptr != NULL);
+                dst = (uint32_t *)ADD_POINTERS(context->stream_desc[index].bo->ptr, 
+                                               context->stream_desc[index].bo_offset);
+
+                switch (context->stream_desc[index].dwords) 
+                {
+                case 1:                     
+                    radeonEmitVec4(dst, input[i]->Ptr, input[i]->StrideB, local_count);                         
+                                       context->stream_desc[index].stride = 4; 
+                    break;
+                case 2: 
+                    radeonEmitVec8(dst, input[i]->Ptr, input[i]->StrideB, local_count); 
+                                       context->stream_desc[index].stride = 8; 
+                    break;
+                case 3: 
+                    radeonEmitVec12(dst, input[i]->Ptr, input[i]->StrideB, local_count); 
+                                       context->stream_desc[index].stride = 12; 
+                    break;
+                case 4: 
+                    radeonEmitVec16(dst, input[i]->Ptr, input[i]->StrideB, local_count); 
+                                       context->stream_desc[index].stride = 16; 
+                    break;
+                default: 
+                    assert(0); 
+                    break;
+                }
+            }
+        }
+
+        aos->count = context->stream_desc[index].stride == 0 ? 1 : count;
+        aos->stride = context->stream_desc[index].stride / sizeof(float);
+        aos->components = context->stream_desc[index].dwords;
+        aos->bo = context->stream_desc[index].bo;
+        aos->offset = context->stream_desc[index].bo_offset;
+
+        if(context->stream_desc[index].is_named_bo) 
+        {
+            radeon_cs_space_add_persistent_bo(context->radeon.cmdbuf.cs, 
+                                              context->stream_desc[index].bo, 
+                                              RADEON_GEM_DOMAIN_GTT, 0);
+        }
+    }
+
+    context->radeon.tcl.aos_count = context->nNumActiveAos;
+    ret = radeon_cs_space_check_with_bo(context->radeon.cmdbuf.cs, 
+                                        first_elem(&context->radeon.dma.reserved)->bo, 
+                                        RADEON_GEM_DOMAIN_GTT, 0);    
+}
+
+static void r700FreeData(GLcontext *ctx)
+{
+    /* Need to zero tcl.aos[n].bo and tcl.elt_dma_bo
+     * to prevent double unref in radeonReleaseArrays
+     * called during context destroy
+     */
+    context_t *context = R700_CONTEXT(ctx);
+    
+    int i;
+
+    for (i = 0; i < context->nNumActiveAos; i++) 
+    {
+        if (!context->stream_desc[i].is_named_bo) 
+        {
+               radeon_bo_unref(context->stream_desc[i].bo);
+        }
+        context->radeon.tcl.aos[i].bo = NULL;
+    }
+    
+    if (context->ind_buf.bo != NULL) 
+    {
+        if(context->ind_buf.bHostIb != GL_TRUE)
+        {
+            radeon_bo_unref(context->ind_buf.bo);
+        }
+        else
+        {
+            FREE(context->ind_buf.bo->ptr);
+            FREE(context->ind_buf.bo);
+            context->ind_buf.bo = NULL;
+        }
+    }
+}
+
+static void r700FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
+{
+    context_t *context = R700_CONTEXT(ctx);
+    GLvoid *src_ptr;
+    GLuint *out;
+    int i;
+    GLboolean mapped_named_bo = GL_FALSE;
+
+    if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer) 
+    {
+        ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj);
+        mapped_named_bo = GL_TRUE;
+        assert(mesa_ind_buf->obj->Pointer != NULL);
+    }
+    src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr);
+
+    if (mesa_ind_buf->type == GL_UNSIGNED_BYTE) 
+    {
+        GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
+        GLubyte *in = (GLubyte *)src_ptr;
+
+        if(context->ind_buf.bHostIb != GL_TRUE)
+        {
+            radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo, 
+                                 &context->ind_buf.bo_offset, size, 4);
+
+            assert(context->ind_buf.bo->ptr != NULL);
+            out = (GLuint *)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+        }
+        else
+        {
+            context->ind_buf.bo        = MALLOC_STRUCT(radeon_bo);
+            context->ind_buf.bo->ptr   = ALIGN_MALLOC(size, 4);
+            context->ind_buf.bo_offset = 0;
+            out                        = (GLuint *)context->ind_buf.bo->ptr;
+        }
+
+        for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) 
+        {
+            *out++ = in[i] | in[i + 1] << 16;
+        }
+
+        if (i < mesa_ind_buf->count) 
+        {
+            *out++ = in[i];
+        }
+
+#if MESA_BIG_ENDIAN
+    } 
+    else 
+    { /* if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) */
+        GLushort *in = (GLushort *)src_ptr;
+        GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
+
+        if(context->ind_buf.bHostIb != GL_TRUE)
+        {
+            radeonAllocDmaRegion(&context->radeon, &r300->ind_buf.bo,
+                                 &context->ind_buf.bo_offset, size, 4);
+
+            assert(context->ind_buf.bo->ptr != NULL);
+            out = (GLuint *)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+        }
+        else
+        {
+            context->ind_buf.bo        = MALLOC_STRUCT(radeon_bo);
+            context->ind_buf.bo->ptr   = ALIGN_MALLOC(size, 4);
+            context->ind_buf.bo_offset = 0;
+            out                        = (GLuint *)context->ind_buf.bo->ptr;
+        }
+
+        for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) 
+        {
+            *out++ = in[i] | in[i + 1] << 16;
+        }
+
+        if (i < mesa_ind_buf->count) 
+        {
+            *out++ = in[i];
+        }
+#endif
+    }
+
+    context->ind_buf.is_32bit = GL_FALSE;
+    context->ind_buf.count = mesa_ind_buf->count;
+
+    if (mapped_named_bo) 
+    {
+        ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj);
+    }
+}
+
+static void r700SetupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
+{
+    context_t *context = R700_CONTEXT(ctx);
+
+    if (!mesa_ind_buf) {
+        context->ind_buf.bo = NULL;
+        return;
+    }
+
+    context->ind_buf.bHostIb = GL_TRUE;
+
+#if MESA_BIG_ENDIAN
+    if (mesa_ind_buf->type == GL_UNSIGNED_INT) 
+    {
+#else
+    if (mesa_ind_buf->type != GL_UNSIGNED_BYTE) 
+    {
+#endif
+        const GLvoid *src_ptr;
+        GLvoid *dst_ptr;
+        GLboolean mapped_named_bo = GL_FALSE;
+
+        if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer) 
+        {
+               ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj);
+               assert(mesa_ind_buf->obj->Pointer != NULL);
+               mapped_named_bo = GL_TRUE;
+        }
+
+        src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr);
+
+        const GLuint size = mesa_ind_buf->count * getTypeSize(mesa_ind_buf->type);
+
+        if(context->ind_buf.bHostIb != GL_TRUE)
+        {
+            radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo, 
+                                 &context->ind_buf.bo_offset, size, 4);
+            assert(context->ind_buf.bo->ptr != NULL);
+            dst_ptr = ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+        }
+        else
+        {
+            context->ind_buf.bo        = MALLOC_STRUCT(radeon_bo);
+            context->ind_buf.bo->ptr   = ALIGN_MALLOC(size, 4);
+            context->ind_buf.bo_offset = 0;
+            dst_ptr                    = context->ind_buf.bo->ptr;
+        }
+
+        _mesa_memcpy(dst_ptr, src_ptr, size);
+
+        context->ind_buf.is_32bit = (mesa_ind_buf->type == GL_UNSIGNED_INT);
+        context->ind_buf.count = mesa_ind_buf->count;
+
+        if (mapped_named_bo) 
+        {
+               ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj);
+        }
+    } 
+    else 
+    {
+           r700FixupIndexBuffer(ctx, mesa_ind_buf);
+    }
+}
+
+static GLboolean r700TryDrawPrims(GLcontext *ctx,
+                                        const struct gl_client_array *arrays[],
+                                        const struct _mesa_prim *prim,
+                                        GLuint nr_prims,
+                                        const struct _mesa_index_buffer *ib,
+                                        GLuint min_index,
+                                        GLuint max_index )
+{
+    context_t *context = R700_CONTEXT(ctx);
+    radeonContextPtr radeon = &context->radeon;
+    GLuint i, id = 0;
+    GLboolean bValidedbuffer;
+    struct radeon_renderbuffer *rrb;
+
+    if (ctx->NewState)
+    {
+        _mesa_update_state( ctx );
+    }
+
+    bValidedbuffer = r600ValidateBuffers(ctx);
+
+    /* always emit CB base to prevent
+     * lock ups on some chips.
+     */
+    R600_STATECHANGE(context, cb_target);
+    /* mark vtx as dirty since it changes per-draw */
+    R600_STATECHANGE(context, vtx);
+
+    _tnl_UpdateFixedFunctionProgram(ctx);
+    r700SetVertexFormat(ctx, arrays, max_index + 1);
+       r700SetupStreams2(ctx, arrays, max_index + 1);
+    r700UpdateShaders2(ctx);
+
+    r700SetScissor(context);
+
+    r700SetupVertexProgram(ctx);
+
+    r700SetupFragmentProgram(ctx);
+
+    r600UpdateTextureState(ctx);
+
+    GLuint emit_end = r700PredictRenderSize(ctx) 
+                    + context->radeon.cmdbuf.cs->cdw;
+
+    r700SetupIndexBuffer(ctx, ib);
+
+    radeonEmitState(radeon);
+
+    for (i = 0; i < nr_prims; ++i) 
+    {
+           r700RunRenderPrimitive(ctx, 
+                               prim[i].start, 
+                               prim[i].start + prim[i].count, 
+                               prim[i].mode);
+    }
+    /* Flush render op cached for last several quads. */
+    r700WaitForIdleClean(context);
+
+    rrb = radeon_get_colorbuffer(&context->radeon);
+    if (rrb && rrb->bo)
+           r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
+                        CB_ACTION_ENA_bit | (1 << (id + 6)));
+
+    rrb = radeon_get_depthbuffer(&context->radeon);
+    if (rrb && rrb->bo)
+           r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
+                        DB_ACTION_ENA_bit | DB_DEST_BASE_ENA_bit);
+
+    r700FreeData(ctx);
+
+    if (emit_end < context->radeon.cmdbuf.cs->cdw)
+    {
+        WARN_ONCE("Rendering was %d commands larger than predicted size."
+            " We might overflow  command buffer.\n", context->radeon.cmdbuf.cs->cdw - emit_end);
+    }
+
+    return GL_TRUE;
+}
+
+static void r700DrawPrimsRe(GLcontext *ctx,
+                        const struct gl_client_array *arrays[],
+                        const struct _mesa_prim *prim,
+                        GLuint nr_prims,
+                        const struct _mesa_index_buffer *ib,
+                        GLboolean index_bounds_valid,
+                        GLuint min_index,
+                        GLuint max_index)
+{
+    GLboolean retval = GL_FALSE;
+
+    /* This check should get folded into just the places that
+        * min/max index are really needed.
+        */
+       if (!index_bounds_valid) {
+               vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+       }
+
+       if (min_index) {
+               vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, r700DrawPrimsRe );
+               return;
+       }
+
+       /* Make an attempt at drawing */
+       retval = r700TryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
+
+       /* If failed run tnl pipeline - it should take care of fallbacks */
+       if (!retval)
+               _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
+}
+
+static void r700DrawPrims(GLcontext *ctx,
+                        const struct gl_client_array *arrays[],
+                        const struct _mesa_prim *prim,
+                        GLuint nr_prims,
+                        const struct _mesa_index_buffer *ib,
+                        GLboolean index_bounds_valid,
+                        GLuint min_index,
+                        GLuint max_index)
+{
+    context_t *context = R700_CONTEXT(ctx);
+
+    /* For non indexed drawing, using tnl pipe. */
+    if(!ib)
+    {
+        context->ind_buf.bo = NULL;
+
+        _tnl_vbo_draw_prims(ctx, arrays, prim, nr_prims, ib,
+                            index_bounds_valid, min_index, max_index);
+        return;
+    }
+
+       r700DrawPrimsRe(ctx, arrays, prim, nr_prims, ib, index_bounds_valid, min_index, max_index);
+}
+
+void r700InitDraw(GLcontext *ctx)
+{
+       struct vbo_context *vbo = vbo_context(ctx);
+
+       vbo->draw_prims = r700DrawPrims;
+}
+
 
index b4fd51c137019ce3a4297317d5c541a7e9eef294..955ea4e4e1da925398c4f72de2ba4f9f04937ba5 100644 (file)
@@ -60,6 +60,55 @@ void AddInstToList(TypedShaderList * plstCFInstructions, R700ShaderInstruction *
        plstCFInstructions->uNumOfNode++;
 }
 
+void TakeInstOutFromList(TypedShaderList * plstCFInstructions, R700ShaderInstruction * pInst)
+{
+    GLuint    ulIndex = 0;
+    GLboolean bFound  = GL_FALSE;
+    R700ShaderInstruction * pPrevInst = NULL;
+    R700ShaderInstruction * pCurInst = plstCFInstructions->pHead;
+
+    /* Need go thro list to make sure pInst is there. */
+    while(NULL != pCurInst)
+    {
+        if(pCurInst == pInst)
+        {                        
+            bFound  = GL_TRUE;
+            break;
+        }
+
+        pPrevInst = pCurInst;
+        pCurInst  = pCurInst->pNextInst;
+    }
+    if(GL_TRUE == bFound)
+    {
+        plstCFInstructions->uNumOfNode--;
+
+        pCurInst = pInst->pNextInst;
+        ulIndex  = pInst->m_uIndex;
+        while(NULL != pCurInst)
+        {
+            pCurInst->m_uIndex = ulIndex;
+            ulIndex++;
+            pCurInst = pCurInst->pNextInst;
+        }
+
+        if(plstCFInstructions->pHead == pInst)
+        {
+            plstCFInstructions->pHead = pInst->pNextInst;
+        }
+        if(plstCFInstructions->pTail == pInst)
+        {
+            plstCFInstructions->pTail = pPrevInst;
+        }
+        if(NULL != pPrevInst)
+        {
+            pPrevInst->pNextInst = pInst->pNextInst;
+        }
+
+        FREE(pInst);
+    }
+}
+
 void Init_R700_Shader(R700_Shader * pShader)
 {
        pShader->Type = R700_SHADER_INVALID;
@@ -488,6 +537,47 @@ void DebugPrint(void)
 {
 }
 
+void cleanup_vfetch_shaderinst(R700_Shader *pShader)
+{
+    R700ShaderInstruction      *pInst;
+    R700ShaderInstruction      *pInstToFree;
+    R700VertexInstruction      *pVTXInst;
+    R700ControlFlowInstruction *pCFInst;
+
+    pInst = pShader->lstVTXInstructions.pHead;
+    while(NULL != pInst)
+    {
+        pVTXInst = (R700VertexInstruction  *)pInst;        
+        pShader->uShaderBinaryDWORDSize -= GetInstructionSize(pVTXInst->m_ShaderInstType);
+
+        if(NULL != pVTXInst->m_pLinkedGenericClause)
+        {
+            pCFInst = (R700ControlFlowInstruction*)(pVTXInst->m_pLinkedGenericClause);
+
+            TakeInstOutFromList(&(pShader->lstCFInstructions), 
+                                 (R700ShaderInstruction*)pCFInst);
+
+            pShader->uShaderBinaryDWORDSize -= GetInstructionSize(pCFInst->m_ShaderInstType);
+        }
+
+        pInst = pInst->pNextInst;
+    };
+
+    //destroy each item in pShader->lstVTXInstructions;
+    pInst = pShader->lstVTXInstructions.pHead;
+    while(NULL != pInst)
+    {
+        pInstToFree = pInst;
+        pInst = pInst->pNextInst;
+        FREE(pInstToFree);
+    };
+
+    //set NULL pShader->lstVTXInstructions
+    pShader->lstVTXInstructions.pHead=NULL; 
+       pShader->lstVTXInstructions.pTail=NULL; 
+       pShader->lstVTXInstructions.uNumOfNode=0;
+}
+
 void Clean_Up_Shader(R700_Shader *pShader)
 {
     FREE(pShader->pProgram);
index bfd01e1a93a8038a13291b38b7c683192856ab4f..997cb05aaf806f1806500bff10cb811c782e0465 100644 (file)
@@ -143,6 +143,7 @@ void LoadProgram(R700_Shader *pShader);
 void UpdateShaderRegisters(R700_Shader *pShader);
 void DeleteInstructions(R700_Shader *pShader);
 void DebugPrint(void);
+void cleanup_vfetch_shaderinst(R700_Shader *pShader);
 
 void Clean_Up_Shader(R700_Shader *pShader);
 
index fc0b5116843725e595fe7c652ee1611fdcb4dd15..1043eabb149132de031d875ce28cab471ea79d61 100644 (file)
@@ -92,7 +92,25 @@ void r700UpdateShaders (GLcontext * ctx)  //----------------------------------
            }
     }
 
-    r700SelectVertexShader(ctx);
+    r700SelectVertexShader(ctx, 1);
+    r700UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+    context->radeon.NewGLState = 0;
+}
+
+void r700UpdateShaders2(GLcontext * ctx)  
+{
+    context_t *context = R700_CONTEXT(ctx);
+
+    /* should only happenen once, just after context is created */
+    /* TODO: shouldn't we fallback to sw here? */
+    if (!ctx->FragmentProgram._Current) {
+           _mesa_fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");
+           return;
+    }
+
+    r700SelectFragmentShader(ctx);
+
+    r700SelectVertexShader(ctx, 2);
     r700UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
     context->radeon.NewGLState = 0;
 }
index 0f53d5b4c59fd60d38e1e2d73f062e9fad07c570..209189d8d72813f55a45a60d7c2885e85437c122 100644 (file)
@@ -35,6 +35,7 @@
 
 extern void r700UpdateStateParameters(GLcontext * ctx, GLuint new_state);
 extern void r700UpdateShaders (GLcontext * ctx);
+extern void r700UpdateShaders2(GLcontext * ctx);
 
 extern void r700UpdateViewportOffset(GLcontext * ctx);
 
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);
index c48764c43ba423989f6173b4cc7066a7be191f31..f9a3e395ee9fbe49d84565be1aa30e0bb82582b8 100644 (file)
@@ -52,7 +52,7 @@ struct r700_vertex_program
 
     GLboolean translated;
     GLboolean loaded;
-    GLboolean needUpdateVF;
+    GLint     uiVersion;
        
     void * shaderbo;
 
@@ -76,19 +76,28 @@ unsigned int Map_Vertex_Input(r700_AssemblerBase       *pAsm,
 GLboolean Process_Vertex_Program_Vfetch_Instructions(
        struct r700_vertex_program *vp,
        struct gl_vertex_program   *mesa_vp);
-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);
+void Map_Vertex_Program(GLcontext *ctx,
+            struct r700_vertex_program *vp,
                        struct gl_vertex_program   *mesa_vp);
 GLboolean Find_Instruction_Dependencies_vp(struct r700_vertex_program *vp,
                                           struct gl_vertex_program   *mesa_vp);
 
 struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
-                                   struct gl_vertex_program   *mesa_vp);
+                                   struct gl_vertex_program   *mesa_vp,
+                    GLint nVer);
 
 /* Interface */
-extern void r700SelectVertexShader(GLcontext *ctx);
+extern void r700SelectVertexShader(GLcontext *ctx, GLint nVersion);
+extern void r700SetVertexFormat(GLcontext *ctx, const struct gl_client_array *arrays[], int count);
 
 extern GLboolean r700SetupVertexProgram(GLcontext * ctx);
 
 extern void *    r700GetActiveVpShaderBo(GLcontext * ctx);
 
+extern int getTypeSize(GLenum type);
+
 #endif /* _R700_VERTPROG_H_ */
diff --git a/src/mesa/drivers/dri/r600/radeon_buffer_objects.c b/src/mesa/drivers/dri/r600/radeon_buffer_objects.c
new file mode 120000 (symlink)
index 0000000..f6a5f66
--- /dev/null
@@ -0,0 +1 @@
+../radeon/radeon_buffer_objects.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/radeon_buffer_objects.h b/src/mesa/drivers/dri/r600/radeon_buffer_objects.h
new file mode 120000 (symlink)
index 0000000..2f134fd
--- /dev/null
@@ -0,0 +1 @@
+../radeon/radeon_buffer_objects.h
\ No newline at end of file