summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2017-07-18 10:53:14 +0200
committerSamuel Pitoiset <[email protected]>2017-07-31 13:53:39 +0200
commit68c43ae8b2026acca482639292b3a673fb06ef6f (patch)
tree28af6150db26e5e08146b00970610c09e464bcf4 /src/mesa/main
parent789cc87063c0cbb20941053b54fcbe4862912a14 (diff)
mesa: add texture_view() helper
Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Timothy Arceri <[email protected]>
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/textureview.c336
1 files changed, 175 insertions, 161 deletions
diff --git a/src/mesa/main/textureview.c b/src/mesa/main/textureview.c
index cef9caff41c..165af3c7469 100644
--- a/src/mesa/main/textureview.c
+++ b/src/mesa/main/textureview.c
@@ -518,119 +518,19 @@ _mesa_set_texture_view_state(struct gl_context *ctx,
* 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;
@@ -668,7 +568,7 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
/* 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);
@@ -687,7 +587,7 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
* 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)",
@@ -698,62 +598,65 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
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
@@ -777,8 +680,8 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
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;
@@ -792,3 +695,114 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
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);
+}