mirror of
https://gitee.com/openharmony/third_party_mesa3d
synced 2025-02-23 11:42:55 +00:00
mesa: rewrite glTexStorage() code
Simplify the code and make it more like the other glTexImage commands. Call _mesa_legal_texture_dimensions() to validate width, height, depth. Call ctx->Driver.TestProxyTexImage() to make sure texture is not too large. Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
This commit is contained in:
parent
e6eaa85a43
commit
ff24ed09fa
@ -118,39 +118,42 @@ next_mipmap_level_size(GLenum target,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do actual memory allocation for glTexStorage1/2/3D().
|
||||
*/
|
||||
static void
|
||||
setup_texstorage(struct gl_context *ctx,
|
||||
struct gl_texture_object *texObj,
|
||||
GLuint dims,
|
||||
gl_format texFormat,
|
||||
GLsizei levels, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLsizei depth)
|
||||
/** Helper to get a particular texture image in a texture object */
|
||||
static struct gl_texture_image *
|
||||
get_tex_image(struct gl_context *ctx,
|
||||
struct gl_texture_object *texObj,
|
||||
GLuint face, GLuint level)
|
||||
{
|
||||
const GLenum faceTarget =
|
||||
(texObj->Target == GL_TEXTURE_CUBE_MAP ||
|
||||
texObj->Target == GL_PROXY_TEXTURE_CUBE_MAP)
|
||||
? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : texObj->Target;
|
||||
return _mesa_get_tex_image(ctx, texObj, faceTarget, level);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static GLboolean
|
||||
initialize_texture_fields(struct gl_context *ctx,
|
||||
struct gl_texture_object *texObj,
|
||||
GLint levels,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum internalFormat, gl_format texFormat)
|
||||
{
|
||||
const GLenum target = texObj->Target;
|
||||
const GLuint numFaces = _mesa_num_tex_faces(target);
|
||||
GLint level, levelWidth = width, levelHeight = height, levelDepth = depth;
|
||||
GLuint face;
|
||||
|
||||
assert(levels > 0);
|
||||
assert(width > 0);
|
||||
assert(height > 0);
|
||||
assert(depth > 0);
|
||||
|
||||
/* Set up all the texture object's gl_texture_images */
|
||||
for (level = 0; level < levels; level++) {
|
||||
for (face = 0; face < numFaces; face++) {
|
||||
const GLenum faceTarget =
|
||||
(target == GL_TEXTURE_CUBE_MAP)
|
||||
? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : target;
|
||||
struct gl_texture_image *texImage =
|
||||
_mesa_get_tex_image(ctx, texObj, faceTarget, level);
|
||||
get_tex_image(ctx, texObj, face, level);
|
||||
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
|
||||
return;
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage");
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
_mesa_init_teximage_fields(ctx, texImage,
|
||||
@ -160,49 +163,18 @@ setup_texstorage(struct gl_context *ctx,
|
||||
|
||||
next_mipmap_level_size(target, &levelWidth, &levelHeight, &levelDepth);
|
||||
}
|
||||
|
||||
assert(levelWidth > 0);
|
||||
assert(levelHeight > 0);
|
||||
assert(levelDepth > 0);
|
||||
|
||||
if (!_mesa_is_proxy_texture(texObj->Target)) {
|
||||
/* Do actual texture memory allocation */
|
||||
if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels,
|
||||
width, height, depth)) {
|
||||
/* Reset the texture images' info to zeros.
|
||||
* Strictly speaking, we probably don't have to do this since
|
||||
* generating GL_OUT_OF_MEMORY can leave things in an undefined
|
||||
* state but this puts things in a consistent state.
|
||||
*/
|
||||
for (level = 0; level < levels; level++) {
|
||||
for (face = 0; face < numFaces; face++) {
|
||||
struct gl_texture_image *texImage = texObj->Image[face][level];
|
||||
if (texImage) {
|
||||
_mesa_init_teximage_fields(ctx, texImage,
|
||||
0, 0, 0, 0,
|
||||
GL_NONE, MESA_FORMAT_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage%uD", dims);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only set this field for non-proxy texture objects */
|
||||
texObj->Immutable = GL_TRUE;
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear all fields of texture object to zeros. Used for proxy texture tests.
|
||||
* Used for proxy texture tests (and to clean up when a texture memory
|
||||
* allocation fails).
|
||||
*/
|
||||
static void
|
||||
clear_image_fields(struct gl_context *ctx,
|
||||
GLuint dims,
|
||||
struct gl_texture_object *texObj)
|
||||
clear_texture_fields(struct gl_context *ctx,
|
||||
struct gl_texture_object *texObj)
|
||||
{
|
||||
const GLenum target = texObj->Target;
|
||||
const GLuint numFaces = _mesa_num_tex_faces(target);
|
||||
@ -211,19 +183,17 @@ clear_image_fields(struct gl_context *ctx,
|
||||
|
||||
for (level = 0; level < Elements(texObj->Image[0]); level++) {
|
||||
for (face = 0; face < numFaces; face++) {
|
||||
const GLenum faceTarget =
|
||||
(target == GL_TEXTURE_CUBE_MAP)
|
||||
? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : target;
|
||||
struct gl_texture_image *texImage =
|
||||
_mesa_get_tex_image(ctx, texObj, faceTarget, level);
|
||||
get_tex_image(ctx, texObj, face, level);
|
||||
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage%uD", dims);
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage");
|
||||
return;
|
||||
}
|
||||
|
||||
_mesa_init_teximage_fields(ctx, texImage,
|
||||
0, 0, 0, 0, GL_NONE, MESA_FORMAT_NONE);
|
||||
0, 0, 0, 0, /* w, h, d, border */
|
||||
GL_NONE, MESA_FORMAT_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -356,7 +326,7 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLsizei depth)
|
||||
{
|
||||
struct gl_texture_object *texObj;
|
||||
GLboolean sizeOK;
|
||||
GLboolean sizeOK, dimensionsOK;
|
||||
gl_format texFormat;
|
||||
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
@ -373,24 +343,59 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,
|
||||
internalformat, GL_NONE, GL_NONE);
|
||||
assert(texFormat != MESA_FORMAT_NONE);
|
||||
|
||||
/* check that width, height, depth are legal for the mipmap level */
|
||||
dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
|
||||
width, height, depth, 0);
|
||||
|
||||
sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat,
|
||||
width, height, depth, 0);
|
||||
|
||||
if (!sizeOK) {
|
||||
if (_mesa_is_proxy_texture(texObj->Target)) {
|
||||
/* clear all image fields for [levels] */
|
||||
clear_image_fields(ctx, dims, texObj);
|
||||
if (_mesa_is_proxy_texture(texObj->Target)) {
|
||||
if (dimensionsOK && sizeOK) {
|
||||
initialize_texture_fields(ctx, texObj, levels, width, height, depth,
|
||||
internalformat, texFormat);
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glTexStorage%uD(invalid width, height or depth)",
|
||||
dims);
|
||||
return;
|
||||
/* clear all image fields for [levels] */
|
||||
clear_texture_fields(ctx, texObj);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setup_texstorage(ctx, texObj, dims, texFormat, levels, internalformat,
|
||||
width, height, depth);
|
||||
if (!dimensionsOK) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||
"glTexStorage%uD(invalid width, height or depth)", dims);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sizeOK) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY,
|
||||
"glTexStorage%uD(texture too large)", dims);
|
||||
}
|
||||
|
||||
assert(levels > 0);
|
||||
assert(width > 0);
|
||||
assert(height > 0);
|
||||
assert(depth > 0);
|
||||
|
||||
if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth,
|
||||
internalformat, texFormat)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Do actual texture memory allocation */
|
||||
if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels,
|
||||
width, height, depth)) {
|
||||
/* Reset the texture images' info to zeros.
|
||||
* Strictly speaking, we probably don't have to do this since
|
||||
* generating GL_OUT_OF_MEMORY can leave things in an undefined
|
||||
* state but this puts things in a consistent state.
|
||||
*/
|
||||
clear_texture_fields(ctx, texObj);
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage%uD", dims);
|
||||
return;
|
||||
}
|
||||
|
||||
texObj->Immutable = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user