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.enableAlphaToOne = VK_FALSE;
|
||||||
m_msState.enableSampleShading = VK_FALSE;
|
m_msState.enableSampleShading = VK_FALSE;
|
||||||
m_msState.minSampleShading = 0.0f;
|
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;
|
DxvkMultisampleState msState = m_msState;
|
||||||
msState.sampleMask = sampleMask;
|
msState.sampleMask = sampleMask;
|
||||||
ctx->setMultisampleState(msState);
|
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(
|
void BindToContext(
|
||||||
const Rc<DxvkContext>& ctx,
|
const Rc<DxvkContext>& ctx,
|
||||||
uint32_t sampleMask) const;
|
UINT sampleMask) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -41,6 +41,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
std::array<DxvkBlendMode, 8> m_blendModes;
|
std::array<DxvkBlendMode, 8> m_blendModes;
|
||||||
DxvkMultisampleState m_msState;
|
DxvkMultisampleState m_msState;
|
||||||
|
DxvkLogicOpState m_loState;
|
||||||
|
|
||||||
static DxvkBlendMode DecodeBlendMode(
|
static DxvkBlendMode DecodeBlendMode(
|
||||||
const D3D11_RENDER_TARGET_BLEND_DESC& blendDesc);
|
const D3D11_RENDER_TARGET_BLEND_DESC& blendDesc);
|
||||||
|
@ -15,9 +15,30 @@ namespace dxvk {
|
|||||||
m_context = m_device->createContext();
|
m_context = m_device->createContext();
|
||||||
m_context->beginRecording(
|
m_context->beginRecording(
|
||||||
m_device->createCommandList());
|
m_device->createCommandList());
|
||||||
this->SetDefaultBlendState();
|
// Create default state objects. We won't ever return them
|
||||||
this->SetDefaultDepthStencilState();
|
// to the application, but we'll use them to apply state.
|
||||||
this->SetDefaultRasterizerState();
|
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,
|
ID3D11BlendState* pBlendState,
|
||||||
const FLOAT BlendFactor[4],
|
const FLOAT BlendFactor[4],
|
||||||
UINT SampleMask) {
|
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(
|
void D3D11DeviceContext::OMSetDepthStencilState(
|
||||||
ID3D11DepthStencilState* pDepthStencilState,
|
ID3D11DepthStencilState* pDepthStencilState,
|
||||||
UINT StencilRef) {
|
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) {
|
if (m_state.rs.state != rasterizerState) {
|
||||||
m_state.rs.state = rasterizerState;
|
m_state.rs.state = rasterizerState;
|
||||||
|
|
||||||
if (rasterizerState != nullptr)
|
if (rasterizerState == nullptr)
|
||||||
rasterizerState->BindToContext(m_context);
|
rasterizerState = m_defaultRasterizerState.ptr();
|
||||||
else
|
|
||||||
this->SetDefaultRasterizerState();
|
rasterizerState->BindToContext(m_context);
|
||||||
|
|
||||||
// In D3D11, the rasterizer state defines
|
// In D3D11, the rasterizer state defines
|
||||||
// whether the scissor test is enabled, so
|
// whether the scissor test is enabled, so
|
||||||
@ -1553,75 +1604,4 @@ namespace dxvk {
|
|||||||
scissors.data());
|
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<DxvkDevice> m_device;
|
||||||
Rc<DxvkContext> m_context;
|
Rc<DxvkContext> m_context;
|
||||||
|
|
||||||
|
Com<D3D11BlendState> m_defaultBlendState;
|
||||||
|
Com<D3D11DepthStencilState> m_defaultDepthStencilState;
|
||||||
|
Com<D3D11RasterizerState> m_defaultRasterizerState;
|
||||||
|
|
||||||
D3D11ContextState m_state;
|
D3D11ContextState m_state;
|
||||||
|
|
||||||
void BindConstantBuffers(
|
void BindConstantBuffers(
|
||||||
@ -572,14 +576,6 @@ namespace dxvk {
|
|||||||
|
|
||||||
void ApplyViewportState();
|
void ApplyViewportState();
|
||||||
|
|
||||||
void SetupIAStateObjects();
|
|
||||||
|
|
||||||
void SetDefaultBlendState();
|
|
||||||
|
|
||||||
void SetDefaultDepthStencilState();
|
|
||||||
|
|
||||||
void SetDefaultRasterizerState();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,13 @@ namespace dxvk {
|
|||||||
struct D3D11ContextStateOM {
|
struct D3D11ContextStateOM {
|
||||||
std::array<Com<D3D11RenderTargetView>, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> renderTargetViews;
|
std::array<Com<D3D11RenderTargetView>, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> renderTargetViews;
|
||||||
Com<D3D11DepthStencilView> depthStencilView;
|
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(
|
void D3D11DepthStencilState::BindToContext(
|
||||||
const Rc<DxvkContext>& ctx) {
|
const Rc<DxvkContext>& ctx) {
|
||||||
ctx->setDepthStencilState(m_state);
|
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(
|
void DxvkCommandList::cmdSetScissor(
|
||||||
uint32_t firstScissor,
|
uint32_t firstScissor,
|
||||||
uint32_t scissorCount,
|
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(
|
void DxvkCommandList::cmdSetViewport(
|
||||||
uint32_t firstViewport,
|
uint32_t firstViewport,
|
||||||
uint32_t viewportCount,
|
uint32_t viewportCount,
|
||||||
|
@ -169,11 +169,18 @@ namespace dxvk {
|
|||||||
VkDeviceSize dataSize,
|
VkDeviceSize dataSize,
|
||||||
const void* pData);
|
const void* pData);
|
||||||
|
|
||||||
|
void cmdSetBlendConstants(
|
||||||
|
float blendConstants[4]);
|
||||||
|
|
||||||
void cmdSetScissor(
|
void cmdSetScissor(
|
||||||
uint32_t firstScissor,
|
uint32_t firstScissor,
|
||||||
uint32_t scissorCount,
|
uint32_t scissorCount,
|
||||||
const VkRect2D* scissors);
|
const VkRect2D* scissors);
|
||||||
|
|
||||||
|
void cmdSetStencilReference(
|
||||||
|
VkStencilFaceFlags faceMask,
|
||||||
|
uint32_t reference);
|
||||||
|
|
||||||
void cmdSetViewport(
|
void cmdSetViewport(
|
||||||
uint32_t firstViewport,
|
uint32_t firstViewport,
|
||||||
uint32_t viewportCount,
|
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(
|
void DxvkContext::setInputAssemblyState(
|
||||||
const DxvkInputAssemblyState& state) {
|
const DxvkInputAssemblyState& state) {
|
||||||
m_state.ia = state;
|
m_state.ia = state;
|
||||||
@ -785,6 +802,8 @@ namespace dxvk {
|
|||||||
m_flags.clr(DxvkContextFlag::GpDirtyDynamicState);
|
m_flags.clr(DxvkContextFlag::GpDirtyDynamicState);
|
||||||
|
|
||||||
this->updateViewports();
|
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() {
|
void DxvkContext::updateIndexBufferBinding() {
|
||||||
if (m_flags.test(DxvkContextFlag::GpDirtyIndexBuffer)) {
|
if (m_flags.test(DxvkContextFlag::GpDirtyIndexBuffer)) {
|
||||||
m_flags.clr(DxvkContextFlag::GpDirtyIndexBuffer);
|
m_flags.clr(DxvkContextFlag::GpDirtyIndexBuffer);
|
||||||
|
@ -295,6 +295,26 @@ namespace dxvk {
|
|||||||
const VkViewport* viewports,
|
const VkViewport* viewports,
|
||||||
const VkRect2D* scissorRects);
|
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
|
* \brief Sets input assembly state
|
||||||
* \param [in] state New state object
|
* \param [in] state New state object
|
||||||
@ -377,6 +397,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
void updateDynamicState();
|
void updateDynamicState();
|
||||||
void updateViewports();
|
void updateViewports();
|
||||||
|
void updateBlendConstants();
|
||||||
|
void updateStencilReference();
|
||||||
|
|
||||||
void updateIndexBufferBinding();
|
void updateIndexBufferBinding();
|
||||||
void updateVertexBufferBindings();
|
void updateVertexBufferBindings();
|
||||||
|
@ -57,7 +57,10 @@ namespace dxvk {
|
|||||||
struct DxvkOutputMergerState {
|
struct DxvkOutputMergerState {
|
||||||
Rc<DxvkFramebuffer> framebuffer;
|
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