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>
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)
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
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
/* 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,
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;
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 -
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");
}
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;
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;
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,
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,