diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 972482643..f0f605abe 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -83,6 +83,8 @@ DrawEngineD3D11::DrawEngineD3D11(Draw::DrawContext *draw, ID3D11Device *device, vertexCountInDrawCalls(0), decodeCounter_(0), dcid_(0) { + device1_ = (ID3D11Device1 *)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX); + context1_ = (ID3D11DeviceContext1 *)draw->GetNativeObject(Draw::NativeObject::CONTEXT_EX); decOptions_.expandAllWeightsToFloat = true; decOptions_.expand8BitNormalsToFloat = true; diff --git a/GPU/D3D11/DrawEngineD3D11.h b/GPU/D3D11/DrawEngineD3D11.h index c6031ae32..4581e1fae 100644 --- a/GPU/D3D11/DrawEngineD3D11.h +++ b/GPU/D3D11/DrawEngineD3D11.h @@ -20,6 +20,7 @@ #include #include +#include #include "GPU/GPUState.h" #include "GPU/Common/GPUDebugInterface.h" @@ -172,7 +173,9 @@ private: Draw::DrawContext *draw_; // Used for framebuffer related things exclusively. ID3D11Device *device_; + ID3D11Device1 *device1_; ID3D11DeviceContext *context_; + ID3D11DeviceContext1 *context1_; // Defer all vertex decoding to a Flush, so that we can hash and cache the // generated buffers without having to redecode them every time. @@ -236,13 +239,15 @@ private: // D3D11 state object caches std::map blendCache_; + std::map blendCache1_; std::map depthStencilCache_; std::map rasterCache_; // Keep the depth state between ApplyDrawState and ApplyDrawStateLate - ID3D11RasterizerState *rasterState_; - ID3D11BlendState *blendState_; - ID3D11DepthStencilState *depthStencilState_; + ID3D11RasterizerState *rasterState_ = nullptr; + ID3D11BlendState *blendState_ = nullptr; + ID3D11BlendState1 *blendState1_ = nullptr; + ID3D11DepthStencilState *depthStencilState_ = nullptr; // State keys D3D11StateKeys keys_{}; diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index f6dc4f09a..21b72dd5e 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -517,8 +517,7 @@ void GPU_D3D11::CheckGPUFeatures() { } if (draw_->GetDeviceCaps().logicOpSupported) { - // This requires a little bit more code in statemapping, and passing in a device1_ object. - // features |= GPU_SUPPORTS_LOGIC_OP; + features |= GPU_SUPPORTS_LOGIC_OP; } if (!g_Config.bHighQualityDepth) { diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index d2fc454c8..c0ce1d4b5 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -355,30 +355,52 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { } ID3D11BlendState *bs = nullptr; + ID3D11BlendState1 *bs1 = nullptr; ID3D11DepthStencilState *ds = nullptr; ID3D11RasterizerState *rs = nullptr; - auto blendIter = blendCache_.find(keys_.blend.value); - if (blendIter == blendCache_.end()) { - D3D11_BLEND_DESC desc{}; - D3D11_RENDER_TARGET_BLEND_DESC &rt = desc.RenderTarget[0]; - rt.BlendEnable = keys_.blend.blendEnable; - rt.BlendOp = (D3D11_BLEND_OP)keys_.blend.blendOpColor; - rt.BlendOpAlpha = (D3D11_BLEND_OP)keys_.blend.blendOpAlpha; - rt.SrcBlend = (D3D11_BLEND)keys_.blend.srcColor; - rt.DestBlend = (D3D11_BLEND)keys_.blend.destColor; - rt.SrcBlendAlpha = (D3D11_BLEND)keys_.blend.srcAlpha; - rt.DestBlendAlpha = (D3D11_BLEND)keys_.blend.destAlpha; - rt.RenderTargetWriteMask = keys_.blend.colorWriteMask; - // TODO: Add logic op support, requires a device1_ and CreateBlendState1 - device_->CreateBlendState(&desc, &bs); - blendCache_.insert(std::pair(keys_.blend.value, bs)); + if (!device1_) { + auto blendIter = blendCache_.find(keys_.blend.value); + if (blendIter == blendCache_.end()) { + D3D11_BLEND_DESC desc{}; + D3D11_RENDER_TARGET_BLEND_DESC &rt = desc.RenderTarget[0]; + rt.BlendEnable = keys_.blend.blendEnable; + rt.BlendOp = (D3D11_BLEND_OP)keys_.blend.blendOpColor; + rt.BlendOpAlpha = (D3D11_BLEND_OP)keys_.blend.blendOpAlpha; + rt.SrcBlend = (D3D11_BLEND)keys_.blend.srcColor; + rt.DestBlend = (D3D11_BLEND)keys_.blend.destColor; + rt.SrcBlendAlpha = (D3D11_BLEND)keys_.blend.srcAlpha; + rt.DestBlendAlpha = (D3D11_BLEND)keys_.blend.destAlpha; + rt.RenderTargetWriteMask = keys_.blend.colorWriteMask; + device_->CreateBlendState(&desc, &bs); + blendCache_.insert(std::pair(keys_.blend.value, bs)); + } else { + bs = blendIter->second; + } + blendState_ = bs; } else { - bs = blendIter->second; + auto blendIter = blendCache1_.find(keys_.blend.value); + if (blendIter == blendCache1_.end()) { + D3D11_BLEND_DESC1 desc1{}; + D3D11_RENDER_TARGET_BLEND_DESC1 &rt = desc1.RenderTarget[0]; + rt.BlendEnable = keys_.blend.blendEnable; + rt.BlendOp = (D3D11_BLEND_OP)keys_.blend.blendOpColor; + rt.BlendOpAlpha = (D3D11_BLEND_OP)keys_.blend.blendOpAlpha; + rt.SrcBlend = (D3D11_BLEND)keys_.blend.srcColor; + rt.DestBlend = (D3D11_BLEND)keys_.blend.destColor; + rt.SrcBlendAlpha = (D3D11_BLEND)keys_.blend.srcAlpha; + rt.DestBlendAlpha = (D3D11_BLEND)keys_.blend.destAlpha; + rt.RenderTargetWriteMask = keys_.blend.colorWriteMask; + rt.LogicOpEnable = keys_.blend.logicOpEnable; + rt.LogicOp = (D3D11_LOGIC_OP)keys_.blend.logicOp; + device1_->CreateBlendState1(&desc1, &bs1); + blendCache1_.insert(std::pair(keys_.blend.value, bs1)); + } else { + bs1 = blendIter->second; + } + blendState1_ = bs1; } - blendState_ = bs; - auto depthIter = depthStencilCache_.find(keys_.depthStencil.value); if (depthIter == depthStencilCache_.end()) { D3D11_DEPTH_STENCIL_DESC desc{}; @@ -433,6 +455,10 @@ void DrawEngineD3D11::ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRe context_->RSSetViewports(1, &dynState_.viewport); context_->RSSetScissorRects(1, &dynState_.scissor); context_->RSSetState(rasterState_); - context_->OMSetBlendState(blendState_, blendColor, 0xFFFFFFFF); + if (device1_) { + context1_->OMSetBlendState(blendState1_, blendColor, 0xFFFFFFFF); + } else { + context_->OMSetBlendState(blendState_, blendColor, 0xFFFFFFFF); + } context_->OMSetDepthStencilState(depthStencilState_, applyStencilRef ? stencilRef : dynState_.stencilRef); } \ No newline at end of file