r600g: build fetch shader from vertex elements
[mesa.git] / src / gallium / drivers / r600 / evergreen_state.c
index ebd541d5f8d79913db43b877338a865f1a81122f..b313d5250129da7d38c2fe5869799e973f64c7f4 100644 (file)
@@ -1259,6 +1259,90 @@ void evergreen_polygon_offset_update(struct r600_pipe_context *rctx)
        }
 }
 
+void evergreen_vertex_buffer_update(struct r600_pipe_context *rctx)
+{
+       struct r600_pipe_state *rstate;
+       struct r600_resource *rbuffer;
+       struct pipe_vertex_buffer *vertex_buffer;
+       unsigned i, offset;
+
+       /* we don't update until we know vertex elements */
+       if (rctx->vertex_elements == NULL || !rctx->nvertex_buffer)
+               return;
+
+       /* delete previous translated vertex elements */
+       if (rctx->tran.new_velems) {
+               r600_end_vertex_translate(rctx);
+       }
+
+       if (rctx->vertex_elements->incompatible_layout) {
+               /* translate rebind new vertex elements so
+                * return once translated
+                */
+               r600_begin_vertex_translate(rctx);
+               return;
+       }
+
+       if (rctx->any_user_vbs) {
+               r600_upload_user_buffers(rctx);
+               rctx->any_user_vbs = FALSE;
+       }
+
+       if (rctx->vertex_elements->vbuffer_need_offset) {
+               /* one resource per vertex elements */
+               rctx->nvs_resource = rctx->vertex_elements->count;
+       } else {
+               /* bind vertex buffer once */
+               rctx->nvs_resource = rctx->nvertex_buffer;
+       }
+
+       for (i = 0 ; i < rctx->nvs_resource; i++) {
+               rstate = &rctx->vs_resource[i];
+               rstate->id = R600_PIPE_STATE_RESOURCE;
+               rstate->nregs = 0;
+
+               if (rctx->vertex_elements->vbuffer_need_offset) {
+                       /* one resource per vertex elements */
+                       unsigned vbuffer_index;
+                       vbuffer_index = rctx->vertex_elements->elements[i].vertex_buffer_index;
+                       vertex_buffer = &rctx->vertex_buffer[vbuffer_index];
+                       rbuffer = (struct r600_resource*)vertex_buffer->buffer;
+                       offset = rctx->vertex_elements->vbuffer_offset[i] +
+                               vertex_buffer->buffer_offset +
+                               r600_bo_offset(rbuffer->bo);
+               } else {
+                       /* bind vertex buffer once */
+                       vertex_buffer = &rctx->vertex_buffer[i];
+                       rbuffer = (struct r600_resource*)vertex_buffer->buffer;
+                       offset = vertex_buffer->buffer_offset +
+                               r600_bo_offset(rbuffer->bo);
+               }
+
+               r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0,
+                                       offset, 0xFFFFFFFF, rbuffer->bo);
+               r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1,
+                                       rbuffer->size - offset - 1, 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2,
+                                       S_030008_STRIDE(vertex_buffer->stride),
+                                       0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_03000C_RESOURCE0_WORD3,
+                                       S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) |
+                                       S_03000C_DST_SEL_Y(V_03000C_SQ_SEL_Y) |
+                                       S_03000C_DST_SEL_Z(V_03000C_SQ_SEL_Z) |
+                                       S_03000C_DST_SEL_W(V_03000C_SQ_SEL_W),
+                                       0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_030010_RESOURCE0_WORD4,
+                                       0x00000000, 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_030014_RESOURCE0_WORD5,
+                                       0x00000000, 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_030018_RESOURCE0_WORD6,
+                                       0x00000000, 0xFFFFFFFF, NULL);
+               r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7,
+                                       0xC0000000, 0xFFFFFFFF, NULL);
+               evergreen_fs_resource_set(&rctx->ctx, rstate, i);
+       }
+}
+
 int r600_conv_pipe_prim(unsigned pprim, unsigned *prim);
 void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
 {
@@ -1273,6 +1357,7 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
        struct r600_drawl draw;
        boolean translate = FALSE;
 
+#if 0
        if (rctx->vertex_elements->incompatible_layout) {
                r600_begin_vertex_translate(rctx);
                translate = TRUE;
@@ -1282,6 +1367,7 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
                r600_upload_user_buffers(rctx);
                rctx->any_user_vbs = FALSE;
        }
+#endif
 
        memset(&draw, 0, sizeof(struct r600_drawl));
        draw.ctx = ctx;
@@ -1338,6 +1424,7 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
        if (r600_pipe_shader_update(&rctx->context, rctx->ps_shader))
                return;
 
+#if 0
        for (i = 0 ; i < rctx->vertex_elements->count; i++) {
                uint32_t word3, word2;
                uint32_t format;
@@ -1372,6 +1459,7 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info)
                r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7, 0xC0000000, 0xFFFFFFFF, NULL);
                evergreen_fs_resource_set(&rctx->ctx, rstate, i);
        }
+#endif
 
        mask = 0;
        for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) {
@@ -1587,15 +1675,18 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader
        r600_pipe_state_add_reg(rstate,
                                R_028864_SQ_PGM_RESOURCES_2_VS,
                                0x0, 0xFFFFFFFF, NULL);
-       r600_pipe_state_add_reg(rstate,
-                       R_0288A8_SQ_PGM_RESOURCES_FS,
-                       0x00000000, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate,
                        R_02885C_SQ_PGM_START_VS,
                        (r600_bo_offset(shader->bo)) >> 8, 0xFFFFFFFF, shader->bo);
+
+#if 0
+       r600_pipe_state_add_reg(rstate,
+                       R_0288A8_SQ_PGM_RESOURCES_FS,
+                       0x00000000, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate,
                        R_0288A4_SQ_PGM_START_FS,
                        (r600_bo_offset(shader->bo)) >> 8, 0xFFFFFFFF, shader->bo_fetch);
+#endif
 
        r600_pipe_state_add_reg(rstate,
                                R_03A200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF,