static struct pipe_sampler_view * fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, const struct pipe_sampler_view *cso) { struct fd4_pipe_sampler_view *so = CALLOC_STRUCT(fd4_pipe_sampler_view); struct fd_resource *rsc = fd_resource(prsc); unsigned lvl = fd_sampler_first_level(cso); unsigned miplevels = fd_sampler_last_level(cso) - lvl; 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->texconst0 = A4XX_TEX_CONST_0_TYPE(tex_type(prsc->target)) | A4XX_TEX_CONST_0_FMT(fd4_pipe2tex(cso->format)) | A4XX_TEX_CONST_0_MIPLVLS(miplevels) | fd4_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g, cso->swizzle_b, cso->swizzle_a); if (util_format_is_srgb(cso->format)) so->texconst0 |= A4XX_TEX_CONST_0_SRGB; so->texconst1 = A4XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) | A4XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl)); so->texconst2 = A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) | A4XX_TEX_CONST_2_PITCH(rsc->slices[lvl].pitch * rsc->cpp); switch (prsc->target) { case PIPE_TEXTURE_1D_ARRAY: case PIPE_TEXTURE_2D_ARRAY: so->texconst3 = A4XX_TEX_CONST_3_DEPTH(prsc->array_size) | A4XX_TEX_CONST_3_LAYERSZ(rsc->layer_size); break; case PIPE_TEXTURE_CUBE: case PIPE_TEXTURE_CUBE_ARRAY: so->texconst3 = A4XX_TEX_CONST_3_DEPTH(prsc->array_size / 6) | A4XX_TEX_CONST_3_LAYERSZ(rsc->layer_size); break; case PIPE_TEXTURE_3D: so->texconst3 = A4XX_TEX_CONST_3_DEPTH(u_minify(prsc->depth0, lvl)) | A4XX_TEX_CONST_3_LAYERSZ(rsc->slices[0].size0); break; default: so->texconst3 = 0x00000000; break; } return &so->base; }
static struct pipe_sampler_view * fd5_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, const struct pipe_sampler_view *cso) { struct fd5_pipe_sampler_view *so = CALLOC_STRUCT(fd5_pipe_sampler_view); struct fd_resource *rsc = fd_resource(prsc); enum pipe_format format = cso->format; unsigned lvl, layers = 0; if (!so) return NULL; if (format == PIPE_FORMAT_X32_S8X24_UINT) { rsc = rsc->stencil; format = rsc->base.format; } so->base = *cso; pipe_reference(NULL, &prsc->reference); so->base.texture = prsc; so->base.reference.count = 1; so->base.context = pctx; so->texconst0 = A5XX_TEX_CONST_0_FMT(fd5_pipe2tex(format)) | A5XX_TEX_CONST_0_SAMPLES(fd_msaa_samples(prsc->nr_samples)) | fd5_tex_swiz(format, cso->swizzle_r, cso->swizzle_g, cso->swizzle_b, cso->swizzle_a); /* NOTE: since we sample z24s8 using 8888_UINT format, the swizzle * we get isn't quite right. Use SWAP(XYZW) as a cheap and cheerful * way to re-arrange things so stencil component is where the swiz * expects. * * Note that gallium expects stencil sampler to return (s,s,s,s) * which isn't quite true. To make that happen we'd have to massage * the swizzle. But in practice only the .x component is used. */ if (format == PIPE_FORMAT_X24S8_UINT) { so->texconst0 |= A5XX_TEX_CONST_0_SWAP(XYZW); } if (util_format_is_srgb(format)) { if (use_astc_srgb_workaround(pctx, format)) so->astc_srgb = true; so->texconst0 |= A5XX_TEX_CONST_0_SRGB; } if (cso->target == PIPE_BUFFER) { unsigned elements = cso->u.buf.size / util_format_get_blocksize(format); lvl = 0; so->texconst1 = A5XX_TEX_CONST_1_WIDTH(elements) | A5XX_TEX_CONST_1_HEIGHT(1); so->texconst2 = A5XX_TEX_CONST_2_FETCHSIZE(fd5_pipe2fetchsize(format)) | A5XX_TEX_CONST_2_PITCH(elements * rsc->cpp); so->offset = cso->u.buf.offset; } else { unsigned miplevels; lvl = fd_sampler_first_level(cso); miplevels = fd_sampler_last_level(cso) - lvl; layers = cso->u.tex.last_layer - cso->u.tex.first_layer + 1; so->texconst0 |= A5XX_TEX_CONST_0_MIPLVLS(miplevels); so->texconst1 = A5XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) | A5XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl)); so->texconst2 = A5XX_TEX_CONST_2_FETCHSIZE(fd5_pipe2fetchsize(format)) | A5XX_TEX_CONST_2_PITCH( util_format_get_nblocksx( format, rsc->slices[lvl].pitch) * rsc->cpp); so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer); } so->texconst2 |= A5XX_TEX_CONST_2_TYPE(fd5_tex_type(cso->target)); switch (cso->target) { case PIPE_TEXTURE_RECT: case PIPE_TEXTURE_1D: case PIPE_TEXTURE_2D: so->texconst3 = A5XX_TEX_CONST_3_ARRAY_PITCH(rsc->layer_size); so->texconst5 = A5XX_TEX_CONST_5_DEPTH(1); break; case PIPE_TEXTURE_1D_ARRAY: case PIPE_TEXTURE_2D_ARRAY: so->texconst3 = A5XX_TEX_CONST_3_ARRAY_PITCH(rsc->layer_size); so->texconst5 = A5XX_TEX_CONST_5_DEPTH(layers); break; case PIPE_TEXTURE_CUBE: case PIPE_TEXTURE_CUBE_ARRAY: so->texconst3 = A5XX_TEX_CONST_3_ARRAY_PITCH(rsc->layer_size); so->texconst5 = A5XX_TEX_CONST_5_DEPTH(layers / 6); break; case PIPE_TEXTURE_3D: so->texconst3 = A5XX_TEX_CONST_3_ARRAY_PITCH(rsc->slices[lvl].size0); so->texconst5 = A5XX_TEX_CONST_5_DEPTH(u_minify(prsc->depth0, lvl)); break; default: so->texconst3 = 0x00000000; break; } return &so->base; }
static struct pipe_sampler_view * fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, const struct pipe_sampler_view *cso) { struct fd3_pipe_sampler_view *so = CALLOC_STRUCT(fd3_pipe_sampler_view); struct fd_resource *rsc = fd_resource(prsc); unsigned lvl; uint32_t sz2 = 0; 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->texconst0 = A3XX_TEX_CONST_0_TYPE(tex_type(prsc->target)) | A3XX_TEX_CONST_0_FMT(fd3_pipe2tex(cso->format)) | fd3_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g, cso->swizzle_b, cso->swizzle_a); if (prsc->target == PIPE_BUFFER || util_format_is_pure_integer(cso->format)) so->texconst0 |= A3XX_TEX_CONST_0_NOCONVERT; if (util_format_is_srgb(cso->format)) so->texconst0 |= A3XX_TEX_CONST_0_SRGB; if (prsc->target == PIPE_BUFFER) { lvl = 0; so->texconst1 = A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) | A3XX_TEX_CONST_1_WIDTH(cso->u.buf.size / util_format_get_blocksize(cso->format)) | A3XX_TEX_CONST_1_HEIGHT(1); } else { unsigned miplevels; lvl = fd_sampler_first_level(cso); miplevels = fd_sampler_last_level(cso) - lvl; so->texconst0 |= A3XX_TEX_CONST_0_MIPLVLS(miplevels); so->texconst1 = A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) | A3XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) | A3XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl)); } /* when emitted, A3XX_TEX_CONST_2_INDX() must be OR'd in: */ so->texconst2 = A3XX_TEX_CONST_2_PITCH(fd3_pipe2nblocksx(cso->format, rsc->slices[lvl].pitch) * rsc->cpp); switch (prsc->target) { case PIPE_TEXTURE_1D_ARRAY: case PIPE_TEXTURE_2D_ARRAY: so->texconst3 = A3XX_TEX_CONST_3_DEPTH(prsc->array_size - 1) | A3XX_TEX_CONST_3_LAYERSZ1(rsc->slices[0].size0); break; case PIPE_TEXTURE_3D: so->texconst3 = A3XX_TEX_CONST_3_DEPTH(u_minify(prsc->depth0, lvl)) | A3XX_TEX_CONST_3_LAYERSZ1(rsc->slices[lvl].size0); while (lvl < cso->u.tex.last_level && sz2 != rsc->slices[lvl+1].size0) sz2 = rsc->slices[++lvl].size0; so->texconst3 |= A3XX_TEX_CONST_3_LAYERSZ2(sz2); break; default: so->texconst3 = 0x00000000; break; } return &so->base; }