mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 04:50:11 +01:00
mesa: glTexStorage* support sparse texture allocation
Reviewed-by: Marek Olšák <marek.olsak@amd.com> Signed-off-by: Qiang Yu <yuq825@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14223>
This commit is contained in:
parent
482fe76300
commit
34e5c14f70
6 changed files with 106 additions and 10 deletions
|
|
@ -384,6 +384,87 @@ tex_storage_error_check(struct gl_context *ctx,
|
|||
return GL_FALSE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
sparse_texture_error_check(struct gl_context *ctx, GLuint dims,
|
||||
struct gl_texture_object *texObj,
|
||||
mesa_format format, GLenum target, GLsizei levels,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
bool dsa)
|
||||
{
|
||||
const char* suffix = dsa ? "ture" : "";
|
||||
|
||||
int px, py, pz;
|
||||
int index = texObj->VirtualPageSizeIndex;
|
||||
if (!st_GetSparseTextureVirtualPageSize(ctx, target, format, index,
|
||||
&px, &py, &pz)) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(sparse index = %d)",
|
||||
suffix, dims, index);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
if (target == GL_TEXTURE_3D) {
|
||||
if (width > ctx->Const.MaxSparse3DTextureSize ||
|
||||
height > ctx->Const.MaxSparse3DTextureSize ||
|
||||
depth > ctx->Const.MaxSparse3DTextureSize)
|
||||
goto exceed_max_size;
|
||||
} else {
|
||||
if (width > ctx->Const.MaxSparseTextureSize ||
|
||||
height > ctx->Const.MaxSparseTextureSize)
|
||||
goto exceed_max_size;
|
||||
|
||||
if (target == GL_TEXTURE_2D_ARRAY ||
|
||||
target == GL_TEXTURE_CUBE_MAP_ARRAY) {
|
||||
if (depth > ctx->Const.MaxSparseArrayTextureLayers)
|
||||
goto exceed_max_size;
|
||||
} else if (target == GL_TEXTURE_1D_ARRAY) {
|
||||
if (height > ctx->Const.MaxSparseArrayTextureLayers)
|
||||
goto exceed_max_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (width % px || height % py || depth % pz) {
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(sparse page size)",
|
||||
suffix, dims);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* ARB_sparse_texture spec:
|
||||
*
|
||||
* If the value of SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB is FALSE,
|
||||
* then TexStorage* will generate an INVALID_OPERATION error if
|
||||
* * the texture's TEXTURE_SPARSE_ARB parameter is TRUE,
|
||||
* * <target> is one of TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY,
|
||||
* TEXTURE_CUBE_MAP, or TEXTURE_CUBE_MAP_ARRAY, and
|
||||
* * for the virtual page size corresponding to the
|
||||
* VIRTUAL_PAGE_SIZE_INDEX_ARB parameter, either of the following is
|
||||
* true:
|
||||
* - <width> is not a multiple of VIRTUAL_PAGE_SIZE_X_ARB *
|
||||
* 2^(<levels>-1), or
|
||||
* - <height> is not a multiple of VIRTUAL_PAGE_SIZE_Y_ARB *
|
||||
* 2^(<levels>-1).
|
||||
*
|
||||
* This make sure all allocated mipmap level size is multiple of virtual
|
||||
* page size when SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB is FALSE.
|
||||
*/
|
||||
if (!ctx->Const.SparseTextureFullArrayCubeMipmaps &&
|
||||
(target == GL_TEXTURE_1D_ARRAY ||
|
||||
target == GL_TEXTURE_2D_ARRAY ||
|
||||
target == GL_TEXTURE_CUBE_MAP ||
|
||||
target == GL_TEXTURE_CUBE_MAP_ARRAY) &&
|
||||
(width % (px << (levels - 1)) ||
|
||||
height % (py << (levels - 1)))) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(sparse array align)",
|
||||
suffix, dims);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
return GL_FALSE;
|
||||
|
||||
exceed_max_size:
|
||||
_mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(exceed max sparse size)",
|
||||
suffix, dims);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that does the storage allocation for _mesa_TexStorage1/2/3D()
|
||||
|
|
@ -448,6 +529,11 @@ texture_storage(struct gl_context *ctx, GLuint dims,
|
|||
suffix, dims);
|
||||
return;
|
||||
}
|
||||
|
||||
if (texObj->IsSparse &&
|
||||
sparse_texture_error_check(ctx, dims, texObj, texFormat, target, levels,
|
||||
width, height, depth, dsa))
|
||||
return; /* error was recorded */
|
||||
}
|
||||
|
||||
assert(levels > 0);
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height,
|
|||
*/
|
||||
pt = st_texture_create(st, st->internal_target, st->bitmap.tex_format,
|
||||
0, width, height, 1, 1, 0,
|
||||
PIPE_BIND_SAMPLER_VIEW);
|
||||
PIPE_BIND_SAMPLER_VIEW, false);
|
||||
if (!pt) {
|
||||
_mesa_unmap_pbo_source(ctx, unpack);
|
||||
return NULL;
|
||||
|
|
@ -363,7 +363,8 @@ reset_cache(struct st_context *st)
|
|||
st->bitmap.tex_format, 0,
|
||||
BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
|
||||
1, 1, 0,
|
||||
PIPE_BIND_SAMPLER_VIEW);
|
||||
PIPE_BIND_SAMPLER_VIEW,
|
||||
false);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -473,7 +473,7 @@ alloc_texture(struct st_context *st, GLsizei width, GLsizei height,
|
|||
struct pipe_resource *pt;
|
||||
|
||||
pt = st_texture_create(st, st->internal_target, texFormat, 0,
|
||||
width, height, 1, 1, 0, bind);
|
||||
width, height, 1, 1, 0, bind, false);
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -985,7 +985,8 @@ guess_and_alloc_texture(struct st_context *st,
|
|||
ptHeight,
|
||||
ptDepth,
|
||||
ptLayers, 0,
|
||||
bindings);
|
||||
bindings,
|
||||
false);
|
||||
|
||||
stObj->lastLevel = lastLevel;
|
||||
|
||||
|
|
@ -1080,7 +1081,8 @@ st_AllocTextureImageBuffer(struct gl_context *ctx,
|
|||
ptHeight,
|
||||
ptDepth,
|
||||
ptLayers, 0,
|
||||
bindings);
|
||||
bindings,
|
||||
false);
|
||||
return stImage->pt != NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -3126,7 +3128,8 @@ st_finalize_texture(struct gl_context *ctx,
|
|||
ptHeight,
|
||||
ptDepth,
|
||||
ptLayers, ptNumSamples,
|
||||
bindings);
|
||||
bindings,
|
||||
false);
|
||||
|
||||
if (!stObj->pt) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
|
||||
|
|
@ -3337,7 +3340,8 @@ st_texture_storage(struct gl_context *ctx,
|
|||
ptHeight,
|
||||
ptDepth,
|
||||
ptLayers, num_samples,
|
||||
bindings);
|
||||
bindings,
|
||||
texObj->IsSparse);
|
||||
}
|
||||
|
||||
if (!stObj->pt)
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ st_texture_create(struct st_context *st,
|
|||
GLuint depth0,
|
||||
GLuint layers,
|
||||
GLuint nr_samples,
|
||||
GLuint bind)
|
||||
GLuint bind,
|
||||
bool sparse)
|
||||
{
|
||||
struct pipe_resource pt, *newtex;
|
||||
struct pipe_screen *screen = st->screen;
|
||||
|
|
@ -97,6 +98,9 @@ st_texture_create(struct st_context *st,
|
|||
pt.nr_samples = nr_samples;
|
||||
pt.nr_storage_samples = nr_samples;
|
||||
|
||||
if (sparse)
|
||||
pt.flags |= PIPE_RESOURCE_FLAG_SPARSE;
|
||||
|
||||
newtex = screen->resource_create(screen, &pt);
|
||||
|
||||
assert(!newtex || pipe_is_referenced(&newtex->reference));
|
||||
|
|
@ -422,7 +426,7 @@ st_create_color_map_texture(struct gl_context *ctx)
|
|||
|
||||
/* create texture for color map/table */
|
||||
pt = st_texture_create(st, PIPE_TEXTURE_2D, format, 0,
|
||||
texSize, texSize, 1, 1, 0, PIPE_BIND_SAMPLER_VIEW);
|
||||
texSize, texSize, 1, 1, 0, PIPE_BIND_SAMPLER_VIEW, false);
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -287,7 +287,8 @@ st_texture_create(struct st_context *st,
|
|||
GLuint depth0,
|
||||
GLuint layers,
|
||||
GLuint nr_samples,
|
||||
GLuint tex_usage );
|
||||
GLuint tex_usage,
|
||||
bool sparse);
|
||||
|
||||
|
||||
extern void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue