v3d: add support for ARB_texture_cube_map_array
authorJuan A. Suarez Romero <jasuarez@igalia.com>
Thu, 13 Apr 2023 16:57:39 +0000 (18:57 +0200)
committerMarge Bot <emma+marge@anholt.net>
Mon, 24 Apr 2023 15:07:32 +0000 (15:07 +0000)
This implements support for texture cubemap arrays.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22482>

docs/features.txt
src/broadcom/ci/broadcom-rpi4-fails.txt
src/gallium/drivers/v3d/v3d_blit.c
src/gallium/drivers/v3d/v3d_screen.c
src/gallium/drivers/v3d/v3d_uniforms.c
src/gallium/drivers/v3d/v3dx_state.c

index 2fb145c..f8e88fa 100644 (file)
@@ -133,7 +133,7 @@ GL 4.0, GLSL 4.00 --- all DONE: freedreno/a6xx, i965/gen7+, nvc0, r600, radeonsi
   GL_ARB_shader_subroutine                              DONE (freedreno, i965/gen6+, nv50, softpipe)
   GL_ARB_tessellation_shader                            DONE (freedreno/a6xx, i965/gen7+, )
   GL_ARB_texture_buffer_object_rgb32                    DONE (freedreno, i965/gen6+, softpipe, panfrost, asahi)
-  GL_ARB_texture_cube_map_array                         DONE (freedreno/a4xx+, i965/gen6+, nv50, softpipe)
+  GL_ARB_texture_cube_map_array                         DONE (freedreno/a4xx+, i965/gen6+, nv50, softpipe, v3d)
   GL_ARB_texture_gather                                 DONE (freedreno, i965/gen6+, nv50, softpipe, v3d, panfrost, asahi)
   GL_ARB_texture_query_lod                              DONE (freedreno, i965, nv50, softpipe, v3d, panfrost)
   GL_ARB_transform_feedback2                            DONE (freedreno/a3xx+, i965/gen6+, nv50, softpipe, v3d, panfrost)
index 112dc50..370369e 100644 (file)
@@ -120,7 +120,6 @@ spec@!opengl 3.0@render-integer@GL_RGB8UI,Fail
 spec@!opengl 3.0@render-integer@GL_RGBA8I,Fail
 spec@!opengl 3.0@render-integer@GL_RGBA8UI,Fail
 spec@!opengl 3.0@required-texture-attachment-formats,Fail
-spec@!opengl 3.0@sampler-cube-shadow,Fail
 spec@!opengl 3.1@minmax,Fail
 spec@!opengl 3.1@primitive-restart-xfb flush,Fail
 spec@!opengl 3.1@primitive-restart-xfb generated,Fail
@@ -505,6 +504,11 @@ spec@oes_egl_image_external_essl3@oes_egl_image_external_essl3,Crash
 spec@oes_point_sprite@arb_point_sprite-checkerboard_gles1,Fail
 spec@oes_shader_io_blocks@compiler@layout-location-aliasing.vert,Fail
 
+# OpenGL 3.1 applies non-seamless cubemap texturing, while our
+# driver/GLES uses seamless cubemap texturing.
+spec@!opengl 3.0@sampler-cube-shadow,Fail
+spec@arb_texture_cube_map_array@arb_texture_cube_map_array-sampler-cube-array-shadow,Fail
+
 # https://gitlab.freedesktop.org/mesa/piglit/-/merge_requests/800
 spec@!opengl es 3.0@gles-3.0-transform-feedback-uniform-buffer-object,Fail
 
index c5dede6..be63d1d 100644 (file)
@@ -174,7 +174,9 @@ v3d_stencil_blit(struct pipe_context *ctx, struct pipe_blit_info *info)
 
         /* Initialize the sampler view. */
         struct pipe_sampler_view src_tmpl = {
-                .target = src->base.target,
+                .target = (src->base.target == PIPE_TEXTURE_CUBE_ARRAY) ?
+                          PIPE_TEXTURE_2D_ARRAY :
+                          src->base.target,
                 .format = src_format,
                 .u.tex = {
                         .first_level = info->src.level,
index 4f4e315..bf6811a 100644 (file)
@@ -148,11 +148,13 @@ v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
         case PIPE_CAP_INDEP_BLEND_FUNC:
         case PIPE_CAP_CONDITIONAL_RENDER:
         case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
+        case PIPE_CAP_CUBE_MAP_ARRAY:
                 return 1;
 
         case PIPE_CAP_POLYGON_OFFSET_CLAMP:
                 return screen->devinfo.ver >= 41;
 
+
         case PIPE_CAP_TEXTURE_QUERY_LOD:
                 return screen->devinfo.ver >= 42;
                 break;
index 1b10486..95eb838 100644 (file)
@@ -72,7 +72,12 @@ get_texture_size(struct v3d_texture_stateobj *texstate,
                                 texture->u.tex.first_level);
         case QUNIFORM_TEXTURE_ARRAY_SIZE:
                 assert(texture->target != PIPE_BUFFER);
-                return texture->texture->array_size;
+                if (texture->target != PIPE_TEXTURE_CUBE_ARRAY) {
+                        return texture->texture->array_size;
+                } else {
+                        assert(texture->texture->array_size % 6 == 0);
+                        return texture->texture->array_size / 6;
+                }
         case QUNIFORM_TEXTURE_LEVELS:
                 assert(texture->target != PIPE_BUFFER);
                 return (texture->u.tex.last_level -
@@ -108,7 +113,12 @@ get_image_size(struct v3d_shaderimg_stateobj *shaderimg,
                                 image->base.u.tex.level);
         case QUNIFORM_IMAGE_ARRAY_SIZE:
                 assert(image->base.resource->target != PIPE_BUFFER);
-                return image->base.resource->array_size;
+                if (image->base.resource->target != PIPE_TEXTURE_CUBE_ARRAY) {
+                        return image->base.resource->array_size;
+                } else {
+                        assert(image->base.resource->array_size % 6 == 0);
+                        return image->base.resource->array_size / 6;
+                }
         default:
                 unreachable("Bad texture size field");
         }
index d7b9f82..4a9a23d 100644 (file)
@@ -872,8 +872,16 @@ static void
 v3d_setup_texture_shader_state(struct V3DX(TEXTURE_SHADER_STATE) *tex,
                                struct pipe_resource *prsc,
                                int base_level, int last_level,
-                               int first_layer, int last_layer)
+                               int first_layer, int last_layer,
+                               bool sampling_cube_array)
 {
+        /* Due to ARB_texture_view, a cubemap array can be seen as 2D texture
+         * array.
+         */
+        assert(!sampling_cube_array ||
+               prsc->target == PIPE_TEXTURE_CUBE_ARRAY ||
+               prsc->target == PIPE_TEXTURE_2D_ARRAY);
+
         struct v3d_resource *rsc = v3d_resource(prsc);
         int msaa_scale = prsc->nr_samples > 1 ? 2 : 1;
 
@@ -899,6 +907,15 @@ v3d_setup_texture_shader_state(struct V3DX(TEXTURE_SHADER_STATE) *tex,
                 tex->image_depth = (last_layer - first_layer) + 1;
         }
 
+        /* Empirical testing with CTS shows that when we are sampling from
+         * cube arrays we want to set image depth to layers / 6, but not when
+         * doing image load/store or sampling from 2d image arrays.
+         */
+        if (sampling_cube_array) {
+                assert(tex->image_depth % 6 == 0);
+                tex->image_depth /= 6;
+        }
+
         tex->base_level = base_level;
 #if V3D_VERSION >= 40
         tex->max_level = last_level;
@@ -964,7 +981,8 @@ v3dX(create_texture_shader_state_bo)(struct v3d_context *v3d,
                                                        cso->u.tex.first_level,
                                                        cso->u.tex.last_level,
                                                        cso->u.tex.first_layer,
-                                                       cso->u.tex.last_layer);
+                                                       cso->u.tex.last_layer,
+                                                       cso->target == PIPE_TEXTURE_CUBE_ARRAY);
                 } else {
                         v3d_setup_texture_shader_state_from_buffer(&tex, prsc,
                                                                    cso->format,
@@ -1391,7 +1409,8 @@ v3d_create_image_view_texture_shader_state(struct v3d_context *v3d,
                                                        iview->base.u.tex.level,
                                                        iview->base.u.tex.level,
                                                        iview->base.u.tex.first_layer,
-                                                       iview->base.u.tex.last_layer);
+                                                       iview->base.u.tex.last_layer,
+                                                       false);
                 } else {
                         v3d_setup_texture_shader_state_from_buffer(&tex, prsc,
                                                                    iview->base.format,