Clear depth stencil textures on first use if the RDD requires it.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -403,7 +403,8 @@ public:
|
||||
void _texture_copy_shared(RID p_src_texture_rid, Texture *p_src_texture, RID p_dst_texture_rid, Texture *p_dst_texture);
|
||||
void _texture_create_reinterpret_buffer(Texture *p_texture);
|
||||
void _texture_check_pending_clear(RID p_texture_rid, Texture *p_texture);
|
||||
void _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 _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);
|
||||
void _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);
|
||||
uint32_t _texture_vrs_method_to_usage_bits() const;
|
||||
|
||||
struct TextureGetDataRequest {
|
||||
|
||||
@@ -821,6 +821,21 @@ uint32_t RenderingDeviceCommons::get_image_required_mipmaps(uint32_t p_width, ui
|
||||
return mipmaps;
|
||||
}
|
||||
|
||||
bool RenderingDeviceCommons::format_has_depth(DataFormat p_format) {
|
||||
switch (p_format) {
|
||||
case DATA_FORMAT_D16_UNORM:
|
||||
case DATA_FORMAT_X8_D24_UNORM_PACK32:
|
||||
case DATA_FORMAT_D32_SFLOAT:
|
||||
case DATA_FORMAT_D16_UNORM_S8_UINT:
|
||||
case DATA_FORMAT_D24_UNORM_S8_UINT:
|
||||
case DATA_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
return true;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RenderingDeviceCommons::format_has_stencil(DataFormat p_format) {
|
||||
switch (p_format) {
|
||||
case DATA_FORMAT_S8_UINT:
|
||||
|
||||
@@ -1012,6 +1012,7 @@ protected:
|
||||
static uint32_t get_compressed_image_format_pixel_rshift(DataFormat p_format);
|
||||
static uint32_t get_image_format_required_size(DataFormat p_format, uint32_t p_width, uint32_t p_height, uint32_t p_depth, uint32_t p_mipmaps, uint32_t *r_blockw = nullptr, uint32_t *r_blockh = nullptr, uint32_t *r_depth = nullptr);
|
||||
static uint32_t get_image_required_mipmaps(uint32_t p_width, uint32_t p_height, uint32_t p_depth);
|
||||
static bool format_has_depth(DataFormat p_format);
|
||||
static bool format_has_stencil(DataFormat p_format);
|
||||
static uint32_t format_get_plane_count(DataFormat p_format);
|
||||
|
||||
|
||||
@@ -556,6 +556,7 @@ public:
|
||||
virtual void command_copy_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView<TextureCopyRegion> p_regions) = 0;
|
||||
virtual void command_resolve_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, uint32_t p_src_layer, uint32_t p_src_mipmap, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, uint32_t p_dst_layer, uint32_t p_dst_mipmap) = 0;
|
||||
virtual void command_clear_color_texture(CommandBufferID p_cmd_buffer, TextureID p_texture, TextureLayout p_texture_layout, const Color &p_color, const TextureSubresourceRange &p_subresources) = 0;
|
||||
virtual void command_clear_depth_stencil_texture(CommandBufferID p_cmd_buffer, TextureID p_texture, TextureLayout p_texture_layout, float p_depth, uint8_t p_stencil, const TextureSubresourceRange &p_subresources) = 0;
|
||||
|
||||
virtual void command_copy_buffer_to_texture(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView<BufferTextureCopyRegion> p_regions) = 0;
|
||||
virtual void command_copy_texture_to_buffer(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, BufferID p_dst_buffer, VectorView<BufferTextureCopyRegion> p_regions) = 0;
|
||||
|
||||
@@ -1095,9 +1095,13 @@ void RenderingDeviceGraph::_run_render_commands(int32_t p_level, const RecordedC
|
||||
driver->command_end_render_pass(r_command_buffer);
|
||||
}
|
||||
} break;
|
||||
case RecordedCommand::TYPE_TEXTURE_CLEAR: {
|
||||
const RecordedTextureClearCommand *texture_clear_command = reinterpret_cast<const RecordedTextureClearCommand *>(command);
|
||||
driver->command_clear_color_texture(r_command_buffer, texture_clear_command->texture, RDD::TEXTURE_LAYOUT_COPY_DST_OPTIMAL, texture_clear_command->color, texture_clear_command->range);
|
||||
case RecordedCommand::TYPE_TEXTURE_CLEAR_COLOR: {
|
||||
const RecordedTextureClearColorCommand *texture_clear_color_command = reinterpret_cast<const RecordedTextureClearColorCommand *>(command);
|
||||
driver->command_clear_color_texture(r_command_buffer, texture_clear_color_command->texture, RDD::TEXTURE_LAYOUT_COPY_DST_OPTIMAL, texture_clear_color_command->color, texture_clear_color_command->range);
|
||||
} break;
|
||||
case RecordedCommand::TYPE_TEXTURE_CLEAR_DEPTH_STENCIL: {
|
||||
const RecordedTextureClearDepthStencilCommand *texture_clear_depth_stencil_command = reinterpret_cast<const RecordedTextureClearDepthStencilCommand *>(command);
|
||||
driver->command_clear_depth_stencil_texture(r_command_buffer, texture_clear_depth_stencil_command->texture, RDD::TEXTURE_LAYOUT_COPY_DST_OPTIMAL, texture_clear_depth_stencil_command->depth, texture_clear_depth_stencil_command->stencil, texture_clear_depth_stencil_command->range);
|
||||
} break;
|
||||
case RecordedCommand::TYPE_TEXTURE_COPY: {
|
||||
const RecordedTextureCopyCommand *texture_copy_command = reinterpret_cast<const RecordedTextureCopyCommand *>(command);
|
||||
@@ -1179,7 +1183,8 @@ void RenderingDeviceGraph::_run_label_command_change(RDD::CommandBufferID p_comm
|
||||
case RecordedCommand::TYPE_BUFFER_COPY:
|
||||
case RecordedCommand::TYPE_BUFFER_GET_DATA:
|
||||
case RecordedCommand::TYPE_BUFFER_UPDATE:
|
||||
case RecordedCommand::TYPE_TEXTURE_CLEAR:
|
||||
case RecordedCommand::TYPE_TEXTURE_CLEAR_COLOR:
|
||||
case RecordedCommand::TYPE_TEXTURE_CLEAR_DEPTH_STENCIL:
|
||||
case RecordedCommand::TYPE_TEXTURE_COPY:
|
||||
case RecordedCommand::TYPE_TEXTURE_GET_DATA:
|
||||
case RecordedCommand::TYPE_TEXTURE_RESOLVE:
|
||||
@@ -1379,9 +1384,13 @@ void RenderingDeviceGraph::_print_render_commands(const RecordedCommandSort *p_s
|
||||
const RecordedDrawListCommand *draw_list_command = reinterpret_cast<const RecordedDrawListCommand *>(command);
|
||||
print_line(command_index, "LEVEL", command_level, "DRAW LIST SIZE", draw_list_command->instruction_data_size);
|
||||
} break;
|
||||
case RecordedCommand::TYPE_TEXTURE_CLEAR: {
|
||||
const RecordedTextureClearCommand *texture_clear_command = reinterpret_cast<const RecordedTextureClearCommand *>(command);
|
||||
print_line(command_index, "LEVEL", command_level, "TEXTURE CLEAR", itos(texture_clear_command->texture.id), "COLOR", texture_clear_command->color);
|
||||
case RecordedCommand::TYPE_TEXTURE_CLEAR_COLOR: {
|
||||
const RecordedTextureClearColorCommand *texture_clear_color_command = reinterpret_cast<const RecordedTextureClearColorCommand *>(command);
|
||||
print_line(command_index, "LEVEL", command_level, "TEXTURE CLEAR COLOR", itos(texture_clear_color_command->texture.id), "COLOR", texture_clear_color_command->color);
|
||||
} break;
|
||||
case RecordedCommand::TYPE_TEXTURE_CLEAR_DEPTH_STENCIL: {
|
||||
const RecordedTextureClearDepthStencilCommand *texture_clear_depth_stencil_command = reinterpret_cast<const RecordedTextureClearDepthStencilCommand *>(command);
|
||||
print_line(command_index, "LEVEL", command_level, "TEXTURE CLEAR DEPTH STENCIL", itos(texture_clear_depth_stencil_command->texture.id), "DEPTH", rtos(texture_clear_depth_stencil_command->depth), "STENCIL", itos(texture_clear_depth_stencil_command->stencil));
|
||||
} break;
|
||||
case RecordedCommand::TYPE_TEXTURE_COPY: {
|
||||
const RecordedTextureCopyCommand *texture_copy_command = reinterpret_cast<const RecordedTextureCopyCommand *>(command);
|
||||
@@ -2087,12 +2096,12 @@ void RenderingDeviceGraph::add_draw_list_end() {
|
||||
_add_command_to_graph(draw_instruction_list.command_trackers.ptr(), draw_instruction_list.command_tracker_usages.ptr(), draw_instruction_list.command_trackers.size(), command_index, command);
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_texture_clear(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, const Color &p_color, const RDD::TextureSubresourceRange &p_range) {
|
||||
void RenderingDeviceGraph::add_texture_clear_color(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, const Color &p_color, const RDD::TextureSubresourceRange &p_range) {
|
||||
DEV_ASSERT(p_dst_tracker != nullptr);
|
||||
|
||||
int32_t command_index;
|
||||
RecordedTextureClearCommand *command = static_cast<RecordedTextureClearCommand *>(_allocate_command(sizeof(RecordedTextureClearCommand), command_index));
|
||||
command->type = RecordedCommand::TYPE_TEXTURE_CLEAR;
|
||||
RecordedTextureClearColorCommand *command = static_cast<RecordedTextureClearColorCommand *>(_allocate_command(sizeof(RecordedTextureClearColorCommand), command_index));
|
||||
command->type = RecordedCommand::TYPE_TEXTURE_CLEAR_COLOR;
|
||||
command->texture = p_dst;
|
||||
command->color = p_color;
|
||||
command->range = p_range;
|
||||
@@ -2116,6 +2125,31 @@ void RenderingDeviceGraph::add_texture_clear(RDD::TextureID p_dst, ResourceTrack
|
||||
_add_command_to_graph(&p_dst_tracker, &usage, 1, command_index, command);
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_texture_clear_depth_stencil(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, float p_depth, uint8_t p_stencil, const RDD::TextureSubresourceRange &p_range) {
|
||||
DEV_ASSERT(p_dst_tracker != nullptr);
|
||||
|
||||
int32_t command_index;
|
||||
RecordedTextureClearDepthStencilCommand *command = static_cast<RecordedTextureClearDepthStencilCommand *>(_allocate_command(sizeof(RecordedTextureClearDepthStencilCommand), command_index));
|
||||
command->type = RecordedCommand::TYPE_TEXTURE_CLEAR_DEPTH_STENCIL;
|
||||
command->texture = p_dst;
|
||||
command->depth = p_depth;
|
||||
command->stencil = p_stencil;
|
||||
command->range = p_range;
|
||||
|
||||
ResourceUsage usage;
|
||||
if (driver_clears_with_copy_engine) {
|
||||
command->self_stages = RDD::PIPELINE_STAGE_COPY_BIT;
|
||||
usage = RESOURCE_USAGE_COPY_TO;
|
||||
} else {
|
||||
// If the driver is uncapable of using the copy engine for clearing the image (e.g. D3D12), we must transition the
|
||||
// resource to a depth stencil as that's the only way it can perform the operation.
|
||||
command->self_stages = RDD::PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | RDD::PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
usage = RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE;
|
||||
}
|
||||
|
||||
_add_command_to_graph(&p_dst_tracker, &usage, 1, command_index, command);
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_texture_copy(RDD::TextureID p_src, ResourceTracker *p_src_tracker, RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, VectorView<RDD::TextureCopyRegion> p_texture_copy_regions) {
|
||||
DEV_ASSERT(p_src_tracker != nullptr);
|
||||
DEV_ASSERT(p_dst_tracker != nullptr);
|
||||
@@ -2328,7 +2362,8 @@ void RenderingDeviceGraph::end(bool p_reorder_commands, bool p_full_barriers, RD
|
||||
1, // TYPE_BUFFER_UPDATE
|
||||
4, // TYPE_COMPUTE_LIST
|
||||
3, // TYPE_DRAW_LIST
|
||||
2, // TYPE_TEXTURE_CLEAR
|
||||
2, // TYPE_TEXTURE_CLEAR_COLOR
|
||||
2, // TYPE_TEXTURE_CLEAR_DEPTH_STENCIL
|
||||
2, // TYPE_TEXTURE_COPY
|
||||
2, // TYPE_TEXTURE_GET_DATA
|
||||
2, // TYPE_TEXTURE_RESOLVE
|
||||
|
||||
@@ -92,7 +92,8 @@ public:
|
||||
TYPE_BUFFER_UPDATE,
|
||||
TYPE_COMPUTE_LIST,
|
||||
TYPE_DRAW_LIST,
|
||||
TYPE_TEXTURE_CLEAR,
|
||||
TYPE_TEXTURE_CLEAR_COLOR,
|
||||
TYPE_TEXTURE_CLEAR_DEPTH_STENCIL,
|
||||
TYPE_TEXTURE_COPY,
|
||||
TYPE_TEXTURE_GET_DATA,
|
||||
TYPE_TEXTURE_RESOLVE,
|
||||
@@ -414,12 +415,19 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
struct RecordedTextureClearCommand : RecordedCommand {
|
||||
struct RecordedTextureClearColorCommand : RecordedCommand {
|
||||
RDD::TextureID texture;
|
||||
RDD::TextureSubresourceRange range;
|
||||
Color color;
|
||||
};
|
||||
|
||||
struct RecordedTextureClearDepthStencilCommand : RecordedCommand {
|
||||
RDD::TextureID texture;
|
||||
RDD::TextureSubresourceRange range;
|
||||
float depth;
|
||||
uint8_t stencil;
|
||||
};
|
||||
|
||||
struct RecordedTextureCopyCommand : RecordedCommand {
|
||||
RDD::TextureID from_texture;
|
||||
RDD::TextureID to_texture;
|
||||
@@ -813,7 +821,8 @@ public:
|
||||
void add_draw_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage);
|
||||
void add_draw_list_usages(VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);
|
||||
void add_draw_list_end();
|
||||
void add_texture_clear(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, const Color &p_color, const RDD::TextureSubresourceRange &p_range);
|
||||
void add_texture_clear_color(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, const Color &p_color, const RDD::TextureSubresourceRange &p_range);
|
||||
void add_texture_clear_depth_stencil(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, float p_depth, uint8_t p_stencil, const RDD::TextureSubresourceRange &p_range);
|
||||
void add_texture_copy(RDD::TextureID p_src, ResourceTracker *p_src_tracker, RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, VectorView<RDD::TextureCopyRegion> p_texture_copy_regions);
|
||||
void add_texture_get_data(RDD::TextureID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, VectorView<RDD::BufferTextureCopyRegion> p_buffer_texture_copy_regions, ResourceTracker *p_dst_tracker = nullptr);
|
||||
void add_texture_resolve(RDD::TextureID p_src, ResourceTracker *p_src_tracker, RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, uint32_t p_src_layer, uint32_t p_src_mipmap, uint32_t p_dst_layer, uint32_t p_dst_mipmap);
|
||||
|
||||
Reference in New Issue
Block a user