Clear depth stencil textures on first use if the RDD requires it.

This commit is contained in:
Skyth 2025-12-10 13:24:43 +03:00
parent 8aa4a5207f
commit 83af078761
15 changed files with 343 additions and 34 deletions

View file

@ -1081,7 +1081,7 @@ RID RenderingDevice::texture_create(const TextureFormat &p_format, const Texture
if (driver->api_trait_get(RDD::API_TRAIT_TEXTURE_OUTPUTS_REQUIRE_CLEARS)) {
// Check if a clear for this texture must be performed the first time it's used if the driver requires explicit clears after initialization.
texture.pending_clear = !texture.has_initial_data && (format.usage_bits & (TEXTURE_USAGE_STORAGE_BIT | TEXTURE_USAGE_COLOR_ATTACHMENT_BIT));
texture.pending_clear = !texture.has_initial_data && (format.usage_bits & (TEXTURE_USAGE_STORAGE_BIT | TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
}
if ((format.usage_bits & (TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT))) {
@ -1964,16 +1964,20 @@ void RenderingDevice::_texture_check_pending_clear(RID p_texture_rid, Texture *p
}
if (p_texture != nullptr && clear) {
_texture_clear(p_texture_rid, p_texture, Color(), 0, p_texture->mipmaps, 0, p_texture->layers);
if (p_texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
_texture_clear_depth_stencil(p_texture_rid, p_texture, 0.0f, 0, 0, p_texture->mipmaps, 0, p_texture->layers);
} else {
_texture_clear_color(p_texture_rid, p_texture, Color(), 0, p_texture->mipmaps, 0, p_texture->layers);
}
p_texture->pending_clear = false;
}
}
void RenderingDevice::_texture_clear(RID p_texture_rid, Texture *p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers) {
void RenderingDevice::_texture_clear_color(RID p_texture_rid, Texture *p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers) {
_check_transfer_worker_texture(p_texture);
RDD::TextureSubresourceRange range;
range.aspect = p_texture->read_aspect_flags;
range.aspect = RDD::TEXTURE_ASPECT_COLOR_BIT;
range.base_mipmap = p_texture->base_mipmap + p_base_mipmap;
range.mipmap_count = p_mipmaps;
range.base_layer = p_texture->base_layer + p_base_layer;
@ -1987,7 +1991,33 @@ void RenderingDevice::_texture_clear(RID p_texture_rid, Texture *p_texture, cons
draw_graph.add_synchronization();
}
draw_graph.add_texture_clear(p_texture->driver_id, p_texture->draw_tracker, p_color, range);
draw_graph.add_texture_clear_color(p_texture->driver_id, p_texture->draw_tracker, p_color, range);
}
void RenderingDevice::_texture_clear_depth_stencil(RID p_texture_rid, Texture *p_texture, float p_depth, uint8_t p_stencil, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers) {
_check_transfer_worker_texture(p_texture);
RDD::TextureSubresourceRange range;
if (format_has_depth(p_texture->format)) {
range.aspect.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
}
if (format_has_stencil(p_texture->format)) {
range.aspect.set_flag(RDD::TEXTURE_ASPECT_STENCIL_BIT);
}
range.base_mipmap = p_texture->base_mipmap + p_base_mipmap;
range.mipmap_count = p_mipmaps;
range.base_layer = p_texture->base_layer + p_base_layer;
range.layer_count = p_layers;
// Indicate the texture will get modified for the shared texture fallback.
_texture_update_shared_fallback(p_texture_rid, p_texture, true);
if (_texture_make_mutable(p_texture, p_texture_rid)) {
// The texture must be mutable to be used as a clear destination.
draw_graph.add_synchronization();
}
draw_graph.add_texture_clear_depth_stencil(p_texture->driver_id, p_texture->draw_tracker, p_depth, p_stencil, range);
}
Vector<uint8_t> RenderingDevice::texture_get_data(RID p_texture, uint32_t p_layer) {
@ -2453,7 +2483,7 @@ Error RenderingDevice::texture_clear(RID p_texture, const Color &p_color, uint32
// Clear the texture if the driver requires it during its first use.
_texture_check_pending_clear(p_texture, src_tex);
_texture_clear(p_texture, src_tex, p_color, p_base_mipmap, p_mipmaps, p_base_layer, p_layers);
_texture_clear_color(p_texture, src_tex, p_color, p_base_mipmap, p_mipmaps, p_base_layer, p_layers);
return OK;
}