X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_state_tss.c;h=0ab571c05881992422a59d5733784bb63e88e0dd;hb=13862812dc910a4ef57cb72cb9fe777ce3c14515;hp=e42c4f7fce75c95fa974ee2f9b9c5e7d81cbf942;hpb=04094b2da2030a82ff49e647fc8658502f02cea8;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c index e42c4f7fce7..0ab571c0588 100644 --- a/src/gallium/drivers/svga/svga_state_tss.c +++ b/src/gallium/drivers/svga/svga_state_tss.c @@ -24,6 +24,7 @@ **********************************************************/ #include "util/u_inlines.h" +#include "util/u_memory.h" #include "pipe/p_defines.h" #include "util/u_math.h" @@ -36,7 +37,7 @@ void svga_cleanup_tss_binding(struct svga_context *svga) { - int i; + unsigned i; unsigned count = MAX2( svga->curr.num_sampler_views, svga->state.hw_draw.num_views ); @@ -44,7 +45,7 @@ void svga_cleanup_tss_binding(struct svga_context *svga) struct svga_hw_view_state *view = &svga->state.hw_draw.views[i]; svga_sampler_view_reference(&view->v, NULL); - pipe_sampler_view_reference( &svga->curr.sampler_views[i], NULL ); + pipe_sampler_view_release(&svga->pipe, &svga->curr.sampler_views[i]); pipe_resource_reference( &view->texture, NULL ); view->dirty = 1; @@ -52,25 +53,28 @@ void svga_cleanup_tss_binding(struct svga_context *svga) } -static int +struct bind_queue { + struct { + unsigned unit; + struct svga_hw_view_state *view; + } bind[PIPE_MAX_SAMPLERS]; + + unsigned bind_count; +}; + + +static enum pipe_error update_tss_binding(struct svga_context *svga, unsigned dirty ) { + boolean reemit = svga->rebind.texture_samplers; unsigned i; unsigned count = MAX2( svga->curr.num_sampler_views, svga->state.hw_draw.num_views ); unsigned min_lod; unsigned max_lod; - - struct { - struct { - unsigned unit; - struct svga_hw_view_state *view; - } bind[PIPE_MAX_SAMPLERS]; - - unsigned bind_count; - } queue; + struct bind_queue queue; queue.bind_count = 0; @@ -78,12 +82,14 @@ update_tss_binding(struct svga_context *svga, const struct svga_sampler_state *s = svga->curr.sampler[i]; struct svga_hw_view_state *view = &svga->state.hw_draw.views[i]; struct pipe_resource *texture = NULL; + struct pipe_sampler_view *sv = svga->curr.sampler_views[i]; /* get min max lod */ - if (svga->curr.sampler_views[i]) { - min_lod = MAX2(s->view_min_lod, 0); - max_lod = MIN2(s->view_max_lod, svga->curr.sampler_views[i]->texture->last_level); - texture = svga->curr.sampler_views[i]->texture; + if (sv && s) { + min_lod = MAX2(0, (s->view_min_lod + sv->u.tex.first_level)); + max_lod = MIN2(s->view_max_lod + sv->u.tex.first_level, + sv->texture->last_level); + texture = sv->texture; } else { min_lod = 0; max_lod = 0; @@ -107,12 +113,18 @@ update_tss_binding(struct svga_context *svga, max_lod); } - if (view->dirty) { + /* + * We need to reemit non-null texture bindings, even when they are not + * dirty, to ensure that the resources are paged in. + */ + + if (view->dirty || + (reemit && view->v)) { queue.bind[queue.bind_count].unit = i; queue.bind[queue.bind_count].view = view; queue.bind_count++; } - else if (view->v) { + if (!view->dirty && view->v) { svga_validate_sampler_view(svga, view->v); } } @@ -141,6 +153,7 @@ update_tss_binding(struct svga_context *svga, } svga->swc->surface_relocation(svga->swc, &ts[i].value, + NULL, handle, SVGA_RELOC_READ); @@ -150,13 +163,78 @@ update_tss_binding(struct svga_context *svga, SVGA_FIFOCommitAll( svga->swc ); } - return 0; + svga->rebind.texture_samplers = FALSE; + + return PIPE_OK; fail: return PIPE_ERROR_OUT_OF_MEMORY; } +/* + * Rebind textures. + * + * Similar to update_tss_binding, but without any state checking/update. + * + * Called at the beginning of every new command buffer to ensure that + * non-dirty textures are properly paged-in. + */ +enum pipe_error +svga_reemit_tss_bindings(struct svga_context *svga) +{ + unsigned i; + enum pipe_error ret; + struct bind_queue queue; + + assert(svga->rebind.texture_samplers); + + queue.bind_count = 0; + + for (i = 0; i < svga->state.hw_draw.num_views; i++) { + struct svga_hw_view_state *view = &svga->state.hw_draw.views[i]; + + if (view->v) { + queue.bind[queue.bind_count].unit = i; + queue.bind[queue.bind_count].view = view; + queue.bind_count++; + } + } + + if (queue.bind_count) { + SVGA3dTextureState *ts; + + ret = SVGA3D_BeginSetTextureState(svga->swc, + &ts, + queue.bind_count); + if (ret != PIPE_OK) { + return ret; + } + + for (i = 0; i < queue.bind_count; i++) { + struct svga_winsys_surface *handle; + + ts[i].stage = queue.bind[i].unit; + ts[i].name = SVGA3D_TS_BIND_TEXTURE; + + assert(queue.bind[i].view->v); + handle = queue.bind[i].view->v->handle; + svga->swc->surface_relocation(svga->swc, + &ts[i].value, + NULL, + handle, + SVGA_RELOC_READ); + } + + SVGA_FIFOCommitAll(svga->swc); + } + + svga->rebind.texture_samplers = FALSE; + + return PIPE_OK; +} + + struct svga_tracked_state svga_hw_tss_binding = { "texture binding emit", SVGA_NEW_TEXTURE_BINDING | @@ -176,6 +254,8 @@ struct ts_queue { #define EMIT_TS(svga, unit, val, token, fail) \ do { \ + assert(unit < Elements(svga->state.hw_draw.ts)); \ + assert(SVGA3D_TS_##token < Elements(svga->state.hw_draw.ts[unit])); \ if (svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] != val) { \ svga_queue_tss( &queue, unit, SVGA3D_TS_##token, val ); \ svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] = val; \ @@ -185,6 +265,8 @@ do { \ #define EMIT_TS_FLOAT(svga, unit, fvalue, token, fail) \ do { \ unsigned val = fui(fvalue); \ + assert(unit < Elements(svga->state.hw_draw.ts)); \ + assert(SVGA3D_TS_##token < Elements(svga->state.hw_draw.ts[unit])); \ if (svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] != val) { \ svga_queue_tss( &queue, unit, SVGA3D_TS_##token, val ); \ svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] = val; \ @@ -206,7 +288,7 @@ svga_queue_tss( struct ts_queue *q, } -static int +static enum pipe_error update_tss(struct svga_context *svga, unsigned dirty ) { @@ -230,7 +312,6 @@ update_tss(struct svga_context *svga, // TEXCOORDINDEX -- hopefully not needed if (svga->curr.tex_flags.flag_1d & (1 << i)) { - debug_printf("wrap 1d tex %d\n", i); EMIT_TS(svga, i, SVGA3D_TEX_ADDRESS_WRAP, ADDRESSV, fail); } else @@ -259,7 +340,7 @@ update_tss(struct svga_context *svga, SVGA_FIFOCommitAll( svga->swc ); } - return 0; + return PIPE_OK; fail: /* XXX: need to poison cached hardware state on failure to ensure