From e0e7e29554b7a4a723315eef3df5fb9bad28a70a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 3 Nov 2012 20:41:08 +1000 Subject: [PATCH] mesa: add fbo/texture support for ARB_texture_cube_map_array (v2) This adds the mesa core + texture + fbo support for the texture cube map array extension. v2: add comment to _mesa_num_tex_faces related to cube map arrays (Brian) drop wrong comment cut-n-paste (Brian) fix / 6 maximum check issue (Kenneth) coalsece some array case statements (Kenneth) Reviewed-by: Kenneth Graunke Reviewed-by: Brian Paul Signed-off-by: Dave Airlie --- src/mesa/main/fbobject.c | 6 ++- src/mesa/main/mtypes.h | 2 + src/mesa/main/shared.c | 1 + src/mesa/main/teximage.c | 76 ++++++++++++++++++++++++++++++++++++-- src/mesa/main/texobj.c | 11 +++++- src/mesa/main/texobj.h | 2 + src/mesa/main/texparam.c | 5 +++ src/mesa/main/texstate.c | 1 + src/mesa/main/texstorage.c | 3 ++ src/mesa/main/texstore.c | 7 ++++ 10 files changed, 107 insertions(+), 7 deletions(-) diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 0758d55574a..0618b7fabec 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -2025,7 +2025,8 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, */ err = (texObj->Target != GL_TEXTURE_3D) && (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) && - (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT); + (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT) && + (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY); } else { /* Make sure textarget is consistent with the texture's type */ @@ -2058,7 +2059,8 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, } } else if ((texObj->Target == GL_TEXTURE_1D_ARRAY_EXT) || - (texObj->Target == GL_TEXTURE_2D_ARRAY_EXT)) { + (texObj->Target == GL_TEXTURE_2D_ARRAY_EXT) || + (texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY)) { if (zoffset < 0 || zoffset >= (GLint) ctx->Const.MaxArrayTextureLayers) { _mesa_error(ctx, GL_INVALID_VALUE, diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index dcfb7e57c99..b99e7104424 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1146,6 +1146,7 @@ struct gl_stencil_attrib */ typedef enum { + TEXTURE_CUBE_ARRAY_INDEX, TEXTURE_BUFFER_INDEX, TEXTURE_2D_ARRAY_INDEX, TEXTURE_1D_ARRAY_INDEX, @@ -1164,6 +1165,7 @@ typedef enum * Used for Texture.Unit[]._ReallyEnabled flags. */ /*@{*/ +#define TEXTURE_CUBE_ARRAY_BIT (1 << TEXTURE_CUBE_ARRAY_INDEX) #define TEXTURE_BUFFER_BIT (1 << TEXTURE_BUFFER_INDEX) #define TEXTURE_2D_ARRAY_BIT (1 << TEXTURE_2D_ARRAY_INDEX) #define TEXTURE_1D_ARRAY_BIT (1 << TEXTURE_1D_ARRAY_INDEX) diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c index 2d2f7bd1d78..ba82628f3eb 100644 --- a/src/mesa/main/shared.c +++ b/src/mesa/main/shared.c @@ -90,6 +90,7 @@ _mesa_alloc_shared_state(struct gl_context *ctx) for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { /* NOTE: the order of these enums matches the TEXTURE_x_INDEX values */ static const GLenum targets[] = { + GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BUFFER, GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_1D_ARRAY_EXT, diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index b88931743ab..0f28009b0cd 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -649,7 +649,7 @@ _mesa_is_proxy_texture(GLenum target) * NUM_TEXTURE_TARGETS should match number of terms below, except there's no * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES. */ - assert(NUM_TEXTURE_TARGETS == 7 + 2); + assert(NUM_TEXTURE_TARGETS == 8 + 2); return (target == GL_PROXY_TEXTURE_1D || target == GL_PROXY_TEXTURE_2D || @@ -657,7 +657,8 @@ _mesa_is_proxy_texture(GLenum target) target == GL_PROXY_TEXTURE_CUBE_MAP_ARB || target == GL_PROXY_TEXTURE_RECTANGLE_NV || target == GL_PROXY_TEXTURE_1D_ARRAY_EXT || - target == GL_PROXY_TEXTURE_2D_ARRAY_EXT); + target == GL_PROXY_TEXTURE_2D_ARRAY_EXT || + target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY); } @@ -695,6 +696,9 @@ _mesa_get_proxy_target(GLenum target) case GL_TEXTURE_2D_ARRAY_EXT: case GL_PROXY_TEXTURE_2D_ARRAY_EXT: return GL_PROXY_TEXTURE_2D_ARRAY_EXT; + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + return GL_PROXY_TEXTURE_CUBE_MAP_ARRAY; default: _mesa_problem(NULL, "unexpected target in _mesa_get_proxy_target()"); return 0; @@ -745,6 +749,12 @@ _mesa_select_tex_object(struct gl_context *ctx, case GL_PROXY_TEXTURE_CUBE_MAP_ARB: return ctx->Extensions.ARB_texture_cube_map ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; + case GL_TEXTURE_CUBE_MAP_ARRAY: + return ctx->Extensions.ARB_texture_cube_map_array + ? texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + return ctx->Extensions.ARB_texture_cube_map_array + ? ctx->Texture.ProxyTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; case GL_TEXTURE_RECTANGLE_NV: return ctx->Extensions.NV_texture_rectangle ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL; @@ -891,6 +901,11 @@ get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level) return NULL; texIndex = TEXTURE_2D_ARRAY_INDEX; break; + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + if (level >= ctx->Const.MaxCubeTextureLevels) + return NULL; + texIndex = TEXTURE_CUBE_ARRAY_INDEX; + break; default: return NULL; } @@ -953,6 +968,10 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target) return (ctx->Extensions.MESA_texture_array || ctx->Extensions.EXT_texture_array) ? ctx->Const.MaxTextureLevels : 0; + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + return ctx->Extensions.ARB_texture_cube_map_array + ? ctx->Const.MaxCubeTextureLevels : 0; case GL_TEXTURE_BUFFER: return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_buffer_object @@ -995,6 +1014,8 @@ _mesa_get_texture_dimensions(GLenum target) case GL_PROXY_TEXTURE_3D: case GL_TEXTURE_2D_ARRAY: case GL_PROXY_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: return 3; case GL_TEXTURE_BUFFER: /* fall-through */ @@ -1174,6 +1195,8 @@ _mesa_init_teximage_fields(struct gl_context *ctx, break; case GL_TEXTURE_2D_ARRAY: case GL_PROXY_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ img->HeightLog2 = _mesa_logbase2(img->Height2); img->Depth2 = depth; /* no border */ @@ -1341,6 +1364,24 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, } return GL_TRUE; + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); + if (width < 2 * border || width > 2 * border + maxSize) + return GL_FALSE; + if (height < 2 * border || height > 2 * border + maxSize) + return GL_FALSE; + if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers) + return GL_FALSE; + if (level >= ctx->Const.MaxCubeTextureLevels) + return GL_FALSE; + if (!ctx->Extensions.ARB_texture_non_power_of_two) { + if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) + return GL_FALSE; + if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) + return GL_FALSE; + } + return GL_TRUE; default: _mesa_problem(ctx, "Invalid target in _mesa_legal_texture_dimensions()"); return GL_FALSE; @@ -1549,6 +1590,9 @@ target_can_be_compressed(const struct gl_context *ctx, GLenum target, case GL_TEXTURE_2D_ARRAY_EXT: return (ctx->Extensions.MESA_texture_array || ctx->Extensions.EXT_texture_array); + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + case GL_TEXTURE_CUBE_MAP_ARRAY: + return ctx->Extensions.ARB_texture_cube_map_array; default: return GL_FALSE; } @@ -1614,6 +1658,9 @@ legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target) return _mesa_is_desktop_gl(ctx) && (ctx->Extensions.MESA_texture_array || ctx->Extensions.EXT_texture_array); + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + return ctx->Extensions.ARB_texture_cube_map_array; default: return GL_FALSE; } @@ -1666,6 +1713,9 @@ legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target) && (ctx->Extensions.MESA_texture_array || ctx->Extensions.EXT_texture_array)) || _mesa_is_gles3(ctx); + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + return ctx->Extensions.ARB_texture_cube_map_array; default: return GL_FALSE; } @@ -1782,6 +1832,7 @@ texture_error_check( struct gl_context *ctx, * Formats and types that require additional extensions (e.g., GL_FLOAT * requires GL_OES_texture_float) are filtered elsewhere. */ + if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) { if (format != internalFormat) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -1810,6 +1861,20 @@ texture_error_check( struct gl_context *ctx, return GL_TRUE; } + if ((target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY || + target == GL_TEXTURE_CUBE_MAP_ARRAY) && width != height) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glTexImage3D(cube array width != height)"); + return GL_TRUE; + } + + if ((target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY || + target == GL_TEXTURE_CUBE_MAP_ARRAY) && (depth % 6)) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glTexImage3D(cube array depth not multiple of 6)"); + return GL_TRUE; + } + /* Check internalFormat */ if (_mesa_base_tex_format(ctx, internalFormat) < 0) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -1886,7 +1951,10 @@ texture_error_check( struct gl_context *ctx, target != GL_TEXTURE_RECTANGLE_ARB && target != GL_PROXY_TEXTURE_RECTANGLE_ARB && !((_mesa_is_cube_face(target) || target == GL_PROXY_TEXTURE_CUBE_MAP) && - (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))) { + (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4)) && + !((target == GL_TEXTURE_CUBE_MAP_ARRAY || + target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY) && + ctx->Extensions.ARB_texture_cube_map_array)) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%dD(bad target for depth texture)", dimensions); @@ -2684,7 +2752,7 @@ strip_texture_border(GLenum target, *height = *height - 2; /* reduce the height by two border pixels */ } - if (*depth >= 3 && target != GL_TEXTURE_2D_ARRAY) { + if (*depth >= 3 && target != GL_TEXTURE_2D_ARRAY && target != GL_TEXTURE_CUBE_MAP_ARRAY) { unpackNew->SkipImages++; /* skip the border */ *depth = *depth - 2; /* reduce the depth by two border pixels */ } diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 8525ff9fd41..c083c72e2aa 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -108,6 +108,7 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj, target == GL_TEXTURE_1D_ARRAY_EXT || target == GL_TEXTURE_2D_ARRAY_EXT || target == GL_TEXTURE_EXTERNAL_OES || + target == GL_TEXTURE_CUBE_MAP_ARRAY || target == GL_TEXTURE_BUFFER); memset(obj, 0, sizeof(*obj)); @@ -316,6 +317,7 @@ valid_texture_object(const struct gl_texture_object *tex) case GL_TEXTURE_2D_ARRAY_EXT: case GL_TEXTURE_BUFFER: case GL_TEXTURE_EXTERNAL_OES: + case GL_TEXTURE_CUBE_MAP_ARRAY: return GL_TRUE; case 0x99: _mesa_problem(NULL, "invalid reference to a deleted texture object"); @@ -515,6 +517,7 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, maxLevels = ctx->Const.Max3DTextureLevels; break; case GL_TEXTURE_CUBE_MAP_ARB: + case GL_TEXTURE_CUBE_MAP_ARRAY: maxLog2 = MAX2(baseImage->WidthLog2, baseImage->HeightLog2); maxLevels = ctx->Const.MaxCubeTextureLevels; @@ -599,7 +602,7 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, if (height > 1 && t->Target != GL_TEXTURE_1D_ARRAY) { height /= 2; } - if (depth > 1 && t->Target != GL_TEXTURE_2D_ARRAY) { + if (depth > 1 && t->Target != GL_TEXTURE_2D_ARRAY && t->Target != GL_TEXTURE_CUBE_MAP_ARRAY) { depth /= 2; } @@ -768,6 +771,10 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex) dims = 0; target = GL_TEXTURE_BUFFER; break; + case TEXTURE_CUBE_ARRAY_INDEX: + dims = 3; + target = GL_TEXTURE_CUBE_MAP_ARRAY; + break; case TEXTURE_EXTERNAL_INDEX: dims = 2; target = GL_TEXTURE_EXTERNAL_OES; @@ -1155,6 +1162,8 @@ target_enum_to_index(struct gl_context *ctx, GLenum target) case GL_TEXTURE_EXTERNAL_OES: return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external ? TEXTURE_EXTERNAL_INDEX : -1; + case GL_TEXTURE_CUBE_MAP_ARRAY: + return TEXTURE_CUBE_ARRAY_INDEX; default: return -1; } diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index f22c58cade4..f86b4ebcdd4 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -81,6 +81,8 @@ _mesa_reference_texobj(struct gl_texture_object **ptr, /** * Return number of faces for a texture target. This will be 6 for * cube maps (and cube map arrays) and 1 otherwise. + * NOTE: this function is not used for cube map arrays which operate + * more like 2D arrays than cube maps. */ static inline GLuint _mesa_num_tex_faces(GLenum target) diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index f73e2b5f022..8ce0546180c 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -170,6 +170,11 @@ get_texobj(struct gl_context *ctx, GLenum target, GLboolean get) return texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX]; } break; + case GL_TEXTURE_CUBE_MAP_ARRAY: + if (ctx->Extensions.ARB_texture_cube_map_array) { + return texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX]; + } + break; default: ; } diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 0e5ba44ed49..1f765086b6d 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -706,6 +706,7 @@ alloc_proxy_textures( struct gl_context *ctx ) * values! */ static const GLenum targets[] = { + GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BUFFER, GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_1D_ARRAY_EXT, diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c index 968f6f90408..9e0b54317c3 100644 --- a/src/mesa/main/texstorage.c +++ b/src/mesa/main/texstorage.c @@ -87,6 +87,9 @@ legal_texobj_target(struct gl_context *ctx, GLuint dims, GLenum target) case GL_PROXY_TEXTURE_2D_ARRAY: return (ctx->Extensions.MESA_texture_array || ctx->Extensions.EXT_texture_array); + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + return ctx->Extensions.ARB_texture_cube_map_array; default: return GL_FALSE; } diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index e6914553c87..1c088106fce 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -4273,6 +4273,7 @@ store_texsubimage(struct gl_context *ctx, dims = 1; break; case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_TEXTURE_3D: dims = 3; break; @@ -4324,6 +4325,12 @@ store_texsubimage(struct gl_context *ctx, srcImageStride = _mesa_image_image_stride(packing, width, height, format, type); break; + case GL_TEXTURE_CUBE_MAP_ARRAY: + numSlices = depth; + sliceOffset = zoffset; + srcImageStride = _mesa_image_image_stride(packing, width, height, + format, type); + break; default: _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target); return; -- 2.30.2