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

[dxvk,d3d9,d3d11] Refactor rasterizer state object

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

View File

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

View File

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

View File

@ -12,8 +12,8 @@ namespace dxvk {
// a polygon or renders lines connecting the vertices.
switch (desc.FillMode) {
default:
case D3D11_FILL_SOLID: m_state.polygonMode = VK_POLYGON_MODE_FILL; break;
case D3D11_FILL_WIREFRAME: m_state.polygonMode = VK_POLYGON_MODE_LINE; break;
case D3D11_FILL_SOLID: m_state.setPolygonMode(VK_POLYGON_MODE_FILL); break;
case D3D11_FILL_WIREFRAME: m_state.setPolygonMode(VK_POLYGON_MODE_LINE); break;
}
// Face culling properties. The rasterizer may discard
@ -21,38 +21,40 @@ namespace dxvk {
// viewer, depending on the options below.
switch (desc.CullMode) {
default:
case D3D11_CULL_NONE: m_state.cullMode = VK_CULL_MODE_NONE; break;
case D3D11_CULL_FRONT: m_state.cullMode = VK_CULL_MODE_FRONT_BIT; break;
case D3D11_CULL_BACK: m_state.cullMode = VK_CULL_MODE_BACK_BIT; break;
case D3D11_CULL_NONE: m_state.setCullMode(VK_CULL_MODE_NONE); break;
case D3D11_CULL_FRONT: m_state.setCullMode(VK_CULL_MODE_FRONT_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_CLOCKWISE;
: VK_FRONT_FACE_CLOCKWISE);
// In the backend we treat depth bias as a dynamic state because
// some games like to put random/uninitialized numbers here, but
// 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.depthClipEnable = desc.DepthClipEnable;
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_state.setDepthBias(desc.DepthBias != 0 || desc.SlopeScaledDepthBias != 0.0f);
m_state.setDepthClip(desc.DepthClipEnable);
m_state.setConservativeMode(DecodeConservativeRasterizationMode(desc.ConservativeRaster));
m_state.setSampleCount(desc.ForcedSampleCount);
m_state.setFlatShading(false);
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
const auto& features = device->GetDXVKDevice()->features();
if (desc.MultisampleEnable) {
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) {
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(
const D3D11_RASTERIZER_DESC* pSrcDesc) {
D3D11_RASTERIZER_DESC2 dstDesc;

View File

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

View File

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

View File

@ -118,15 +118,94 @@ namespace dxvk {
* rasterizer, including the depth bias.
*/
struct DxvkRasterizerState {
VkPolygonMode polygonMode;
VkCullModeFlags cullMode;
VkFrontFace frontFace;
VkBool32 depthClipEnable;
VkBool32 depthBiasEnable;
VkConservativeRasterizationModeEXT conservativeMode;
VkSampleCountFlags sampleCount;
VkBool32 flatShading;
VkLineRasterizationModeEXT lineMode;
public:
VkPolygonMode polygonMode() const {
return VkPolygonMode(m_polygonMode);
}
VkCullModeFlags cullMode() const {
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

@ -2727,14 +2727,17 @@ namespace dxvk {
void DxvkContext::setRasterizerState(const DxvkRasterizerState& rs) {
if (m_state.dyn.cullMode != rs.cullMode || m_state.dyn.frontFace != rs.frontFace) {
m_state.dyn.cullMode = rs.cullMode;
m_state.dyn.frontFace = rs.frontFace;
VkCullModeFlags cullMode = rs.cullMode();
VkFrontFace 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);
}
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())
m_flags.set(DxvkContextFlag::GpDirtyMultisampleState);
@ -2743,20 +2746,20 @@ namespace dxvk {
}
DxvkRsInfo rsInfo(
rs.depthClipEnable,
rs.depthBiasEnable,
rs.polygonMode,
rs.sampleCount,
rs.conservativeMode,
rs.flatShading,
rs.lineMode);
rs.depthClip(),
rs.depthBias(),
rs.polygonMode(),
rs.sampleCount(),
rs.conservativeMode(),
rs.flatShading(),
rs.lineMode());
if (!m_state.gp.state.rs.eq(rsInfo)) {
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
// Since depth bias enable is only dynamic for base pipelines,
// 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_state.gp.state.rs = rsInfo;