diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 15015d36a20..9793131d4f1 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -74,6 +74,8 @@ struct cso_context { boolean has_compute_shader; boolean has_streamout; + uint32_t max_fs_samplerviews : 16; + unsigned saved_state; /**< bitmask of CSO_BIT_x flags */ unsigned saved_compute_state; /**< bitmask of CSO_BIT_COMPUTE_x flags */ @@ -283,6 +285,9 @@ cso_create_context(struct pipe_context *pipe, unsigned flags) ctx->has_streamout = TRUE; } + ctx->max_fs_samplerviews = pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_FRAGMENT, + PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS); + ctx->max_sampler_seen = -1; return ctx; } @@ -320,8 +325,7 @@ void cso_unbind_context(struct cso_context *ctx) break; } - int maxsam = scr->get_shader_param(scr, sh, - PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS); + int maxsam = ctx->max_fs_samplerviews; int maxview = scr->get_shader_param(scr, sh, PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS); int maxssbo = scr->get_shader_param(scr, sh, @@ -1479,7 +1483,7 @@ cso_save_state(struct cso_context *cso, unsigned state_mask) * Restore the state which was saved by cso_save_state(). */ void -cso_restore_state(struct cso_context *cso) +cso_restore_state(struct cso_context *cso, unsigned unbind) { unsigned state_mask = cso->saved_state; @@ -1499,8 +1503,16 @@ cso_restore_state(struct cso_context *cso) cso_restore_tessctrl_shader(cso); if (state_mask & CSO_BIT_VERTEX_SHADER) cso_restore_vertex_shader(cso); + if (unbind & CSO_UNBIND_FS_SAMPLERVIEWS) + cso->pipe->set_sampler_views(cso->pipe, PIPE_SHADER_FRAGMENT, 0, 0, + cso->max_fs_samplerviews, false, NULL); + if (unbind & CSO_UNBIND_FS_SAMPLERVIEW0) + cso->pipe->set_sampler_views(cso->pipe, PIPE_SHADER_FRAGMENT, 0, 0, + 1, false, NULL); if (state_mask & CSO_BIT_FRAGMENT_SAMPLERS) cso_restore_fragment_samplers(cso); + if (unbind & CSO_UNBIND_FS_IMAGE0) + cso->pipe->set_shader_images(cso->pipe, PIPE_SHADER_FRAGMENT, 0, 0, 1, NULL); if (state_mask & CSO_BIT_FRAMEBUFFER) cso_restore_framebuffer(cso); if (state_mask & CSO_BIT_BLEND) @@ -1515,8 +1527,14 @@ cso_restore_state(struct cso_context *cso) cso_restore_sample_mask(cso); if (state_mask & CSO_BIT_VIEWPORT) cso_restore_viewport(cso); + if (unbind & CSO_UNBIND_VS_CONSTANTS) + cso->pipe->set_constant_buffer(cso->pipe, PIPE_SHADER_VERTEX, 0, false, NULL); + if (unbind & CSO_UNBIND_FS_CONSTANTS) + cso->pipe->set_constant_buffer(cso->pipe, PIPE_SHADER_FRAGMENT, 0, false, NULL); if (state_mask & CSO_BIT_VERTEX_ELEMENTS) cso_restore_vertex_elements(cso); + if (unbind & CSO_UNBIND_VERTEX_BUFFER0) + cso->pipe->set_vertex_buffers(cso->pipe, 0, 0, 1, false, NULL); if (state_mask & CSO_BIT_STREAM_OUTPUTS) cso_restore_stream_outputs(cso); if (state_mask & CSO_BIT_PAUSE_QUERIES) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 32420fe3845..6507bd026c4 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -98,6 +98,15 @@ void cso_set_stream_outputs(struct cso_context *ctx, const unsigned *offsets); +enum cso_unbind_flags { + CSO_UNBIND_FS_SAMPLERVIEWS = (1 << 0), + CSO_UNBIND_FS_SAMPLERVIEW0 = (1 << 1), + CSO_UNBIND_FS_IMAGE0 = (1 << 2), + CSO_UNBIND_VS_CONSTANTS = (1 << 3), + CSO_UNBIND_FS_CONSTANTS = (1 << 4), + CSO_UNBIND_VERTEX_BUFFER0 = (1 << 5), +}; + /* * We don't provide shader caching in CSO. Most of the time the api provides * object semantics for shaders anyway, and the cases where it doesn't @@ -165,7 +174,7 @@ void cso_set_render_condition(struct cso_context *cso, #define CSO_BIT_COMPUTE_SAMPLERS (1<<1) void cso_save_state(struct cso_context *cso, unsigned state_mask); -void cso_restore_state(struct cso_context *cso); +void cso_restore_state(struct cso_context *cso, unsigned unbind); void cso_save_compute_state(struct cso_context *cso, unsigned state_mask); void cso_restore_compute_state(struct cso_context *cso); diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c index 98fdfec95e1..b1887aa8498 100644 --- a/src/gallium/auxiliary/hud/hud_context.c +++ b/src/gallium/auxiliary/hud/hud_context.c @@ -609,12 +609,7 @@ hud_draw_results(struct hud_context *hud, struct pipe_resource *tex) } done: - cso_restore_state(cso); - - /* Unbind resources that we have bound. */ - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, NULL); - pipe->set_vertex_buffers(pipe, 0, 0, 1, false, NULL); - pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 0, 1, false, NULL); + cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEW0 | CSO_UNBIND_VS_CONSTANTS | CSO_UNBIND_VERTEX_BUFFER0); /* restore states not restored by cso */ if (hud->st) { diff --git a/src/gallium/auxiliary/postprocess/pp_run.c b/src/gallium/auxiliary/postprocess/pp_run.c index a4e71251ac8..93e0fa7b717 100644 --- a/src/gallium/auxiliary/postprocess/pp_run.c +++ b/src/gallium/auxiliary/postprocess/pp_run.c @@ -184,14 +184,11 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in, } /* restore state we changed */ - cso_restore_state(cso); - - /* Unbind resources that we have bound. */ - struct pipe_context *pipe = ppq->p->pipe; - pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, NULL); - pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, false, NULL); - pipe->set_vertex_buffers(pipe, 0, 0, 1, false, NULL); - pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 0, 3, false, NULL); + cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEWS | + CSO_UNBIND_FS_IMAGE0 | + CSO_UNBIND_VS_CONSTANTS | + CSO_UNBIND_FS_CONSTANTS | + CSO_UNBIND_VERTEX_BUFFER0); /* restore states not restored by cso */ if (ppq->p->st) { diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 0164ca7d9b6..e1cf5509ace 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -273,16 +273,11 @@ restore_render_state(struct gl_context *ctx) { struct st_context *st = st_context(ctx); struct cso_context *cso = st->cso_context; - struct pipe_context *pipe = st->pipe; - - cso_restore_state(cso); /* Unbind all because st/mesa won't do it if the current shader doesn't * use them. */ - pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 0, - st->state.num_sampler_views[PIPE_SHADER_FRAGMENT], - false, NULL); + cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEWS); st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = 0; st->dirty |= ST_NEW_VERTEX_ARRAYS | diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 729e244ea91..414e61be0ba 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -360,7 +360,7 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers) } /* Restore pipe state */ - cso_restore_state(cso); + cso_restore_state(cso, 0); st->dirty |= ST_NEW_VERTEX_ARRAYS; } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index c64381aafe7..d3a392ca2c4 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -942,14 +942,10 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, } /* restore state */ - cso_restore_state(cso); - /* Unbind all because st/mesa won't do it if the current shader doesn't * use them. */ - pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 0, - st->state.num_sampler_views[PIPE_SHADER_FRAGMENT], - false, NULL); + cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEWS); st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = 0; st->dirty |= ST_NEW_VERTEX_ARRAYS | diff --git a/src/mesa/state_tracker/st_cb_drawtex.c b/src/mesa/state_tracker/st_cb_drawtex.c index 31c429a9b8f..262ce39fbe1 100644 --- a/src/mesa/state_tracker/st_cb_drawtex.c +++ b/src/mesa/state_tracker/st_cb_drawtex.c @@ -348,7 +348,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, pipe_resource_reference(&vbuffer, NULL); /* restore state */ - cso_restore_state(cso); + cso_restore_state(cso, 0); st->dirty |= ST_NEW_VERTEX_ARRAYS; } diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index e9cd0b4149f..c8d7d9c7d63 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -254,16 +254,11 @@ try_pbo_readpixels(struct st_context *st, struct st_renderbuffer *strb, pipe->memory_barrier(pipe, PIPE_BARRIER_ALL); fail: - cso_restore_state(cso); - /* Unbind all because st/mesa won't do it if the current shader doesn't * use them. */ - pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 0, - st->state.num_sampler_views[PIPE_SHADER_FRAGMENT], - false, NULL); + cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEWS | CSO_UNBIND_FS_IMAGE0); st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = 0; - pipe->set_shader_images(pipe, PIPE_SHADER_FRAGMENT, 0, 0, 1, NULL); st->dirty |= ST_NEW_FS_CONSTANTS | ST_NEW_FS_IMAGES | diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index deb1aaeea74..85a23f84018 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1655,14 +1655,10 @@ try_pbo_upload_common(struct gl_context *ctx, success = st_pbo_draw(st, addr, surface->width, surface->height); fail: - cso_restore_state(cso); - /* Unbind all because st/mesa won't do it if the current shader doesn't * use them. */ - pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 0, - st->state.num_sampler_views[PIPE_SHADER_FRAGMENT], - false, NULL); + cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEWS); st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = 0; st->dirty |= ST_NEW_VERTEX_ARRAYS | @@ -1949,16 +1945,11 @@ try_pbo_download(struct st_context *st, pipe->memory_barrier(pipe, PIPE_BARRIER_IMAGE | PIPE_BARRIER_TEXTURE | PIPE_BARRIER_FRAMEBUFFER); fail: - cso_restore_state(cso); - /* Unbind all because st/mesa won't do it if the current shader doesn't * use them. */ - pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 0, - st->state.num_sampler_views[PIPE_SHADER_FRAGMENT], - false, NULL); + cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEWS | CSO_UNBIND_FS_IMAGE0); st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = 0; - pipe->set_shader_images(pipe, PIPE_SHADER_FRAGMENT, 0, 0, 1, NULL); st->dirty |= ST_NEW_FS_CONSTANTS | ST_NEW_FS_IMAGES |