freedreno/ir3: images can be arrays too
[mesa.git] / src / gallium / drivers / freedreno / a4xx / fd4_texture.c
index 4faeceee5e61f890ea68a78c59ebcca06e3b09f4..fd0e4367b575e989b2341545af77902d629d2453 100644 (file)
@@ -224,12 +224,18 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 {
        struct fd4_pipe_sampler_view *so = CALLOC_STRUCT(fd4_pipe_sampler_view);
        struct fd_resource *rsc = fd_resource(prsc);
+       enum pipe_format format = cso->format;
        unsigned lvl, layers;
        uint32_t sz2 = 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;
@@ -238,25 +244,25 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 
        so->texconst0 =
                A4XX_TEX_CONST_0_TYPE(tex_type(cso->target)) |
-               A4XX_TEX_CONST_0_FMT(fd4_pipe2tex(cso->format)) |
-               fd4_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
+               A4XX_TEX_CONST_0_FMT(fd4_pipe2tex(format)) |
+               fd4_tex_swiz(format, cso->swizzle_r, cso->swizzle_g,
                                cso->swizzle_b, cso->swizzle_a);
 
-       if (util_format_is_srgb(cso->format)) {
-               if (use_astc_srgb_workaround(pctx, cso->format))
+       if (util_format_is_srgb(format)) {
+               if (use_astc_srgb_workaround(pctx, format))
                        so->astc_srgb = true;
                so->texconst0 |= A4XX_TEX_CONST_0_SRGB;
        }
 
        if (cso->target == PIPE_BUFFER) {
-               unsigned elements = cso->u.buf.size / util_format_get_blocksize(cso->format);
+               unsigned elements = cso->u.buf.size / util_format_get_blocksize(format);
 
                lvl = 0;
                so->texconst1 =
                        A4XX_TEX_CONST_1_WIDTH(elements) |
                        A4XX_TEX_CONST_1_HEIGHT(1);
                so->texconst2 =
-                       A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
+                       A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(format)) |
                        A4XX_TEX_CONST_2_PITCH(elements * rsc->cpp);
                so->offset = cso->u.buf.offset;
        } else {
@@ -271,13 +277,25 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
                        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_FETCHSIZE(fd4_pipe2fetchsize(format)) |
                        A4XX_TEX_CONST_2_PITCH(
                                        util_format_get_nblocksx(
-                                                       cso->format, rsc->slices[lvl].pitch) * rsc->cpp);
+                                                       format, rsc->slices[lvl].pitch) * rsc->cpp);
                so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer);
        }
 
+       /* 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->texconst2 |= A4XX_TEX_CONST_2_SWAP(XYZW);
+
        switch (cso->target) {
        case PIPE_TEXTURE_1D_ARRAY:
        case PIPE_TEXTURE_2D_ARRAY: