mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
render: add depth attachment feedback support
Co-authored-by: DeathWhispers <56944463+Death-Whispers-U@users.noreply.github.com>
This commit is contained in:
@@ -32,6 +32,7 @@ struct GraphicContext {
|
||||
bool rt_extensions_enabled = false;
|
||||
bool compute_subgroup_size_control_enabled = false;
|
||||
bool sample_rate_shading_enabled = false;
|
||||
bool attachment_feedback_loop_enabled = false;
|
||||
bool mesh_shader_enabled = false;
|
||||
vk::PhysicalDeviceMeshShaderPropertiesEXT mesh_shader_properties = {};
|
||||
uint32_t subgroup_size = 0;
|
||||
|
||||
@@ -54,6 +54,9 @@ namespace {
|
||||
}
|
||||
if (DepthAspectTransferFormat(info.pixel_format) != vk::Format::eUndefined) {
|
||||
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||
if (graphics.attachment_feedback_loop_enabled && (usage & vk::ImageUsageFlagBits::eSampled)) {
|
||||
usage |= vk::ImageUsageFlagBits::eAttachmentFeedbackLoopEXT;
|
||||
}
|
||||
return usage;
|
||||
}
|
||||
if (HasFormatFeature(properties, vk::FormatFeatureFlagBits::eColorAttachment)) {
|
||||
|
||||
@@ -1007,12 +1007,13 @@ void RenderExecutor::CommitBindings(CommandBuffer& buffer,
|
||||
std::ranges::find(image.views, binding.image_view, &CachedImageView::view);
|
||||
EXIT_IF(storage || host_view == image.views.end());
|
||||
const auto aspect = host_view->info.aspect;
|
||||
const bool feedback = layout == vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT;
|
||||
const bool depth_read =
|
||||
layout == vk::ImageLayout::eDepthReadOnlyOptimal ||
|
||||
feedback || layout == vk::ImageLayout::eDepthReadOnlyOptimal ||
|
||||
layout == vk::ImageLayout::eDepthStencilReadOnlyOptimal ||
|
||||
layout == vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal;
|
||||
const bool stencil_read =
|
||||
layout == vk::ImageLayout::eStencilReadOnlyOptimal ||
|
||||
feedback || layout == vk::ImageLayout::eStencilReadOnlyOptimal ||
|
||||
layout == vk::ImageLayout::eDepthStencilReadOnlyOptimal ||
|
||||
layout == vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal;
|
||||
if ((aspect & vk::ImageAspectFlagBits::eDepth && !depth_read) ||
|
||||
|
||||
@@ -702,7 +702,7 @@ void CreatePipelineInternal(
|
||||
depth_stencil_info.minDepthBounds = static_params.depth_min_bounds;
|
||||
depth_stencil_info.maxDepthBounds = static_params.depth_max_bounds;
|
||||
|
||||
const vk::DynamicState dynamic_states[] = {
|
||||
std::vector<vk::DynamicState> dynamic_states {
|
||||
vk::DynamicState::eViewportWithCount,
|
||||
vk::DynamicState::eScissorWithCount,
|
||||
vk::DynamicState::eLineWidth,
|
||||
@@ -715,22 +715,20 @@ void CreatePipelineInternal(
|
||||
vk::DynamicState::eStencilReference,
|
||||
vk::DynamicState::eStencilWriteMask,
|
||||
vk::DynamicState::eBlendConstants,
|
||||
#if !defined(__APPLE__)
|
||||
// Keep last so depth-only pipelines can omit this dynamic state.
|
||||
vk::DynamicState::eColorWriteEnableEXT, // unsupported by MoltenVK; static mask instead
|
||||
#endif
|
||||
};
|
||||
auto dynamic_states_count =
|
||||
static_cast<uint32_t>(sizeof(dynamic_states) / sizeof(dynamic_states[0]));
|
||||
#if !defined(__APPLE__)
|
||||
if (rendering.color_count == 0) {
|
||||
dynamic_states_count--;
|
||||
if (rendering.color_count != 0) {
|
||||
dynamic_states.push_back(vk::DynamicState::eColorWriteEnableEXT);
|
||||
}
|
||||
#endif
|
||||
if (graphics.attachment_feedback_loop_enabled) {
|
||||
dynamic_states.push_back(vk::DynamicState::eAttachmentFeedbackLoopEnableEXT);
|
||||
}
|
||||
const auto dynamic_states_count = static_cast<uint32_t>(dynamic_states.size());
|
||||
|
||||
vk::PipelineDynamicStateCreateInfo dynamic_state {};
|
||||
dynamic_state.dynamicStateCount = dynamic_states_count;
|
||||
dynamic_state.pDynamicStates = dynamic_states;
|
||||
dynamic_state.pDynamicStates = dynamic_states.data();
|
||||
|
||||
vk::GraphicsPipelineCreateInfo pipeline_info {};
|
||||
vk::PipelineRenderingCreateInfo rendering_info {};
|
||||
|
||||
@@ -568,7 +568,12 @@ RenderState RenderExecutor::AcquireRenderTargets(CommandBuffer& buffer, RenderCo
|
||||
EXIT("mixed color/depth sample counts are unsupported: %u and %u\n", attachment_samples,
|
||||
depth.desc.info.samples);
|
||||
}
|
||||
const auto layout = depth_attachment_layout(depth);
|
||||
const bool feedback = image.binding.is_bound && !depth_attachment_read_only(depth);
|
||||
if (feedback && !m_context.GetGraphics().attachment_feedback_loop_enabled) {
|
||||
EXIT("depth attachment feedback loop is not supported by the host\n");
|
||||
}
|
||||
const auto layout = feedback ? vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT
|
||||
: depth_attachment_layout(depth);
|
||||
// The attachment store writes even when guest depth/stencil tests do not.
|
||||
const auto access = vk::AccessFlagBits2::eDepthStencilAttachmentRead |
|
||||
vk::AccessFlagBits2::eDepthStencilAttachmentWrite;
|
||||
@@ -1143,6 +1148,14 @@ void RenderExecutor::ExecutePreparedDraw(uint64_t submit_id, CommandBuffer& buff
|
||||
|
||||
SetGraphicsDynamicParams(buffer, vk_buffer, state.vs_input_info, state.color_info,
|
||||
state.color_count, state.depth_info);
|
||||
if (m_context.GetGraphics().attachment_feedback_loop_enabled) {
|
||||
const auto aspects =
|
||||
rendering.depth_stencil_attachment.image_layout ==
|
||||
vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT
|
||||
? ImageViewOps::DepthAspectMask(state.depth_info.desc.view_info.format)
|
||||
: vk::ImageAspectFlags {};
|
||||
vk_buffer.setAttachmentFeedbackLoopEnableEXT(aspects);
|
||||
}
|
||||
|
||||
LogDrawPhase(draw.name, "BeginRendering");
|
||||
if (set_auto_debug) {
|
||||
|
||||
@@ -623,7 +623,22 @@ static vk::Device VulkanCreateDevice(vk::PhysicalDevice physical_device, const V
|
||||
supported_features2.sType = vk::StructureType::ePhysicalDeviceFeatures2;
|
||||
supported_features2.pNext = mesh_extension ? static_cast<void*>(&supported_mesh)
|
||||
: static_cast<void*>(&supported_features13);
|
||||
const bool feedback_extensions =
|
||||
HasExtension(device_extensions, VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME) &&
|
||||
HasExtension(device_extensions, VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME);
|
||||
vk::PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT feedback_layout {};
|
||||
vk::PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT feedback_dynamic {};
|
||||
if (feedback_extensions) {
|
||||
feedback_dynamic.pNext = supported_features2.pNext;
|
||||
feedback_layout.pNext = &feedback_dynamic;
|
||||
supported_features2.pNext = &feedback_layout;
|
||||
}
|
||||
physical_device.getFeatures2(&supported_features2);
|
||||
graphics.attachment_feedback_loop_enabled =
|
||||
feedback_extensions && feedback_layout.attachmentFeedbackLoopLayout &&
|
||||
feedback_dynamic.attachmentFeedbackLoopDynamicState;
|
||||
LOGF("Vulkan attachment feedback loop: %s\n",
|
||||
graphics.attachment_feedback_loop_enabled ? "true" : "false");
|
||||
graphics.mesh_shader_enabled = mesh_extension && supported_mesh.meshShader;
|
||||
if (graphics.mesh_shader_enabled) {
|
||||
vk::PhysicalDeviceProperties2 properties {};
|
||||
@@ -731,6 +746,11 @@ static vk::Device VulkanCreateDevice(vk::PhysicalDevice physical_device, const V
|
||||
create_info.sType = vk::StructureType::eDeviceCreateInfo;
|
||||
create_info.pNext =
|
||||
mesh_extension ? static_cast<void*>(&mesh_features) : static_cast<void*>(&features13);
|
||||
if (graphics.attachment_feedback_loop_enabled) {
|
||||
feedback_dynamic.pNext =
|
||||
mesh_extension ? static_cast<void*>(&mesh_features) : static_cast<void*>(&features13);
|
||||
create_info.pNext = &feedback_layout;
|
||||
}
|
||||
create_info.flags = {};
|
||||
create_info.pQueueCreateInfos = &queue_create_info;
|
||||
create_info.queueCreateInfoCount = 1;
|
||||
@@ -1117,6 +1137,11 @@ void WindowContext::CreateVulkan() {
|
||||
device_extensions.push_back(extension);
|
||||
}
|
||||
}
|
||||
if (HasExtension(available_extensions, VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME) &&
|
||||
HasExtension(available_extensions, VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME)) {
|
||||
device_extensions.push_back(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME);
|
||||
device_extensions.push_back(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
VulkanInitSubgroupSizeControl(graphic_ctx.physical_device, graphic_ctx);
|
||||
|
||||
Reference in New Issue
Block a user