mirror of https://github.com/PCSX2/pcsx2.git
GS/Vulkan: Use VK_ARM_rasterization_order_attachment_access if available
This commit is contained in:
parent
a6b4ca69db
commit
4e6b86f8f4
|
@ -352,6 +352,11 @@ namespace Vulkan
|
|||
}
|
||||
}
|
||||
|
||||
void GraphicsPipelineBuilder::AddBlendFlags(u32 flags)
|
||||
{
|
||||
m_blend_state.flags |= flags;
|
||||
}
|
||||
|
||||
void GraphicsPipelineBuilder::ClearBlendAttachments()
|
||||
{
|
||||
m_blend_attachments = {};
|
||||
|
|
|
@ -112,6 +112,7 @@ namespace Vulkan
|
|||
VkBlendOp op, VkBlendFactor alpha_src_factor, VkBlendFactor alpha_dst_factor, VkBlendOp alpha_op,
|
||||
VkColorComponentFlags write_mask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
|
||||
void AddBlendFlags(u32 flags);
|
||||
void ClearBlendAttachments();
|
||||
|
||||
void SetBlendConstants(float r, float g, float b, float a);
|
||||
|
|
|
@ -445,6 +445,8 @@ namespace Vulkan
|
|||
SupportsExtension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, false);
|
||||
m_optional_extensions.vk_khr_driver_properties =
|
||||
SupportsExtension(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, false);
|
||||
m_optional_extensions.vk_arm_rasterization_order_attachment_access =
|
||||
SupportsExtension(VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -597,11 +599,19 @@ namespace Vulkan
|
|||
// provoking vertex
|
||||
VkPhysicalDeviceProvokingVertexFeaturesEXT provoking_vertex_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT};
|
||||
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM rasterization_order_access_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM};
|
||||
|
||||
if (m_optional_extensions.vk_ext_provoking_vertex)
|
||||
{
|
||||
provoking_vertex_feature.provokingVertexLast = VK_TRUE;
|
||||
Util::AddPointerToChain(&device_info, &provoking_vertex_feature);
|
||||
}
|
||||
if (m_optional_extensions.vk_arm_rasterization_order_attachment_access)
|
||||
{
|
||||
rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess = VK_TRUE;
|
||||
Util::AddPointerToChain(&device_info, &rasterization_order_access_feature);
|
||||
}
|
||||
|
||||
VkResult res = vkCreateDevice(m_physical_device, &device_info, nullptr, &m_device);
|
||||
if (res != VK_SUCCESS)
|
||||
|
@ -636,20 +646,21 @@ namespace Vulkan
|
|||
VkPhysicalDeviceFeatures2 features2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
|
||||
VkPhysicalDeviceProvokingVertexFeaturesEXT provoking_vertex_features = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT};
|
||||
void** pNext = &features2.pNext;
|
||||
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM rasterization_order_access_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM};
|
||||
|
||||
// add in optional feature structs
|
||||
if (m_optional_extensions.vk_ext_provoking_vertex)
|
||||
{
|
||||
*pNext = &provoking_vertex_features;
|
||||
pNext = &provoking_vertex_features.pNext;
|
||||
}
|
||||
Util::AddPointerToChain(&features2, &provoking_vertex_features);
|
||||
if (m_optional_extensions.vk_arm_rasterization_order_attachment_access)
|
||||
Util::AddPointerToChain(&features2, &rasterization_order_access_feature);
|
||||
|
||||
// query
|
||||
vkGetPhysicalDeviceFeatures2(m_physical_device, &features2);
|
||||
|
||||
// confirm we actually support it
|
||||
m_optional_extensions.vk_ext_provoking_vertex &= (provoking_vertex_features.provokingVertexLast == VK_TRUE);
|
||||
m_optional_extensions.vk_arm_rasterization_order_attachment_access &= (rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess == VK_TRUE);
|
||||
}
|
||||
|
||||
if (vkGetPhysicalDeviceProperties2)
|
||||
|
@ -670,6 +681,8 @@ namespace Vulkan
|
|||
|
||||
Console.WriteLn("VK_EXT_provoking_vertex is %s",
|
||||
m_optional_extensions.vk_ext_provoking_vertex ? "supported" : "NOT supported");
|
||||
Console.WriteLn("VK_ARM_rasterization_order_attachment_access is %s",
|
||||
m_optional_extensions.vk_arm_rasterization_order_attachment_access ? "supported" : "NOT supported");
|
||||
}
|
||||
|
||||
bool Context::CreateAllocator()
|
||||
|
@ -1388,6 +1401,9 @@ namespace Vulkan
|
|||
input_reference.layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
input_reference_ptr = &input_reference;
|
||||
|
||||
if (!g_vulkan_context->GetOptionalExtensions().vk_arm_rasterization_order_attachment_access)
|
||||
{
|
||||
// don't need the framebuffer-local dependency when we have rasterization order attachment access
|
||||
subpass_dependency.srcSubpass = 0;
|
||||
subpass_dependency.dstSubpass = 0;
|
||||
subpass_dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
|
@ -1398,6 +1414,7 @@ namespace Vulkan
|
|||
subpass_dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
|
||||
subpass_dependency_ptr = &subpass_dependency;
|
||||
}
|
||||
}
|
||||
|
||||
num_attachments++;
|
||||
}
|
||||
|
@ -1415,7 +1432,10 @@ namespace Vulkan
|
|||
num_attachments++;
|
||||
}
|
||||
|
||||
const VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, input_reference_ptr ? 1u : 0u,
|
||||
const VkSubpassDescriptionFlags subpass_flags =
|
||||
(key.color_feedback_loop && g_vulkan_context->GetOptionalExtensions().vk_arm_rasterization_order_attachment_access)
|
||||
? VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM : 0;
|
||||
const VkSubpassDescription subpass = {subpass_flags, VK_PIPELINE_BIND_POINT_GRAPHICS, input_reference_ptr ? 1u : 0u,
|
||||
input_reference_ptr ? input_reference_ptr : nullptr, color_reference_ptr ? 1u : 0u,
|
||||
color_reference_ptr ? color_reference_ptr : nullptr, nullptr, depth_reference_ptr, 0, nullptr};
|
||||
const VkRenderPassCreateInfo pass_info = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0u,
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace Vulkan
|
|||
bool vk_ext_provoking_vertex : 1;
|
||||
bool vk_ext_memory_budget : 1;
|
||||
bool vk_khr_driver_properties : 1;
|
||||
bool vk_arm_rasterization_order_attachment_access : 1;
|
||||
};
|
||||
|
||||
~Context();
|
||||
|
|
|
@ -237,13 +237,13 @@ bool GSDeviceVK::CheckFeatures()
|
|||
const bool isAMD = (vendorID == 0x1002 || vendorID == 0x1022);
|
||||
// const bool isNVIDIA = (vendorID == 0x10DE);
|
||||
|
||||
m_features.framebuffer_fetch = g_vulkan_context->GetOptionalExtensions().vk_arm_rasterization_order_attachment_access && !GSConfig.DisableFramebufferFetch;
|
||||
m_features.texture_barrier = GSConfig.OverrideTextureBarriers != 0;
|
||||
m_features.broken_point_sampler = isAMD;
|
||||
m_features.geometry_shader = features.geometryShader && GSConfig.OverrideGeometryShaders != 0;
|
||||
m_features.image_load_store = features.fragmentStoresAndAtomics && m_features.texture_barrier;
|
||||
m_features.prefer_new_textures = true;
|
||||
m_features.provoking_vertex_last = g_vulkan_context->GetOptionalExtensions().vk_ext_provoking_vertex;
|
||||
m_features.framebuffer_fetch = false;
|
||||
m_features.dual_source_blend = features.dualSrcBlend && !GSConfig.DisableDualSourceBlend;
|
||||
|
||||
if (!m_features.dual_source_blend)
|
||||
|
@ -259,6 +259,12 @@ bool GSDeviceVK::CheckFeatures()
|
|||
m_features.stencil_buffer = ((props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0);
|
||||
}
|
||||
|
||||
// Fbfetch is useless if we don't have barriers enabled.
|
||||
m_features.framebuffer_fetch &= m_features.texture_barrier;
|
||||
|
||||
// Use D32F depth instead of D32S8 when we have framebuffer fetch.
|
||||
m_features.stencil_buffer &= !m_features.framebuffer_fetch;
|
||||
|
||||
// whether we can do point/line expand depends on the range of the device
|
||||
const float f_upscale = static_cast<float>(GSConfig.UpscaleMultiplier);
|
||||
m_features.point_expand =
|
||||
|
@ -1930,6 +1936,12 @@ VkPipeline GSDeviceVK::CreateTFXPipeline(const PipelineSelector& p)
|
|||
if (m_features.provoking_vertex_last)
|
||||
gpb.SetProvokingVertex(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT);
|
||||
|
||||
// Tests have shown that it's faster to just enable rast order on the entire pass, rather than alternating
|
||||
// between turning it on and off for different draws, and adding the required barrier between non-rast-order
|
||||
// and rast-order draws.
|
||||
if (m_features.framebuffer_fetch && p.feedback_loop)
|
||||
gpb.AddBlendFlags(VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM);
|
||||
|
||||
VkPipeline pipeline = gpb.Create(g_vulkan_context->GetDevice(), g_vulkan_shader_cache->GetPipelineCache(true));
|
||||
if (pipeline)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue