svga: avoid emitting redundant SetShaderResource command

Tested with Lightsmark2008, Heaven, MTT piglit, glretrace, viewperf, conform.

Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
Charmaine Lee 2016-08-17 16:50:23 -07:00 committed by Brian Paul
parent 5313b294e6
commit 2781d60375
4 changed files with 63 additions and 34 deletions

View file

@ -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 */

View file

@ -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];
};

View file

@ -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);

View file

@ -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;
}