1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-04-01 09:25:24 +02:00

[dxvk,d3d9,d3d11] Refactor rasterizer state object

This commit is contained in:
Philip Rebohle 2025-03-22 17:34:39 +01:00
parent 17a1e3f5c6
commit ebee4ef5ae
7 changed files with 162 additions and 82 deletions

View File

@ -3438,16 +3438,17 @@ namespace dxvk {
void D3D11CommonContext<ContextType>::ApplyRasterizerState() { void D3D11CommonContext<ContextType>::ApplyRasterizerState() {
if (m_state.rs.state != nullptr) { if (m_state.rs.state != nullptr) {
EmitCs([ EmitCs([
cRasterizerState = m_state.rs.state cState = m_state.rs.state->GetState(),
cDepthBias = m_state.rs.state->GetDepthBias()
] (DxvkContext* ctx) { ] (DxvkContext* ctx) {
cRasterizerState->BindToContext(ctx); ctx->setRasterizerState(cState);
if (cState.depthBias())
ctx->setDepthBias(cDepthBias);
}); });
} else { } else {
EmitCs([] (DxvkContext* ctx) { EmitCs([] (DxvkContext* ctx) {
DxvkRasterizerState rsState; ctx->setRasterizerState(InitDefaultRasterizerState());
InitDefaultRasterizerState(&rsState);
ctx->setRasterizerState(rsState);
}); });
} }
} }
@ -4727,12 +4728,9 @@ namespace dxvk {
DxvkInputAssemblyState iaState; DxvkInputAssemblyState iaState;
InitDefaultPrimitiveTopology(&iaState); InitDefaultPrimitiveTopology(&iaState);
DxvkRasterizerState rsState;
InitDefaultRasterizerState(&rsState);
ctx->setInputAssemblyState(iaState); ctx->setInputAssemblyState(iaState);
ctx->setDepthStencilState(InitDefaultDepthStencilState()); ctx->setDepthStencilState(InitDefaultDepthStencilState());
ctx->setRasterizerState(rsState); ctx->setRasterizerState(InitDefaultRasterizerState());
ctx->setLogicOpState(InitDefaultLogicOpState()); ctx->setLogicOpState(InitDefaultLogicOpState());
ctx->setMultisampleState(InitDefaultMultisampleState(D3D11_DEFAULT_SAMPLE_MASK)); ctx->setMultisampleState(InitDefaultMultisampleState(D3D11_DEFAULT_SAMPLE_MASK));
@ -5787,17 +5785,18 @@ namespace dxvk {
template<typename ContextType> template<typename ContextType>
void D3D11CommonContext<ContextType>::InitDefaultRasterizerState( DxvkRasterizerState D3D11CommonContext<ContextType>::InitDefaultRasterizerState() {
DxvkRasterizerState* pRsState) { DxvkRasterizerState rsState = { };
pRsState->polygonMode = VK_POLYGON_MODE_FILL; rsState.setPolygonMode(VK_POLYGON_MODE_FILL);
pRsState->cullMode = VK_CULL_MODE_BACK_BIT; rsState.setCullMode(VK_CULL_MODE_BACK_BIT);
pRsState->frontFace = VK_FRONT_FACE_CLOCKWISE; rsState.setFrontFace(VK_FRONT_FACE_CLOCKWISE);
pRsState->depthClipEnable = VK_TRUE; rsState.setDepthClip(true);
pRsState->depthBiasEnable = VK_FALSE; rsState.setDepthBias(false);
pRsState->conservativeMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT; rsState.setConservativeMode(VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT);
pRsState->sampleCount = 0; rsState.setSampleCount(0);
pRsState->flatShading = VK_FALSE; rsState.setFlatShading(false);
pRsState->lineMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT; rsState.setLineMode(VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT);
return rsState;
} }

View File

@ -1146,8 +1146,7 @@ namespace dxvk {
static void InitDefaultPrimitiveTopology( static void InitDefaultPrimitiveTopology(
DxvkInputAssemblyState* pIaState); DxvkInputAssemblyState* pIaState);
static void InitDefaultRasterizerState( static DxvkRasterizerState InitDefaultRasterizerState();
DxvkRasterizerState* pRsState);
static DxvkDepthStencilState InitDefaultDepthStencilState(); static DxvkDepthStencilState InitDefaultDepthStencilState();

View File

@ -12,8 +12,8 @@ namespace dxvk {
// a polygon or renders lines connecting the vertices. // a polygon or renders lines connecting the vertices.
switch (desc.FillMode) { switch (desc.FillMode) {
default: default:
case D3D11_FILL_SOLID: m_state.polygonMode = VK_POLYGON_MODE_FILL; break; case D3D11_FILL_SOLID: m_state.setPolygonMode(VK_POLYGON_MODE_FILL); break;
case D3D11_FILL_WIREFRAME: m_state.polygonMode = VK_POLYGON_MODE_LINE; break; case D3D11_FILL_WIREFRAME: m_state.setPolygonMode(VK_POLYGON_MODE_LINE); break;
} }
// Face culling properties. The rasterizer may discard // Face culling properties. The rasterizer may discard
@ -21,38 +21,40 @@ namespace dxvk {
// viewer, depending on the options below. // viewer, depending on the options below.
switch (desc.CullMode) { switch (desc.CullMode) {
default: default:
case D3D11_CULL_NONE: m_state.cullMode = VK_CULL_MODE_NONE; break; case D3D11_CULL_NONE: m_state.setCullMode(VK_CULL_MODE_NONE); break;
case D3D11_CULL_FRONT: m_state.cullMode = VK_CULL_MODE_FRONT_BIT; break; case D3D11_CULL_FRONT: m_state.setCullMode(VK_CULL_MODE_FRONT_BIT); break;
case D3D11_CULL_BACK: m_state.cullMode = VK_CULL_MODE_BACK_BIT; break; case D3D11_CULL_BACK: m_state.setCullMode(VK_CULL_MODE_BACK_BIT); break;
} }
m_state.frontFace = desc.FrontCounterClockwise m_state.setFrontFace(desc.FrontCounterClockwise
? VK_FRONT_FACE_COUNTER_CLOCKWISE ? VK_FRONT_FACE_COUNTER_CLOCKWISE
: VK_FRONT_FACE_CLOCKWISE; : VK_FRONT_FACE_CLOCKWISE);
// In the backend we treat depth bias as a dynamic state because // In the backend we treat depth bias as a dynamic state because
// some games like to put random/uninitialized numbers here, but // some games like to put random/uninitialized numbers here, but
// we do not need to enable it in case the parameters are both 0. // we do not need to enable it in case the parameters are both 0.
m_state.depthBiasEnable = desc.DepthBias != 0 || desc.SlopeScaledDepthBias != 0.0f; m_state.setDepthBias(desc.DepthBias != 0 || desc.SlopeScaledDepthBias != 0.0f);
m_state.depthClipEnable = desc.DepthClipEnable; m_state.setDepthClip(desc.DepthClipEnable);
m_state.conservativeMode = DecodeConservativeRasterizationMode(desc.ConservativeRaster); m_state.setConservativeMode(DecodeConservativeRasterizationMode(desc.ConservativeRaster));
m_state.sampleCount = VkSampleCountFlags(desc.ForcedSampleCount); m_state.setSampleCount(desc.ForcedSampleCount);
m_state.flatShading = VK_FALSE; m_state.setFlatShading(false);
m_state.lineMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT; m_state.setLineMode(VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT);
if (m_state.depthBias()) {
m_depthBias.depthBiasConstant = float(desc.DepthBias);
m_depthBias.depthBiasSlope = desc.SlopeScaledDepthBias;
m_depthBias.depthBiasClamp = desc.DepthBiasClamp;
}
m_depthBias.depthBiasConstant = float(desc.DepthBias);
m_depthBias.depthBiasSlope = desc.SlopeScaledDepthBias;
m_depthBias.depthBiasClamp = desc.DepthBiasClamp;
// Set up line rasterization mode // Set up line rasterization mode
const auto& features = device->GetDXVKDevice()->features(); const auto& features = device->GetDXVKDevice()->features();
if (desc.MultisampleEnable) { if (desc.MultisampleEnable) {
if (features.extLineRasterization.rectangularLines) if (features.extLineRasterization.rectangularLines)
m_state.lineMode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT; m_state.setLineMode(VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT);
} else if (desc.AntialiasedLineEnable) { } else if (desc.AntialiasedLineEnable) {
if (features.extLineRasterization.smoothLines) if (features.extLineRasterization.smoothLines)
m_state.lineMode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT; m_state.setLineMode(VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT);
} }
} }
@ -126,14 +128,6 @@ namespace dxvk {
} }
void D3D11RasterizerState::BindToContext(DxvkContext* ctx) {
ctx->setRasterizerState(m_state);
if (m_state.depthBiasEnable)
ctx->setDepthBias(m_depthBias);
}
D3D11_RASTERIZER_DESC2 D3D11RasterizerState::PromoteDesc( D3D11_RASTERIZER_DESC2 D3D11RasterizerState::PromoteDesc(
const D3D11_RASTERIZER_DESC* pSrcDesc) { const D3D11_RASTERIZER_DESC* pSrcDesc) {
D3D11_RASTERIZER_DESC2 dstDesc; D3D11_RASTERIZER_DESC2 dstDesc;

View File

@ -38,7 +38,13 @@ namespace dxvk {
return &m_desc; return &m_desc;
} }
void BindToContext(DxvkContext* ctx); DxvkRasterizerState GetState() const {
return m_state;
}
DxvkDepthBias GetDepthBias() const {
return m_depthBias;
}
D3D10RasterizerState* GetD3D10Iface() { D3D10RasterizerState* GetD3D10Iface() {
return &m_d3d10; return &m_d3d10;
@ -56,8 +62,8 @@ namespace dxvk {
private: private:
D3D11_RASTERIZER_DESC2 m_desc; D3D11_RASTERIZER_DESC2 m_desc;
DxvkRasterizerState m_state; DxvkRasterizerState m_state = { };
DxvkDepthBias m_depthBias; DxvkDepthBias m_depthBias = { };
D3D10RasterizerState m_d3d10; D3D10RasterizerState m_d3d10;
}; };

View File

@ -6957,12 +6957,12 @@ namespace dxvk {
auto& rs = m_state.renderStates; auto& rs = m_state.renderStates;
DxvkRasterizerState state = { }; DxvkRasterizerState state = { };
state.cullMode = DecodeCullMode(D3DCULL(rs[D3DRS_CULLMODE])); state.setCullMode(DecodeCullMode(D3DCULL(rs[D3DRS_CULLMODE])));
state.depthBiasEnable = IsDepthBiasEnabled(); state.setDepthBias(IsDepthBiasEnabled());
state.depthClipEnable = true; state.setDepthClip(true);
state.frontFace = VK_FRONT_FACE_CLOCKWISE; state.setFrontFace(VK_FRONT_FACE_CLOCKWISE);
state.polygonMode = DecodeFillMode(D3DFILLMODE(rs[D3DRS_FILLMODE])); state.setPolygonMode(DecodeFillMode(D3DFILLMODE(rs[D3DRS_FILLMODE])));
state.flatShading = m_state.renderStates[D3DRS_SHADEMODE] == D3DSHADE_FLAT; state.setFlatShading(m_state.renderStates[D3DRS_SHADEMODE] == D3DSHADE_FLAT);
EmitCs([ EmitCs([
cState = state cState = state

View File

@ -118,15 +118,94 @@ namespace dxvk {
* rasterizer, including the depth bias. * rasterizer, including the depth bias.
*/ */
struct DxvkRasterizerState { struct DxvkRasterizerState {
VkPolygonMode polygonMode;
VkCullModeFlags cullMode; public:
VkFrontFace frontFace;
VkBool32 depthClipEnable; VkPolygonMode polygonMode() const {
VkBool32 depthBiasEnable; return VkPolygonMode(m_polygonMode);
VkConservativeRasterizationModeEXT conservativeMode; }
VkSampleCountFlags sampleCount;
VkBool32 flatShading; VkCullModeFlags cullMode() const {
VkLineRasterizationModeEXT lineMode; return VkCullModeFlags(m_cullMode);
}
VkFrontFace frontFace() const {
return VkFrontFace(m_frontFace);
}
bool depthClip() const {
return m_depthClipEnable;
}
bool depthBias() const {
return m_depthBiasEnable;
}
VkConservativeRasterizationModeEXT conservativeMode() const {
return VkConservativeRasterizationModeEXT(m_conservativeMode);
}
VkSampleCountFlags sampleCount() const {
return VkSampleCountFlags(m_sampleCount);
}
bool flatShading() const {
return m_flatShading;
}
VkLineRasterizationModeEXT lineMode() const {
return VkLineRasterizationModeEXT(m_lineMode);
}
void setPolygonMode(VkPolygonMode mode) {
m_polygonMode = uint32_t(mode);
}
void setCullMode(VkCullModeFlags mode) {
m_cullMode = uint32_t(mode);
}
void setFrontFace(VkFrontFace face) {
m_frontFace = uint32_t(face);
}
void setDepthClip(bool enable) {
m_depthClipEnable = enable;
}
void setDepthBias(bool enable) {
m_depthBiasEnable = enable;
}
void setConservativeMode(VkConservativeRasterizationModeEXT mode) {
m_conservativeMode = uint32_t(mode);
}
void setSampleCount(VkSampleCountFlags count) {
m_sampleCount = uint32_t(count);
}
void setFlatShading(bool enable) {
m_flatShading = enable;
}
void setLineMode(VkLineRasterizationModeEXT mode) {
m_lineMode = uint32_t(mode);
}
private:
uint32_t m_polygonMode : 2;
uint32_t m_cullMode : 2;
uint32_t m_frontFace : 1;
uint32_t m_depthClipEnable : 1;
uint32_t m_depthBiasEnable : 1;
uint32_t m_conservativeMode : 2;
uint32_t m_sampleCount : 5;
uint32_t m_flatShading : 1;
uint32_t m_lineMode : 2;
uint32_t m_reserved : 15;
}; };

View File

@ -2840,14 +2840,17 @@ namespace dxvk {
void DxvkContext::setRasterizerState(const DxvkRasterizerState& rs) { void DxvkContext::setRasterizerState(const DxvkRasterizerState& rs) {
if (m_state.dyn.cullMode != rs.cullMode || m_state.dyn.frontFace != rs.frontFace) { VkCullModeFlags cullMode = rs.cullMode();
m_state.dyn.cullMode = rs.cullMode; VkFrontFace frontFace = rs.frontFace();
m_state.dyn.frontFace = rs.frontFace;
if (m_state.dyn.cullMode != cullMode || m_state.dyn.frontFace != frontFace) {
m_state.dyn.cullMode = cullMode;
m_state.dyn.frontFace = frontFace;
m_flags.set(DxvkContextFlag::GpDirtyRasterizerState); m_flags.set(DxvkContextFlag::GpDirtyRasterizerState);
} }
if (unlikely(rs.sampleCount != m_state.gp.state.rs.sampleCount())) { if (unlikely(rs.sampleCount() != m_state.gp.state.rs.sampleCount())) {
if (!m_state.gp.state.ms.sampleCount()) if (!m_state.gp.state.ms.sampleCount())
m_flags.set(DxvkContextFlag::GpDirtyMultisampleState); m_flags.set(DxvkContextFlag::GpDirtyMultisampleState);
@ -2856,20 +2859,20 @@ namespace dxvk {
} }
DxvkRsInfo rsInfo( DxvkRsInfo rsInfo(
rs.depthClipEnable, rs.depthClip(),
rs.depthBiasEnable, rs.depthBias(),
rs.polygonMode, rs.polygonMode(),
rs.sampleCount, rs.sampleCount(),
rs.conservativeMode, rs.conservativeMode(),
rs.flatShading, rs.flatShading(),
rs.lineMode); rs.lineMode());
if (!m_state.gp.state.rs.eq(rsInfo)) { if (!m_state.gp.state.rs.eq(rsInfo)) {
m_flags.set(DxvkContextFlag::GpDirtyPipelineState); m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
// Since depth bias enable is only dynamic for base pipelines, // Since depth bias enable is only dynamic for base pipelines,
// it is applied as part of the dynamic depth-stencil state // it is applied as part of the dynamic depth-stencil state
if (m_state.gp.state.rs.depthBiasEnable() != rs.depthBiasEnable) if (m_state.gp.state.rs.depthBiasEnable() != rs.depthBias())
m_flags.set(DxvkContextFlag::GpDirtyDepthStencilState); m_flags.set(DxvkContextFlag::GpDirtyDepthStencilState);
m_state.gp.state.rs = rsInfo; m_state.gp.state.rs = rsInfo;