You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-28 16:07:14 +00:00
Resolve depth buffer in pass if supported by driver
This commit is contained in:
@@ -2014,6 +2014,9 @@
|
|||||||
<constant name="TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT" value="4" enum="TextureUsageBits" is_bitfield="true">
|
<constant name="TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT" value="4" enum="TextureUsageBits" is_bitfield="true">
|
||||||
Texture can be used as a depth/stencil attachment in a framebuffer.
|
Texture can be used as a depth/stencil attachment in a framebuffer.
|
||||||
</constant>
|
</constant>
|
||||||
|
<constant name="TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT" value="4096" enum="TextureUsageBits" is_bitfield="true">
|
||||||
|
Texture can be used as a depth/stencil resolve attachment in a framebuffer.
|
||||||
|
</constant>
|
||||||
<constant name="TEXTURE_USAGE_STORAGE_BIT" value="8" enum="TextureUsageBits" is_bitfield="true">
|
<constant name="TEXTURE_USAGE_STORAGE_BIT" value="8" enum="TextureUsageBits" is_bitfield="true">
|
||||||
Texture can be used as a [url=https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#descriptorsets-storageimage]storage image[/url].
|
Texture can be used as a [url=https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#descriptorsets-storageimage]storage image[/url].
|
||||||
</constant>
|
</constant>
|
||||||
|
|||||||
@@ -535,6 +535,7 @@ Error RenderingDeviceDriverVulkan::_initialize_device_extensions() {
|
|||||||
_register_requested_device_extension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, false);
|
_register_requested_device_extension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, false);
|
||||||
_register_requested_device_extension(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME, false);
|
_register_requested_device_extension(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME, false);
|
||||||
_register_requested_device_extension(VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME, false);
|
_register_requested_device_extension(VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME, false);
|
||||||
|
_register_requested_device_extension(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, false);
|
||||||
|
|
||||||
// We don't actually use this extension, but some runtime components on some platforms
|
// We don't actually use this extension, but some runtime components on some platforms
|
||||||
// can and will fill the validation layers with useless info otherwise if not enabled.
|
// can and will fill the validation layers with useless info otherwise if not enabled.
|
||||||
@@ -745,6 +746,9 @@ Error RenderingDeviceDriverVulkan::_check_device_capabilities() {
|
|||||||
device_capabilities.version_major = VK_API_VERSION_MAJOR(physical_device_properties.apiVersion);
|
device_capabilities.version_major = VK_API_VERSION_MAJOR(physical_device_properties.apiVersion);
|
||||||
device_capabilities.version_minor = VK_API_VERSION_MINOR(physical_device_properties.apiVersion);
|
device_capabilities.version_minor = VK_API_VERSION_MINOR(physical_device_properties.apiVersion);
|
||||||
|
|
||||||
|
// Cache extension availability we query often.
|
||||||
|
framebuffer_depth_resolve = enabled_device_extension_names.has(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME);
|
||||||
|
|
||||||
// References:
|
// References:
|
||||||
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_multiview.html
|
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_multiview.html
|
||||||
// https://www.khronos.org/blog/vulkan-subgroup-tutorial
|
// https://www.khronos.org/blog/vulkan-subgroup-tutorial
|
||||||
@@ -1982,7 +1986,7 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create(const TextureFormat &
|
|||||||
if ((p_format.usage_bits & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) {
|
if ((p_format.usage_bits & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) {
|
||||||
create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
}
|
}
|
||||||
if ((p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
|
if ((p_format.usage_bits & (TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT))) {
|
||||||
create_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
create_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||||
}
|
}
|
||||||
if ((p_format.usage_bits & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)) {
|
if ((p_format.usage_bits & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)) {
|
||||||
@@ -2073,7 +2077,7 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create(const TextureFormat &
|
|||||||
image_view_create_info.components.a = (VkComponentSwizzle)p_view.swizzle_a;
|
image_view_create_info.components.a = (VkComponentSwizzle)p_view.swizzle_a;
|
||||||
image_view_create_info.subresourceRange.levelCount = create_info.mipLevels;
|
image_view_create_info.subresourceRange.levelCount = create_info.mipLevels;
|
||||||
image_view_create_info.subresourceRange.layerCount = create_info.arrayLayers;
|
image_view_create_info.subresourceRange.layerCount = create_info.arrayLayers;
|
||||||
if ((p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
|
if ((p_format.usage_bits & (TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT))) {
|
||||||
image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
} else {
|
} else {
|
||||||
image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
@@ -2454,6 +2458,7 @@ BitField<RDD::TextureUsageBits> RenderingDeviceDriverVulkan::texture_get_usages_
|
|||||||
}
|
}
|
||||||
if (!(flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
|
if (!(flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
|
||||||
supported.clear_flag(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
supported.clear_flag(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||||
|
supported.clear_flag(TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT);
|
||||||
}
|
}
|
||||||
if (!(flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
|
if (!(flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
|
||||||
supported.clear_flag(TEXTURE_USAGE_STORAGE_BIT);
|
supported.clear_flag(TEXTURE_USAGE_STORAGE_BIT);
|
||||||
@@ -4851,12 +4856,32 @@ RDD::RenderPassID RenderingDeviceDriverVulkan::render_pass_create(VectorView<Att
|
|||||||
VkFragmentShadingRateAttachmentInfoKHR *vk_fsr_info = ALLOCA_SINGLE(VkFragmentShadingRateAttachmentInfoKHR);
|
VkFragmentShadingRateAttachmentInfoKHR *vk_fsr_info = ALLOCA_SINGLE(VkFragmentShadingRateAttachmentInfoKHR);
|
||||||
*vk_fsr_info = {};
|
*vk_fsr_info = {};
|
||||||
vk_fsr_info->sType = VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR;
|
vk_fsr_info->sType = VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR;
|
||||||
|
vk_fsr_info->pNext = vk_subpasses[i].pNext;
|
||||||
vk_fsr_info->pFragmentShadingRateAttachment = vk_subpass_fsr_attachment;
|
vk_fsr_info->pFragmentShadingRateAttachment = vk_subpass_fsr_attachment;
|
||||||
vk_fsr_info->shadingRateAttachmentTexelSize.width = p_subpasses[i].fragment_shading_rate_texel_size.x;
|
vk_fsr_info->shadingRateAttachmentTexelSize.width = p_subpasses[i].fragment_shading_rate_texel_size.x;
|
||||||
vk_fsr_info->shadingRateAttachmentTexelSize.height = p_subpasses[i].fragment_shading_rate_texel_size.y;
|
vk_fsr_info->shadingRateAttachmentTexelSize.height = p_subpasses[i].fragment_shading_rate_texel_size.y;
|
||||||
|
|
||||||
vk_subpasses[i].pNext = vk_fsr_info;
|
vk_subpasses[i].pNext = vk_fsr_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Depth resolve.
|
||||||
|
if (framebuffer_depth_resolve && p_subpasses[i].depth_resolve_reference.attachment != AttachmentReference::UNUSED) {
|
||||||
|
VkAttachmentReference2KHR *vk_subpass_depth_resolve_attachment = ALLOCA_SINGLE(VkAttachmentReference2KHR);
|
||||||
|
*vk_subpass_depth_resolve_attachment = {};
|
||||||
|
vk_subpass_depth_resolve_attachment->sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
|
||||||
|
vk_subpass_depth_resolve_attachment->attachment = p_subpasses[i].depth_resolve_reference.attachment;
|
||||||
|
vk_subpass_depth_resolve_attachment->layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkSubpassDescriptionDepthStencilResolveKHR *vk_depth_resolve_info = ALLOCA_SINGLE(VkSubpassDescriptionDepthStencilResolveKHR);
|
||||||
|
*vk_depth_resolve_info = {};
|
||||||
|
vk_depth_resolve_info->sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE;
|
||||||
|
vk_depth_resolve_info->pNext = vk_subpasses[i].pNext;
|
||||||
|
vk_depth_resolve_info->depthResolveMode = VK_RESOLVE_MODE_MAX_BIT_KHR;
|
||||||
|
vk_depth_resolve_info->stencilResolveMode = VK_RESOLVE_MODE_NONE_KHR; // we don't resolve our stencil (for now)
|
||||||
|
vk_depth_resolve_info->pDepthStencilResolveAttachment = vk_subpass_depth_resolve_attachment;
|
||||||
|
|
||||||
|
vk_subpasses[i].pNext = vk_depth_resolve_info;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSubpassDependency2KHR *vk_subpass_dependencies = ALLOCA_ARRAY(VkSubpassDependency2KHR, p_subpass_dependencies.size());
|
VkSubpassDependency2KHR *vk_subpass_dependencies = ALLOCA_ARRAY(VkSubpassDependency2KHR, p_subpass_dependencies.size());
|
||||||
@@ -6225,6 +6250,8 @@ bool RenderingDeviceDriverVulkan::has_feature(Features p_feature) {
|
|||||||
#endif
|
#endif
|
||||||
case SUPPORTS_VULKAN_MEMORY_MODEL:
|
case SUPPORTS_VULKAN_MEMORY_MODEL:
|
||||||
return vulkan_memory_model_support && vulkan_memory_model_device_scope_support;
|
return vulkan_memory_model_support && vulkan_memory_model_device_scope_support;
|
||||||
|
case SUPPORTS_FRAMEBUFFER_DEPTH_RESOLVE:
|
||||||
|
return framebuffer_depth_resolve;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver {
|
|||||||
bool vulkan_memory_model_device_scope_support = false;
|
bool vulkan_memory_model_device_scope_support = false;
|
||||||
bool pipeline_cache_control_support = false;
|
bool pipeline_cache_control_support = false;
|
||||||
bool device_fault_support = false;
|
bool device_fault_support = false;
|
||||||
|
bool framebuffer_depth_resolve = false;
|
||||||
#if defined(VK_TRACK_DEVICE_MEMORY)
|
#if defined(VK_TRACK_DEVICE_MEMORY)
|
||||||
bool device_memory_report_support = false;
|
bool device_memory_report_support = false;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -326,15 +326,15 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
|
|||||||
break;
|
break;
|
||||||
case VK_FORMAT_D32_SFLOAT:
|
case VK_FORMAT_D32_SFLOAT:
|
||||||
format = RenderingDevice::DATA_FORMAT_D32_SFLOAT;
|
format = RenderingDevice::DATA_FORMAT_D32_SFLOAT;
|
||||||
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RenderingDevice::TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT;
|
||||||
break;
|
break;
|
||||||
case VK_FORMAT_D24_UNORM_S8_UINT:
|
case VK_FORMAT_D24_UNORM_S8_UINT:
|
||||||
format = RenderingDevice::DATA_FORMAT_D24_UNORM_S8_UINT;
|
format = RenderingDevice::DATA_FORMAT_D24_UNORM_S8_UINT;
|
||||||
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RenderingDevice::TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT;
|
||||||
break;
|
break;
|
||||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||||
format = RenderingDevice::DATA_FORMAT_D32_SFLOAT_S8_UINT;
|
format = RenderingDevice::DATA_FORMAT_D32_SFLOAT_S8_UINT;
|
||||||
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RenderingDevice::TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// continue with our default value
|
// continue with our default value
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ RID RendererSceneRenderImplementation::RenderForwardMobile::RenderBufferDataForw
|
|||||||
return RID();
|
return RID();
|
||||||
}
|
}
|
||||||
|
|
||||||
RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(FramebufferConfigType p_config_type) {
|
RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(FramebufferConfigType p_config_type, bool p_resolve_depth) {
|
||||||
ERR_FAIL_NULL_V(render_buffers, RID());
|
ERR_FAIL_NULL_V(render_buffers, RID());
|
||||||
|
|
||||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||||
@@ -225,17 +225,22 @@ RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(Framebuffe
|
|||||||
|
|
||||||
Vector<RID> textures;
|
Vector<RID> textures;
|
||||||
int color_buffer_id = 0;
|
int color_buffer_id = 0;
|
||||||
textures.push_back(use_msaa ? render_buffers->get_color_msaa() : render_buffers->get_internal_texture()); // 0 - color buffer
|
int depth_buffer_id = 1;
|
||||||
textures.push_back(use_msaa ? render_buffers->get_depth_msaa() : render_buffers->get_depth_texture()); // 1 - depth buffer
|
textures.push_back(use_msaa ? render_buffers->get_color_msaa() : render_buffers->get_internal_texture()); // 0 - color buffer.
|
||||||
|
textures.push_back(use_msaa ? render_buffers->get_depth_msaa() : render_buffers->get_depth_texture()); // 1 - depth buffer.
|
||||||
if (vrs_texture.is_valid()) {
|
if (vrs_texture.is_valid()) {
|
||||||
textures.push_back(vrs_texture); // 2 - vrs texture
|
textures.push_back(vrs_texture); // 2 - vrs texture.
|
||||||
}
|
}
|
||||||
if (use_msaa) {
|
if (use_msaa) {
|
||||||
color_buffer_id = textures.size();
|
color_buffer_id = textures.size();
|
||||||
textures.push_back(render_buffers->get_internal_texture()); // color buffer for resolve
|
textures.push_back(render_buffers->get_internal_texture()); // Color buffer for resolve.
|
||||||
|
}
|
||||||
|
if (use_msaa && p_resolve_depth) {
|
||||||
|
depth_buffer_id = textures.size();
|
||||||
|
textures.push_back(render_buffers->get_depth_texture()); // Depth buffer for resolve.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now define our subpasses
|
// Now define our subpasses.
|
||||||
Vector<RD::FramebufferPass> passes;
|
Vector<RD::FramebufferPass> passes;
|
||||||
|
|
||||||
switch (p_config_type) {
|
switch (p_config_type) {
|
||||||
@@ -245,8 +250,13 @@ RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(Framebuffe
|
|||||||
pass.depth_attachment = 1;
|
pass.depth_attachment = 1;
|
||||||
|
|
||||||
if (use_msaa) {
|
if (use_msaa) {
|
||||||
// Add resolve
|
// Add color resolve.
|
||||||
pass.resolve_attachments.push_back(color_buffer_id);
|
pass.resolve_attachments.push_back(color_buffer_id);
|
||||||
|
|
||||||
|
if (p_resolve_depth) {
|
||||||
|
// Add depth resolve.
|
||||||
|
pass.depth_resolve_attachment = depth_buffer_id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
passes.push_back(pass);
|
passes.push_back(pass);
|
||||||
|
|
||||||
@@ -257,7 +267,7 @@ RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(Framebuffe
|
|||||||
Size2i target_size = render_buffers->get_target_size();
|
Size2i target_size = render_buffers->get_target_size();
|
||||||
Size2i internal_size = render_buffers->get_internal_size();
|
Size2i internal_size = render_buffers->get_internal_size();
|
||||||
|
|
||||||
// can't do our blit pass if resolutions don't match, this should already have been checked.
|
// Can't do our blit pass if resolutions don't match, this should already have been checked.
|
||||||
ERR_FAIL_COND_V(target_size != internal_size, RID());
|
ERR_FAIL_COND_V(target_size != internal_size, RID());
|
||||||
|
|
||||||
RD::FramebufferPass pass;
|
RD::FramebufferPass pass;
|
||||||
@@ -265,13 +275,18 @@ RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(Framebuffe
|
|||||||
pass.depth_attachment = 1;
|
pass.depth_attachment = 1;
|
||||||
|
|
||||||
if (use_msaa) {
|
if (use_msaa) {
|
||||||
// add resolve
|
// Add color resolve.
|
||||||
pass.resolve_attachments.push_back(color_buffer_id);
|
pass.resolve_attachments.push_back(color_buffer_id);
|
||||||
|
|
||||||
|
if (p_resolve_depth) {
|
||||||
|
// Add depth resolve.
|
||||||
|
pass.depth_resolve_attachment = depth_buffer_id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
passes.push_back(pass);
|
passes.push_back(pass);
|
||||||
|
|
||||||
// - add blit to 2D pass
|
// Add blit to 2D pass.
|
||||||
RID render_target = render_buffers->get_render_target();
|
RID render_target = render_buffers->get_render_target();
|
||||||
ERR_FAIL_COND_V(render_target.is_null(), RID());
|
ERR_FAIL_COND_V(render_target.is_null(), RID());
|
||||||
RID target_buffer;
|
RID target_buffer;
|
||||||
@@ -284,12 +299,12 @@ RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(Framebuffe
|
|||||||
ERR_FAIL_COND_V(target_buffer.is_null(), RID());
|
ERR_FAIL_COND_V(target_buffer.is_null(), RID());
|
||||||
|
|
||||||
int target_buffer_id = textures.size();
|
int target_buffer_id = textures.size();
|
||||||
textures.push_back(target_buffer); // target buffer
|
textures.push_back(target_buffer); // Target buffer.
|
||||||
|
|
||||||
RD::FramebufferPass blit_pass;
|
RD::FramebufferPass blit_pass;
|
||||||
blit_pass.input_attachments.push_back(color_buffer_id); // Read from our (resolved) color buffer
|
blit_pass.input_attachments.push_back(color_buffer_id); // Read from our (resolved) color buffer.
|
||||||
blit_pass.color_attachments.push_back(target_buffer_id); // Write into our target buffer
|
blit_pass.color_attachments.push_back(target_buffer_id); // Write into our target buffer.
|
||||||
// this doesn't need VRS
|
// This doesn't need VRS or depth.
|
||||||
passes.push_back(blit_pass);
|
passes.push_back(blit_pass);
|
||||||
|
|
||||||
return FramebufferCacheRD::get_singleton()->get_cache_multipass(textures, passes, view_count);
|
return FramebufferCacheRD::get_singleton()->get_cache_multipass(textures, passes, view_count);
|
||||||
@@ -807,9 +822,13 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||||||
|
|
||||||
RENDER_TIMESTAMP("Setup 3D Scene");
|
RENDER_TIMESTAMP("Setup 3D Scene");
|
||||||
|
|
||||||
|
bool has_depth_texture_override = false;
|
||||||
|
bool supports_depth_resolve = RenderingDevice::get_singleton()->has_feature(RD::SUPPORTS_FRAMEBUFFER_DEPTH_RESOLVE);
|
||||||
|
|
||||||
RID render_target = rb->get_render_target();
|
RID render_target = rb->get_render_target();
|
||||||
if (render_target.is_valid()) {
|
if (render_target.is_valid()) {
|
||||||
p_render_data->scene_data->calculate_motion_vectors = RendererRD::TextureStorage::get_singleton()->render_target_get_override_velocity(render_target).is_valid();
|
p_render_data->scene_data->calculate_motion_vectors = texture_storage->render_target_get_override_velocity(render_target).is_valid();
|
||||||
|
has_depth_texture_override = texture_storage->render_target_get_override_depth(render_target).is_valid();
|
||||||
} else {
|
} else {
|
||||||
p_render_data->scene_data->calculate_motion_vectors = false;
|
p_render_data->scene_data->calculate_motion_vectors = false;
|
||||||
}
|
}
|
||||||
@@ -834,6 +853,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||||||
|
|
||||||
RS::ViewportMSAA msaa = rb->get_msaa_3d();
|
RS::ViewportMSAA msaa = rb->get_msaa_3d();
|
||||||
bool use_msaa = msaa != RS::VIEWPORT_MSAA_DISABLED;
|
bool use_msaa = msaa != RS::VIEWPORT_MSAA_DISABLED;
|
||||||
|
bool resolve_depth_buffer = (use_msaa && has_depth_texture_override); // We'll check more conditions later.
|
||||||
|
|
||||||
bool ce_has_post_opaque = _has_compositor_effect(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE, p_render_data);
|
bool ce_has_post_opaque = _has_compositor_effect(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE, p_render_data);
|
||||||
bool ce_has_pre_transparent = _has_compositor_effect(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT, p_render_data);
|
bool ce_has_pre_transparent = _has_compositor_effect(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT, p_render_data);
|
||||||
@@ -937,6 +957,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||||||
if (use_msaa && p_render_data->environment.is_valid() && RSG::camera_attributes->camera_attributes_uses_dof(p_render_data->camera_attributes)) {
|
if (use_msaa && p_render_data->environment.is_valid() && RSG::camera_attributes->camera_attributes_uses_dof(p_render_data->camera_attributes)) {
|
||||||
// Need to resolve depth texture for DOF when using MSAA.
|
// Need to resolve depth texture for DOF when using MSAA.
|
||||||
scene_state.used_depth_texture = true;
|
scene_state.used_depth_texture = true;
|
||||||
|
resolve_depth_buffer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scene_state.used_screen_texture || scene_state.used_depth_texture) {
|
if (scene_state.used_screen_texture || scene_state.used_depth_texture) {
|
||||||
@@ -945,13 +966,17 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||||||
using_subpass_post_process = false;
|
using_subpass_post_process = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_msaa && (global_surface_data.depth_texture_used || scene_state.used_depth_texture)) {
|
||||||
|
resolve_depth_buffer = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (using_subpass_post_process) {
|
if (using_subpass_post_process) {
|
||||||
// We can do all in one go.
|
// We can do all in one go.
|
||||||
framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_RENDER_AND_POST_PASS);
|
framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_RENDER_AND_POST_PASS, resolve_depth_buffer && supports_depth_resolve);
|
||||||
global_pipeline_data_required.use_subpass_post_pass = true;
|
global_pipeline_data_required.use_subpass_post_pass = true;
|
||||||
} else {
|
} else {
|
||||||
// We separate things out.
|
// We separate things out.
|
||||||
framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_RENDER_PASS);
|
framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_RENDER_PASS, resolve_depth_buffer && supports_depth_resolve);
|
||||||
global_pipeline_data_required.use_separate_post_pass = true;
|
global_pipeline_data_required.use_separate_post_pass = true;
|
||||||
}
|
}
|
||||||
samplers = rb->get_samplers();
|
samplers = rb->get_samplers();
|
||||||
@@ -1242,8 +1267,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||||||
RD::get_singleton()->draw_command_end_label(); // Render Transparent Subpass
|
RD::get_singleton()->draw_command_end_label(); // Render Transparent Subpass
|
||||||
}
|
}
|
||||||
|
|
||||||
// note if we are using MSAA we should get an automatic resolve through our subpass configuration.
|
|
||||||
|
|
||||||
// blit to tonemap
|
// blit to tonemap
|
||||||
if (rb_data.is_valid() && using_subpass_post_process) {
|
if (rb_data.is_valid() && using_subpass_post_process) {
|
||||||
_post_process_subpass(p_render_data->render_buffers->get_internal_texture(), framebuffer, p_render_data);
|
_post_process_subpass(p_render_data->render_buffers->get_internal_texture(), framebuffer, p_render_data);
|
||||||
@@ -1252,6 +1275,13 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||||||
RD::get_singleton()->draw_command_end_label(); // Render 3D Pass / Render Reflection Probe Pass
|
RD::get_singleton()->draw_command_end_label(); // Render 3D Pass / Render Reflection Probe Pass
|
||||||
|
|
||||||
RD::get_singleton()->draw_list_end();
|
RD::get_singleton()->draw_list_end();
|
||||||
|
|
||||||
|
// note, if MSAA is used we should get an automatic resolve of the color buffer here.
|
||||||
|
|
||||||
|
if (use_msaa && has_depth_texture_override && !supports_depth_resolve) {
|
||||||
|
// We don't have a fallback for this, See PR #111322
|
||||||
|
WARN_PRINT_ONCE("MSAA Depth buffer resolve is not supported on this platform.");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// We're done with our subpasses so end our container pass
|
// We're done with our subpasses so end our container pass
|
||||||
// note, if MSAA is used we should get an automatic resolve of the color buffer here.
|
// note, if MSAA is used we should get an automatic resolve of the color buffer here.
|
||||||
@@ -1274,12 +1304,17 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_msaa && has_depth_texture_override && !supports_depth_resolve) {
|
||||||
|
// We don't have a fallback for this, See PR #111322
|
||||||
|
WARN_PRINT_ONCE("MSAA Depth buffer resolve is not supported on this platform.");
|
||||||
|
}
|
||||||
|
|
||||||
if (scene_state.used_depth_texture || global_surface_data.depth_texture_used) {
|
if (scene_state.used_depth_texture || global_surface_data.depth_texture_used) {
|
||||||
_render_buffers_ensure_depth_texture(p_render_data);
|
_render_buffers_ensure_depth_texture(p_render_data);
|
||||||
|
|
||||||
if (scene_state.used_depth_texture) {
|
if (scene_state.used_depth_texture) {
|
||||||
// Copy depth texture to backbuffer so we can read from it.
|
// Copy depth texture to backbuffer so we can read from it.
|
||||||
_render_buffers_copy_depth_texture(p_render_data, use_msaa);
|
_render_buffers_copy_depth_texture(p_render_data, use_msaa && !supports_depth_resolve); // Note, once fallback for has_depth_texture_override works, we also don't need to do our resolve here.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ private:
|
|||||||
FB_CONFIG_MAX
|
FB_CONFIG_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
RID get_color_fbs(FramebufferConfigType p_config_type);
|
RID get_color_fbs(FramebufferConfigType p_config_type, bool p_resolve_depth = false);
|
||||||
virtual void free_data() override;
|
virtual void free_data() override;
|
||||||
virtual void configure(RenderSceneBuffersRD *p_render_buffers) override;
|
virtual void configure(RenderSceneBuffersRD *p_render_buffers) override;
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ class FramebufferCacheRD : public Object {
|
|||||||
|
|
||||||
static _FORCE_INLINE_ uint32_t _hash_pass(const RD::FramebufferPass &p, uint32_t h) {
|
static _FORCE_INLINE_ uint32_t _hash_pass(const RD::FramebufferPass &p, uint32_t h) {
|
||||||
h = hash_murmur3_one_32(p.depth_attachment, h);
|
h = hash_murmur3_one_32(p.depth_attachment, h);
|
||||||
|
h = hash_murmur3_one_32(p.depth_resolve_attachment, h);
|
||||||
|
|
||||||
h = hash_murmur3_one_32(p.color_attachments.size(), h);
|
h = hash_murmur3_one_32(p.color_attachments.size(), h);
|
||||||
for (int i = 0; i < p.color_attachments.size(); i++) {
|
for (int i = 0; i < p.color_attachments.size(); i++) {
|
||||||
@@ -82,6 +83,10 @@ class FramebufferCacheRD : public Object {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (a.depth_resolve_attachment != b.depth_resolve_attachment) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (a.color_attachments.size() != b.color_attachments.size()) {
|
if (a.color_attachments.size() != b.color_attachments.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -730,7 +730,11 @@ uint32_t RenderSceneBuffersRD::get_color_usage_bits(bool p_resolve, bool p_msaa,
|
|||||||
}
|
}
|
||||||
|
|
||||||
RD::DataFormat RenderSceneBuffersRD::get_depth_format(bool p_resolve, bool p_msaa, bool p_storage) {
|
RD::DataFormat RenderSceneBuffersRD::get_depth_format(bool p_resolve, bool p_msaa, bool p_storage) {
|
||||||
if (p_resolve) {
|
// TODO Our rendering engine does not support just having a depth attachment, it always assumed we combine with stencil.
|
||||||
|
// We thus can't configure our depth resolve with RD::DATA_FORMAT_R32_SFLOAT.
|
||||||
|
// We should add support for TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT or add a TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT
|
||||||
|
|
||||||
|
if (p_resolve && !RenderingDevice::get_singleton()->has_feature(RD::SUPPORTS_FRAMEBUFFER_DEPTH_RESOLVE)) {
|
||||||
return RD::DATA_FORMAT_R32_SFLOAT;
|
return RD::DATA_FORMAT_R32_SFLOAT;
|
||||||
} else {
|
} else {
|
||||||
const RenderingDeviceCommons::DataFormat preferred_formats[2] = {
|
const RenderingDeviceCommons::DataFormat preferred_formats[2] = {
|
||||||
@@ -749,7 +753,13 @@ uint32_t RenderSceneBuffersRD::get_depth_usage_bits(bool p_resolve, bool p_msaa,
|
|||||||
if (p_msaa) {
|
if (p_msaa) {
|
||||||
usage_bits |= RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
|
usage_bits |= RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
|
||||||
} else if (p_resolve) {
|
} else if (p_resolve) {
|
||||||
usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | (p_storage ? RD::TEXTURE_USAGE_STORAGE_BIT : 0);
|
usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
|
||||||
|
if (p_storage) {
|
||||||
|
usage_bits |= RD::TEXTURE_USAGE_STORAGE_BIT;
|
||||||
|
} else if (RenderingDevice::get_singleton()->has_feature(RD::SUPPORTS_FRAMEBUFFER_DEPTH_RESOLVE)) {
|
||||||
|
// We're able to resolve depth in (sub)passes and we make use of this in our mobile renderer.
|
||||||
|
usage_bits |= RD::TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
usage_bits |= RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
usage_bits |= RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1080,7 +1080,7 @@ RID RenderingDevice::texture_create(const TextureFormat &p_format, const Texture
|
|||||||
texture.allowed_shared_formats = format.shareable_formats;
|
texture.allowed_shared_formats = format.shareable_formats;
|
||||||
texture.has_initial_data = !data.is_empty();
|
texture.has_initial_data = !data.is_empty();
|
||||||
|
|
||||||
if ((format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
|
if ((format.usage_bits & (TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT))) {
|
||||||
texture.read_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
|
texture.read_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
|
||||||
texture.barrier_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
|
texture.barrier_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
|
||||||
if (format_has_stencil(format.format)) {
|
if (format_has_stencil(format.format)) {
|
||||||
@@ -1094,7 +1094,7 @@ RID RenderingDevice::texture_create(const TextureFormat &p_format, const Texture
|
|||||||
texture.bound = false;
|
texture.bound = false;
|
||||||
|
|
||||||
// Textures are only assumed to be immutable if they have initial data and none of the other bits that indicate write usage are enabled.
|
// Textures are only assumed to be immutable if they have initial data and none of the other bits that indicate write usage are enabled.
|
||||||
bool texture_mutable_by_default = texture.usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_STORAGE_BIT | TEXTURE_USAGE_STORAGE_ATOMIC_BIT);
|
bool texture_mutable_by_default = texture.usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT | TEXTURE_USAGE_STORAGE_BIT | TEXTURE_USAGE_STORAGE_ATOMIC_BIT);
|
||||||
if (data.is_empty() || texture_mutable_by_default) {
|
if (data.is_empty() || texture_mutable_by_default) {
|
||||||
_texture_make_mutable(&texture, RID());
|
_texture_make_mutable(&texture, RID());
|
||||||
}
|
}
|
||||||
@@ -1225,7 +1225,7 @@ RID RenderingDevice::texture_create_from_extension(TextureType p_type, DataForma
|
|||||||
texture.allowed_shared_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
|
texture.allowed_shared_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
|
||||||
texture.allowed_shared_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
|
texture.allowed_shared_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
|
||||||
|
|
||||||
if (p_usage.has_flag(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
|
if (p_usage.has_flag(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) || p_usage.has_flag(TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT)) {
|
||||||
texture.read_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
|
texture.read_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
|
||||||
texture.barrier_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
|
texture.barrier_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
|
||||||
/*if (format_has_stencil(p_format.format)) {
|
/*if (format_has_stencil(p_format.format)) {
|
||||||
@@ -1236,7 +1236,7 @@ RID RenderingDevice::texture_create_from_extension(TextureType p_type, DataForma
|
|||||||
texture.barrier_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_COLOR_BIT);
|
texture.barrier_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_COLOR_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
texture.driver_id = driver->texture_create_from_extension(p_image, p_type, p_format, p_layers, (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT), p_mipmaps);
|
texture.driver_id = driver->texture_create_from_extension(p_image, p_type, p_format, p_layers, (texture.usage_flags & (TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT)), p_mipmaps);
|
||||||
ERR_FAIL_COND_V(!texture.driver_id, RID());
|
ERR_FAIL_COND_V(!texture.driver_id, RID());
|
||||||
|
|
||||||
_texture_make_mutable(&texture, RID());
|
_texture_make_mutable(&texture, RID());
|
||||||
@@ -2468,7 +2468,7 @@ RDD::RenderPassID RenderingDevice::_render_pass_create(RenderingDeviceDriver *p_
|
|||||||
|
|
||||||
ERR_FAIL_INDEX_V(p_attachments[i].format, DATA_FORMAT_MAX, RDD::RenderPassID());
|
ERR_FAIL_INDEX_V(p_attachments[i].format, DATA_FORMAT_MAX, RDD::RenderPassID());
|
||||||
ERR_FAIL_INDEX_V(p_attachments[i].samples, TEXTURE_SAMPLES_MAX, RDD::RenderPassID());
|
ERR_FAIL_INDEX_V(p_attachments[i].samples, TEXTURE_SAMPLES_MAX, RDD::RenderPassID());
|
||||||
ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT | TEXTURE_USAGE_VRS_ATTACHMENT_BIT)),
|
ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT | TEXTURE_USAGE_VRS_ATTACHMENT_BIT)),
|
||||||
RDD::RenderPassID(), "Texture format for index (" + itos(i) + ") requires an attachment (color, depth-stencil, input or VRS) bit set.");
|
RDD::RenderPassID(), "Texture format for index (" + itos(i) + ") requires an attachment (color, depth-stencil, input or VRS) bit set.");
|
||||||
|
|
||||||
RDD::Attachment description;
|
RDD::Attachment description;
|
||||||
@@ -2501,6 +2501,13 @@ RDD::RenderPassID RenderingDevice::_render_pass_create(RenderingDeviceDriver *p_
|
|||||||
description.stencil_store_op = p_store_ops[i];
|
description.stencil_store_op = p_store_ops[i];
|
||||||
description.initial_layout = RDD::TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
description.initial_layout = RDD::TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
description.final_layout = RDD::TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
description.final_layout = RDD::TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
} else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT) {
|
||||||
|
description.load_op = p_load_ops[i];
|
||||||
|
description.store_op = p_store_ops[i];
|
||||||
|
description.stencil_load_op = p_load_ops[i];
|
||||||
|
description.stencil_store_op = p_store_ops[i];
|
||||||
|
description.initial_layout = RDD::TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
description.final_layout = RDD::TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
} else {
|
} else {
|
||||||
description.load_op = RDD::ATTACHMENT_LOAD_OP_DONT_CARE;
|
description.load_op = RDD::ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
description.store_op = RDD::ATTACHMENT_STORE_OP_DONT_CARE;
|
description.store_op = RDD::ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
@@ -2613,6 +2620,21 @@ RDD::RenderPassID RenderingDevice::_render_pass_create(RenderingDeviceDriver *p_
|
|||||||
ERR_FAIL_COND_V_MSG(texture_samples != p_attachments[attachment].samples, RDD::RenderPassID(), "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), if an attachment is marked as multisample, all of them should be multisample and use the same number of samples including the depth.");
|
ERR_FAIL_COND_V_MSG(texture_samples != p_attachments[attachment].samples, RDD::RenderPassID(), "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), if an attachment is marked as multisample, all of them should be multisample and use the same number of samples including the depth.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pass->depth_resolve_attachment != ATTACHMENT_UNUSED) {
|
||||||
|
attachment = pass->depth_resolve_attachment;
|
||||||
|
|
||||||
|
// As our fallbacks are handled outside of our pass, we should never be setting up a render pass with a depth resolve attachment when not supported.
|
||||||
|
ERR_FAIL_COND_V_MSG(!p_driver->has_feature(SUPPORTS_FRAMEBUFFER_DEPTH_RESOLVE), RDD::RenderPassID(), "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), a depth resolve attachment was supplied when driver doesn't support this feature.");
|
||||||
|
|
||||||
|
ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), RDD::RenderPassID(), "Invalid framebuffer depth resolve format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), depth resolve attachment.");
|
||||||
|
ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT), RDD::RenderPassID(), "Invalid framebuffer depth resolve format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it's marked as depth, but it's not a depth resolve attachment.");
|
||||||
|
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, RDD::RenderPassID(), "Invalid framebuffer depth resolve format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
|
||||||
|
|
||||||
|
subpass.depth_resolve_reference.attachment = attachment_remap[attachment];
|
||||||
|
subpass.depth_resolve_reference.layout = RDD::TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
attachment_last_pass[attachment] = i;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
subpass.depth_stencil_reference.attachment = RDD::AttachmentReference::UNUSED;
|
subpass.depth_stencil_reference.attachment = RDD::AttachmentReference::UNUSED;
|
||||||
subpass.depth_stencil_reference.layout = RDD::TEXTURE_LAYOUT_UNDEFINED;
|
subpass.depth_stencil_reference.layout = RDD::TEXTURE_LAYOUT_UNDEFINED;
|
||||||
@@ -2757,6 +2779,8 @@ RenderingDevice::FramebufferFormatID RenderingDevice::framebuffer_format_create(
|
|||||||
for (int i = 0; i < p_format.size(); i++) {
|
for (int i = 0; i < p_format.size(); i++) {
|
||||||
if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||||
pass.depth_attachment = i;
|
pass.depth_attachment = i;
|
||||||
|
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT) {
|
||||||
|
pass.depth_resolve_attachment = i;
|
||||||
} else {
|
} else {
|
||||||
pass.color_attachments.push_back(i);
|
pass.color_attachments.push_back(i);
|
||||||
}
|
}
|
||||||
@@ -2903,6 +2927,8 @@ RID RenderingDevice::framebuffer_create(const Vector<RID> &p_texture_attachments
|
|||||||
|
|
||||||
if (texture && texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
if (texture && texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||||
pass.depth_attachment = i;
|
pass.depth_attachment = i;
|
||||||
|
} else if (texture && texture->usage_flags & TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT) {
|
||||||
|
pass.depth_resolve_attachment = i;
|
||||||
} else if (texture && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) {
|
} else if (texture && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) {
|
||||||
// Prevent the VRS attachment from being added to the color_attachments.
|
// Prevent the VRS attachment from being added to the color_attachments.
|
||||||
} else {
|
} else {
|
||||||
@@ -3661,7 +3687,7 @@ RID RenderingDevice::uniform_set_create(const VectorView<RD::Uniform> &p_uniform
|
|||||||
ERR_FAIL_COND_V_MSG(!(texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT), RID(),
|
ERR_FAIL_COND_V_MSG(!(texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT), RID(),
|
||||||
"Texture (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") needs the TEXTURE_USAGE_SAMPLING_BIT usage flag set in order to be used as uniform.");
|
"Texture (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") needs the TEXTURE_USAGE_SAMPLING_BIT usage flag set in order to be used as uniform.");
|
||||||
|
|
||||||
if ((texture->usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT))) {
|
if ((texture->usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT))) {
|
||||||
UniformSet::AttachableTexture attachable_texture;
|
UniformSet::AttachableTexture attachable_texture;
|
||||||
attachable_texture.bind = set_uniform.binding;
|
attachable_texture.bind = set_uniform.binding;
|
||||||
attachable_texture.texture = texture->owner.is_valid() ? texture->owner : uniform.get_id(j + 1);
|
attachable_texture.texture = texture->owner.is_valid() ? texture->owner : uniform.get_id(j + 1);
|
||||||
@@ -3707,7 +3733,7 @@ RID RenderingDevice::uniform_set_create(const VectorView<RD::Uniform> &p_uniform
|
|||||||
ERR_FAIL_COND_V_MSG(!(texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT), RID(),
|
ERR_FAIL_COND_V_MSG(!(texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT), RID(),
|
||||||
"Texture (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") needs the TEXTURE_USAGE_SAMPLING_BIT usage flag set in order to be used as uniform.");
|
"Texture (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") needs the TEXTURE_USAGE_SAMPLING_BIT usage flag set in order to be used as uniform.");
|
||||||
|
|
||||||
if ((texture->usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT))) {
|
if ((texture->usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT))) {
|
||||||
UniformSet::AttachableTexture attachable_texture;
|
UniformSet::AttachableTexture attachable_texture;
|
||||||
attachable_texture.bind = set_uniform.binding;
|
attachable_texture.bind = set_uniform.binding;
|
||||||
attachable_texture.texture = texture->owner.is_valid() ? texture->owner : uniform.get_id(j);
|
attachable_texture.texture = texture->owner.is_valid() ? texture->owner : uniform.get_id(j);
|
||||||
@@ -4490,7 +4516,7 @@ RenderingDevice::DrawListID RenderingDevice::draw_list_begin(RID p_framebuffer,
|
|||||||
resource_usages.push_back(RDG::RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE);
|
resource_usages.push_back(RDG::RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE);
|
||||||
stages.set_flag(RDD::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
stages.set_flag(RDD::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||||
color_index++;
|
color_index++;
|
||||||
} else if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
} else if (texture->usage_flags & (TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT)) {
|
||||||
if (p_draw_flags.has_flag(DRAW_CLEAR_DEPTH) || p_draw_flags.has_flag(DRAW_CLEAR_STENCIL)) {
|
if (p_draw_flags.has_flag(DRAW_CLEAR_DEPTH) || p_draw_flags.has_flag(DRAW_CLEAR_STENCIL)) {
|
||||||
operation = RDG::ATTACHMENT_OPERATION_CLEAR;
|
operation = RDG::ATTACHMENT_OPERATION_CLEAR;
|
||||||
clear_value.depth = p_clear_depth_value;
|
clear_value.depth = p_clear_depth_value;
|
||||||
@@ -5222,6 +5248,9 @@ void RenderingDevice::draw_list_end() {
|
|||||||
if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||||
texture->bound = false;
|
texture->bound = false;
|
||||||
}
|
}
|
||||||
|
if (texture->usage_flags & TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT) {
|
||||||
|
texture->bound = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_list_bound_textures.clear();
|
draw_list_bound_textures.clear();
|
||||||
@@ -7946,6 +7975,7 @@ void RenderingDevice::_bind_methods() {
|
|||||||
BIND_BITFIELD_FLAG(TEXTURE_USAGE_SAMPLING_BIT);
|
BIND_BITFIELD_FLAG(TEXTURE_USAGE_SAMPLING_BIT);
|
||||||
BIND_BITFIELD_FLAG(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT);
|
BIND_BITFIELD_FLAG(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||||
BIND_BITFIELD_FLAG(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
BIND_BITFIELD_FLAG(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||||
|
BIND_BITFIELD_FLAG(TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT);
|
||||||
BIND_BITFIELD_FLAG(TEXTURE_USAGE_STORAGE_BIT);
|
BIND_BITFIELD_FLAG(TEXTURE_USAGE_STORAGE_BIT);
|
||||||
BIND_BITFIELD_FLAG(TEXTURE_USAGE_STORAGE_ATOMIC_BIT);
|
BIND_BITFIELD_FLAG(TEXTURE_USAGE_STORAGE_ATOMIC_BIT);
|
||||||
BIND_BITFIELD_FLAG(TEXTURE_USAGE_CPU_READ_BIT);
|
BIND_BITFIELD_FLAG(TEXTURE_USAGE_CPU_READ_BIT);
|
||||||
|
|||||||
@@ -518,6 +518,7 @@ public:
|
|||||||
Vector<int32_t> resolve_attachments;
|
Vector<int32_t> resolve_attachments;
|
||||||
Vector<int32_t> preserve_attachments;
|
Vector<int32_t> preserve_attachments;
|
||||||
int32_t depth_attachment = ATTACHMENT_UNUSED;
|
int32_t depth_attachment = ATTACHMENT_UNUSED;
|
||||||
|
int32_t depth_resolve_attachment = ATTACHMENT_UNUSED;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int64_t FramebufferFormatID;
|
typedef int64_t FramebufferFormatID;
|
||||||
|
|||||||
@@ -421,7 +421,8 @@ public:
|
|||||||
// Try to set this bit as much as possible. If you set it, validation doesn't complain
|
// Try to set this bit as much as possible. If you set it, validation doesn't complain
|
||||||
// and it works fine on mobile, then go ahead.
|
// and it works fine on mobile, then go ahead.
|
||||||
TEXTURE_USAGE_TRANSIENT_BIT = (1 << 11),
|
TEXTURE_USAGE_TRANSIENT_BIT = (1 << 11),
|
||||||
TEXTURE_USAGE_MAX_BIT = TEXTURE_USAGE_TRANSIENT_BIT,
|
TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT = (1 << 12),
|
||||||
|
TEXTURE_USAGE_MAX_BIT = TEXTURE_USAGE_DEPTH_RESOLVE_ATTACHMENT_BIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureFormat {
|
struct TextureFormat {
|
||||||
@@ -970,6 +971,7 @@ public:
|
|||||||
SUPPORTS_BUFFER_DEVICE_ADDRESS,
|
SUPPORTS_BUFFER_DEVICE_ADDRESS,
|
||||||
SUPPORTS_IMAGE_ATOMIC_32_BIT,
|
SUPPORTS_IMAGE_ATOMIC_32_BIT,
|
||||||
SUPPORTS_VULKAN_MEMORY_MODEL,
|
SUPPORTS_VULKAN_MEMORY_MODEL,
|
||||||
|
SUPPORTS_FRAMEBUFFER_DEPTH_RESOLVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SubgroupOperations {
|
enum SubgroupOperations {
|
||||||
|
|||||||
@@ -618,6 +618,7 @@ public:
|
|||||||
LocalVector<AttachmentReference> input_references;
|
LocalVector<AttachmentReference> input_references;
|
||||||
LocalVector<AttachmentReference> color_references;
|
LocalVector<AttachmentReference> color_references;
|
||||||
AttachmentReference depth_stencil_reference;
|
AttachmentReference depth_stencil_reference;
|
||||||
|
AttachmentReference depth_resolve_reference;
|
||||||
LocalVector<AttachmentReference> resolve_references;
|
LocalVector<AttachmentReference> resolve_references;
|
||||||
LocalVector<uint32_t> preserve_attachments;
|
LocalVector<uint32_t> preserve_attachments;
|
||||||
AttachmentReference fragment_shading_rate_reference;
|
AttachmentReference fragment_shading_rate_reference;
|
||||||
|
|||||||
Reference in New Issue
Block a user