From 2781d603753148771c1a706150b7a9a54592befe Mon Sep 17 00:00:00 2001 From: Charmaine Lee Date: Wed, 17 Aug 2016 16:50:23 -0700 Subject: [PATCH] svga: avoid emitting redundant SetShaderResource command Tested with Lightsmark2008, Heaven, MTT piglit, glretrace, viewperf, conform. Reviewed-by: Brian Paul --- src/gallium/drivers/svga/svga_context.c | 2 + src/gallium/drivers/svga/svga_context.h | 5 +- src/gallium/drivers/svga/svga_pipe_sampler.c | 11 +++ src/gallium/drivers/svga/svga_state_sampler.c | 79 +++++++++++-------- 4 files changed, 63 insertions(+), 34 deletions(-) diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c index 475b2b53f5e..ffecef59eb9 100644 --- a/src/gallium/drivers/svga/svga_context.c +++ b/src/gallium/drivers/svga/svga_context.c @@ -226,6 +226,8 @@ struct pipe_context *svga_context_create(struct pipe_screen *screen, sizeof(svga->state.hw_draw.num_samplers)); memset(&svga->state.hw_draw.num_sampler_views, 0, sizeof(svga->state.hw_draw.num_sampler_views)); + memset(svga->state.hw_draw.sampler_views, 0, + sizeof(svga->state.hw_draw.sampler_views)); svga->state.hw_draw.num_views = 0; /* Initialize the shader pointers */ diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index a5ec78c9093..a635ef1fc95 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -377,12 +377,15 @@ struct svga_hw_draw_state unsigned num_samplers[PIPE_SHADER_TYPES]; SVGA3dSamplerId samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; + unsigned num_sampler_views[PIPE_SHADER_TYPES]; + struct pipe_sampler_view + *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; + unsigned num_rendertargets; struct pipe_surface *rtv[SVGA3D_MAX_RENDER_TARGETS]; struct pipe_surface *dsv; /* used for rebinding */ - unsigned num_sampler_views[PIPE_SHADER_TYPES]; unsigned default_constbuf_size[PIPE_SHADER_TYPES]; }; diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index ae19b7ee0a6..59609b84e20 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -544,9 +544,20 @@ done: void svga_cleanup_sampler_state(struct svga_context *svga) { + unsigned shader; + if (!svga_have_vgpu10(svga)) return; + for (shader = 0; shader <= PIPE_SHADER_GEOMETRY; shader++) { + unsigned i; + + for (i = 0; i < svga->state.hw_draw.num_sampler_views[shader]; i++) { + pipe_sampler_view_release(&svga->pipe, + &svga->state.hw_draw.sampler_views[shader][i]); + } + } + /* free polygon stipple state */ if (svga->polygon_stipple.sampler) { svga->pipe.delete_sampler_state(&svga->pipe, svga->polygon_stipple.sampler); diff --git a/src/gallium/drivers/svga/svga_state_sampler.c b/src/gallium/drivers/svga/svga_state_sampler.c index 216ab8180fb..420a5667efb 100644 --- a/src/gallium/drivers/svga/svga_state_sampler.c +++ b/src/gallium/drivers/svga/svga_state_sampler.c @@ -205,6 +205,7 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty) for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) { SVGA3dShaderResourceViewId ids[PIPE_MAX_SAMPLERS]; struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; unsigned count; unsigned nviews; unsigned i; @@ -213,10 +214,9 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty) for (i = 0; i < count; i++) { struct svga_pipe_sampler_view *sv = svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]); - struct svga_winsys_surface *surface; if (sv) { - surface = svga_resource_handle(sv->base.texture); + surfaces[i] = svga_resource_handle(sv->base.texture); ret = svga_validate_pipe_sampler_view(svga, sv); if (ret != PIPE_OK) @@ -224,39 +224,19 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty) assert(sv->id != SVGA3D_INVALID_ID); ids[i] = sv->id; + sampler_views[i] = &sv->base; } else { - surface = NULL; + surfaces[i] = NULL; ids[i] = SVGA3D_INVALID_ID; + sampler_views[i] = NULL; } - surfaces[i] = surface; } - for (; i < ARRAY_SIZE(ids); i++) { + for (; i < svga->state.hw_draw.num_sampler_views[shader]; i++) { ids[i] = SVGA3D_INVALID_ID; surfaces[i] = NULL; - } - - if (shader == PIPE_SHADER_FRAGMENT) { - /* Handle polygon stipple sampler view */ - if (svga->curr.rast->templ.poly_stipple_enable) { - const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit; - struct svga_pipe_sampler_view *sv = - svga->polygon_stipple.sampler_view; - - assert(sv); - if (!sv) { - return PIPE_OK; /* probably out of memory */ - } - - ret = svga_validate_pipe_sampler_view(svga, sv); - if (ret != PIPE_OK) - return ret; - - ids[unit] = sv->id; - surfaces[unit] = svga_resource_handle(sv->base.texture); - count = MAX2(count, unit+1); - } + sampler_views[i] = NULL; } /* Number of ShaderResources that need to be modified. This includes @@ -264,20 +244,53 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty) */ nviews = MAX2(svga->state.hw_draw.num_sampler_views[shader], count); if (nviews > 0) { - ret = SVGA3D_vgpu10_SetShaderResources(svga->swc, + if (count != svga->state.hw_draw.num_sampler_views[shader] || + memcmp(sampler_views, svga->state.hw_draw.sampler_views[shader], + count * sizeof(sampler_views[0])) != 0) { + ret = SVGA3D_vgpu10_SetShaderResources(svga->swc, svga_shader_type(shader), 0, /* startView */ nviews, ids, surfaces); - if (ret != PIPE_OK) - return ret; - } + if (ret != PIPE_OK) + return ret; - /* Number of sampler views enabled in the device */ - svga->state.hw_draw.num_sampler_views[shader] = count; + /* Save referenced sampler views in the hw draw state. */ + svga->state.hw_draw.num_sampler_views[shader] = count; + for (i = 0; i < nviews; i++) { + pipe_sampler_view_reference( + &svga->state.hw_draw.sampler_views[shader][i], + sampler_views[i]); + } + } + } } + /* Handle polygon stipple sampler view */ + if (svga->curr.rast->templ.poly_stipple_enable) { + const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit; + struct svga_pipe_sampler_view *sv = svga->polygon_stipple.sampler_view; + struct svga_winsys_surface *surface; + + assert(sv); + if (!sv) { + return PIPE_OK; /* probably out of memory */ + } + + ret = svga_validate_pipe_sampler_view(svga, sv); + if (ret != PIPE_OK) + return ret; + + surface = svga_resource_handle(sv->base.texture); + ret = SVGA3D_vgpu10_SetShaderResources( + svga->swc, + svga_shader_type(PIPE_SHADER_FRAGMENT), + unit, /* startView */ + 1, + &sv->id, + &surface); + } return ret; } -- 2.30.2