mirror of https://github.com/PCSX2/pcsx2.git
GS/Vulkan: Use VK_EXT_provoking_vertex where supported
This commit is contained in:
parent
bf389b94d6
commit
220c7c271b
|
@ -149,6 +149,9 @@ namespace Vulkan
|
||||||
m_multisample_state = {};
|
m_multisample_state = {};
|
||||||
m_multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
m_multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||||
|
|
||||||
|
m_provoking_vertex = {};
|
||||||
|
m_provoking_vertex.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT;
|
||||||
|
|
||||||
// set defaults
|
// set defaults
|
||||||
SetNoCullRasterizationState();
|
SetNoCullRasterizationState();
|
||||||
SetNoDepthTestState();
|
SetNoDepthTestState();
|
||||||
|
@ -420,6 +423,13 @@ namespace Vulkan
|
||||||
m_ci.subpass = subpass;
|
m_ci.subpass = subpass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphicsPipelineBuilder::SetProvokingVertex(VkProvokingVertexModeEXT mode)
|
||||||
|
{
|
||||||
|
Util::AddPointerToChain(&m_rasterization_state, &m_provoking_vertex);
|
||||||
|
|
||||||
|
m_provoking_vertex.provokingVertexMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
SamplerBuilder::SamplerBuilder() { Clear(); }
|
SamplerBuilder::SamplerBuilder() { Clear(); }
|
||||||
|
|
||||||
void SamplerBuilder::Clear()
|
void SamplerBuilder::Clear()
|
||||||
|
|
|
@ -128,6 +128,8 @@ namespace Vulkan
|
||||||
void SetPipelineLayout(VkPipelineLayout layout);
|
void SetPipelineLayout(VkPipelineLayout layout);
|
||||||
void SetRenderPass(VkRenderPass render_pass, u32 subpass);
|
void SetRenderPass(VkRenderPass render_pass, u32 subpass);
|
||||||
|
|
||||||
|
void SetProvokingVertex(VkProvokingVertexModeEXT mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VkGraphicsPipelineCreateInfo m_ci;
|
VkGraphicsPipelineCreateInfo m_ci;
|
||||||
std::array<VkPipelineShaderStageCreateInfo, MAX_SHADER_STAGES> m_shader_stages;
|
std::array<VkPipelineShaderStageCreateInfo, MAX_SHADER_STAGES> m_shader_stages;
|
||||||
|
@ -152,6 +154,8 @@ namespace Vulkan
|
||||||
std::array<VkDynamicState, MAX_DYNAMIC_STATE> m_dynamic_state_values;
|
std::array<VkDynamicState, MAX_DYNAMIC_STATE> m_dynamic_state_values;
|
||||||
|
|
||||||
VkPipelineMultisampleStateCreateInfo m_multisample_state;
|
VkPipelineMultisampleStateCreateInfo m_multisample_state;
|
||||||
|
|
||||||
|
VkPipelineRasterizationProvokingVertexStateCreateInfoEXT m_provoking_vertex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SamplerBuilder
|
class SamplerBuilder
|
||||||
|
|
|
@ -458,6 +458,9 @@ namespace Vulkan
|
||||||
if (enable_surface && !SupportsExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME, true))
|
if (enable_surface && !SupportsExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME, true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
m_optional_extensions.vk_ext_provoking_vertex =
|
||||||
|
SupportsExtension(VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,6 +608,15 @@ namespace Vulkan
|
||||||
device_info.ppEnabledLayerNames = layer_names;
|
device_info.ppEnabledLayerNames = layer_names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// provoking vertex
|
||||||
|
VkPhysicalDeviceProvokingVertexFeaturesEXT provoking_vertex_feature = {
|
||||||
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT};
|
||||||
|
if (m_optional_extensions.vk_ext_provoking_vertex)
|
||||||
|
{
|
||||||
|
provoking_vertex_feature.provokingVertexLast = VK_TRUE;
|
||||||
|
Util::AddPointerToChain(&device_info, &provoking_vertex_feature);
|
||||||
|
}
|
||||||
|
|
||||||
VkResult res = vkCreateDevice(m_physical_device, &device_info, nullptr, &m_device);
|
VkResult res = vkCreateDevice(m_physical_device, &device_info, nullptr, &m_device);
|
||||||
if (res != VK_SUCCESS)
|
if (res != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -622,9 +634,39 @@ namespace Vulkan
|
||||||
{
|
{
|
||||||
vkGetDeviceQueue(m_device, m_present_queue_family_index, 0, &m_present_queue);
|
vkGetDeviceQueue(m_device, m_present_queue_family_index, 0, &m_present_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProcessDeviceExtensions();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::ProcessDeviceExtensions()
|
||||||
|
{
|
||||||
|
// advanced feature checks
|
||||||
|
if (vkGetPhysicalDeviceFeatures2)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
// add in optional feature structs
|
||||||
|
if (m_optional_extensions.vk_ext_provoking_vertex)
|
||||||
|
{
|
||||||
|
*pNext = &provoking_vertex_features;
|
||||||
|
pNext = &provoking_vertex_features.pNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
// query
|
||||||
|
vkGetPhysicalDeviceFeatures2(m_physical_device, &features2);
|
||||||
|
|
||||||
|
// confirm we actually support it
|
||||||
|
m_optional_extensions.vk_ext_provoking_vertex &= (provoking_vertex_features.provokingVertexLast == VK_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLn("VK_EXT_provoking_vertex is %s",
|
||||||
|
m_optional_extensions.vk_ext_provoking_vertex ? "supported" : "NOT supported");
|
||||||
|
}
|
||||||
|
|
||||||
bool Context::CreateAllocator()
|
bool Context::CreateAllocator()
|
||||||
{
|
{
|
||||||
VmaAllocatorCreateInfo ci = {};
|
VmaAllocatorCreateInfo ci = {};
|
||||||
|
@ -1124,7 +1166,8 @@ namespace Vulkan
|
||||||
void Context::DeferBufferDestruction(VkBuffer object, VmaAllocation allocation)
|
void Context::DeferBufferDestruction(VkBuffer object, VmaAllocation allocation)
|
||||||
{
|
{
|
||||||
FrameResources& resources = m_frame_resources[m_current_frame];
|
FrameResources& resources = m_frame_resources[m_current_frame];
|
||||||
resources.cleanup_resources.push_back([this, object, allocation]() { vmaDestroyBuffer(m_allocator, object, allocation); });
|
resources.cleanup_resources.push_back(
|
||||||
|
[this, object, allocation]() { vmaDestroyBuffer(m_allocator, object, allocation); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::DeferBufferViewDestruction(VkBufferView object)
|
void Context::DeferBufferViewDestruction(VkBufferView object)
|
||||||
|
|
|
@ -46,6 +46,11 @@ namespace Vulkan
|
||||||
TEXTURE_BUFFER_SIZE = 64 * 1024 * 1024,
|
TEXTURE_BUFFER_SIZE = 64 * 1024 * 1024,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OptionalExtensions
|
||||||
|
{
|
||||||
|
bool vk_ext_provoking_vertex : 1;
|
||||||
|
};
|
||||||
|
|
||||||
~Context();
|
~Context();
|
||||||
|
|
||||||
// Determines if the Vulkan validation layer is available on the system.
|
// Determines if the Vulkan validation layer is available on the system.
|
||||||
|
@ -89,6 +94,7 @@ namespace Vulkan
|
||||||
__fi const VkPhysicalDeviceProperties& GetDeviceProperties() const { return m_device_properties; }
|
__fi const VkPhysicalDeviceProperties& GetDeviceProperties() const { return m_device_properties; }
|
||||||
__fi const VkPhysicalDeviceFeatures& GetDeviceFeatures() const { return m_device_features; }
|
__fi const VkPhysicalDeviceFeatures& GetDeviceFeatures() const { return m_device_features; }
|
||||||
__fi const VkPhysicalDeviceLimits& GetDeviceLimits() const { return m_device_properties.limits; }
|
__fi const VkPhysicalDeviceLimits& GetDeviceLimits() const { return m_device_properties.limits; }
|
||||||
|
__fi const OptionalExtensions& GetOptionalExtensions() const { return m_optional_extensions; }
|
||||||
|
|
||||||
// Helpers for getting constants
|
// Helpers for getting constants
|
||||||
__fi VkDeviceSize GetUniformBufferAlignment() const
|
__fi VkDeviceSize GetUniformBufferAlignment() const
|
||||||
|
@ -239,6 +245,7 @@ namespace Vulkan
|
||||||
bool CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer, const char** required_device_extensions,
|
bool CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer, const char** required_device_extensions,
|
||||||
u32 num_required_device_extensions, const char** required_device_layers, u32 num_required_device_layers,
|
u32 num_required_device_extensions, const char** required_device_layers, u32 num_required_device_layers,
|
||||||
const VkPhysicalDeviceFeatures* required_features);
|
const VkPhysicalDeviceFeatures* required_features);
|
||||||
|
void ProcessDeviceExtensions();
|
||||||
|
|
||||||
bool CreateAllocator();
|
bool CreateAllocator();
|
||||||
void DestroyAllocator();
|
void DestroyAllocator();
|
||||||
|
@ -323,6 +330,7 @@ namespace Vulkan
|
||||||
VkPhysicalDeviceFeatures m_device_features = {};
|
VkPhysicalDeviceFeatures m_device_features = {};
|
||||||
VkPhysicalDeviceProperties m_device_properties = {};
|
VkPhysicalDeviceProperties m_device_properties = {};
|
||||||
VkPhysicalDeviceMemoryProperties m_device_memory_properties = {};
|
VkPhysicalDeviceMemoryProperties m_device_memory_properties = {};
|
||||||
|
OptionalExtensions m_optional_extensions = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|
|
@ -257,6 +257,20 @@ namespace Vulkan
|
||||||
command_buffer, src_stage_mask, dst_stage_mask, 0, 0, nullptr, 1, &buffer_info, 0, nullptr);
|
command_buffer, src_stage_mask, dst_stage_mask, 0, 0, nullptr, 1, &buffer_info, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddPointerToChain(void* head, const void* ptr)
|
||||||
|
{
|
||||||
|
VkBaseInStructure* last_st = static_cast<VkBaseInStructure*>(head);
|
||||||
|
while (last_st->pNext)
|
||||||
|
{
|
||||||
|
if (last_st->pNext == ptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
last_st = const_cast<VkBaseInStructure*>(last_st->pNext);
|
||||||
|
}
|
||||||
|
|
||||||
|
last_st->pNext = static_cast<const VkBaseInStructure*>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
const char* VkResultToString(VkResult res)
|
const char* VkResultToString(VkResult res)
|
||||||
{
|
{
|
||||||
switch (res)
|
switch (res)
|
||||||
|
|
|
@ -49,6 +49,9 @@ namespace Vulkan
|
||||||
VkAccessFlags dst_access_mask, VkDeviceSize offset, VkDeviceSize size, VkPipelineStageFlags src_stage_mask,
|
VkAccessFlags dst_access_mask, VkDeviceSize offset, VkDeviceSize size, VkPipelineStageFlags src_stage_mask,
|
||||||
VkPipelineStageFlags dst_stage_mask);
|
VkPipelineStageFlags dst_stage_mask);
|
||||||
|
|
||||||
|
// Adds a structure to a chain.
|
||||||
|
void AddPointerToChain(void* head, const void* ptr);
|
||||||
|
|
||||||
const char* VkResultToString(VkResult res);
|
const char* VkResultToString(VkResult res);
|
||||||
void LogVulkanResult(const char* func_name, VkResult res, const char* msg, ...) /*printflike(4, 5)*/;
|
void LogVulkanResult(const char* func_name, VkResult res, const char* msg, ...) /*printflike(4, 5)*/;
|
||||||
|
|
||||||
|
|
|
@ -244,6 +244,7 @@ bool GSDeviceVK::CheckFeatures()
|
||||||
m_features.image_load_store = features.fragmentStoresAndAtomics;
|
m_features.image_load_store = features.fragmentStoresAndAtomics;
|
||||||
m_features.texture_barrier = true;
|
m_features.texture_barrier = true;
|
||||||
m_features.prefer_new_textures = true;
|
m_features.prefer_new_textures = true;
|
||||||
|
m_features.provoking_vertex_last = g_vulkan_context->GetOptionalExtensions().vk_ext_provoking_vertex;
|
||||||
|
|
||||||
if (!features.dualSrcBlend)
|
if (!features.dualSrcBlend)
|
||||||
{
|
{
|
||||||
|
@ -1271,6 +1272,10 @@ bool GSDeviceVK::CompileConvertPipelines()
|
||||||
gpb.SetNoBlendingState();
|
gpb.SetNoBlendingState();
|
||||||
gpb.SetVertexShader(vs);
|
gpb.SetVertexShader(vs);
|
||||||
|
|
||||||
|
// we enable provoking vertex here anyway, in case it doesn't support multiple modes in the same pass
|
||||||
|
if (m_features.provoking_vertex_last)
|
||||||
|
gpb.SetProvokingVertex(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT);
|
||||||
|
|
||||||
for (ShaderConvert i = ShaderConvert::COPY; static_cast<int>(i) < static_cast<int>(ShaderConvert::Count);
|
for (ShaderConvert i = ShaderConvert::COPY; static_cast<int>(i) < static_cast<int>(ShaderConvert::Count);
|
||||||
i = static_cast<ShaderConvert>(static_cast<int>(i) + 1))
|
i = static_cast<ShaderConvert>(static_cast<int>(i) + 1))
|
||||||
{
|
{
|
||||||
|
@ -1494,6 +1499,10 @@ bool GSDeviceVK::CompileInterlacePipelines()
|
||||||
gpb.SetRenderPass(rp, 0);
|
gpb.SetRenderPass(rp, 0);
|
||||||
gpb.SetVertexShader(vs);
|
gpb.SetVertexShader(vs);
|
||||||
|
|
||||||
|
// we enable provoking vertex here anyway, in case it doesn't support multiple modes in the same pass
|
||||||
|
if (m_features.provoking_vertex_last)
|
||||||
|
gpb.SetProvokingVertex(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT);
|
||||||
|
|
||||||
for (int i = 0; i < static_cast<int>(m_interlace.size()); i++)
|
for (int i = 0; i < static_cast<int>(m_interlace.size()); i++)
|
||||||
{
|
{
|
||||||
VkShaderModule ps = GetUtilityFragmentShader(*shader, StringUtil::StdStringFromFormat("ps_main%d", i).c_str());
|
VkShaderModule ps = GetUtilityFragmentShader(*shader, StringUtil::StdStringFromFormat("ps_main%d", i).c_str());
|
||||||
|
@ -1543,6 +1552,10 @@ bool GSDeviceVK::CompileMergePipelines()
|
||||||
gpb.SetRenderPass(rp, 0);
|
gpb.SetRenderPass(rp, 0);
|
||||||
gpb.SetVertexShader(vs);
|
gpb.SetVertexShader(vs);
|
||||||
|
|
||||||
|
// we enable provoking vertex here anyway, in case it doesn't support multiple modes in the same pass
|
||||||
|
if (m_features.provoking_vertex_last)
|
||||||
|
gpb.SetProvokingVertex(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT);
|
||||||
|
|
||||||
for (int i = 0; i < static_cast<int>(m_merge.size()); i++)
|
for (int i = 0; i < static_cast<int>(m_merge.size()); i++)
|
||||||
{
|
{
|
||||||
VkShaderModule ps = GetUtilityFragmentShader(*shader, StringUtil::StdStringFromFormat("ps_main%d", i).c_str());
|
VkShaderModule ps = GetUtilityFragmentShader(*shader, StringUtil::StdStringFromFormat("ps_main%d", i).c_str());
|
||||||
|
@ -1872,6 +1885,9 @@ VkPipeline GSDeviceVK::CreateTFXPipeline(const PipelineSelector& p)
|
||||||
VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, p.cms.wrgba);
|
VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, p.cms.wrgba);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_features.provoking_vertex_last)
|
||||||
|
gpb.SetProvokingVertex(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT);
|
||||||
|
|
||||||
VkPipeline pipeline = gpb.Create(g_vulkan_context->GetDevice(), g_vulkan_shader_cache->GetPipelineCache(true));
|
VkPipeline pipeline = gpb.Create(g_vulkan_context->GetDevice(), g_vulkan_shader_cache->GetPipelineCache(true));
|
||||||
if (pipeline)
|
if (pipeline)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue