X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_state_vdecl.c;h=a33eda3836605ed6b99b911d31d176df6b3edad2;hb=df6a5666b6398613e552f66cd092369b12cce9ed;hp=958d00393f2f28b90ddbd58fd80eb8cafd203d2d;hpb=9032d2a13ecd019206a48767d9205c0aafa7cca2;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c index 958d00393f2..a33eda38366 100644 --- a/src/gallium/drivers/svga/svga_state_vdecl.c +++ b/src/gallium/drivers/svga/svga_state_vdecl.c @@ -34,135 +34,113 @@ #include "svga_tgsi.h" #include "svga_screen.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 svga_buffer *buffer = svga_buffer(svga->curr.vb[i].buffer); - - if (!buffer->uploaded.buffer) { - boolean flushed; - ret = u_upload_buffer( svga->upload_vb, - 0, 0, - buffer->b.b.width0, - &buffer->b.b, - &buffer->uploaded.offset, - &buffer->uploaded.buffer, - &flushed); - if (ret) - return ret; - - if (0) - debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n", - __FUNCTION__, - i, - buffer, - buffer->uploaded.buffer, - buffer->uploaded.offset, - buffer->b.b.width0); - } - - pipe_resource_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer ); - svga->curr.vb[i].buffer_offset = buffer->uploaded.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, unsigned dirty) { const struct pipe_vertex_element *ve = svga->curr.velems->velem; - SVGA3dVertexDecl decl; unsigned i; + unsigned neg_bias = 0; assert(svga->curr.velems->count >= svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]); - svga_hwtnl_reset_vdecl( svga->hwtnl, + /* specify number of vertex element declarations to come */ + svga_hwtnl_reset_vdecl( svga->hwtnl, svga->curr.velems->count ); + /** + * 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.velems->count; i++) { - const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index]; + const struct pipe_vertex_buffer *vb = + &svga->curr.vb[ve[i].vertex_buffer_index]; + const struct svga_buffer *buffer; + unsigned int offset = vb->buffer_offset + ve[i].src_offset; + + if (!vb->buffer) + continue; + + buffer = svga_buffer(vb->buffer); + if (buffer->uploaded.start > offset) { + unsigned 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; + const struct svga_buffer *buffer; + SVGA3dVertexDecl decl; + if (!vb->buffer) + continue; + buffer = svga_buffer(vb->buffer); svga_generate_vdecl_semantics( i, &usage, &index ); /* SVGA_NEW_VELEMENT */ - decl.identity.type = svga->state.sw.ve_format[i]; + decl.identity.type = svga->curr.velems->decl_type[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); + + /* Compensate for partially uploaded vbo, and + * for the negative index bias. + */ + decl.array.offset = (vb->buffer_offset + + ve[i].src_offset + + neg_bias * vb->stride + - buffer->uploaded.start); + + assert(decl.array.offset >= 0); svga_hwtnl_vdecl( svga->hwtnl, i, &decl, + buffer->uploaded.buffer ? buffer->uploaded.buffer : vb->buffer ); } - return 0; + 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, unsigned 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 | @@ -173,9 +151,3 @@ struct svga_tracked_state svga_hw_vdecl = SVGA_NEW_VS ), emit_hw_vdecl }; - - - - - -