mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 22:00:13 +01:00
mesa: (more) correctly handle incomplete depth textures
according to GL spec, incomplete shadow samplers should return 0 this is technically possible for drivers to do using a RGBA texture in the sense that somehow it's been working, but it's broken at the gallium-level for what drivers should be expecting to see in such circumstances given that such scenarios have been binding a RGBA texture to use with shadow samplers instead, we can give drivers a fallback Z32 texture to avoid format/sampler mismatches and complying with expected behavior see also KHR-GL46.incomplete_texture_access.sampler for driver-specific testing Reviewed-by: Emma Anholt <emma@anholt.net> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20817>
This commit is contained in:
parent
818cc30852
commit
0c6e56c391
6 changed files with 37 additions and 22 deletions
|
|
@ -2413,7 +2413,7 @@ struct gl_shared_state
|
||||||
struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS];
|
struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS];
|
||||||
|
|
||||||
/** Fallback texture used when a bound texture is incomplete */
|
/** Fallback texture used when a bound texture is incomplete */
|
||||||
struct gl_texture_object *FallbackTex[NUM_TEXTURE_TARGETS];
|
struct gl_texture_object *FallbackTex[NUM_TEXTURE_TARGETS][2]; /**< [color, depth] */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \name Thread safety and statechange notification for texture
|
* \name Thread safety and statechange notification for texture
|
||||||
|
|
|
||||||
|
|
@ -335,8 +335,10 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
|
||||||
|
|
||||||
/* Free the dummy/fallback texture objects */
|
/* Free the dummy/fallback texture objects */
|
||||||
for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
|
for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
|
||||||
if (shared->FallbackTex[i])
|
for (unsigned j = 0; j < ARRAY_SIZE(shared->FallbackTex[0]); j++) {
|
||||||
_mesa_delete_texture_object(ctx, shared->FallbackTex[i]);
|
if (shared->FallbackTex[i][j])
|
||||||
|
_mesa_delete_texture_object(ctx, shared->FallbackTex[i][j]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -974,14 +974,15 @@ _mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return pointer to a default/fallback texture of the given type/target.
|
* Return pointer to a default/fallback texture of the given type/target.
|
||||||
* The texture is an RGBA texture with all texels = (0,0,0,1).
|
* The texture is an RGBA texture with all texels = (0,0,0,1) OR
|
||||||
|
* a depth texture that returns 0.
|
||||||
* That's the value a GLSL sampler should get when sampling from an
|
* That's the value a GLSL sampler should get when sampling from an
|
||||||
* incomplete texture.
|
* incomplete texture.
|
||||||
*/
|
*/
|
||||||
struct gl_texture_object *
|
struct gl_texture_object *
|
||||||
_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
|
_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex, bool is_depth)
|
||||||
{
|
{
|
||||||
if (!ctx->Shared->FallbackTex[tex]) {
|
if (!ctx->Shared->FallbackTex[tex][is_depth]) {
|
||||||
/* create fallback texture now */
|
/* create fallback texture now */
|
||||||
const GLsizei width = 1, height = 1;
|
const GLsizei width = 1, height = 1;
|
||||||
GLsizei depth = 1;
|
GLsizei depth = 1;
|
||||||
|
|
@ -1067,6 +1068,11 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
|
||||||
texObj->Sampler.Attrib.state.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
texObj->Sampler.Attrib.state.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
||||||
texObj->Sampler.Attrib.state.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
|
texObj->Sampler.Attrib.state.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
|
||||||
|
|
||||||
|
if (is_depth)
|
||||||
|
texFormat = st_ChooseTextureFormat(ctx, target,
|
||||||
|
GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT,
|
||||||
|
GL_NONE);
|
||||||
|
else
|
||||||
texFormat = st_ChooseTextureFormat(ctx, target,
|
texFormat = st_ChooseTextureFormat(ctx, target,
|
||||||
GL_RGBA, GL_RGBA,
|
GL_RGBA, GL_RGBA,
|
||||||
GL_UNSIGNED_BYTE);
|
GL_UNSIGNED_BYTE);
|
||||||
|
|
@ -1083,8 +1089,13 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
|
||||||
(dims > 1) ? height : 1,
|
(dims > 1) ? height : 1,
|
||||||
(dims > 2) ? depth : 1,
|
(dims > 2) ? depth : 1,
|
||||||
0, /* border */
|
0, /* border */
|
||||||
GL_RGBA, texFormat);
|
is_depth ? GL_DEPTH_COMPONENT : GL_RGBA, texFormat);
|
||||||
_mesa_update_texture_object_swizzle(ctx, texObj);
|
_mesa_update_texture_object_swizzle(ctx, texObj);
|
||||||
|
if (is_depth)
|
||||||
|
st_TexImage(ctx, dims, texImage,
|
||||||
|
GL_DEPTH_COMPONENT, GL_FLOAT, texel,
|
||||||
|
&ctx->DefaultPacking);
|
||||||
|
else
|
||||||
st_TexImage(ctx, dims, texImage,
|
st_TexImage(ctx, dims, texImage,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, texel,
|
GL_RGBA, GL_UNSIGNED_BYTE, texel,
|
||||||
&ctx->DefaultPacking);
|
&ctx->DefaultPacking);
|
||||||
|
|
@ -1094,13 +1105,13 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
|
||||||
assert(texObj->_BaseComplete);
|
assert(texObj->_BaseComplete);
|
||||||
assert(texObj->_MipmapComplete);
|
assert(texObj->_MipmapComplete);
|
||||||
|
|
||||||
ctx->Shared->FallbackTex[tex] = texObj;
|
ctx->Shared->FallbackTex[tex][is_depth] = texObj;
|
||||||
|
|
||||||
/* Complete the driver's operation in case another context will also
|
/* Complete the driver's operation in case another context will also
|
||||||
* use the same fallback texture. */
|
* use the same fallback texture. */
|
||||||
st_glFinish(ctx);
|
st_glFinish(ctx);
|
||||||
}
|
}
|
||||||
return ctx->Shared->FallbackTex[tex];
|
return ctx->Shared->FallbackTex[tex][is_depth];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ extern void
|
||||||
_mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj);
|
_mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj);
|
||||||
|
|
||||||
extern struct gl_texture_object *
|
extern struct gl_texture_object *
|
||||||
_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex);
|
_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex, bool is_depth);
|
||||||
|
|
||||||
extern GLuint
|
extern GLuint
|
||||||
_mesa_total_texture_memory(struct gl_context *ctx);
|
_mesa_total_texture_memory(struct gl_context *ctx);
|
||||||
|
|
|
||||||
|
|
@ -704,7 +704,7 @@ update_single_program_texture(struct gl_context *ctx, struct gl_program *prog,
|
||||||
* Mesa implements this by creating a hidden texture object with a pixel of
|
* Mesa implements this by creating a hidden texture object with a pixel of
|
||||||
* that value.
|
* that value.
|
||||||
*/
|
*/
|
||||||
texObj = _mesa_get_fallback_texture(ctx, target_index);
|
texObj = _mesa_get_fallback_texture(ctx, target_index, !!(prog->ShadowSamplers & BITFIELD_BIT(unit)));
|
||||||
assert(texObj);
|
assert(texObj);
|
||||||
|
|
||||||
return texObj;
|
return texObj;
|
||||||
|
|
@ -870,7 +870,7 @@ fix_missing_textures_for_atifs(struct gl_context *ctx,
|
||||||
|
|
||||||
if (!ctx->Texture.Unit[unit]._Current) {
|
if (!ctx->Texture.Unit[unit]._Current) {
|
||||||
struct gl_texture_object *texObj =
|
struct gl_texture_object *texObj =
|
||||||
_mesa_get_fallback_texture(ctx, target_index);
|
_mesa_get_fallback_texture(ctx, target_index, false);
|
||||||
_mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
|
_mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
|
||||||
BITSET_SET(enabled_texture_units, unit);
|
BITSET_SET(enabled_texture_units, unit);
|
||||||
ctx->Texture._MaxEnabledTexImageUnit =
|
ctx->Texture._MaxEnabledTexImageUnit =
|
||||||
|
|
|
||||||
|
|
@ -944,12 +944,14 @@ st_destroy_context(struct st_context *st)
|
||||||
* context.
|
* context.
|
||||||
*/
|
*/
|
||||||
for (unsigned i = 0; i < NUM_TEXTURE_TARGETS; i++) {
|
for (unsigned i = 0; i < NUM_TEXTURE_TARGETS; i++) {
|
||||||
|
for (unsigned j = 0; j < ARRAY_SIZE(ctx->Shared->FallbackTex[0]); j++) {
|
||||||
struct gl_texture_object *stObj =
|
struct gl_texture_object *stObj =
|
||||||
ctx->Shared->FallbackTex[i];
|
ctx->Shared->FallbackTex[i][j];
|
||||||
if (stObj) {
|
if (stObj) {
|
||||||
st_texture_release_context_sampler_view(st, stObj);
|
st_texture_release_context_sampler_view(st, stObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
st_release_program(st, &st->fp);
|
st_release_program(st, &st->fp);
|
||||||
st_release_program(st, &st->gp);
|
st_release_program(st, &st->gp);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue