X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Ffreedreno%2Ffreedreno_texture.c;h=eaa6629f2b80c50e45760db0d5bd30adc6ec4639;hb=57f0d3b3c6ae3b9f79a03517410b8dbfab0382c6;hp=3ea51ce1e5e00031c59a6fb77f734bb603d8b5fe;hpb=f706d4d340f0778de23062ef13c54b07bfac7967;p=mesa.git diff --git a/src/gallium/drivers/freedreno/freedreno_texture.c b/src/gallium/drivers/freedreno/freedreno_texture.c index 3ea51ce1e5e..eaa6629f2b8 100644 --- a/src/gallium/drivers/freedreno/freedreno_texture.c +++ b/src/gallium/drivers/freedreno/freedreno_texture.c @@ -32,110 +32,15 @@ #include "util/u_inlines.h" #include "freedreno_texture.h" +#include "freedreno_context.h" #include "freedreno_util.h" -static enum sq_tex_clamp -tex_clamp(unsigned wrap) -{ - switch (wrap) { - case PIPE_TEX_WRAP_REPEAT: - return SQ_TEX_WRAP; - case PIPE_TEX_WRAP_CLAMP: - return SQ_TEX_CLAMP_HALF_BORDER; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - return SQ_TEX_CLAMP_LAST_TEXEL; - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - return SQ_TEX_CLAMP_BORDER; - case PIPE_TEX_WRAP_MIRROR_REPEAT: - return SQ_TEX_MIRROR; - case PIPE_TEX_WRAP_MIRROR_CLAMP: - return SQ_TEX_MIRROR_ONCE_HALF_BORDER; - case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: - return SQ_TEX_MIRROR_ONCE_LAST_TEXEL; - case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: - return SQ_TEX_MIRROR_ONCE_BORDER; - default: - DBG("invalid wrap: %u", wrap); - return 0; - } -} - -static enum sq_tex_filter -tex_filter(unsigned filter) -{ - switch (filter) { - case PIPE_TEX_FILTER_NEAREST: - return SQ_TEX_FILTER_POINT; - case PIPE_TEX_FILTER_LINEAR: - return SQ_TEX_FILTER_BILINEAR; - default: - DBG("invalid filter: %u", filter); - return 0; - } -} - -static void * -fd_sampler_state_create(struct pipe_context *pctx, - const struct pipe_sampler_state *cso) -{ - struct fd_sampler_stateobj *so = CALLOC_STRUCT(fd_sampler_stateobj); - - if (!so) - return NULL; - - so->base = *cso; - - /* SQ_TEX0_PITCH() must be OR'd in later when we know the bound texture: */ - so->tex0 = - A2XX_SQ_TEX_0_CLAMP_X(tex_clamp(cso->wrap_s)) | - A2XX_SQ_TEX_0_CLAMP_Y(tex_clamp(cso->wrap_t)) | - A2XX_SQ_TEX_0_CLAMP_Z(tex_clamp(cso->wrap_r)); - - so->tex3 = - A2XX_SQ_TEX_3_XY_MAG_FILTER(tex_filter(cso->mag_img_filter)) | - A2XX_SQ_TEX_3_XY_MIN_FILTER(tex_filter(cso->min_img_filter)); - - so->tex4 = 0x00000000; /* ??? */ - so->tex5 = 0x00000200; /* ??? */ - - return so; -} - static void fd_sampler_state_delete(struct pipe_context *pctx, void *hwcso) { FREE(hwcso); } -static struct pipe_sampler_view * -fd_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, - const struct pipe_sampler_view *cso) -{ - struct fd_pipe_sampler_view *so = CALLOC_STRUCT(fd_pipe_sampler_view); - struct fd_resource *rsc = fd_resource(prsc); - - if (!so) - return NULL; - - so->base = *cso; - pipe_reference(NULL, &prsc->reference); - so->base.texture = prsc; - so->base.reference.count = 1; - so->base.context = pctx; - - so->tex_resource = rsc; - so->fmt = fd_pipe2surface(cso->format); - - so->tex0 = A2XX_SQ_TEX_0_PITCH(rsc->pitch); - so->tex2 = - A2XX_SQ_TEX_2_HEIGHT(prsc->height0 - 1) | - A2XX_SQ_TEX_2_WIDTH(prsc->width0 - 1); - so->tex3 = fd_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g, - cso->swizzle_b, cso->swizzle_a); - - return &so->base; -} - static void fd_sampler_view_destroy(struct pipe_context *pctx, struct pipe_sampler_view *view) @@ -144,57 +49,65 @@ fd_sampler_view_destroy(struct pipe_context *pctx, FREE(view); } -static void bind_sampler_states(struct fd_texture_stateobj *prog, +static void bind_sampler_states(struct fd_texture_stateobj *tex, unsigned nr, void **hwcso) { unsigned i; + unsigned new_nr = 0; for (i = 0; i < nr; i++) { - prog->samplers[i] = hwcso[i]; - prog->dirty_samplers |= (1 << i); + if (hwcso[i]) + new_nr = i + 1; + tex->samplers[i] = hwcso[i]; + tex->dirty_samplers |= (1 << i); } - for (; i < prog->num_samplers; i++) { - prog->samplers[i] = NULL; - prog->dirty_samplers |= (1 << i); + for (; i < tex->num_samplers; i++) { + tex->samplers[i] = NULL; + tex->dirty_samplers |= (1 << i); } - prog->num_samplers = nr; + tex->num_samplers = new_nr; } -static void set_sampler_views(struct fd_texture_stateobj *prog, +static void set_sampler_views(struct fd_texture_stateobj *tex, unsigned nr, struct pipe_sampler_view **views) { unsigned i; + unsigned new_nr = 0; for (i = 0; i < nr; i++) { - pipe_sampler_view_reference(&prog->textures[i], views[i]); - prog->dirty_samplers |= (1 << i); + if (views[i]) + new_nr = i + 1; + pipe_sampler_view_reference(&tex->textures[i], views[i]); + tex->dirty_samplers |= (1 << i); } - for (; i < prog->num_textures; i++) { - pipe_sampler_view_reference(&prog->textures[i], NULL); - prog->dirty_samplers |= (1 << i); + for (; i < tex->num_textures; i++) { + pipe_sampler_view_reference(&tex->textures[i], NULL); + tex->dirty_samplers |= (1 << i); } - prog->num_textures = nr; + tex->num_textures = new_nr; } -static void -fd_fragtex_sampler_states_bind(struct pipe_context *pctx, +void +fd_sampler_states_bind(struct pipe_context *pctx, + unsigned shader, unsigned start, unsigned nr, void **hwcso) { struct fd_context *ctx = fd_context(pctx); - /* on a2xx, since there is a flat address space for textures/samplers, - * a change in # of fragment textures/samplers will trigger patching and - * re-emitting the vertex shader: - */ - if (nr != ctx->fragtex.num_samplers) - ctx->dirty |= FD_DIRTY_TEXSTATE; + assert(start == 0); - bind_sampler_states(&ctx->fragtex, nr, hwcso); - ctx->dirty |= FD_DIRTY_FRAGTEX; + if (shader == PIPE_SHADER_FRAGMENT) { + bind_sampler_states(&ctx->fragtex, nr, hwcso); + ctx->dirty |= FD_DIRTY_FRAGTEX; + } + else if (shader == PIPE_SHADER_VERTEX) { + bind_sampler_states(&ctx->verttex, nr, hwcso); + ctx->dirty |= FD_DIRTY_VERTTEX; + } } @@ -215,16 +128,6 @@ fd_fragtex_set_sampler_views(struct pipe_context *pctx, unsigned nr, ctx->dirty |= FD_DIRTY_FRAGTEX; } -static void -fd_verttex_sampler_states_bind(struct pipe_context *pctx, - unsigned nr, void **hwcso) -{ - struct fd_context *ctx = fd_context(pctx); - bind_sampler_states(&ctx->verttex, nr, hwcso); - ctx->dirty |= FD_DIRTY_VERTTEX; -} - - static void fd_verttex_set_sampler_views(struct pipe_context *pctx, unsigned nr, struct pipe_sampler_view **views) @@ -234,38 +137,28 @@ fd_verttex_set_sampler_views(struct pipe_context *pctx, unsigned nr, ctx->dirty |= FD_DIRTY_VERTTEX; } -/* map gallium sampler-id to hw const-idx.. adreno uses a flat address - * space of samplers (const-idx), so we need to map the gallium sampler-id - * which is per-shader to a global const-idx space. - * - * Fragment shader sampler maps directly to const-idx, and vertex shader - * is offset by the # of fragment shader samplers. If the # of fragment - * shader samplers changes, this shifts the vertex shader indexes. - * - * TODO maybe we can do frag shader 0..N and vert shader N..0 to avoid - * this?? - */ -unsigned -fd_get_const_idx(struct fd_context *ctx, struct fd_texture_stateobj *tex, - unsigned samp_id) +void +fd_set_sampler_views(struct pipe_context *pctx, unsigned shader, + unsigned start, unsigned nr, + struct pipe_sampler_view **views) { - if (tex == &ctx->fragtex) - return samp_id; - return samp_id + ctx->fragtex.num_samplers; + assert(start == 0); + switch (shader) { + case PIPE_SHADER_FRAGMENT: + fd_fragtex_set_sampler_views(pctx, nr, views); + break; + case PIPE_SHADER_VERTEX: + fd_verttex_set_sampler_views(pctx, nr, views); + break; + default: + ; + } } void fd_texture_init(struct pipe_context *pctx) { - pctx->create_sampler_state = fd_sampler_state_create; pctx->delete_sampler_state = fd_sampler_state_delete; - pctx->create_sampler_view = fd_sampler_view_create; pctx->sampler_view_destroy = fd_sampler_view_destroy; - - pctx->bind_fragment_sampler_states = fd_fragtex_sampler_states_bind; - pctx->set_fragment_sampler_views = fd_fragtex_set_sampler_views; - - pctx->bind_vertex_sampler_states = fd_verttex_sampler_states_bind; - pctx->set_vertex_sampler_views = fd_verttex_set_sampler_views; }