/** * Helper used by _mesa_TexStorage1/2/3D(). */ static void texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { struct gl_texture_object *texObj; GLboolean error; GET_CURRENT_CONTEXT(ctx); texObj = _mesa_get_current_tex_object(ctx, target); error = tex_storage_error_check(ctx, dims, target, levels, internalformat, width, height, depth); if (!error) { setup_texstorage(ctx, texObj, dims, levels, internalformat, width, height, depth); } else if (_mesa_is_proxy_texture(target)) { /* clear all image fields for [levels] */ clear_image_fields(ctx, dims, texObj); } }
/** * Helper that does the storage allocation for _mesa_TexStorage1/2/3D() * and _mesa_TextureStorage1/2/3D(). */ static void texture_storage(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texObj, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool dsa) { GLboolean sizeOK, dimensionsOK; mesa_format texFormat; const char* suffix = dsa ? "ture" : ""; assert(texObj); if (tex_storage_error_check(ctx, texObj, dims, target, levels, internalformat, width, height, depth, dsa)) { return; /* error was recorded */ } texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, internalformat, GL_NONE, GL_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, levels, 0, texFormat, 1, width, height, depth); if (_mesa_is_proxy_texture(target)) { if (dimensionsOK && sizeOK) { initialize_texture_fields(ctx, texObj, levels, width, height, depth, internalformat, texFormat); } else { /* clear all image fields for [levels] */ clear_texture_fields(ctx, texObj); } } else { if (!dimensionsOK) { _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(invalid width, height or depth)", suffix, dims); return; } if (!sizeOK) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD(texture too large)", suffix, 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, "glTex%sStorage%uD", suffix, dims); return; } _mesa_set_texture_view_state(ctx, texObj, target, levels); update_fbo_texture(ctx, texObj); } }
/** * Helper used by _mesa_TexStorage1/2/3D(). */ static void texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { struct gl_texture_object *texObj; GLboolean sizeOK, dimensionsOK; gl_format texFormat; GET_CURRENT_CONTEXT(ctx); if (tex_storage_error_check(ctx, dims, target, levels, internalformat, width, height, depth)) { return; /* error was recorded */ } texObj = _mesa_get_current_tex_object(ctx, target); assert(texObj); texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, 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 (_mesa_is_proxy_texture(texObj->Target)) { if (dimensionsOK && sizeOK) { initialize_texture_fields(ctx, texObj, levels, width, height, depth, internalformat, texFormat); } else { /* clear all image fields for [levels] */ clear_texture_fields(ctx, texObj); } } else { 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; texObj->ImmutableLevels = levels; } }