X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_swtnl_backend.c;h=576fd853e7f4ae9321d613ae0c98d14309a3b177;hb=c72dcd9a718628638957bfd99549bf788c2e6b36;hp=ff3da842729e183e6cd072b7bfd933a8f29f8834;hpb=bcc13b74443137043e8a34f8cb64a5add0d8af93;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_swtnl_backend.c b/src/gallium/drivers/svga/svga_swtnl_backend.c index ff3da842729..576fd853e7f 100644 --- a/src/gallium/drivers/svga/svga_swtnl_backend.c +++ b/src/gallium/drivers/svga/svga_swtnl_backend.c @@ -40,6 +40,7 @@ #include "svga_reg.h" #include "svga3d_reg.h" #include "svga_draw.h" +#include "svga_shader.h" #include "svga_swtnl_private.h" @@ -67,6 +68,9 @@ svga_vbuf_render_allocate_vertices( struct vbuf_render *render, boolean new_vbuf = FALSE; boolean new_ibuf = FALSE; + SVGA_STATS_TIME_PUSH(svga_sws(svga), + SVGA_STATS_TIME_VBUFRENDERALLOCVERT); + if (svga_render->vertex_size != vertex_size) svga->swtnl.new_vdecl = TRUE; svga_render->vertex_size = (size_t)vertex_size; @@ -87,13 +91,18 @@ svga_vbuf_render_allocate_vertices( struct vbuf_render *render, svga_render->vbuf_size = MAX2(size, svga_render->vbuf_alloc_size); svga_render->vbuf = pipe_buffer_create(screen, PIPE_BIND_VERTEX_BUFFER, + PIPE_USAGE_STREAM, svga_render->vbuf_size); if(!svga_render->vbuf) { svga_context_flush(svga, NULL); + assert(!svga_render->vbuf); svga_render->vbuf = pipe_buffer_create(screen, PIPE_BIND_VERTEX_BUFFER, + PIPE_USAGE_STREAM, svga_render->vbuf_size); - assert(svga_render->vbuf); + /* The buffer allocation may fail if we run out of memory. + * The draw module's vbuf code should handle that without crashing. + */ } svga->swtnl.new_vdecl = TRUE; @@ -107,6 +116,8 @@ svga_vbuf_render_allocate_vertices( struct vbuf_render *render, if (svga->swtnl.new_vdecl) svga_render->vdecl_offset = svga_render->vbuf_offset; + SVGA_STATS_TIME_POP(svga_sws(svga)); + return TRUE; } @@ -115,15 +126,36 @@ svga_vbuf_render_map_vertices( struct vbuf_render *render ) { struct svga_vbuf_render *svga_render = svga_vbuf_render(render); struct svga_context *svga = svga_render->svga; + void * retPtr = NULL; + + SVGA_STATS_TIME_PUSH(svga_sws(svga), + SVGA_STATS_TIME_VBUFRENDERMAPVERT); + + if (svga_render->vbuf) { + char *ptr = (char*)pipe_buffer_map(&svga->pipe, + svga_render->vbuf, + PIPE_TRANSFER_WRITE | + PIPE_TRANSFER_FLUSH_EXPLICIT | + PIPE_TRANSFER_DISCARD_RANGE | + PIPE_TRANSFER_UNSYNCHRONIZED, + &svga_render->vbuf_transfer); + if (ptr) { + svga_render->vbuf_ptr = ptr; + retPtr = ptr + svga_render->vbuf_offset; + } + else { + svga_render->vbuf_ptr = NULL; + svga_render->vbuf_transfer = NULL; + retPtr = NULL; + } + } + else { + /* we probably ran out of memory when allocating the vertex buffer */ + retPtr = NULL; + } - char *ptr = (char*)pipe_buffer_map(&svga->pipe, - svga_render->vbuf, - PIPE_TRANSFER_WRITE | - PIPE_TRANSFER_FLUSH_EXPLICIT | - PIPE_TRANSFER_DISCARD | - PIPE_TRANSFER_UNSYNCHRONIZED, - &svga_render->vbuf_transfer); - return ptr + svga_render->vbuf_offset; + SVGA_STATS_TIME_POP(svga_sws(svga)); + return retPtr; } static void @@ -136,60 +168,88 @@ svga_vbuf_render_unmap_vertices( struct vbuf_render *render, unsigned offset, length; size_t used = svga_render->vertex_size * ((size_t)max_index + 1); + SVGA_STATS_TIME_PUSH(svga_sws(svga), + SVGA_STATS_TIME_VBUFRENDERUNMAPVERT); + offset = svga_render->vbuf_offset + svga_render->vertex_size * min_index; length = svga_render->vertex_size * (max_index + 1 - min_index); + + if (0) { + /* dump vertex data */ + const float *f = (const float *) ((char *) svga_render->vbuf_ptr + + svga_render->vbuf_offset); + unsigned i; + debug_printf("swtnl vertex data:\n"); + for (i = 0; i < length / 4; i += 4) { + debug_printf("%u: %f %f %f %f\n", i, f[i], f[i+1], f[i+2], f[i+3]); + } + } + pipe_buffer_flush_mapped_range(&svga->pipe, svga_render->vbuf_transfer, offset, length); - pipe_buffer_unmap(&svga->pipe, svga_render->vbuf, svga_render->vbuf_transfer); + pipe_buffer_unmap(&svga->pipe, svga_render->vbuf_transfer); svga_render->min_index = min_index; svga_render->max_index = max_index; svga_render->vbuf_used = MAX2(svga_render->vbuf_used, used); + + SVGA_STATS_TIME_POP(svga_sws(svga)); } -static boolean +static void svga_vbuf_render_set_primitive( struct vbuf_render *render, - unsigned prim ) + enum pipe_prim_type prim ) { struct svga_vbuf_render *svga_render = svga_vbuf_render(render); svga_render->prim = prim; - - return TRUE; } static void -svga_vbuf_sumbit_state( struct svga_vbuf_render *svga_render ) +svga_vbuf_submit_state( struct svga_vbuf_render *svga_render ) { struct svga_context *svga = svga_render->svga; SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS]; enum pipe_error ret; - int i; + unsigned i; + static const unsigned zero[PIPE_MAX_ATTRIBS] = {0}; /* if the vdecl or vbuf hasn't changed do nothing */ if (!svga->swtnl.new_vdecl) return; + SVGA_STATS_TIME_PUSH(svga_sws(svga), + SVGA_STATS_TIME_VBUFSUBMITSTATE); + memcpy(vdecl, svga_render->vdecl, sizeof(vdecl)); /* flush the hw state */ ret = svga_hwtnl_flush(svga->hwtnl); - if (ret) { + if (ret != PIPE_OK) { svga_context_flush(svga, NULL); ret = svga_hwtnl_flush(svga->hwtnl); /* if we hit this path we might become synced with hw */ svga->swtnl.new_vbuf = TRUE; - assert(ret == 0); + assert(ret == PIPE_OK); } - svga_hwtnl_reset_vdecl(svga->hwtnl, svga_render->vdecl_count); - for (i = 0; i < svga_render->vdecl_count; i++) { vdecl[i].array.offset += svga_render->vdecl_offset; + } - svga_hwtnl_vdecl( svga->hwtnl, - i, - &vdecl[i], - svga_render->vbuf ); + svga_hwtnl_vertex_decls(svga->hwtnl, + svga_render->vdecl_count, + vdecl, + zero, + svga_render->layout_id); + + /* Specify the vertex buffer (there's only ever one) */ + { + struct pipe_vertex_buffer vb; + vb.buffer = svga_render->vbuf; + vb.buffer_offset = svga_render->vdecl_offset; + vb.stride = vdecl[0].array.stride; + vb.user_buffer = NULL; + svga_hwtnl_vertex_buffers(svga->hwtnl, 1, &vb); } /* We have already taken care of flatshading, so let the hwtnl @@ -197,31 +257,37 @@ svga_vbuf_sumbit_state( struct svga_vbuf_render *svga_render ) */ if (svga->state.sw.need_pipeline) { svga_hwtnl_set_flatshade(svga->hwtnl, FALSE, FALSE); - svga_hwtnl_set_unfilled(svga->hwtnl, PIPE_POLYGON_MODE_FILL); + svga_hwtnl_set_fillmode(svga->hwtnl, PIPE_POLYGON_MODE_FILL); } else { svga_hwtnl_set_flatshade( svga->hwtnl, - svga->curr.rast->templ.flatshade, + svga->curr.rast->templ.flatshade || + svga->state.hw_draw.fs->uses_flat_interp, svga->curr.rast->templ.flatshade_first ); - svga_hwtnl_set_unfilled( svga->hwtnl, - svga->curr.rast->hw_unfilled ); + svga_hwtnl_set_fillmode(svga->hwtnl, svga->curr.rast->hw_fillmode); } svga->swtnl.new_vdecl = FALSE; + SVGA_STATS_TIME_POP(svga_sws(svga)); } static void svga_vbuf_render_draw_arrays( struct vbuf_render *render, - unsigned start, - uint nr ) + unsigned start, uint nr ) { struct svga_vbuf_render *svga_render = svga_vbuf_render(render); struct svga_context *svga = svga_render->svga; unsigned bias = (svga_render->vbuf_offset - svga_render->vdecl_offset) / svga_render->vertex_size; - enum pipe_error ret = 0; + enum pipe_error ret = PIPE_OK; + /* instancing will already have been resolved at this point by 'draw' */ + const unsigned start_instance = 0; + const unsigned instance_count = 1; + + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_VBUFDRAWARRAYS); - svga_vbuf_sumbit_state(svga_render); + /* off to hardware */ + svga_vbuf_submit_state(svga_render); /* Need to call update_state() again as the draw module may have * altered some of our state behind our backs. Testcase: @@ -229,13 +295,17 @@ svga_vbuf_render_draw_arrays( struct vbuf_render *render, */ svga_update_state_retry( svga, SVGA_STATE_HW_DRAW ); - ret = svga_hwtnl_draw_arrays(svga->hwtnl, svga_render->prim, start + bias, nr); + ret = svga_hwtnl_draw_arrays(svga->hwtnl, svga_render->prim, start + bias, nr, + start_instance, instance_count); if (ret != PIPE_OK) { svga_context_flush(svga, NULL); - ret = svga_hwtnl_draw_arrays(svga->hwtnl, svga_render->prim, start + bias, nr); + ret = svga_hwtnl_draw_arrays(svga->hwtnl, svga_render->prim, + start + bias, nr, + start_instance, instance_count); svga->swtnl.new_vbuf = TRUE; assert(ret == PIPE_OK); } + SVGA_STATS_TIME_POP(svga_sws(svga)); } @@ -250,9 +320,14 @@ svga_vbuf_render_draw_elements( struct vbuf_render *render, int bias = (svga_render->vbuf_offset - svga_render->vdecl_offset) / svga_render->vertex_size; boolean ret; size_t size = 2 * nr_indices; + /* instancing will already have been resolved at this point by 'draw' */ + const unsigned start_instance = 0; + const unsigned instance_count = 1; assert(( svga_render->vbuf_offset - svga_render->vdecl_offset) % svga_render->vertex_size == 0); + SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_VBUFDRAWELEMENTS); + if (svga_render->ibuf_size < svga_render->ibuf_offset + size) pipe_resource_reference(&svga_render->ibuf, NULL); @@ -260,6 +335,7 @@ svga_vbuf_render_draw_elements( struct vbuf_render *render, svga_render->ibuf_size = MAX2(size, svga_render->ibuf_alloc_size); svga_render->ibuf = pipe_buffer_create(screen, PIPE_BIND_INDEX_BUFFER, + PIPE_USAGE_STREAM, svga_render->ibuf_size); svga_render->ibuf_offset = 0; } @@ -267,9 +343,8 @@ svga_vbuf_render_draw_elements( struct vbuf_render *render, pipe_buffer_write_nooverlap(&svga->pipe, svga_render->ibuf, svga_render->ibuf_offset, 2 * nr_indices, indices); - /* off to hardware */ - svga_vbuf_sumbit_state(svga_render); + svga_vbuf_submit_state(svga_render); /* Need to call update_state() again as the draw module may have * altered some of our state behind our backs. Testcase: @@ -284,7 +359,8 @@ svga_vbuf_render_draw_elements( struct vbuf_render *render, svga_render->min_index, svga_render->max_index, svga_render->prim, - svga_render->ibuf_offset / 2, nr_indices); + svga_render->ibuf_offset / 2, nr_indices, + start_instance, instance_count); if(ret != PIPE_OK) { svga_context_flush(svga, NULL); ret = svga_hwtnl_draw_range_elements(svga->hwtnl, @@ -294,12 +370,15 @@ svga_vbuf_render_draw_elements( struct vbuf_render *render, svga_render->min_index, svga_render->max_index, svga_render->prim, - svga_render->ibuf_offset / 2, nr_indices); + svga_render->ibuf_offset / 2, + nr_indices, + start_instance, instance_count); svga->swtnl.new_vbuf = TRUE; assert(ret == PIPE_OK); } - svga_render->ibuf_offset += size; + + SVGA_STATS_TIME_POP(svga_sws(svga)); } @@ -334,6 +413,7 @@ svga_vbuf_render_create( struct svga_context *svga ) svga_render->vbuf_size = 0; svga_render->ibuf_alloc_size = 4*1024; svga_render->vbuf_alloc_size = 64*1024; + svga_render->layout_id = SVGA3D_INVALID_ID; svga_render->base.max_vertex_buffer_bytes = 64*1024/10; svga_render->base.max_indices = 65536; svga_render->base.get_vertex_info = svga_vbuf_render_get_vertex_info;