diff options
Diffstat (limited to 'src/gallium/drivers/svga')
-rw-r--r-- | src/gallium/drivers/svga/svga_pipe_sampler.c | 89 |
1 files changed, 65 insertions, 24 deletions
diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index 7675daac5ab..0d2745e25ef 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -146,31 +146,52 @@ svga_create_sampler_state(struct pipe_context *pipe, } static void -svga_bind_fragment_sampler_states(struct pipe_context *pipe, - unsigned num, void **sampler) +svga_bind_sampler_states(struct pipe_context *pipe, + unsigned shader, + unsigned start, + unsigned num, + void **samplers) { struct svga_context *svga = svga_context(pipe); unsigned i; - assert(num <= PIPE_MAX_SAMPLERS); + assert(shader < PIPE_SHADER_TYPES); + assert(start + num <= PIPE_MAX_SAMPLERS); + + /* we only support fragment shader samplers at this time */ + if (shader != PIPE_SHADER_FRAGMENT) + return; /* Check for no-op */ - if (num == svga->curr.num_samplers && - !memcmp(svga->curr.sampler, sampler, num * sizeof(void *))) { + if (start + num <= svga->curr.num_samplers && + !memcmp(svga->curr.sampler + start, samplers, num * sizeof(void *))) { if (0) debug_printf("sampler noop\n"); return; } for (i = 0; i < num; i++) - svga->curr.sampler[i] = sampler[i]; + svga->curr.sampler[start + i] = samplers[i]; - for (i = num; i < svga->curr.num_samplers; i++) - svga->curr.sampler[i] = NULL; + /* find highest non-null sampler_views[] entry */ + { + unsigned j = MAX2(svga->curr.num_samplers, start + num); + while (j > 0 && svga->curr.sampler[j - 1] == NULL) + j--; + svga->curr.num_samplers = j; + } - svga->curr.num_samplers = num; svga->dirty |= SVGA_NEW_SAMPLER; } + +static void +svga_bind_fragment_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + svga_bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, num, sampler); +} + + static void svga_delete_sampler_state(struct pipe_context *pipe, void *sampler) { @@ -206,49 +227,61 @@ svga_sampler_view_destroy(struct pipe_context *pipe, } static void -svga_set_fragment_sampler_views(struct pipe_context *pipe, - unsigned num, - struct pipe_sampler_view **views) +svga_set_sampler_views(struct pipe_context *pipe, + unsigned shader, + unsigned start, + unsigned num, + struct pipe_sampler_view **views) { struct svga_context *svga = svga_context(pipe); unsigned flag_1d = 0; unsigned flag_srgb = 0; uint i; - assert(num <= PIPE_MAX_SAMPLERS); + assert(shader < PIPE_SHADER_TYPES); + assert(start + num <= Elements(svga->curr.sampler_views)); + + /* we only support fragment shader sampler views at this time */ + if (shader != PIPE_SHADER_FRAGMENT) + return; /* Check for no-op */ - if (num == svga->curr.num_sampler_views && - !memcmp(svga->curr.sampler_views, views, num * sizeof(struct pipe_sampler_view *))) { + if (start + num <= svga->curr.num_sampler_views && + !memcmp(svga->curr.sampler_views + start, views, + num * sizeof(struct pipe_sampler_view *))) { if (0) debug_printf("texture noop\n"); return; } for (i = 0; i < num; i++) { - if (svga->curr.sampler_views[i] != views[i]) { + if (svga->curr.sampler_views[start + i] != views[i]) { /* Note: we're using pipe_sampler_view_release() here to work around * a possible crash when the old view belongs to another context that * was already destroyed. */ - pipe_sampler_view_release(pipe, &svga->curr.sampler_views[i]); - pipe_sampler_view_reference(&svga->curr.sampler_views[i], views[i]); + pipe_sampler_view_release(pipe, &svga->curr.sampler_views[start + i]); + pipe_sampler_view_reference(&svga->curr.sampler_views[start + i], + views[i]); } if (!views[i]) continue; if (util_format_is_srgb(views[i]->format)) - flag_srgb |= 1 << i; + flag_srgb |= 1 << (start + i); if (views[i]->texture->target == PIPE_TEXTURE_1D) - flag_1d |= 1 << i; + flag_1d |= 1 << (start + i); } - for (i = num; i < svga->curr.num_sampler_views; i++) - pipe_sampler_view_reference(&svga->curr.sampler_views[i], - NULL); + /* find highest non-null sampler_views[] entry */ + { + unsigned j = MAX2(svga->curr.num_sampler_views, start + num); + while (j > 0 && svga->curr.sampler_views[j - 1] == NULL) + j--; + svga->curr.num_sampler_views = j; + } - svga->curr.num_sampler_views = num; svga->dirty |= SVGA_NEW_TEXTURE_BINDING; if (flag_srgb != svga->curr.tex_flags.flag_srgb || @@ -261,6 +294,14 @@ svga_set_fragment_sampler_views(struct pipe_context *pipe, } +static void +svga_set_fragment_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) +{ + svga_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, num, views); +} + void svga_init_sampler_functions( struct svga_context *svga ) { |