mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 20:52:10 +01:00
[d3d11] Implemented blend state and depth-stencil state binding
This commit is contained in:
parent
352b46fe80
commit
50b7293b8f
@ -23,6 +23,11 @@ namespace dxvk {
|
||||
m_msState.enableAlphaToOne = VK_FALSE;
|
||||
m_msState.enableSampleShading = VK_FALSE;
|
||||
m_msState.minSampleShading = 0.0f;
|
||||
|
||||
// In 11_0, there is no logic op state. Later versions
|
||||
// of D3D11 however put it into the blend state object.
|
||||
m_loState.enableLogicOp = VK_FALSE;
|
||||
m_loState.logicOp = VK_LOGIC_OP_NO_OP;
|
||||
}
|
||||
|
||||
|
||||
@ -64,6 +69,11 @@ namespace dxvk {
|
||||
DxvkMultisampleState msState = m_msState;
|
||||
msState.sampleMask = sampleMask;
|
||||
ctx->setMultisampleState(msState);
|
||||
|
||||
// Set up logic op state as well
|
||||
ctx->setLogicOpState(m_loState);
|
||||
|
||||
// TODO set blend factor
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace dxvk {
|
||||
|
||||
void BindToContext(
|
||||
const Rc<DxvkContext>& ctx,
|
||||
uint32_t sampleMask) const;
|
||||
UINT sampleMask) const;
|
||||
|
||||
private:
|
||||
|
||||
@ -41,6 +41,7 @@ namespace dxvk {
|
||||
|
||||
std::array<DxvkBlendMode, 8> m_blendModes;
|
||||
DxvkMultisampleState m_msState;
|
||||
DxvkLogicOpState m_loState;
|
||||
|
||||
static DxvkBlendMode DecodeBlendMode(
|
||||
const D3D11_RENDER_TARGET_BLEND_DESC& blendDesc);
|
||||
|
@ -15,9 +15,30 @@ namespace dxvk {
|
||||
m_context = m_device->createContext();
|
||||
m_context->beginRecording(
|
||||
m_device->createCommandList());
|
||||
this->SetDefaultBlendState();
|
||||
this->SetDefaultDepthStencilState();
|
||||
this->SetDefaultRasterizerState();
|
||||
// Create default state objects. We won't ever return them
|
||||
// to the application, but we'll use them to apply state.
|
||||
Com<ID3D11BlendState> defaultBlendState;
|
||||
Com<ID3D11DepthStencilState> defaultDepthStencilState;
|
||||
Com<ID3D11RasterizerState> defaultRasterizerState;
|
||||
|
||||
if (FAILED(m_parent->CreateBlendState (nullptr, &defaultBlendState))
|
||||
|| FAILED(m_parent->CreateDepthStencilState(nullptr, &defaultDepthStencilState))
|
||||
|| FAILED(m_parent->CreateRasterizerState (nullptr, &defaultRasterizerState)))
|
||||
throw DxvkError("D3D11DeviceContext: Failed to create default state objects");
|
||||
|
||||
// Apply default state to the context. This is required
|
||||
// in order to initialize the DXVK contex properly.
|
||||
m_defaultBlendState = static_cast<D3D11BlendState*>(defaultBlendState.ptr());
|
||||
m_defaultBlendState->BindToContext(m_context, 0xFFFFFFFF);
|
||||
|
||||
m_defaultDepthStencilState = static_cast<D3D11DepthStencilState*>(defaultDepthStencilState.ptr());
|
||||
m_defaultDepthStencilState->BindToContext(m_context);
|
||||
|
||||
m_defaultRasterizerState = static_cast<D3D11RasterizerState*>(defaultRasterizerState.ptr());
|
||||
m_defaultRasterizerState->BindToContext(m_context);
|
||||
|
||||
m_context->setBlendConstants(m_state.om.blendFactor);
|
||||
m_context->setStencilReference(m_state.om.stencilRef);
|
||||
}
|
||||
|
||||
|
||||
@ -1201,14 +1222,44 @@ namespace dxvk {
|
||||
ID3D11BlendState* pBlendState,
|
||||
const FLOAT BlendFactor[4],
|
||||
UINT SampleMask) {
|
||||
Logger::err("D3D11DeviceContext::OMSetBlendState: Not implemented");
|
||||
auto blendState = static_cast<D3D11BlendState*>(pBlendState);
|
||||
|
||||
if (m_state.om.cbState != blendState
|
||||
|| m_state.om.sampleMask != SampleMask) {
|
||||
m_state.om.cbState = blendState;
|
||||
m_state.om.sampleMask = SampleMask;
|
||||
|
||||
if (blendState == nullptr)
|
||||
blendState = m_defaultBlendState.ptr();
|
||||
|
||||
blendState->BindToContext(m_context, SampleMask);
|
||||
}
|
||||
|
||||
if ((BlendFactor != nullptr) && (!std::memcmp(m_state.om.blendFactor, BlendFactor, 4 * sizeof(FLOAT)))) {
|
||||
std::memcpy(m_state.om.blendFactor, BlendFactor, 4 * sizeof(FLOAT));
|
||||
m_context->setBlendConstants(BlendFactor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void D3D11DeviceContext::OMSetDepthStencilState(
|
||||
ID3D11DepthStencilState* pDepthStencilState,
|
||||
UINT StencilRef) {
|
||||
Logger::err("D3D11DeviceContext::OMSetDepthStencilState: Not implemented");
|
||||
auto depthStencilState = static_cast<D3D11DepthStencilState*>(pDepthStencilState);
|
||||
|
||||
if (m_state.om.dsState != depthStencilState) {
|
||||
m_state.om.dsState = depthStencilState;
|
||||
|
||||
if (depthStencilState == nullptr)
|
||||
depthStencilState = m_defaultDepthStencilState.ptr();
|
||||
|
||||
depthStencilState->BindToContext(m_context);
|
||||
}
|
||||
|
||||
if (m_state.om.stencilRef != StencilRef) {
|
||||
m_state.om.stencilRef = StencilRef;
|
||||
m_context->setStencilReference(StencilRef);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1262,10 +1313,10 @@ namespace dxvk {
|
||||
if (m_state.rs.state != rasterizerState) {
|
||||
m_state.rs.state = rasterizerState;
|
||||
|
||||
if (rasterizerState != nullptr)
|
||||
rasterizerState->BindToContext(m_context);
|
||||
else
|
||||
this->SetDefaultRasterizerState();
|
||||
if (rasterizerState == nullptr)
|
||||
rasterizerState = m_defaultRasterizerState.ptr();
|
||||
|
||||
rasterizerState->BindToContext(m_context);
|
||||
|
||||
// In D3D11, the rasterizer state defines
|
||||
// whether the scissor test is enabled, so
|
||||
@ -1553,75 +1604,4 @@ namespace dxvk {
|
||||
scissors.data());
|
||||
}
|
||||
|
||||
|
||||
void D3D11DeviceContext::SetDefaultBlendState() {
|
||||
DxvkMultisampleState msState;
|
||||
msState.sampleMask = 0xffffffff;
|
||||
msState.enableAlphaToCoverage = VK_FALSE;
|
||||
msState.enableAlphaToOne = VK_FALSE;
|
||||
msState.enableSampleShading = VK_FALSE;
|
||||
msState.minSampleShading = 0.0f;
|
||||
m_context->setMultisampleState(msState);
|
||||
|
||||
DxvkLogicOpState loState;
|
||||
loState.enableLogicOp = VK_FALSE;
|
||||
loState.logicOp = VK_LOGIC_OP_CLEAR;
|
||||
m_context->setLogicOpState(loState);
|
||||
|
||||
DxvkBlendMode blendMode;
|
||||
blendMode.enableBlending = VK_FALSE;
|
||||
blendMode.colorSrcFactor = VK_BLEND_FACTOR_ONE;
|
||||
blendMode.colorDstFactor = VK_BLEND_FACTOR_ZERO;
|
||||
blendMode.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
blendMode.alphaSrcFactor = VK_BLEND_FACTOR_ONE;
|
||||
blendMode.alphaDstFactor = VK_BLEND_FACTOR_ZERO;
|
||||
blendMode.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
blendMode.writeMask = VK_COLOR_COMPONENT_R_BIT
|
||||
| VK_COLOR_COMPONENT_G_BIT
|
||||
| VK_COLOR_COMPONENT_B_BIT
|
||||
| VK_COLOR_COMPONENT_A_BIT;
|
||||
|
||||
for (uint32_t i = 0; i < DxvkLimits::MaxNumRenderTargets; i++)
|
||||
m_context->setBlendMode(i, blendMode);
|
||||
}
|
||||
|
||||
|
||||
void D3D11DeviceContext::SetDefaultDepthStencilState() {
|
||||
VkStencilOpState stencilOp;
|
||||
stencilOp.failOp = VK_STENCIL_OP_KEEP;
|
||||
stencilOp.passOp = VK_STENCIL_OP_KEEP;
|
||||
stencilOp.depthFailOp = VK_STENCIL_OP_KEEP;
|
||||
stencilOp.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
stencilOp.compareMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
||||
stencilOp.writeMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
||||
stencilOp.reference = 0;
|
||||
|
||||
DxvkDepthStencilState dsState;
|
||||
dsState.enableDepthTest = VK_TRUE;
|
||||
dsState.enableDepthWrite = VK_TRUE;
|
||||
dsState.enableDepthBounds = VK_FALSE;
|
||||
dsState.enableStencilTest = VK_FALSE;
|
||||
dsState.depthCompareOp = VK_COMPARE_OP_LESS;
|
||||
dsState.stencilOpFront = stencilOp;
|
||||
dsState.stencilOpBack = stencilOp;
|
||||
dsState.depthBoundsMin = 0.0f;
|
||||
dsState.depthBoundsMax = 1.0f;
|
||||
m_context->setDepthStencilState(dsState);
|
||||
}
|
||||
|
||||
|
||||
void D3D11DeviceContext::SetDefaultRasterizerState() {
|
||||
DxvkRasterizerState rsState;
|
||||
rsState.enableDepthClamp = VK_FALSE;
|
||||
rsState.enableDiscard = VK_FALSE;
|
||||
rsState.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rsState.cullMode = VK_CULL_MODE_BACK_BIT;
|
||||
rsState.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||
rsState.depthBiasEnable = VK_FALSE;
|
||||
rsState.depthBiasConstant = 0.0f;
|
||||
rsState.depthBiasClamp = 0.0f;
|
||||
rsState.depthBiasSlope = 0.0f;
|
||||
m_context->setRasterizerState(rsState);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -547,6 +547,10 @@ namespace dxvk {
|
||||
Rc<DxvkDevice> m_device;
|
||||
Rc<DxvkContext> m_context;
|
||||
|
||||
Com<D3D11BlendState> m_defaultBlendState;
|
||||
Com<D3D11DepthStencilState> m_defaultDepthStencilState;
|
||||
Com<D3D11RasterizerState> m_defaultRasterizerState;
|
||||
|
||||
D3D11ContextState m_state;
|
||||
|
||||
void BindConstantBuffers(
|
||||
@ -572,14 +576,6 @@ namespace dxvk {
|
||||
|
||||
void ApplyViewportState();
|
||||
|
||||
void SetupIAStateObjects();
|
||||
|
||||
void SetDefaultBlendState();
|
||||
|
||||
void SetDefaultDepthStencilState();
|
||||
|
||||
void SetDefaultRasterizerState();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -97,6 +97,13 @@ namespace dxvk {
|
||||
struct D3D11ContextStateOM {
|
||||
std::array<Com<D3D11RenderTargetView>, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> renderTargetViews;
|
||||
Com<D3D11DepthStencilView> depthStencilView;
|
||||
|
||||
Com<D3D11BlendState> cbState = nullptr;
|
||||
Com<D3D11DepthStencilState> dsState = nullptr;
|
||||
|
||||
FLOAT blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
UINT sampleMask = 0xFFFFFFFFu;
|
||||
UINT stencilRef = 0u;
|
||||
};
|
||||
|
||||
|
||||
|
@ -48,7 +48,7 @@ namespace dxvk {
|
||||
|
||||
|
||||
void D3D11DepthStencilState::BindToContext(
|
||||
const Rc<DxvkContext>& ctx) {
|
||||
const Rc<DxvkContext>& ctx) {
|
||||
ctx->setDepthStencilState(m_state);
|
||||
}
|
||||
|
||||
|
@ -284,6 +284,12 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkCommandList::cmdSetBlendConstants(
|
||||
float blendConstants[4]) {
|
||||
m_vkd->vkCmdSetBlendConstants(m_buffer, blendConstants);
|
||||
}
|
||||
|
||||
|
||||
void DxvkCommandList::cmdSetScissor(
|
||||
uint32_t firstScissor,
|
||||
uint32_t scissorCount,
|
||||
@ -293,6 +299,14 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkCommandList::cmdSetStencilReference(
|
||||
VkStencilFaceFlags faceMask,
|
||||
uint32_t reference) {
|
||||
m_vkd->vkCmdSetStencilReference(m_buffer,
|
||||
faceMask, reference);
|
||||
}
|
||||
|
||||
|
||||
void DxvkCommandList::cmdSetViewport(
|
||||
uint32_t firstViewport,
|
||||
uint32_t viewportCount,
|
||||
|
@ -169,11 +169,18 @@ namespace dxvk {
|
||||
VkDeviceSize dataSize,
|
||||
const void* pData);
|
||||
|
||||
void cmdSetBlendConstants(
|
||||
float blendConstants[4]);
|
||||
|
||||
void cmdSetScissor(
|
||||
uint32_t firstScissor,
|
||||
uint32_t scissorCount,
|
||||
const VkRect2D* scissors);
|
||||
|
||||
void cmdSetStencilReference(
|
||||
VkStencilFaceFlags faceMask,
|
||||
uint32_t reference);
|
||||
|
||||
void cmdSetViewport(
|
||||
uint32_t firstViewport,
|
||||
uint32_t viewportCount,
|
||||
|
@ -538,6 +538,23 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::setBlendConstants(
|
||||
const float blendConstants[4]) {
|
||||
for (uint32_t i = 0; i < 4; i++)
|
||||
m_state.om.blendConstants[i] = blendConstants[i];
|
||||
|
||||
this->updateBlendConstants();
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::setStencilReference(
|
||||
const uint32_t reference) {
|
||||
m_state.om.stencilReference = reference;
|
||||
|
||||
this->updateStencilReference();
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::setInputAssemblyState(
|
||||
const DxvkInputAssemblyState& state) {
|
||||
m_state.ia = state;
|
||||
@ -785,6 +802,8 @@ namespace dxvk {
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyDynamicState);
|
||||
|
||||
this->updateViewports();
|
||||
this->updateBlendConstants();
|
||||
this->updateStencilReference();
|
||||
}
|
||||
}
|
||||
|
||||
@ -795,6 +814,18 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::updateBlendConstants() {
|
||||
m_cmd->cmdSetBlendConstants(m_state.om.blendConstants);
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::updateStencilReference() {
|
||||
m_cmd->cmdSetStencilReference(
|
||||
VK_STENCIL_FRONT_AND_BACK,
|
||||
m_state.om.stencilReference);
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::updateIndexBufferBinding() {
|
||||
if (m_flags.test(DxvkContextFlag::GpDirtyIndexBuffer)) {
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyIndexBuffer);
|
||||
|
@ -295,6 +295,26 @@ namespace dxvk {
|
||||
const VkViewport* viewports,
|
||||
const VkRect2D* scissorRects);
|
||||
|
||||
/**
|
||||
* \brief Sets blend constants
|
||||
*
|
||||
* Blend constants are a set of four floating
|
||||
* point numbers that may be used as an input
|
||||
* for blending operations.
|
||||
* \param [in] blendConstants Blend constants
|
||||
*/
|
||||
void setBlendConstants(
|
||||
const float blendConstants[4]);
|
||||
|
||||
/**
|
||||
* \brief Sets stencil reference
|
||||
*
|
||||
* Sets the reference value for stencil compare operations.
|
||||
* \param [in] reference Reference value
|
||||
*/
|
||||
void setStencilReference(
|
||||
const uint32_t reference);
|
||||
|
||||
/**
|
||||
* \brief Sets input assembly state
|
||||
* \param [in] state New state object
|
||||
@ -377,6 +397,8 @@ namespace dxvk {
|
||||
|
||||
void updateDynamicState();
|
||||
void updateViewports();
|
||||
void updateBlendConstants();
|
||||
void updateStencilReference();
|
||||
|
||||
void updateIndexBufferBinding();
|
||||
void updateVertexBufferBindings();
|
||||
|
@ -57,7 +57,10 @@ namespace dxvk {
|
||||
struct DxvkOutputMergerState {
|
||||
Rc<DxvkFramebuffer> framebuffer;
|
||||
|
||||
std::array<DxvkBlendMode, DxvkLimits::MaxNumRenderTargets> blendModes;
|
||||
std::array<DxvkBlendMode,
|
||||
DxvkLimits::MaxNumRenderTargets> blendModes;
|
||||
float blendConstants[4];
|
||||
uint32_t stencilReference;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user