* If an error is found, record it with _mesa_error()
* \return none.
*/
-void GLAPIENTRY
-_mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
- GLenum internalformat,
- GLuint minlevel, GLuint numlevels,
- GLuint minlayer, GLuint numlayers)
+static ALWAYS_INLINE void
+texture_view(struct gl_context *ctx, struct gl_texture_object *origTexObj,
+ struct gl_texture_object *texObj, GLenum target,
+ GLenum internalformat, GLuint minlevel, GLuint numlevels,
+ GLuint minlayer, GLuint numlayers, bool no_error)
{
- struct gl_texture_object *texObj;
- struct gl_texture_object *origTexObj;
struct gl_texture_image *origTexImage;
- GLuint newViewMinLevel, newViewMinLayer;
GLuint newViewNumLevels, newViewNumLayers;
GLsizei width, height, depth;
mesa_format texFormat;
GLboolean sizeOK, dimensionsOK;
GLenum faceTarget;
- GET_CURRENT_CONTEXT(ctx);
-
- if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glTextureView %d %s %d %s %d %d %d %d\n",
- texture, _mesa_enum_to_string(target), origtexture,
- _mesa_enum_to_string(internalformat),
- minlevel, numlevels, minlayer, numlayers);
-
- if (origtexture == 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)",
- origtexture);
- return;
- }
-
- /* Need original texture information to validate arguments */
- origTexObj = _mesa_lookup_texture(ctx, origtexture);
-
- /* If <origtexture> is not the name of a texture, INVALID_VALUE
- * is generated.
- */
- if (!origTexObj) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)",
- origtexture);
- return;
- }
-
- /* If <origtexture>'s TEXTURE_IMMUTABLE_FORMAT value is not TRUE,
- * INVALID_OPERATION is generated.
- */
- if (!origTexObj->Immutable) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTextureView(origtexture not immutable)");
- return;
- }
-
- /* If <texture> is 0, INVALID_VALUE is generated. */
- if (texture == 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(texture = 0)");
- return;
- }
-
- /* If <texture> is not a valid name returned by GenTextures,
- * the error INVALID_OPERATION is generated.
- */
- texObj = _mesa_lookup_texture(ctx, texture);
- if (texObj == NULL) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTextureView(texture = %u non-gen name)", texture);
- return;
- }
-
- /* If <texture> has already been bound and given a target, then
- * the error INVALID_OPERATION is generated.
- */
- if (texObj->Target) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTextureView(texture = %u already bound)", texture);
- return;
- }
-
- /* Check for compatible target */
- if (!target_valid(ctx, origTexObj->Target, target)) {
- return; /* error was recorded */
- }
-
- /* minlevel and minlayer are relative to the view of origtexture.
- * If minlevel or minlayer is greater than level or layer, respectively,
- * return INVALID_VALUE.
- */
- newViewMinLevel = origTexObj->MinLevel + minlevel;
- newViewMinLayer = origTexObj->MinLayer + minlayer;
- if (newViewMinLevel >= (origTexObj->MinLevel + origTexObj->NumLevels)) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTextureView(new minlevel (%d) > orig minlevel (%d)"
- " + orig numlevels (%d))",
- newViewMinLevel, origTexObj->MinLevel, origTexObj->NumLevels);
- return;
- }
-
- if (newViewMinLayer >= (origTexObj->MinLayer + origTexObj->NumLayers)) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTextureView(new minlayer (%d) > orig minlayer (%d)"
- " + orig numlayers (%d))",
- newViewMinLayer, origTexObj->MinLayer, origTexObj->NumLayers);
- return;
- }
-
- if (!_mesa_texture_view_compatible_format(ctx,
- origTexObj->Image[0][0]->InternalFormat,
- internalformat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTextureView(internalformat %s not compatible with origtexture %s)",
- _mesa_enum_to_string(internalformat),
- _mesa_enum_to_string(origTexObj->Image[0][0]->InternalFormat));
- return;
- }
-
texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
internalformat, GL_NONE, GL_NONE);
if (texFormat == MESA_FORMAT_NONE) return;
/* If the new texture's target is TEXTURE_CUBE_MAP, the clamped
* <numlayers> must be equal to 6.
*/
- if (newViewNumLayers != 6) {
+ if (!no_error && newViewNumLayers != 6) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glTextureView(clamped numlayers %d != 6)",
newViewNumLayers);
* and the clamped <numlayers> must be a multiple of 6.
* Otherwise, the error INVALID_VALUE is generated.
*/
- if ((newViewNumLayers % 6) != 0) {
+ if (!no_error && (newViewNumLayers % 6) != 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glTextureView(clamped numlayers %d is not"
" a multiple of 6)",
break;
}
- /* If the dimensions of the original texture are larger than the maximum
- * supported dimensions of the new target, the error INVALID_OPERATION is
- * generated. For example, if the original texture has a TEXTURE_2D_ARRAY
- * target and its width is greater than MAX_CUBE_MAP_TEXTURE_SIZE, an error
- * will be generated if TextureView is called to create a TEXTURE_CUBE_MAP
- * view.
- */
- dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
- width, height, depth, 0);
- if (!dimensionsOK) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTextureView(invalid width or height or depth)");
- return;
- }
-
- sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 1, 0, texFormat,
- origTexImage->NumSamples,
- width, height, depth);
- if (!sizeOK) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTextureView(invalid texture size)");
- return;
- }
+ if (!no_error) {
+ /* If the dimensions of the original texture are larger than the maximum
+ * supported dimensions of the new target, the error INVALID_OPERATION is
+ * generated. For example, if the original texture has a TEXTURE_2D_ARRAY
+ * target and its width is greater than MAX_CUBE_MAP_TEXTURE_SIZE, an
+ * error will be generated if TextureView is called to create a
+ * TEXTURE_CUBE_MAP view.
+ */
+ dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
+ width, height, depth, 0);
+ if (!dimensionsOK) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(invalid width or height or depth)");
+ return;
+ }
- /* If <target> is TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_RECTANGLE,
- * or TEXTURE_2D_MULTISAMPLE and <numlayers> does not equal 1, the error
- * INVALID_VALUE is generated.
- */
- switch (target) {
- case GL_TEXTURE_1D:
- case GL_TEXTURE_2D:
- case GL_TEXTURE_3D:
- case GL_TEXTURE_RECTANGLE:
- case GL_TEXTURE_2D_MULTISAMPLE:
- if (numlayers != 1) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(numlayers %d != 1)",
- numlayers);
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 1, 0, texFormat,
+ origTexImage->NumSamples,
+ width, height, depth);
+ if (!sizeOK) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(invalid texture size)");
return;
}
- break;
- case GL_TEXTURE_CUBE_MAP:
- break;
- case GL_TEXTURE_CUBE_MAP_ARRAY:
- break;
- }
- /* If the new texture's target is TEXTURE_CUBE_MAP or
- * TEXTURE_CUBE_MAP_ARRAY, the width and height of the original texture's
- * levels must be equal otherwise the error INVALID_OPERATION is generated.
- */
- if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) &&
- (origTexImage->Width != origTexImage->Height)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTextureView(origtexture width (%d) != height (%d))",
- origTexImage->Width, origTexImage->Height);
- return;
+ /* If <target> is TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_RECTANGLE,
+ * or TEXTURE_2D_MULTISAMPLE and <numlayers> does not equal 1, the error
+ * INVALID_VALUE is generated.
+ */
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ if (numlayers != 1) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(numlayers %d != 1)",
+ numlayers);
+ return;
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ break;
+ }
+
+ /* If the new texture's target is TEXTURE_CUBE_MAP or
+ * TEXTURE_CUBE_MAP_ARRAY, the width and height of the original texture's
+ * levels must be equal otherwise the error INVALID_OPERATION is
+ * generated.
+ */
+ if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY)
+ && (origTexImage->Width != origTexImage->Height)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(origtexture width (%d) != height (%d))",
+ origTexImage->Width, origTexImage->Height);
+ return;
+ }
}
/* When the original texture's target is TEXTURE_CUBE_MAP, the layer
return; /* Already recorded error */
}
- texObj->MinLevel = newViewMinLevel;
- texObj->MinLayer = newViewMinLayer;
+ texObj->MinLevel = origTexObj->MinLevel + minlevel;
+ texObj->MinLayer = origTexObj->MinLayer + minlayer;
texObj->NumLevels = newViewNumLevels;
texObj->NumLayers = newViewNumLayers;
texObj->Immutable = GL_TRUE;
return; /* driver recorded error */
}
}
+
+void GLAPIENTRY
+_mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
+ GLenum internalformat,
+ GLuint minlevel, GLuint numlevels,
+ GLuint minlayer, GLuint numlayers)
+{
+ struct gl_texture_object *texObj;
+ struct gl_texture_object *origTexObj;
+ GLuint newViewMinLevel, newViewMinLayer;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glTextureView %d %s %d %s %d %d %d %d\n",
+ texture, _mesa_enum_to_string(target), origtexture,
+ _mesa_enum_to_string(internalformat),
+ minlevel, numlevels, minlayer, numlayers);
+
+ if (origtexture == 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)",
+ origtexture);
+ return;
+ }
+
+ /* Need original texture information to validate arguments */
+ origTexObj = _mesa_lookup_texture(ctx, origtexture);
+
+ /* If <origtexture> is not the name of a texture, INVALID_VALUE
+ * is generated.
+ */
+ if (!origTexObj) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)",
+ origtexture);
+ return;
+ }
+
+ /* If <origtexture>'s TEXTURE_IMMUTABLE_FORMAT value is not TRUE,
+ * INVALID_OPERATION is generated.
+ */
+ if (!origTexObj->Immutable) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(origtexture not immutable)");
+ return;
+ }
+
+ /* If <texture> is 0, INVALID_VALUE is generated. */
+ if (texture == 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(texture = 0)");
+ return;
+ }
+
+ /* If <texture> is not a valid name returned by GenTextures,
+ * the error INVALID_OPERATION is generated.
+ */
+ texObj = _mesa_lookup_texture(ctx, texture);
+ if (texObj == NULL) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(texture = %u non-gen name)", texture);
+ return;
+ }
+
+ /* If <texture> has already been bound and given a target, then
+ * the error INVALID_OPERATION is generated.
+ */
+ if (texObj->Target) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(texture = %u already bound)", texture);
+ return;
+ }
+
+ /* Check for compatible target */
+ if (!target_valid(ctx, origTexObj->Target, target)) {
+ return; /* error was recorded */
+ }
+
+ /* minlevel and minlayer are relative to the view of origtexture.
+ * If minlevel or minlayer is greater than level or layer, respectively,
+ * return INVALID_VALUE.
+ */
+ newViewMinLevel = origTexObj->MinLevel + minlevel;
+ newViewMinLayer = origTexObj->MinLayer + minlayer;
+ if (newViewMinLevel >= (origTexObj->MinLevel + origTexObj->NumLevels)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTextureView(new minlevel (%d) > orig minlevel (%d)"
+ " + orig numlevels (%d))",
+ newViewMinLevel, origTexObj->MinLevel, origTexObj->NumLevels);
+ return;
+ }
+
+ if (newViewMinLayer >= (origTexObj->MinLayer + origTexObj->NumLayers)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTextureView(new minlayer (%d) > orig minlayer (%d)"
+ " + orig numlayers (%d))",
+ newViewMinLayer, origTexObj->MinLayer, origTexObj->NumLayers);
+ return;
+ }
+
+ if (!_mesa_texture_view_compatible_format(ctx,
+ origTexObj->Image[0][0]->InternalFormat,
+ internalformat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(internalformat %s not compatible with origtexture %s)",
+ _mesa_enum_to_string(internalformat),
+ _mesa_enum_to_string(origTexObj->Image[0][0]->InternalFormat));
+ return;
+ }
+
+ texture_view(ctx, origTexObj, texObj, target, internalformat, minlevel,
+ numlevels, minlayer, numlayers, false);
+}