mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-28 02:19:26 +01:00
[dxvk] Consider point-mode tessellation for GS topology
This commit is contained in:
parent
aa637d6286
commit
0dec617c4e
@ -44,6 +44,19 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
VkPrimitiveTopology determinePreGsTopology(
|
||||
const DxvkGraphicsPipelineShaders& shaders,
|
||||
const DxvkGraphicsPipelineStateInfo& state) {
|
||||
if (shaders.tcs && shaders.tcs->flags().test(DxvkShaderFlag::TessellationPoints))
|
||||
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
|
||||
if (shaders.tes)
|
||||
return shaders.tes->info().outputTopology;
|
||||
|
||||
return state.ia.primitiveTopology();
|
||||
}
|
||||
|
||||
|
||||
DxvkGraphicsPipelineVertexInputState::DxvkGraphicsPipelineVertexInputState() {
|
||||
|
||||
}
|
||||
@ -52,13 +65,13 @@ namespace dxvk {
|
||||
DxvkGraphicsPipelineVertexInputState::DxvkGraphicsPipelineVertexInputState(
|
||||
const DxvkDevice* device,
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
const DxvkShader* vs) {
|
||||
const DxvkGraphicsPipelineShaders& shaders) {
|
||||
std::array<uint32_t, MaxNumVertexBindings> viBindingMap = { };
|
||||
|
||||
iaInfo.topology = state.ia.primitiveTopology();
|
||||
iaInfo.primitiveRestartEnable = state.ia.primitiveRestart();
|
||||
|
||||
uint32_t attrMask = vs->info().inputMask;
|
||||
uint32_t attrMask = shaders.vs->info().inputMask;
|
||||
uint32_t bindingMask = 0;
|
||||
|
||||
// Find out which bindings are used based on the attribute mask
|
||||
@ -244,10 +257,10 @@ namespace dxvk {
|
||||
DxvkGraphicsPipelineFragmentOutputState::DxvkGraphicsPipelineFragmentOutputState(
|
||||
const DxvkDevice* device,
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
const DxvkShader* fs) {
|
||||
const DxvkGraphicsPipelineShaders& shaders) {
|
||||
// Set up color formats and attachment blend states. Disable the write
|
||||
// mask for any attachment that the fragment shader does not write to.
|
||||
uint32_t fsOutputMask = fs ? fs->info().outputMask : 0u;
|
||||
uint32_t fsOutputMask = shaders.fs ? shaders.fs->info().outputMask : 0u;
|
||||
|
||||
// Dual-source blending can only write to one render target
|
||||
if (state.useDualSourceBlending())
|
||||
@ -331,13 +344,13 @@ namespace dxvk {
|
||||
: VK_SAMPLE_COUNT_1_BIT;
|
||||
}
|
||||
|
||||
if (fs && fs->flags().test(DxvkShaderFlag::HasSampleRateShading)) {
|
||||
if (shaders.fs && shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading)) {
|
||||
msInfo.sampleShadingEnable = VK_TRUE;
|
||||
msInfo.minSampleShading = 1.0f;
|
||||
}
|
||||
|
||||
// Alpha to coverage is not supported with sample mask exports.
|
||||
cbUseDynamicAlphaToCoverage = !fs || !fs->flags().test(DxvkShaderFlag::ExportsSampleMask);
|
||||
cbUseDynamicAlphaToCoverage = !shaders.fs || !shaders.fs->flags().test(DxvkShaderFlag::ExportsSampleMask);
|
||||
|
||||
msSampleMask = state.ms.sampleMask() & ((1u << msInfo.rasterizationSamples) - 1);
|
||||
msInfo.pSampleMask = &msSampleMask;
|
||||
@ -518,9 +531,7 @@ namespace dxvk {
|
||||
DxvkGraphicsPipelinePreRasterizationState::DxvkGraphicsPipelinePreRasterizationState(
|
||||
const DxvkDevice* device,
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
const DxvkShader* tes,
|
||||
const DxvkShader* gs,
|
||||
const DxvkShader* fs) {
|
||||
const DxvkGraphicsPipelineShaders& shaders) {
|
||||
// Set up tessellation state
|
||||
tsInfo.patchControlPoints = state.ia.patchVertexCount();
|
||||
|
||||
@ -532,7 +543,7 @@ namespace dxvk {
|
||||
|
||||
// Set up rasterized stream depending on geometry shader state.
|
||||
// Rasterizing stream 0 is default behaviour in all situations.
|
||||
int32_t streamIndex = gs ? gs->info().xfbRasterizedStream : 0;
|
||||
int32_t streamIndex = shaders.gs ? shaders.gs->info().xfbRasterizedStream : 0;
|
||||
|
||||
if (streamIndex > 0) {
|
||||
rsXfbStreamInfo.pNext = std::exchange(rsInfo.pNext, &rsXfbStreamInfo);
|
||||
@ -558,7 +569,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
// Set up line rasterization mode as requested by the application.
|
||||
if (state.rs.lineMode() != VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT && isLineRendering(state, tes, gs)) {
|
||||
if (state.rs.lineMode() != VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT && isLineRendering(shaders, state)) {
|
||||
rsLineInfo.pNext = std::exchange(rsInfo.pNext, &rsLineInfo);
|
||||
rsLineInfo.lineRasterizationMode = state.rs.lineMode();
|
||||
|
||||
@ -571,7 +582,7 @@ namespace dxvk {
|
||||
// in combination with smooth lines. Override the line mode to
|
||||
// rectangular to fix this, but keep the width fixed at 1.0.
|
||||
bool needsOverride = state.ms.enableAlphaToCoverage()
|
||||
|| (fs && fs->flags().test(DxvkShaderFlag::HasSampleRateShading));
|
||||
|| (shaders.fs && shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading));
|
||||
|
||||
if (needsOverride)
|
||||
rsLineInfo.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
|
||||
@ -633,15 +644,14 @@ namespace dxvk {
|
||||
|
||||
|
||||
bool DxvkGraphicsPipelinePreRasterizationState::isLineRendering(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
const DxvkShader* tes,
|
||||
const DxvkShader* gs) {
|
||||
const DxvkGraphicsPipelineShaders& shaders,
|
||||
const DxvkGraphicsPipelineStateInfo& state) {
|
||||
bool isLineRendering = state.rs.polygonMode() == VK_POLYGON_MODE_LINE;
|
||||
|
||||
if (gs) {
|
||||
isLineRendering |= gs->info().outputTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
} else if (tes) {
|
||||
isLineRendering |= tes->info().outputTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
if (shaders.gs) {
|
||||
isLineRendering |= shaders.gs->info().outputTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
} else if (shaders.tes) {
|
||||
isLineRendering |= shaders.tes->info().outputTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
} else {
|
||||
VkPrimitiveTopology topology = state.ia.primitiveTopology();
|
||||
|
||||
@ -874,7 +884,7 @@ namespace dxvk {
|
||||
|
||||
// Fix up input topology for geometry shaders as necessary
|
||||
if (shaderInfo.stage == VK_SHADER_STAGE_GEOMETRY_BIT) {
|
||||
VkPrimitiveTopology iaTopology = shaders.tes ? shaders.tes->info().outputTopology : state.ia.primitiveTopology();
|
||||
VkPrimitiveTopology iaTopology = determinePreGsTopology(shaders, state);
|
||||
info.inputTopology = determineGsInputTopology(shaderInfo.inputTopology, iaTopology);
|
||||
}
|
||||
|
||||
@ -1207,7 +1217,7 @@ namespace dxvk {
|
||||
|
||||
// We do not implement setting certain rarely used render
|
||||
// states dynamically since they are generally not used
|
||||
bool isLineRendering = DxvkGraphicsPipelinePreRasterizationState::isLineRendering(state, m_shaders.tes.ptr(), m_shaders.gs.ptr());
|
||||
bool isLineRendering = DxvkGraphicsPipelinePreRasterizationState::isLineRendering(m_shaders, state);
|
||||
|
||||
if (state.rs.polygonMode() != VK_POLYGON_MODE_FILL
|
||||
|| state.rs.conservativeMode() != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT
|
||||
@ -1235,7 +1245,7 @@ namespace dxvk {
|
||||
if (m_shaders.gs != nullptr) {
|
||||
// If the geometry shader's input topology is not compatible with
|
||||
// the topology set to the pipeline, we need to patch the GS.
|
||||
VkPrimitiveTopology iaTopology = m_shaders.tes ? m_shaders.tes->info().outputTopology : state.ia.primitiveTopology();
|
||||
VkPrimitiveTopology iaTopology = determinePreGsTopology(m_shaders, state);
|
||||
VkPrimitiveTopology gsTopology = m_shaders.gs->info().inputTopology;
|
||||
|
||||
if (determineGsInputTopology(gsTopology, iaTopology) != gsTopology)
|
||||
@ -1306,8 +1316,8 @@ namespace dxvk {
|
||||
|
||||
VkPipeline DxvkGraphicsPipeline::getBasePipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state) {
|
||||
DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr());
|
||||
DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr());
|
||||
DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders);
|
||||
DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders);
|
||||
|
||||
DxvkGraphicsPipelineBaseInstanceKey key;
|
||||
key.viLibrary = m_manager->createVertexInputLibrary(viState);
|
||||
|
@ -50,7 +50,7 @@ namespace dxvk {
|
||||
DxvkGraphicsPipelineVertexInputState(
|
||||
const DxvkDevice* device,
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
const DxvkShader* vs);
|
||||
const DxvkGraphicsPipelineShaders& shaders);
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo iaInfo = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
|
||||
VkPipelineVertexInputStateCreateInfo viInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO };
|
||||
@ -109,7 +109,7 @@ namespace dxvk {
|
||||
DxvkGraphicsPipelineFragmentOutputState(
|
||||
const DxvkDevice* device,
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
const DxvkShader* fs);
|
||||
const DxvkGraphicsPipelineShaders& shaders);
|
||||
|
||||
VkPipelineRenderingCreateInfo rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO };
|
||||
VkPipelineColorBlendStateCreateInfo cbInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO };
|
||||
@ -170,9 +170,7 @@ namespace dxvk {
|
||||
DxvkGraphicsPipelinePreRasterizationState(
|
||||
const DxvkDevice* device,
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
const DxvkShader* tes,
|
||||
const DxvkShader* gs,
|
||||
const DxvkShader* fs);
|
||||
const DxvkGraphicsPipelineShaders& shaders);
|
||||
|
||||
VkPipelineViewportStateCreateInfo vpInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO };
|
||||
VkPipelineTessellationStateCreateInfo tsInfo = { VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO };
|
||||
@ -187,9 +185,8 @@ namespace dxvk {
|
||||
size_t hash() const;
|
||||
|
||||
static bool isLineRendering(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
const DxvkShader* tes,
|
||||
const DxvkShader* gs);
|
||||
const DxvkGraphicsPipelineShaders& shaders,
|
||||
const DxvkGraphicsPipelineStateInfo& state);
|
||||
|
||||
};
|
||||
|
||||
@ -413,10 +410,10 @@ namespace dxvk {
|
||||
uint32_t specConstantMask)
|
||||
: shState(shaders, state),
|
||||
dyState(device, state, flags),
|
||||
viState(device, state, shaders.vs.ptr()),
|
||||
prState(device, state, shaders.tes.ptr(), shaders.gs.ptr(), shaders.fs.ptr()),
|
||||
viState(device, state, shaders),
|
||||
prState(device, state, shaders),
|
||||
fsState(device, state),
|
||||
foState(device, state, shaders.fs.ptr()),
|
||||
foState(device, state, shaders),
|
||||
scState(specConstantMask, state.sc) { }
|
||||
|
||||
DxvkGraphicsPipelineShaderState shState;
|
||||
|
Loading…
x
Reference in New Issue
Block a user