1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-11 19:24:11 +01:00

[dxvk] Add line rasterization mode to rasterization state

This commit is contained in:
Philip Rebohle 2023-07-19 20:51:07 +02:00
parent 228cd4c331
commit 5ece97f769
11 changed files with 89 additions and 12 deletions

View File

@ -5401,6 +5401,7 @@ namespace dxvk {
pRsState->conservativeMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT;
pRsState->sampleCount = 0;
pRsState->flatShading = VK_FALSE;
pRsState->lineMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
}

View File

@ -38,6 +38,7 @@ namespace dxvk {
m_state.conservativeMode = DecodeConservativeRasterizationMode(desc.ConservativeRaster);
m_state.sampleCount = VkSampleCountFlags(desc.ForcedSampleCount);
m_state.flatShading = VK_FALSE;
m_state.lineMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
m_depthBias.depthBiasConstant = float(desc.DepthBias);
m_depthBias.depthBiasSlope = desc.SlopeScaledDepthBias;

View File

@ -127,6 +127,7 @@ namespace dxvk {
VkConservativeRasterizationModeEXT conservativeMode;
VkSampleCountFlags sampleCount;
VkBool32 flatShading;
VkLineRasterizationModeEXT lineMode;
};

View File

@ -2540,7 +2540,8 @@ namespace dxvk {
rs.polygonMode,
rs.sampleCount,
rs.conservativeMode,
rs.flatShading);
rs.flatShading,
rs.lineMode);
if (!m_state.gp.state.rs.eq(rsInfo)) {
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);

View File

@ -459,7 +459,9 @@ namespace dxvk {
DxvkGraphicsPipelinePreRasterizationState::DxvkGraphicsPipelinePreRasterizationState(
const DxvkDevice* device,
const DxvkGraphicsPipelineStateInfo& state,
const DxvkShader* gs) {
const DxvkShader* tes,
const DxvkShader* gs,
const DxvkShader* fs) {
// Set up tessellation state
tsInfo.patchControlPoints = state.ia.patchVertexCount();
@ -495,6 +497,27 @@ namespace dxvk {
rsConservativeInfo.conservativeRasterizationMode = state.rs.conservativeMode();
rsConservativeInfo.extraPrimitiveOverestimationSize = 0.0f;
}
// Set up line rasterization mode as requested by the application.
if (state.rs.lineMode() != VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT && isLineRendering(state, tes, gs)) {
rsLineInfo.pNext = std::exchange(rsInfo.pNext, &rsLineInfo);
rsLineInfo.lineRasterizationMode = state.rs.lineMode();
if (rsLineInfo.lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT) {
// This line width matches expected D3D behaviour, hard-code this
// so that we don't need to introduce an extra bit of render state.
rsInfo.lineWidth = 1.4f;
} else {
// Vulkan does not allow alphaToCoverage or sample rate shading
// 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));
if (needsOverride)
rsLineInfo.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
}
}
}
@ -521,6 +544,9 @@ namespace dxvk {
&& rsConservativeInfo.extraPrimitiveOverestimationSize == other.rsConservativeInfo.extraPrimitiveOverestimationSize;
}
if (eq)
eq = rsLineInfo.lineRasterizationMode == other.rsLineInfo.lineRasterizationMode;
return eq;
}
@ -541,10 +567,35 @@ namespace dxvk {
hash.add(rsConservativeInfo.conservativeRasterizationMode);
hash.add(bit::cast<uint32_t>(rsConservativeInfo.extraPrimitiveOverestimationSize));
hash.add(rsLineInfo.lineRasterizationMode);
return hash;
}
bool DxvkGraphicsPipelinePreRasterizationState::isLineRendering(
const DxvkGraphicsPipelineStateInfo& state,
const DxvkShader* tes,
const DxvkShader* gs) {
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;
} else {
VkPrimitiveTopology topology = state.ia.primitiveTopology();
isLineRendering |= topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST
|| topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP
|| topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY
|| topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
}
return isLineRendering;
}
DxvkGraphicsPipelineFragmentShaderState::DxvkGraphicsPipelineFragmentShaderState() {
}
@ -1078,11 +1129,13 @@ namespace dxvk {
if (!m_vsLibrary || !m_fsLibrary)
return false;
// Certain rasterization states cannot be set dynamically,
// so we're assuming defaults for them, most notably the
// polygon mode and conservative rasterization settings
// 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());
if (state.rs.polygonMode() != VK_POLYGON_MODE_FILL
|| state.rs.conservativeMode() != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT)
|| state.rs.conservativeMode() != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT
|| (state.rs.lineMode() != VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT && isLineRendering))
return false;
if (m_shaders.tcs != nullptr) {

View File

@ -168,7 +168,9 @@ namespace dxvk {
DxvkGraphicsPipelinePreRasterizationState(
const DxvkDevice* device,
const DxvkGraphicsPipelineStateInfo& state,
const DxvkShader* gs);
const DxvkShader* tes,
const DxvkShader* gs,
const DxvkShader* fs);
VkPipelineViewportStateCreateInfo vpInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO };
VkPipelineTessellationStateCreateInfo tsInfo = { VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO };
@ -176,10 +178,17 @@ namespace dxvk {
VkPipelineRasterizationDepthClipStateCreateInfoEXT rsDepthClipInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT };
VkPipelineRasterizationStateStreamCreateInfoEXT rsXfbStreamInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT };
VkPipelineRasterizationConservativeStateCreateInfoEXT rsConservativeInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT };
VkPipelineRasterizationLineStateCreateInfoEXT rsLineInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT };
bool eq(const DxvkGraphicsPipelinePreRasterizationState& other) const;
size_t hash() const;
static bool isLineRendering(
const DxvkGraphicsPipelineStateInfo& state,
const DxvkShader* tes,
const DxvkShader* gs);
};
@ -406,7 +415,7 @@ namespace dxvk {
: shState(shaders, state),
dyState(device, state, flags),
viState(device, state, shaders.vs.ptr()),
prState(device, state, shaders.gs.ptr()),
prState(device, state, shaders.tes.ptr(), shaders.gs.ptr(), shaders.fs.ptr()),
fsState(device, state),
foState(device, state, shaders.fs.ptr()),
scState(specConstantMask, state.sc) { }

View File

@ -223,13 +223,15 @@ namespace dxvk {
VkPolygonMode polygonMode,
VkSampleCountFlags sampleCount,
VkConservativeRasterizationModeEXT conservativeMode,
VkBool32 flatShading)
VkBool32 flatShading,
VkLineRasterizationModeEXT lineMode)
: m_depthClipEnable (uint16_t(depthClipEnable)),
m_depthBiasEnable (uint16_t(depthBiasEnable)),
m_polygonMode (uint16_t(polygonMode)),
m_sampleCount (uint16_t(sampleCount)),
m_conservativeMode(uint16_t(conservativeMode)),
m_flatShading (uint16_t(flatShading)),
m_lineMode (uint16_t(lineMode)),
m_reserved (0) { }
VkBool32 depthClipEnable() const {
@ -256,6 +258,10 @@ namespace dxvk {
return VkBool32(m_flatShading);
}
VkLineRasterizationModeEXT lineMode() const {
return VkLineRasterizationModeEXT(m_lineMode);
}
bool eq(const DxvkRsInfo& other) const {
return !std::memcmp(this, &other, sizeof(*this));
}
@ -268,7 +274,8 @@ namespace dxvk {
uint16_t m_sampleCount : 5;
uint16_t m_conservativeMode : 2;
uint16_t m_flatShading : 1;
uint16_t m_reserved : 4;
uint16_t m_lineMode : 2;
uint16_t m_reserved : 2;
};

View File

@ -62,6 +62,8 @@ namespace dxvk {
uint32_t patchVertexCount = 0;
/// Transform feedback vertex strides
uint32_t xfbStrides[MaxNumXfbBuffers] = { };
/// Output primitive topology
VkPrimitiveTopology outputTopology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
};

View File

@ -142,7 +142,7 @@ namespace dxvk {
VkPolygonMode(m_polygonMode),
VkSampleCountFlags(m_sampleCount),
VkConservativeRasterizationModeEXT(m_conservativeMode),
VK_FALSE);
VK_FALSE, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT);
}
};
@ -168,7 +168,7 @@ namespace dxvk {
VkPolygonMode(m_polygonMode),
VkSampleCountFlags(m_sampleCount),
VkConservativeRasterizationModeEXT(m_conservativeMode),
VK_FALSE);
VK_FALSE, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT);
}
};

View File

@ -125,6 +125,7 @@ namespace dxvk {
rsState.conservativeMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT;
rsState.sampleCount = VK_SAMPLE_COUNT_1_BIT;
rsState.flatShading = VK_FALSE;
rsState.lineMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
ctx->setRasterizerState(rsState);
DxvkMultisampleState msState;

View File

@ -28,6 +28,7 @@ namespace dxvk::hud {
m_rsState.conservativeMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT;
m_rsState.sampleCount = VK_SAMPLE_COUNT_1_BIT;
m_rsState.flatShading = VK_FALSE;
m_rsState.lineMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
m_blendMode.enableBlending = VK_TRUE;
m_blendMode.colorSrcFactor = VK_BLEND_FACTOR_ONE;