diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index 2c9ebb23c5..eade817c91 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -2562,6 +2562,7 @@ void RenderingDeviceDriverD3D12::command_pool_free(CommandPoolID p_cmd_pool) { resource_descriptor_heap_pool.free(cmd_buf_info->uav_alloc); rtv_descriptor_heap_pool.free(cmd_buf_info->rtv_alloc); + dsv_descriptor_heap_pool.free(cmd_buf_info->dsv_alloc); VersatileResource::free(resources_allocator, cmd_buf_info); } @@ -2606,6 +2607,7 @@ RDD::CommandBufferID RenderingDeviceDriverD3D12::command_buffer_create(CommandPo CPUDescriptorHeapPool::Allocation uav_alloc; CPUDescriptorHeapPool::Allocation rtv_alloc; + CPUDescriptorHeapPool::Allocation dsv_alloc; if (list_type != D3D12_COMMAND_LIST_TYPE_COPY) { Error err = resource_descriptor_heap_pool.allocate(1, device.Get(), uav_alloc); @@ -2616,6 +2618,13 @@ RDD::CommandBufferID RenderingDeviceDriverD3D12::command_buffer_create(CommandPo resource_descriptor_heap_pool.free(uav_alloc); ERR_FAIL_V(CommandBufferID()); } + + err = dsv_descriptor_heap_pool.allocate(1, device.Get(), dsv_alloc); + if (unlikely(err != OK)) { + resource_descriptor_heap_pool.free(uav_alloc); + rtv_descriptor_heap_pool.free(rtv_alloc); + ERR_FAIL_V(CommandBufferID()); + } } // Bookkeep @@ -2626,6 +2635,7 @@ RDD::CommandBufferID RenderingDeviceDriverD3D12::command_buffer_create(CommandPo cmd_buf_info->uav_alloc = uav_alloc; cmd_buf_info->rtv_alloc = rtv_alloc; + cmd_buf_info->dsv_alloc = dsv_alloc; // Add this command buffer to the command pool's list of command buffers. command_pool->command_buffers.add(&cmd_buf_info->command_buffer_info_elem); @@ -3033,7 +3043,7 @@ D3D12_UNORDERED_ACCESS_VIEW_DESC RenderingDeviceDriverD3D12::_make_ranged_uav_fo return uav_desc; } -D3D12_DEPTH_STENCIL_VIEW_DESC RenderingDeviceDriverD3D12::_make_dsv_for_texture(const TextureInfo *p_texture_info) { +D3D12_DEPTH_STENCIL_VIEW_DESC RenderingDeviceDriverD3D12::_make_dsv_for_texture(const TextureInfo *p_texture_info, uint32_t p_mipmap_offset, uint32_t p_layer_offset, uint32_t p_layers, bool p_add_bases) { D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc = {}; dsv_desc.Format = RD_TO_D3D12_FORMAT[p_texture_info->format].dsv_format; dsv_desc.Flags = D3D12_DSV_FLAG_NONE; @@ -3041,23 +3051,23 @@ D3D12_DEPTH_STENCIL_VIEW_DESC RenderingDeviceDriverD3D12::_make_dsv_for_texture( switch (p_texture_info->view_descs.srv.ViewDimension) { case D3D12_SRV_DIMENSION_TEXTURE1D: { dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE1D; - dsv_desc.Texture1D.MipSlice = p_texture_info->base_mip; + dsv_desc.Texture1D.MipSlice = p_texture_info->base_mip + p_mipmap_offset; } break; case D3D12_SRV_DIMENSION_TEXTURE1DARRAY: { dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE1DARRAY; - dsv_desc.Texture1DArray.MipSlice = p_texture_info->base_mip; - dsv_desc.Texture1DArray.FirstArraySlice = p_texture_info->base_layer; - dsv_desc.Texture1DArray.ArraySize = p_texture_info->view_descs.srv.Texture1DArray.ArraySize; + dsv_desc.Texture1DArray.MipSlice = (p_add_bases ? p_texture_info->base_mip : 0) + p_mipmap_offset; + dsv_desc.Texture1DArray.FirstArraySlice = (p_add_bases ? p_texture_info->base_layer : 0) + p_layer_offset; + dsv_desc.Texture1DArray.ArraySize = p_layers == UINT32_MAX ? p_texture_info->view_descs.srv.Texture1DArray.ArraySize : p_layers; } break; case D3D12_SRV_DIMENSION_TEXTURE2D: { dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; - dsv_desc.Texture2D.MipSlice = p_texture_info->view_descs.srv.Texture2D.MostDetailedMip; + dsv_desc.Texture2D.MipSlice = (p_add_bases ? p_texture_info->base_mip : 0) + p_mipmap_offset; } break; case D3D12_SRV_DIMENSION_TEXTURE2DARRAY: { dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY; - dsv_desc.Texture2DArray.MipSlice = p_texture_info->base_mip; - dsv_desc.Texture2DArray.FirstArraySlice = p_texture_info->base_layer; - dsv_desc.Texture2DArray.ArraySize = p_texture_info->view_descs.srv.Texture2DArray.ArraySize; + dsv_desc.Texture2DArray.MipSlice = (p_add_bases ? p_texture_info->base_mip : 0) + p_mipmap_offset; + dsv_desc.Texture2DArray.FirstArraySlice = (p_add_bases ? p_texture_info->base_layer : 0) + p_layer_offset; + dsv_desc.Texture2DArray.ArraySize = p_layers == UINT32_MAX ? p_texture_info->view_descs.srv.Texture2DArray.ArraySize : p_layers; } break; case D3D12_SRV_DIMENSION_TEXTURE2DMS: { dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMS; @@ -3065,8 +3075,20 @@ D3D12_DEPTH_STENCIL_VIEW_DESC RenderingDeviceDriverD3D12::_make_dsv_for_texture( } break; case D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY: { dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY; - dsv_desc.Texture2DMSArray.FirstArraySlice = p_texture_info->base_layer; - dsv_desc.Texture2DMSArray.ArraySize = p_texture_info->view_descs.srv.Texture2DMSArray.ArraySize; + dsv_desc.Texture2DMSArray.FirstArraySlice = (p_add_bases ? p_texture_info->base_layer : 0) + p_layer_offset; + dsv_desc.Texture2DMSArray.ArraySize = p_layers == UINT32_MAX ? p_texture_info->view_descs.srv.Texture2DMSArray.ArraySize : p_layers; + } break; + case D3D12_SRV_DIMENSION_TEXTURECUBE: { + dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY; + dsv_desc.Texture2DArray.MipSlice = (p_add_bases ? p_texture_info->base_mip : 0) + p_mipmap_offset; + dsv_desc.Texture2DArray.FirstArraySlice = (p_add_bases ? p_texture_info->base_layer : 0) + p_layer_offset; + dsv_desc.Texture2DArray.ArraySize = p_layers == UINT32_MAX ? 6 : p_layers; + } break; + case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY: { + dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY; + dsv_desc.Texture2DArray.MipSlice = (p_add_bases ? p_texture_info->base_mip : 0) + p_mipmap_offset; + dsv_desc.Texture2DArray.FirstArraySlice = (p_add_bases ? p_texture_info->base_layer : 0) + p_layer_offset; + dsv_desc.Texture2DArray.ArraySize = p_layers == UINT32_MAX ? (p_texture_info->view_descs.srv.TextureCubeArray.NumCubes * 6) : p_layers; } break; default: { DEV_ASSERT(false); @@ -3139,7 +3161,7 @@ RDD::FramebufferID RenderingDeviceDriverD3D12::_framebuffer_create(RenderPassID fb_info->attachments.push_back(p_attachments[i]); color_idx++; } else if ((tex_info->desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)) { - D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc = _make_dsv_for_texture(tex_info); + D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc = _make_dsv_for_texture(tex_info, 0, 0, UINT32_MAX); device->CreateDepthStencilView(tex_info->resource, &dsv_desc, get_cpu_handle(fb_info->dsv_alloc.cpu_handle, depth_stencil_idx, dsv_descriptor_heap_pool.increment_size)); fb_info->attachments_handle_inds[i] = depth_stencil_idx; @@ -3969,6 +3991,59 @@ void RenderingDeviceDriverD3D12::command_clear_color_texture(CommandBufferID p_c } } +void RenderingDeviceDriverD3D12::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) { + CommandBufferInfo *cmd_buf_info = (CommandBufferInfo *)p_cmd_buffer.id; + TextureInfo *tex_info = (TextureInfo *)p_texture.id; + if (tex_info->main_texture) { + tex_info = tex_info->main_texture; + } + + if ((tex_info->desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)) { + if (!barrier_capabilities.enhanced_barriers_supported) { + uint32_t num_planes = format_get_plane_count(tex_info->format); + + for (uint32_t i = 0; i < p_subresources.layer_count; i++) { + for (uint32_t j = 0; j < p_subresources.mipmap_count; j++) { + UINT subresource = D3D12CalcSubresource( + p_subresources.base_mipmap + j, + p_subresources.base_layer + i, + 0, + tex_info->desc.MipLevels, + tex_info->desc.ArraySize()); + _resource_transition_batch(cmd_buf_info, tex_info, subresource, num_planes, D3D12_RESOURCE_STATE_DEPTH_WRITE); + } + } + _resource_transitions_flush(cmd_buf_info); + } + + D3D12_CLEAR_FLAGS clear_flags = {}; + if (p_subresources.aspect.has_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT)) { + clear_flags |= D3D12_CLEAR_FLAG_DEPTH; + } + if (p_subresources.aspect.has_flag(RDD::TEXTURE_ASPECT_STENCIL_BIT)) { + clear_flags |= D3D12_CLEAR_FLAG_STENCIL; + } + + for (uint32_t i = 0; i < p_subresources.mipmap_count; i++) { + D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc = _make_dsv_for_texture(tex_info, p_subresources.base_mipmap + i, p_subresources.base_layer, p_subresources.layer_count, false); + device->CreateDepthStencilView( + tex_info->resource, + &dsv_desc, + cmd_buf_info->dsv_alloc.cpu_handle); + + cmd_buf_info->cmd_list->ClearDepthStencilView( + cmd_buf_info->dsv_alloc.cpu_handle, + clear_flags, + p_depth, + p_stencil, + 0, + nullptr); + } + } else { + ERR_FAIL_MSG("Cannot clear depth because the texture was not created with the depth attachment bit. You'll need to update its contents through another method."); + } +} + void RenderingDeviceDriverD3D12::command_copy_buffer_to_texture(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView p_regions) { CommandBufferInfo *cmd_buf_info = (CommandBufferInfo *)p_cmd_buffer.id; BufferInfo *buf_info = (BufferInfo *)p_src_buffer.id; diff --git a/drivers/d3d12/rendering_device_driver_d3d12.h b/drivers/d3d12/rendering_device_driver_d3d12.h index eecd483405..d88ebb7f41 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.h +++ b/drivers/d3d12/rendering_device_driver_d3d12.h @@ -508,6 +508,7 @@ private: CPUDescriptorHeapPool::Allocation uav_alloc; CPUDescriptorHeapPool::Allocation rtv_alloc; + CPUDescriptorHeapPool::Allocation dsv_alloc; }; public: @@ -564,7 +565,7 @@ private: D3D12_RENDER_TARGET_VIEW_DESC _make_rtv_for_texture(const TextureInfo *p_texture_info, uint32_t p_mipmap_offset, uint32_t p_layer_offset, uint32_t p_layers, bool p_add_bases = true); D3D12_UNORDERED_ACCESS_VIEW_DESC _make_ranged_uav_for_texture(const TextureInfo *p_texture_info, uint32_t p_mipmap_offset, uint32_t p_layer_offset, uint32_t p_layers, bool p_add_bases = true); - D3D12_DEPTH_STENCIL_VIEW_DESC _make_dsv_for_texture(const TextureInfo *p_texture_info); + D3D12_DEPTH_STENCIL_VIEW_DESC _make_dsv_for_texture(const TextureInfo *p_texture_info, uint32_t p_mipmap_offset, uint32_t p_layer_offset, uint32_t p_layers, bool p_add_bases = true); FramebufferID _framebuffer_create(RenderPassID p_render_pass, VectorView p_attachments, uint32_t p_width, uint32_t p_height, bool p_is_screen); @@ -697,6 +698,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 p_regions) override final; 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) override final; 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) override final; + 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) override final; public: 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 p_regions) override final; diff --git a/drivers/metal/metal_objects.h b/drivers/metal/metal_objects.h index a93cc64ee1..8f6e3222cd 100644 --- a/drivers/metal/metal_objects.h +++ b/drivers/metal/metal_objects.h @@ -694,6 +694,7 @@ private: public: void resolve_texture(RDD::TextureID p_src_texture, RDD::TextureLayout p_src_texture_layout, uint32_t p_src_layer, uint32_t p_src_mipmap, RDD::TextureID p_dst_texture, RDD::TextureLayout p_dst_texture_layout, uint32_t p_dst_layer, uint32_t p_dst_mipmap); void clear_color_texture(RDD::TextureID p_texture, RDD::TextureLayout p_texture_layout, const Color &p_color, const RDD::TextureSubresourceRange &p_subresources); + void clear_depth_stencil_texture(RDD::TextureID p_texture, RDD::TextureLayout p_texture_layout, float p_depth, uint8_t p_stencil, const RDD::TextureSubresourceRange &p_subresources); void clear_buffer(RDD::BufferID p_buffer, uint64_t p_offset, uint64_t p_size); void copy_buffer(RDD::BufferID p_src_buffer, RDD::BufferID p_dst_buffer, VectorView p_regions); void copy_texture(RDD::TextureID p_src_texture, RDD::TextureID p_dst_texture, VectorView p_regions); diff --git a/drivers/metal/metal_objects.mm b/drivers/metal/metal_objects.mm index 4dc17b15fa..e65d915484 100644 --- a/drivers/metal/metal_objects.mm +++ b/drivers/metal/metal_objects.mm @@ -332,6 +332,120 @@ void MDCommandBuffer::clear_color_texture(RDD::TextureID p_texture, RDD::Texture } } +void MDCommandBuffer::clear_depth_stencil_texture(RDD::TextureID p_texture, RDD::TextureLayout p_texture_layout, float p_depth, uint8_t p_stencil, const RDD::TextureSubresourceRange &p_subresources) { + id src_tex = rid::get(p_texture); + + if (src_tex.parentTexture) { + // Clear via the parent texture rather than the view. + src_tex = src_tex.parentTexture; + } + + PixelFormats &pf = device_driver->get_pixel_formats(); + + bool is_depth_format = pf.isDepthFormat(src_tex.pixelFormat); + bool is_stencil_format = pf.isStencilFormat(src_tex.pixelFormat); + + if (!is_depth_format && !is_stencil_format) { + ERR_FAIL_MSG("invalid: color texture format"); + } + + bool clear_depth = is_depth_format && p_subresources.aspect.has_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT); + bool clear_stencil = is_stencil_format && p_subresources.aspect.has_flag(RDD::TEXTURE_ASPECT_STENCIL_BIT); + + if (clear_depth || clear_stencil) { + MTLRenderPassDescriptor *desc = MTLRenderPassDescriptor.renderPassDescriptor; + + MTLRenderPassDepthAttachmentDescriptor *daDesc = desc.depthAttachment; + if (clear_depth) { + daDesc.texture = src_tex; + daDesc.loadAction = MTLLoadActionClear; + daDesc.storeAction = MTLStoreActionStore; + daDesc.clearDepth = p_depth; + } + + MTLRenderPassStencilAttachmentDescriptor *saDesc = desc.stencilAttachment; + if (clear_stencil) { + saDesc.texture = src_tex; + saDesc.loadAction = MTLLoadActionClear; + saDesc.storeAction = MTLStoreActionStore; + saDesc.clearStencil = p_stencil; + } + + // Extract the mipmap levels that are to be updated. + uint32_t mipLvlStart = p_subresources.base_mipmap; + uint32_t mipLvlCnt = p_subresources.mipmap_count; + uint32_t mipLvlEnd = mipLvlStart + mipLvlCnt; + + uint32_t levelCount = src_tex.mipmapLevelCount; + + // Extract the cube or array layers (slices) that are to be updated. + bool is3D = src_tex.textureType == MTLTextureType3D; + uint32_t layerStart = is3D ? 0 : p_subresources.base_layer; + uint32_t layerCnt = p_subresources.layer_count; + uint32_t layerEnd = layerStart + layerCnt; + + MetalFeatures const &features = device_driver->get_device_properties().features; + + // Iterate across mipmap levels and layers, and perform and empty render to clear each. + for (uint32_t mipLvl = mipLvlStart; mipLvl < mipLvlEnd; mipLvl++) { + ERR_FAIL_INDEX_MSG(mipLvl, levelCount, "mip level out of range"); + + if (clear_depth) { + daDesc.level = mipLvl; + } + if (clear_stencil) { + saDesc.level = mipLvl; + } + + // If a 3D image, we need to get the depth for each level. + if (is3D) { + layerCnt = mipmapLevelSizeFromTexture(src_tex, mipLvl).depth; + layerEnd = layerStart + layerCnt; + } + + if ((features.layeredRendering && src_tex.sampleCount == 1) || features.multisampleLayeredRendering) { + // We can clear all layers at once. + if (is3D) { + if (clear_depth) { + daDesc.depthPlane = layerStart; + } + if (clear_stencil) { + saDesc.depthPlane = layerStart; + } + } else { + if (clear_depth) { + daDesc.slice = layerStart; + } + if (clear_stencil) { + saDesc.slice = layerStart; + } + } + desc.renderTargetArrayLength = layerCnt; + encodeRenderCommandEncoderWithDescriptor(desc, @"Clear Image"); + } else { + for (uint32_t layer = layerStart; layer < layerEnd; layer++) { + if (is3D) { + if (clear_depth) { + daDesc.depthPlane = layer; + } + if (clear_stencil) { + saDesc.depthPlane = layer; + } + } else { + if (clear_depth) { + daDesc.slice = layer; + } + if (clear_stencil) { + saDesc.slice = layer; + } + } + encodeRenderCommandEncoderWithDescriptor(desc, @"Clear Image"); + } + } + } + } +} + void MDCommandBuffer::clear_buffer(RDD::BufferID p_buffer, uint64_t p_offset, uint64_t p_size) { id blit_enc = _ensure_blit_encoder(); const RDM::BufferInfo *buffer = (const RDM::BufferInfo *)p_buffer.id; diff --git a/drivers/metal/rendering_device_driver_metal.h b/drivers/metal/rendering_device_driver_metal.h index 77968babe2..c5ca6e9cb6 100644 --- a/drivers/metal/rendering_device_driver_metal.h +++ b/drivers/metal/rendering_device_driver_metal.h @@ -346,6 +346,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 p_regions) override final; 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) override final; 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) override final; + 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) override final; 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 p_regions) override final; 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 p_regions) override final; diff --git a/drivers/metal/rendering_device_driver_metal.mm b/drivers/metal/rendering_device_driver_metal.mm index a4933c370c..2b5dff7434 100644 --- a/drivers/metal/rendering_device_driver_metal.mm +++ b/drivers/metal/rendering_device_driver_metal.mm @@ -1543,6 +1543,11 @@ void RenderingDeviceDriverMetal::command_clear_color_texture(CommandBufferID p_c cb->clear_color_texture(p_texture, p_texture_layout, p_color, p_subresources); } +void RenderingDeviceDriverMetal::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) { + MDCommandBuffer *cb = (MDCommandBuffer *)(p_cmd_buffer.id); + cb->clear_depth_stencil_texture(p_texture, p_texture_layout, p_depth, p_stencil, p_subresources); +} + void RenderingDeviceDriverMetal::command_copy_buffer_to_texture(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView p_regions) { MDCommandBuffer *cmd = (MDCommandBuffer *)(p_cmd_buffer.id); cmd->copy_buffer_to_texture(p_src_buffer, p_dst_texture, p_regions); diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp index 2ef691b1f1..e665e821ed 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.cpp +++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp @@ -4682,6 +4682,24 @@ void RenderingDeviceDriverVulkan::command_clear_color_texture(CommandBufferID p_ vkCmdClearColorImage(command_buffer->vk_command_buffer, tex_info->vk_view_create_info.image, RD_TO_VK_LAYOUT[p_texture_layout], &vk_color, 1, &vk_subresources); } +void RenderingDeviceDriverVulkan::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) { + VkClearDepthStencilValue vk_depth_stencil = {}; + vk_depth_stencil.depth = p_depth; + vk_depth_stencil.stencil = p_stencil; + + VkImageSubresourceRange vk_subresources = {}; + _texture_subresource_range_to_vk(p_subresources, &vk_subresources); + + const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id; + const TextureInfo *tex_info = (const TextureInfo *)p_texture.id; +#ifdef DEBUG_ENABLED + if (tex_info->transient) { + ERR_PRINT("TEXTURE_USAGE_TRANSIENT_BIT p_texture must not be used in command_clear_depth_stencil_texture. Use a clear store action pass instead."); + } +#endif + vkCmdClearDepthStencilImage(command_buffer->vk_command_buffer, tex_info->vk_view_create_info.image, RD_TO_VK_LAYOUT[p_texture_layout], &vk_depth_stencil, 1, &vk_subresources); +} + void RenderingDeviceDriverVulkan::command_copy_buffer_to_texture(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView p_regions) { const TextureInfo *tex_info = (const TextureInfo *)p_dst_texture.id; diff --git a/drivers/vulkan/rendering_device_driver_vulkan.h b/drivers/vulkan/rendering_device_driver_vulkan.h index d6700e211e..fa6838037f 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.h +++ b/drivers/vulkan/rendering_device_driver_vulkan.h @@ -532,6 +532,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 p_regions) override final; 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) override final; 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) override final; + 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) override final; 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 p_regions) override final; 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 p_regions) override final; diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 9e9192d6ee..d04630a250 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -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 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; } diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 4ca7b32adb..87bae4a010 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -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 { diff --git a/servers/rendering/rendering_device_commons.cpp b/servers/rendering/rendering_device_commons.cpp index a11ffe57dd..66499d5a7c 100644 --- a/servers/rendering/rendering_device_commons.cpp +++ b/servers/rendering/rendering_device_commons.cpp @@ -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: diff --git a/servers/rendering/rendering_device_commons.h b/servers/rendering/rendering_device_commons.h index e012e26668..7948f85dc6 100644 --- a/servers/rendering/rendering_device_commons.h +++ b/servers/rendering/rendering_device_commons.h @@ -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); diff --git a/servers/rendering/rendering_device_driver.h b/servers/rendering/rendering_device_driver.h index 11d5f5be97..1e1ffc8a81 100644 --- a/servers/rendering/rendering_device_driver.h +++ b/servers/rendering/rendering_device_driver.h @@ -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 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 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 p_regions) = 0; diff --git a/servers/rendering/rendering_device_graph.cpp b/servers/rendering/rendering_device_graph.cpp index 2b7f2ebd50..8d8c2a0d4d 100644 --- a/servers/rendering/rendering_device_graph.cpp +++ b/servers/rendering/rendering_device_graph.cpp @@ -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(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(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(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(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(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(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(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(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(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(_allocate_command(sizeof(RecordedTextureClearCommand), command_index)); - command->type = RecordedCommand::TYPE_TEXTURE_CLEAR; + RecordedTextureClearColorCommand *command = static_cast(_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(_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 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 diff --git a/servers/rendering/rendering_device_graph.h b/servers/rendering/rendering_device_graph.h index 69e0ad0d63..246c64c067 100644 --- a/servers/rendering/rendering_device_graph.h +++ b/servers/rendering/rendering_device_graph.h @@ -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 p_trackers, VectorView 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 p_texture_copy_regions); void add_texture_get_data(RDD::TextureID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, VectorView 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);