1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-28 02:19:26 +01:00

[dxvk,d3d9,d3d11] Refactor input assembly state object

This commit is contained in:
Philip Rebohle 2025-03-22 18:03:47 +01:00
parent f0b88495ec
commit 74a3478815
6 changed files with 82 additions and 46 deletions

View File

@ -3335,31 +3335,37 @@ namespace dxvk {
template<typename ContextType>
void D3D11CommonContext<ContextType>::ApplyPrimitiveTopology() {
D3D11_PRIMITIVE_TOPOLOGY topology = m_state.ia.primitiveTopology;
DxvkInputAssemblyState iaState = { };
DxvkInputAssemblyState iaState(VK_PRIMITIVE_TOPOLOGY_MAX_ENUM, false);
if (topology <= D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ) {
static const std::array<DxvkInputAssemblyState, 14> s_iaStates = {{
{ VK_PRIMITIVE_TOPOLOGY_MAX_ENUM, VK_FALSE, 0 },
{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_FALSE, 0 },
{ VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_FALSE, 0 },
{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, VK_TRUE, 0 },
{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_FALSE, 0 },
{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, VK_TRUE, 0 },
{ }, { }, { }, { }, // Random gap that exists for no reason
{ VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, VK_FALSE, 0 },
{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, VK_TRUE, 0 },
{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, VK_FALSE, 0 },
{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, VK_TRUE, 0 },
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_MAX_ENUM, false),
// Regular topologies
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_POINT_LIST, false),
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_LINE_LIST, false),
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, true),
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false),
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, true),
// Gap. This includes triangle fan which isn't supported in D3D11
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_MAX_ENUM, false),
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_MAX_ENUM, false),
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_MAX_ENUM, false),
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_MAX_ENUM, false),
// Adjacency topologies
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, false),
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, true),
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, false),
DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, true),
}};
iaState = s_iaStates[uint32_t(topology)];
} else if (topology >= D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST
&& topology <= D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST) {
// The number of control points per patch can be inferred from the enum value in D3D11
uint32_t vertexCount = uint32_t(topology - D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + 1);
iaState = { VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE, vertexCount };
iaState = DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, false);
iaState.setPatchVertexCount(topology - D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + 1);
}
EmitCs([iaState] (DxvkContext* ctx) {
ctx->setInputAssemblyState(iaState);
});
@ -4725,10 +4731,7 @@ namespace dxvk {
ctx->setInputLayout(0, nullptr, 0, nullptr);
// Reset render states
DxvkInputAssemblyState iaState;
InitDefaultPrimitiveTopology(&iaState);
ctx->setInputAssemblyState(iaState);
ctx->setInputAssemblyState(InitDefaultPrimitiveTopology());
ctx->setDepthStencilState(InitDefaultDepthStencilState());
ctx->setRasterizerState(InitDefaultRasterizerState());
ctx->setLogicOpState(InitDefaultLogicOpState());
@ -5776,11 +5779,8 @@ namespace dxvk {
template<typename ContextType>
void D3D11CommonContext<ContextType>::InitDefaultPrimitiveTopology(
DxvkInputAssemblyState* pIaState) {
pIaState->primitiveTopology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
pIaState->primitiveRestart = VK_FALSE;
pIaState->patchVertexCount = 0;
DxvkInputAssemblyState D3D11CommonContext<ContextType>::InitDefaultPrimitiveTopology() {
return DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_MAX_ENUM, false);
}

View File

@ -75,7 +75,6 @@ namespace dxvk {
// Use a local staging buffer to handle tiny uploads, most
// of the time we're fine with hitting the global allocator
constexpr static VkDeviceSize StagingBufferSize = 256ull << 10;
protected:
// Compile-time debug flag to force lazy binding on (True) or off (False)
constexpr static Tristate DebugLazyBinding = Tristate::Auto;
@ -1143,8 +1142,7 @@ namespace dxvk {
ID3D11RenderTargetView* const* ppRenderTargetViews,
ID3D11DepthStencilView* pDepthStencilView);
static void InitDefaultPrimitiveTopology(
DxvkInputAssemblyState* pIaState);
static DxvkInputAssemblyState InitDefaultPrimitiveTopology();
static DxvkRasterizerState InitDefaultRasterizerState();

View File

@ -1196,10 +1196,7 @@ namespace dxvk {
ctx->bindRenderTargets(std::move(rt), 0u);
DxvkInputAssemblyState iaState;
iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
iaState.primitiveRestart = VK_FALSE;
iaState.patchVertexCount = 0;
DxvkInputAssemblyState iaState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false);
ctx->setInputAssemblyState(iaState);
});

View File

@ -142,22 +142,22 @@ namespace dxvk {
switch (type) {
default:
case D3DPT_TRIANGLELIST:
return { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_FALSE, 0 };
return DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false);
case D3DPT_POINTLIST:
return { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_FALSE, 0 };
return DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_POINT_LIST, false);
case D3DPT_LINELIST:
return { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_FALSE, 0 };
return DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_LINE_LIST, false);
case D3DPT_LINESTRIP:
return { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, VK_FALSE, 0 };
return DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, false);
case D3DPT_TRIANGLESTRIP:
return { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, VK_FALSE, 0 };
return DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, false);
case D3DPT_TRIANGLEFAN:
return { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, VK_FALSE, 0 };
return DxvkInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, false);
}
}
@ -382,4 +382,4 @@ namespace dxvk {
|| Format == D3D9Format::D32F_LOCKABLE;
}
}
}

View File

@ -105,12 +105,53 @@ namespace dxvk {
* is enabled.
*/
struct DxvkInputAssemblyState {
VkPrimitiveTopology primitiveTopology;
VkBool32 primitiveRestart;
uint32_t patchVertexCount;
public:
DxvkInputAssemblyState() = default;
DxvkInputAssemblyState(VkPrimitiveTopology topology, bool restart)
: m_primitiveTopology (uint16_t(topology)),
m_primitiveRestart (uint16_t(restart)),
m_patchVertexCount (0u),
m_reserved (0u) { }
VkPrimitiveTopology primitiveTopology() const {
return VkPrimitiveTopology(m_primitiveTopology) <= VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
? VkPrimitiveTopology(m_primitiveTopology)
: VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
}
bool primitiveRestart() const {
return m_primitiveRestart;
}
uint32_t patchVertexCount() const {
return m_patchVertexCount;
}
void setPrimitiveTopology(VkPrimitiveTopology topology) {
m_primitiveTopology = uint16_t(topology);
}
void setPrimitiveRestart(bool enable) {
m_primitiveRestart = enable;
}
void setPatchVertexCount(uint32_t count) {
m_patchVertexCount = count;
}
private:
uint16_t m_primitiveTopology : 4;
uint16_t m_primitiveRestart : 1;
uint16_t m_patchVertexCount : 6;
uint16_t m_reserved : 5;
};
/**
* \brief Rasterizer state
*

View File

@ -2797,9 +2797,9 @@ namespace dxvk {
void DxvkContext::setInputAssemblyState(const DxvkInputAssemblyState& ia) {
m_state.gp.state.ia = DxvkIaInfo(
ia.primitiveTopology,
ia.primitiveRestart,
ia.patchVertexCount);
ia.primitiveTopology(),
ia.primitiveRestart(),
ia.patchVertexCount());
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
}