mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[dxvk] Make use of VK_AMD_rasterization_order
May slightly improve GPU performance in some scenarios.
This commit is contained in:
parent
27573e9b25
commit
d3f84688cc
@ -1,20 +1,22 @@
|
|||||||
#include "dxvk_compute.h"
|
#include "dxvk_compute.h"
|
||||||
|
#include "dxvk_device.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxvkComputePipeline::DxvkComputePipeline(
|
DxvkComputePipeline::DxvkComputePipeline(
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
const DxvkDevice* device,
|
||||||
const Rc<DxvkPipelineCache>& cache,
|
const Rc<DxvkPipelineCache>& cache,
|
||||||
const Rc<DxvkShader>& cs)
|
const Rc<DxvkShader>& cs)
|
||||||
: m_vkd(vkd), m_cache(cache) {
|
: m_device(device), m_vkd(device->vkd()),
|
||||||
|
m_cache(cache) {
|
||||||
DxvkDescriptorSlotMapping slotMapping;
|
DxvkDescriptorSlotMapping slotMapping;
|
||||||
cs->defineResourceSlots(slotMapping);
|
cs->defineResourceSlots(slotMapping);
|
||||||
|
|
||||||
m_layout = new DxvkBindingLayout(vkd,
|
m_layout = new DxvkBindingLayout(m_vkd,
|
||||||
slotMapping.bindingCount(),
|
slotMapping.bindingCount(),
|
||||||
slotMapping.bindingInfos());
|
slotMapping.bindingInfos());
|
||||||
|
|
||||||
m_cs = cs->createShaderModule(vkd, slotMapping);
|
m_cs = cs->createShaderModule(m_vkd, slotMapping);
|
||||||
|
|
||||||
this->compilePipeline();
|
this->compilePipeline();
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
|
class DxvkDevice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Compute pipeline
|
* \brief Compute pipeline
|
||||||
*
|
*
|
||||||
@ -20,7 +22,7 @@ namespace dxvk {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkComputePipeline(
|
DxvkComputePipeline(
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
const DxvkDevice* device,
|
||||||
const Rc<DxvkPipelineCache>& cache,
|
const Rc<DxvkPipelineCache>& cache,
|
||||||
const Rc<DxvkShader>& cs);
|
const Rc<DxvkShader>& cs);
|
||||||
~DxvkComputePipeline();
|
~DxvkComputePipeline();
|
||||||
@ -47,7 +49,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
const DxvkDevice* const m_device;
|
||||||
|
const Rc<vk::DeviceFn> m_vkd;
|
||||||
|
|
||||||
Rc<DxvkPipelineCache> m_cache;
|
Rc<DxvkPipelineCache> m_cache;
|
||||||
Rc<DxvkBindingLayout> m_layout;
|
Rc<DxvkBindingLayout> m_layout;
|
||||||
Rc<DxvkShaderModule> m_cs;
|
Rc<DxvkShaderModule> m_cs;
|
||||||
|
@ -15,7 +15,7 @@ namespace dxvk {
|
|||||||
m_memory (new DxvkMemoryAllocator(adapter, vkd)),
|
m_memory (new DxvkMemoryAllocator(adapter, vkd)),
|
||||||
m_renderPassPool (new DxvkRenderPassPool (vkd)),
|
m_renderPassPool (new DxvkRenderPassPool (vkd)),
|
||||||
m_pipelineCache (new DxvkPipelineCache (vkd)),
|
m_pipelineCache (new DxvkPipelineCache (vkd)),
|
||||||
m_pipelineManager (new DxvkPipelineManager(vkd)),
|
m_pipelineManager (new DxvkPipelineManager(this)),
|
||||||
m_submissionQueue (this) {
|
m_submissionQueue (this) {
|
||||||
m_options.adjustAppOptions(env::getExeName());
|
m_options.adjustAppOptions(env::getExeName());
|
||||||
m_options.adjustDeviceOptions(m_adapter);
|
m_options.adjustDeviceOptions(m_adapter);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "dxvk_device.h"
|
||||||
#include "dxvk_graphics.h"
|
#include "dxvk_graphics.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
@ -33,14 +34,15 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
DxvkGraphicsPipeline::DxvkGraphicsPipeline(
|
DxvkGraphicsPipeline::DxvkGraphicsPipeline(
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
const DxvkDevice* device,
|
||||||
const Rc<DxvkPipelineCache>& cache,
|
const Rc<DxvkPipelineCache>& cache,
|
||||||
const Rc<DxvkShader>& vs,
|
const Rc<DxvkShader>& vs,
|
||||||
const Rc<DxvkShader>& tcs,
|
const Rc<DxvkShader>& tcs,
|
||||||
const Rc<DxvkShader>& tes,
|
const Rc<DxvkShader>& tes,
|
||||||
const Rc<DxvkShader>& gs,
|
const Rc<DxvkShader>& gs,
|
||||||
const Rc<DxvkShader>& fs)
|
const Rc<DxvkShader>& fs)
|
||||||
: m_vkd(vkd), m_cache(cache) {
|
: m_device(device), m_vkd(device->vkd()),
|
||||||
|
m_cache(cache) {
|
||||||
DxvkDescriptorSlotMapping slotMapping;
|
DxvkDescriptorSlotMapping slotMapping;
|
||||||
if (vs != nullptr) vs ->defineResourceSlots(slotMapping);
|
if (vs != nullptr) vs ->defineResourceSlots(slotMapping);
|
||||||
if (tcs != nullptr) tcs->defineResourceSlots(slotMapping);
|
if (tcs != nullptr) tcs->defineResourceSlots(slotMapping);
|
||||||
@ -48,15 +50,15 @@ namespace dxvk {
|
|||||||
if (gs != nullptr) gs ->defineResourceSlots(slotMapping);
|
if (gs != nullptr) gs ->defineResourceSlots(slotMapping);
|
||||||
if (fs != nullptr) fs ->defineResourceSlots(slotMapping);
|
if (fs != nullptr) fs ->defineResourceSlots(slotMapping);
|
||||||
|
|
||||||
m_layout = new DxvkBindingLayout(vkd,
|
m_layout = new DxvkBindingLayout(m_vkd,
|
||||||
slotMapping.bindingCount(),
|
slotMapping.bindingCount(),
|
||||||
slotMapping.bindingInfos());
|
slotMapping.bindingInfos());
|
||||||
|
|
||||||
if (vs != nullptr) m_vs = vs ->createShaderModule(vkd, slotMapping);
|
if (vs != nullptr) m_vs = vs ->createShaderModule(m_vkd, slotMapping);
|
||||||
if (tcs != nullptr) m_tcs = tcs->createShaderModule(vkd, slotMapping);
|
if (tcs != nullptr) m_tcs = tcs->createShaderModule(m_vkd, slotMapping);
|
||||||
if (tes != nullptr) m_tes = tes->createShaderModule(vkd, slotMapping);
|
if (tes != nullptr) m_tes = tes->createShaderModule(m_vkd, slotMapping);
|
||||||
if (gs != nullptr) m_gs = gs ->createShaderModule(vkd, slotMapping);
|
if (gs != nullptr) m_gs = gs ->createShaderModule(m_vkd, slotMapping);
|
||||||
if (fs != nullptr) m_fs = fs ->createShaderModule(vkd, slotMapping);
|
if (fs != nullptr) m_fs = fs ->createShaderModule(m_vkd, slotMapping);
|
||||||
|
|
||||||
m_vsIn = vs != nullptr ? vs->interfaceSlots().inputSlots : 0;
|
m_vsIn = vs != nullptr ? vs->interfaceSlots().inputSlots : 0;
|
||||||
m_fsOut = fs != nullptr ? fs->interfaceSlots().outputSlots : 0;
|
m_fsOut = fs != nullptr ? fs->interfaceSlots().outputSlots : 0;
|
||||||
@ -146,9 +148,14 @@ namespace dxvk {
|
|||||||
vpInfo.scissorCount = state.rsViewportCount;
|
vpInfo.scissorCount = state.rsViewportCount;
|
||||||
vpInfo.pScissors = nullptr;
|
vpInfo.pScissors = nullptr;
|
||||||
|
|
||||||
|
VkPipelineRasterizationStateRasterizationOrderAMD rsOrder;
|
||||||
|
rsOrder.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD;
|
||||||
|
rsOrder.pNext = nullptr;
|
||||||
|
rsOrder.rasterizationOrder = this->pickRasterizationOrder(state);
|
||||||
|
|
||||||
VkPipelineRasterizationStateCreateInfo rsInfo;
|
VkPipelineRasterizationStateCreateInfo rsInfo;
|
||||||
rsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
rsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||||
rsInfo.pNext = nullptr;
|
rsInfo.pNext = m_device->extensions().amdRasterizationOrder.enabled() ? &rsOrder : rsOrder.pNext;
|
||||||
rsInfo.flags = 0;
|
rsInfo.flags = 0;
|
||||||
rsInfo.depthClampEnable = state.rsEnableDepthClamp;
|
rsInfo.depthClampEnable = state.rsEnableDepthClamp;
|
||||||
rsInfo.rasterizerDiscardEnable= state.rsEnableDiscard;
|
rsInfo.rasterizerDiscardEnable= state.rsEnableDiscard;
|
||||||
@ -260,4 +267,29 @@ namespace dxvk {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VkRasterizationOrderAMD DxvkGraphicsPipeline::pickRasterizationOrder(
|
||||||
|
const DxvkGraphicsPipelineStateInfo& state) const {
|
||||||
|
// If blending is not enabled, we can enable out-of-order
|
||||||
|
// rasterization for certain depth-compare modes.
|
||||||
|
bool blendingEnabled = false;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||||
|
if (m_fsOut & (1u << i))
|
||||||
|
blendingEnabled |= state.omBlendAttachments[i].blendEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!blendingEnabled) {
|
||||||
|
if (m_device->hasOption(DxvkOption::AssumeNoZfight))
|
||||||
|
return VK_RASTERIZATION_ORDER_RELAXED_AMD;
|
||||||
|
|
||||||
|
if (state.dsDepthCompareOp == VK_COMPARE_OP_NEVER
|
||||||
|
|| state.dsDepthCompareOp == VK_COMPARE_OP_LESS
|
||||||
|
|| state.dsDepthCompareOp == VK_COMPARE_OP_GREATER)
|
||||||
|
return VK_RASTERIZATION_ORDER_RELAXED_AMD;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VK_RASTERIZATION_ORDER_STRICT_AMD;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
|
class DxvkDevice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Graphics pipeline state info
|
* \brief Graphics pipeline state info
|
||||||
*
|
*
|
||||||
@ -72,7 +74,7 @@ namespace dxvk {
|
|||||||
VkBool32 omEnableLogicOp;
|
VkBool32 omEnableLogicOp;
|
||||||
VkLogicOp omLogicOp;
|
VkLogicOp omLogicOp;
|
||||||
VkRenderPass omRenderPass;
|
VkRenderPass omRenderPass;
|
||||||
VkPipelineColorBlendAttachmentState omBlendAttachments[DxvkLimits::MaxNumRenderTargets];
|
VkPipelineColorBlendAttachmentState omBlendAttachments[MaxNumRenderTargets];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -88,7 +90,7 @@ namespace dxvk {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkGraphicsPipeline(
|
DxvkGraphicsPipeline(
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
const DxvkDevice* device,
|
||||||
const Rc<DxvkPipelineCache>& cache,
|
const Rc<DxvkPipelineCache>& cache,
|
||||||
const Rc<DxvkShader>& vs,
|
const Rc<DxvkShader>& vs,
|
||||||
const Rc<DxvkShader>& tcs,
|
const Rc<DxvkShader>& tcs,
|
||||||
@ -127,7 +129,9 @@ namespace dxvk {
|
|||||||
VkPipeline pipeline;
|
VkPipeline pipeline;
|
||||||
};
|
};
|
||||||
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
const DxvkDevice* const m_device;
|
||||||
|
const Rc<vk::DeviceFn> m_vkd;
|
||||||
|
|
||||||
Rc<DxvkPipelineCache> m_cache;
|
Rc<DxvkPipelineCache> m_cache;
|
||||||
Rc<DxvkBindingLayout> m_layout;
|
Rc<DxvkBindingLayout> m_layout;
|
||||||
|
|
||||||
@ -154,6 +158,9 @@ namespace dxvk {
|
|||||||
bool validatePipelineState(
|
bool validatePipelineState(
|
||||||
const DxvkGraphicsPipelineStateInfo& state) const;
|
const DxvkGraphicsPipelineStateInfo& state) const;
|
||||||
|
|
||||||
|
VkRasterizationOrderAMD pickRasterizationOrder(
|
||||||
|
const DxvkGraphicsPipelineStateInfo& state) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -5,7 +5,7 @@
|
|||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
const static std::unordered_map<std::string, DxvkOptionSet> g_appOptions = {{
|
const static std::unordered_map<std::string, DxvkOptionSet> g_appOptions = {{
|
||||||
|
{ "NieRAutomata.exe", DxvkOptionSet(DxvkOption::AssumeNoZfight) },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,8 +35,8 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkPipelineManager::DxvkPipelineManager(const Rc<vk::DeviceFn>& vkd)
|
DxvkPipelineManager::DxvkPipelineManager(const DxvkDevice* device)
|
||||||
: m_vkd(vkd) {
|
: m_device(device) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ namespace dxvk {
|
|||||||
return pair->second;
|
return pair->second;
|
||||||
|
|
||||||
const Rc<DxvkComputePipeline> pipeline
|
const Rc<DxvkComputePipeline> pipeline
|
||||||
= new DxvkComputePipeline(m_vkd, cache, cs);
|
= new DxvkComputePipeline(m_device, cache, cs);
|
||||||
m_computePipelines.insert(std::make_pair(key, pipeline));
|
m_computePipelines.insert(std::make_pair(key, pipeline));
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ namespace dxvk {
|
|||||||
return pair->second;
|
return pair->second;
|
||||||
|
|
||||||
const Rc<DxvkGraphicsPipeline> pipeline
|
const Rc<DxvkGraphicsPipeline> pipeline
|
||||||
= new DxvkGraphicsPipeline(m_vkd, cache, vs, tcs, tes, gs, fs);
|
= new DxvkGraphicsPipeline(m_device, cache, vs, tcs, tes, gs, fs);
|
||||||
m_graphicsPipelines.insert(std::make_pair(key, pipeline));
|
m_graphicsPipelines.insert(std::make_pair(key, pipeline));
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DxvkPipelineManager(
|
DxvkPipelineManager(const DxvkDevice* device);
|
||||||
const Rc<vk::DeviceFn>& vkd);
|
|
||||||
~DxvkPipelineManager();
|
~DxvkPipelineManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,7 +98,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const Rc<vk::DeviceFn> m_vkd;
|
const DxvkDevice* m_device;
|
||||||
|
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user