diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 0ecbde76f..9ffcbe449 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2240,9 +2240,10 @@ namespace dxvk { void DxvkContext::setInputAssemblyState(const DxvkInputAssemblyState& ia) { - m_state.gp.state.iaPrimitiveTopology = ia.primitiveTopology; - m_state.gp.state.iaPrimitiveRestart = ia.primitiveRestart; - m_state.gp.state.iaPatchVertexCount = ia.patchVertexCount; + m_state.gp.state.ia = DxvkIaInfo( + ia.primitiveTopology, + ia.primitiveRestart, + ia.patchVertexCount); m_flags.set(DxvkContextFlag::GpDirtyPipelineState); } diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index ea52eeb04..c6ac6390d 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -288,14 +288,14 @@ namespace dxvk { iaInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; iaInfo.pNext = nullptr; iaInfo.flags = 0; - iaInfo.topology = state.iaPrimitiveTopology; - iaInfo.primitiveRestartEnable = state.iaPrimitiveRestart; + iaInfo.topology = state.ia.primitiveTopology(); + iaInfo.primitiveRestartEnable = state.ia.primitiveRestart(); VkPipelineTessellationStateCreateInfo tsInfo; tsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; tsInfo.pNext = nullptr; tsInfo.flags = 0; - tsInfo.patchControlPoints = state.iaPatchVertexCount; + tsInfo.patchControlPoints = state.ia.patchVertexCount(); VkPipelineViewportStateCreateInfo vpInfo; vpInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; @@ -461,12 +461,12 @@ namespace dxvk { // If there are no tessellation shaders, we // obviously cannot use tessellation patches. - if ((state.iaPrimitiveTopology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) + if ((state.ia.primitiveTopology() == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) && (m_shaders.tcs == nullptr || m_shaders.tes == nullptr)) return false; // Filter out undefined primitive topologies - if (state.iaPrimitiveTopology == VK_PRIMITIVE_TOPOLOGY_MAX_ENUM) + if (state.ia.primitiveTopology() == VK_PRIMITIVE_TOPOLOGY_MAX_ENUM) return false; // Prevent unintended out-of-bounds access to the IL arrays diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index afa9ff2af..ed89a294c 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -6,6 +6,51 @@ namespace dxvk { + /** + * \brief Packed input assembly state + * + * Stores the primitive topology + * and primitive restart info. + */ + class DxvkIaInfo { + + public: + + DxvkIaInfo() = default; + + DxvkIaInfo( + VkPrimitiveTopology primitiveTopology, + VkBool32 primitiveRestart, + uint32_t patchVertexCount) + : m_primitiveTopology (uint16_t(primitiveTopology)), + m_primitiveRestart (uint16_t(primitiveRestart)), + m_patchVertexCount (uint16_t(patchVertexCount)), + m_reserved (0) { } + + VkPrimitiveTopology primitiveTopology() const { + return m_primitiveTopology <= VK_PRIMITIVE_TOPOLOGY_PATCH_LIST + ? VkPrimitiveTopology(m_primitiveTopology) + : VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; + } + + VkBool32 primitiveRestart() const { + return VkBool32(m_primitiveRestart); + } + + uint32_t patchVertexCount() const { + return m_patchVertexCount; + } + + private: + + uint16_t m_primitiveTopology : 4; + uint16_t m_primitiveRestart : 1; + uint16_t m_patchVertexCount : 6; + uint16_t m_reserved : 5; + + }; + + /** * \brief Packed graphics pipeline state * @@ -62,10 +107,7 @@ namespace dxvk { } DxvkBindingMask bsBindingMask; - - VkPrimitiveTopology iaPrimitiveTopology; - VkBool32 iaPrimitiveRestart; - uint32_t iaPatchVertexCount; + DxvkIaInfo ia; uint32_t ilAttributeCount; uint32_t ilBindingCount;