X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_state_vdecl.c;h=a49bcd0a2630ff631969cc53cf8b4953f7241d07;hb=39d00722b22a0059bbc58f0158a22f384519cd39;hp=c534308f50307464f681be6cec47a11e3f8d2972;hpb=48302e9b309c7ce218de2e522c91bdc87e61cdbc;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c index c534308f503..a49bcd0a263 100644 --- a/src/gallium/drivers/svga/svga_state_vdecl.c +++ b/src/gallium/drivers/svga/svga_state_vdecl.c @@ -23,7 +23,7 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_upload_mgr.h" @@ -33,137 +33,121 @@ #include "svga_draw.h" #include "svga_tgsi.h" #include "svga_screen.h" -#include "svga_screen_buffer.h" - +#include "svga_shader.h" +#include "svga_resource_buffer.h" #include "svga_hw_reg.h" -static int -upload_user_buffers( struct svga_context *svga ) -{ - enum pipe_error ret = PIPE_OK; - int i; - int nr; - - if (0) - debug_printf("%s: %d\n", __FUNCTION__, svga->curr.num_vertex_buffers); - - nr = svga->curr.num_vertex_buffers; - - for (i = 0; i < nr; i++) - { - if (svga_buffer_is_user_buffer(svga->curr.vb[i].buffer)) - { - struct pipe_buffer *upload_buffer = NULL; - unsigned offset = /*svga->curr.vb[i].buffer_offset*/ 0; - unsigned size = svga->curr.vb[i].buffer->size /*- offset*/; - unsigned upload_offset; - - ret = u_upload_buffer( svga->upload_vb, - offset, - size, - svga->curr.vb[i].buffer, - &upload_offset, - &upload_buffer ); - if (ret) - return ret; - - if (0) - debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n", - __FUNCTION__, - i, - svga->curr.vb[i].buffer, - upload_buffer, upload_offset, size); - - /* Make sure we release the old buffer and end up with the - * correct refcount on the uploaded buffer. - */ - pipe_buffer_reference( &svga->curr.vb[i].buffer, NULL ); - svga->curr.vb[i].buffer = upload_buffer; - svga->curr.vb[i].buffer_offset = upload_offset; - } - } - - if (0) - debug_printf("%s: DONE\n", __FUNCTION__); - - return ret; -} - -/*********************************************************************** - */ - - -static int emit_hw_vs_vdecl( struct svga_context *svga, - unsigned dirty ) +static enum pipe_error +emit_hw_vs_vdecl(struct svga_context *svga, uint64_t dirty) { - const struct pipe_vertex_element *ve = svga->curr.ve; - SVGA3dVertexDecl decl; + const struct pipe_vertex_element *ve = svga->curr.velems->velem; + SVGA3dVertexDecl decls[SVGA3D_INPUTREG_MAX]; + unsigned buffer_indexes[SVGA3D_INPUTREG_MAX]; unsigned i; + unsigned neg_bias = 0; - assert(svga->curr.num_vertex_elements >= + assert(svga->curr.velems->count >= svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]); - svga_hwtnl_reset_vdecl( svga->hwtnl, - svga->curr.num_vertex_elements ); + /** + * We can't set the VDECL offset to something negative, so we + * must calculate a common negative additional index bias, and modify + * the VDECL offsets accordingly so they *all* end up positive. + * + * Note that the exact value of the negative index bias is not that + * important, since we compensate for it when we calculate the vertex + * buffer offset below. The important thing is that all vertex buffer + * offsets remain positive. + * + * Note that we use a negative bias variable in order to make the + * rounding maths more easy to follow, and to avoid int / unsigned + * confusion. + */ - for (i = 0; i < svga->curr.num_vertex_elements; i++) { - const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index]; + for (i = 0; i < svga->curr.velems->count; i++) { + const struct pipe_vertex_buffer *vb = + &svga->curr.vb[ve[i].vertex_buffer_index]; + struct svga_buffer *buffer; + unsigned int offset = vb->buffer_offset + ve[i].src_offset; + unsigned tmp_neg_bias = 0; + + if (!vb->buffer.resource) + continue; + + buffer = svga_buffer(vb->buffer.resource); + if (buffer->uploaded.start > offset) { + tmp_neg_bias = buffer->uploaded.start - offset; + if (vb->stride) + tmp_neg_bias = (tmp_neg_bias + vb->stride - 1) / vb->stride; + neg_bias = MAX2(neg_bias, tmp_neg_bias); + } + } + + for (i = 0; i < svga->curr.velems->count; i++) { + const struct pipe_vertex_buffer *vb = + &svga->curr.vb[ve[i].vertex_buffer_index]; unsigned usage, index; + struct svga_buffer *buffer; + if (!vb->buffer.resource) + continue; + buffer = svga_buffer(vb->buffer.resource); svga_generate_vdecl_semantics( i, &usage, &index ); /* SVGA_NEW_VELEMENT */ - decl.identity.type = svga->state.sw.ve_format[i]; - decl.identity.method = SVGA3D_DECLMETHOD_DEFAULT; - decl.identity.usage = usage; - decl.identity.usageIndex = index; - decl.array.stride = vb->stride; - decl.array.offset = (vb->buffer_offset + - ve[i].src_offset); - - svga_hwtnl_vdecl( svga->hwtnl, - i, - &decl, - vb->buffer ); + decls[i].identity.type = svga->curr.velems->decl_type[i]; + decls[i].identity.method = SVGA3D_DECLMETHOD_DEFAULT; + decls[i].identity.usage = usage; + decls[i].identity.usageIndex = index; + decls[i].array.stride = vb->stride; + + /* Compensate for partially uploaded vbo, and + * for the negative index bias. + */ + decls[i].array.offset = (vb->buffer_offset + + ve[i].src_offset + + neg_bias * vb->stride + - buffer->uploaded.start); + + assert(decls[i].array.offset >= 0); + + buffer_indexes[i] = ve[i].vertex_buffer_index; + + assert(!buffer->uploaded.buffer); } - return 0; + svga_hwtnl_vertex_decls(svga->hwtnl, + svga->curr.velems->count, + decls, + buffer_indexes, + svga->curr.velems->id); + + svga_hwtnl_vertex_buffers(svga->hwtnl, + svga->curr.num_vertex_buffers, + svga->curr.vb); + + svga_hwtnl_set_index_bias( svga->hwtnl, -(int) neg_bias ); + return PIPE_OK; } -static int emit_hw_vdecl( struct svga_context *svga, - unsigned dirty ) +static enum pipe_error +emit_hw_vdecl(struct svga_context *svga, uint64_t dirty) { - int ret = 0; - /* SVGA_NEW_NEED_SWTNL */ if (svga->state.sw.need_swtnl) - return 0; /* Do not emit during swtnl */ - - /* If we get to here, we know that we're going to draw. Upload - * userbuffers now and try to combine multiple userbuffers from - * multiple draw calls into a single host buffer for performance. - */ - if (svga->curr.any_user_vertex_buffers && - SVGA_COMBINE_USERBUFFERS) - { - ret = upload_user_buffers( svga ); - if (ret) - return ret; - - svga->curr.any_user_vertex_buffers = FALSE; - } + return PIPE_OK; /* Do not emit during swtnl */ return emit_hw_vs_vdecl( svga, dirty ); } -struct svga_tracked_state svga_hw_vdecl = +struct svga_tracked_state svga_hw_vdecl = { "hw vertex decl state (hwtnl version)", ( SVGA_NEW_NEED_SWTNL | @@ -174,9 +158,3 @@ struct svga_tracked_state svga_hw_vdecl = SVGA_NEW_VS ), emit_hw_vdecl }; - - - - - -