📄 teximage.c
字号:
/** * Test the glTexImage[123]D() parameters for errors. * * \param ctx GL context. * \param target texture target given by the user. * \param level image level given by the user. * \param internalFormat internal format given by the user. * \param format pixel data format given by the user. * \param type pixel data type given by the user. * \param dimensions texture image dimensions (must be 1, 2 or 3). * \param width image width given by the user. * \param height image height given by the user. * \param depth image depth given by the user. * \param border image border given by the user. * * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. * * Verifies each of the parameters against the constants specified in * __GLcontextRec::Const and the supported extensions, and according to the * OpenGL specification. */static GLbooleantexture_error_check( GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLenum format, GLenum type, GLuint dimensions, GLint width, GLint height, GLint depth, GLint border ){ const GLboolean isProxy = _mesa_is_proxy_texture(target); GLboolean sizeOK; GLboolean colorFormat, indexFormat; /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ if (level < 0 || level >= MAX_TEXTURE_LEVELS) { if (!isProxy) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage%dD(level=%d)", dimensions, level); } return GL_TRUE; } /* Check border */ if (border < 0 || border > 1 || ((target == GL_TEXTURE_RECTANGLE_NV || target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { if (!isProxy) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage%dD(border=%d)", dimensions, border); } return GL_TRUE; } if (width < 0 || height < 0 || depth < 0) { if (!isProxy) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage%dD(width, height or depth < 0)", dimensions); } return GL_TRUE; } /* Check target and call ctx->Driver.TestProxyTexImage() to check the * level, width, height and depth. */ if (dimensions == 1) { if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) { sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D, level, internalFormat, format, type, width, 1, 1, border); } else { _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); return GL_TRUE; } } else if (dimensions == 2) { if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) { sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D, level, internalFormat, format, type, width, height, 1, border); } else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB || (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { if (!ctx->Extensions.ARB_texture_cube_map) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); return GL_TRUE; } sizeOK = (width == height) && ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB, level, internalFormat, format, type, width, height, 1, border); } else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV || target == GL_TEXTURE_RECTANGLE_NV) { if (!ctx->Extensions.NV_texture_rectangle) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); return GL_TRUE; } sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_RECTANGLE_NV, level, internalFormat, format, type, width, height, 1, border); } else { _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); return GL_TRUE; } } else if (dimensions == 3) { if (target == GL_PROXY_TEXTURE_3D || target == GL_TEXTURE_3D) { sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_3D, level, internalFormat, format, type, width, height, depth, border); } else { _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); return GL_TRUE; } } else { _mesa_problem( ctx, "bad dims in texture_error_check" ); return GL_TRUE; } if (!sizeOK) { if (!isProxy) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)", dimensions, level, width, height, depth); } return GL_TRUE; } /* Check internalFormat */ if (_mesa_base_tex_format(ctx, internalFormat) < 0) { if (!isProxy) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage%dD(internalFormat=0x%x)", dimensions, internalFormat); } return GL_TRUE; } /* Check incoming image format and type */ if (!_mesa_is_legal_format_and_type(ctx, format, type)) { /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4. */ if (!isProxy) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexImage%dD(format or type)", dimensions); } return GL_TRUE; } /* make sure internal format and format basically agree */ colorFormat = is_color_format(format); indexFormat = is_index_format(format); if ((is_color_format(internalFormat) && !colorFormat && !indexFormat) || (is_index_format(internalFormat) && !indexFormat) || (is_depth_format(internalFormat) != is_depth_format(format)) || (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) || (is_depthstencil_format(internalFormat) != is_depthstencil_format(format))) { if (!isProxy) _mesa_error(ctx, GL_INVALID_OPERATION, "glTexImage(internalFormat/format)"); return GL_TRUE; } /* additional checks for ycbcr textures */ if (internalFormat == GL_YCBCR_MESA) { ASSERT(ctx->Extensions.MESA_ycbcr_texture); if (type != GL_UNSIGNED_SHORT_8_8_MESA && type != GL_UNSIGNED_SHORT_8_8_REV_MESA) { char message[100]; _mesa_sprintf(message, "glTexImage%d(format/type YCBCR mismatch", dimensions); _mesa_error(ctx, GL_INVALID_ENUM, message); return GL_TRUE; /* error */ } if (target != GL_TEXTURE_2D && target != GL_PROXY_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_NV && target != GL_PROXY_TEXTURE_RECTANGLE_NV) { if (!isProxy) _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)"); return GL_TRUE; } if (border != 0) { if (!isProxy) { char message[100]; _mesa_sprintf(message, "glTexImage%d(format=GL_YCBCR_MESA and border=%d)", dimensions, border); _mesa_error(ctx, GL_INVALID_VALUE, message); } return GL_TRUE; } } /* additional checks for depth textures */ if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) { /* Only 1D and 2D textures supported */ if (target != GL_TEXTURE_1D && target != GL_PROXY_TEXTURE_1D && target != GL_TEXTURE_2D && target != GL_PROXY_TEXTURE_2D) { if (!isProxy) _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target/internalFormat)"); return GL_TRUE; } } /* additional checks for compressed textures */ if (is_compressed_format(ctx, internalFormat)) { if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) { /* OK */ } else if (ctx->Extensions.ARB_texture_cube_map && (target == GL_PROXY_TEXTURE_CUBE_MAP || (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) { /* OK */ } else { if (!isProxy) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%d(target)", dimensions); return GL_TRUE; } } if (border != 0) { if (!isProxy) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexImage%D(border!=0)", dimensions); } return GL_TRUE; } } /* if we get here, the parameters are OK */ return GL_FALSE;}/** * Test glTexSubImage[123]D() parameters for errors. * * \param ctx GL context. * \param dimensions texture image dimensions (must be 1, 2 or 3). * \param target texture target given by the user. * \param level image level given by the user. * \param xoffset sub-image x offset given by the user. * \param yoffset sub-image y offset given by the user. * \param zoffset sub-image z offset given by the user. * \param format pixel data format given by the user. * \param type pixel data type given by the user. * \param width image width given by the user. * \param height image height given by the user. * \param depth image depth given by the user. * * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. * * Verifies each of the parameters against the constants specified in * __GLcontextRec::Const and the supported extensions, and according to the * OpenGL specification. */static GLbooleansubtexture_error_check( GLcontext *ctx, GLuint dimensions, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint width, GLint height, GLint depth, GLenum format, GLenum type ){ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; struct gl_texture_image *destTex; /* Check target */ if (dimensions == 1) { if (target != GL_TEXTURE_1D) { _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" ); return GL_TRUE; } } else if (dimensions == 2) { if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && target <=GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { if (!ctx->Extensions.ARB_texture_cube_map) { _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); return GL_TRUE; } } else if (ctx->Extensions.NV_texture_rectangle && target == GL_TEXTURE_RECTANGLE_NV) { if (!ctx->Extensions.NV_texture_rectangle) { _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); return GL_TRUE; } } else if (target != GL_TEXTURE_2D) { _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); return GL_TRUE; } } else if (dimensions == 3) { if (target != GL_TEXTURE_3D) { _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" ); return GL_TRUE; } } else { _mesa_problem( ctx, "invalid dims in texture_error_check" ); return GL_TRUE; } /* Basic level check */ if (level < 0 || level >= MAX_TEXTURE_LEVELS) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level); return GL_TRUE; } if (width < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(width=%d)", dimensions, width); return GL_TRUE; } if (height < 0 && dimensions > 1) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(height=%d)", dimensions, height); return GL_TRUE; } if (depth < 0 && dimensions > 2) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(depth=%d)", dimensions, depth); return GL_TRUE; } destTex = _mesa_select_tex_image(ctx, texUnit, target, level); if (!destTex) { /* undefined image level */ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions); return GL_TRUE; } if (xoffset < -((GLint)destTex->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)", dimensions); return GL_TRUE; } if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)", dimensions); return GL_TRUE; } if (dimensions > 1) { if (yoffset < -((GLint)destTex->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)", dimensions); return GL_TRUE; } if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)", dimensions); return GL_TRUE; } } if (dimensions > 2) { if (zoffset < -((GLint)destTex->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)"); return GL_TRUE; } if (zoffset + depth > (GLint) (destTex->Depth + destTex->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)"); return GL_TRUE; } } if (!_mesa_is_legal_format_and_type(ctx, format, type)) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%dD(format or type)", dimensions); return GL_TRUE; } if (destTex->IsCompressed) { const struct gl_texture_unit *texUnit; const struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) { /* OK */ } else if (ctx->Extensions.ARB_texture_cube_map && (target == GL_PROXY_TEXTURE_CUBE_MAP || (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) { /* OK */ } else { _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%D(target)", dimensions); return GL_TRUE; } /* offset must be multiple of 4 */ if ((xoffset & 3) || (yoffset & 3)) { _mesa_error(ctx, GL_INVALID_OPERATION,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -