diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-08-06 15:52:38 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-08-06 15:52:38 -0700 |
| commit | 73ff6907d723003d30e400f661876e7960de574f (patch) | |
| tree | 76fb87e0d7cdf6310c4a62753556dbf061842d7b /tools/gfx/render-d3d11.cpp | |
| parent | 68d705f6c805c9b4d31b386e065762e6db13ad18 (diff) | |
Add basic support for "Dear IMGUI" (#625)
This isn't being made visible just yet, but it will allow us to have a simple UI for loading models into the model-viewer example.
In order to support rendering with IMGUI I had to add the following to the `Renderer` layer:
* viewports
* scissor rects
* blend support
These are really only fully implemented for D3D11, but adding them to the other back-ends should be a reasonably small task.
Diffstat (limited to 'tools/gfx/render-d3d11.cpp')
| -rw-r--r-- | tools/gfx/render-d3d11.cpp | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/tools/gfx/render-d3d11.cpp b/tools/gfx/render-d3d11.cpp index 57c0672bd..7bf712216 100644 --- a/tools/gfx/render-d3d11.cpp +++ b/tools/gfx/render-d3d11.cpp @@ -86,6 +86,8 @@ public: virtual void setVertexBuffers(UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* strides, const UInt* offsets) override; virtual void setIndexBuffer(BufferResource* buffer, Format indexFormat, UInt offset) override; virtual void setDepthStencilTarget(ResourceView* depthStencilView) override; + void setViewports(UInt count, Viewport const* viewports) override; + void setScissorRects(UInt count, ScissorRect const* rects) override; virtual void setPipelineState(PipelineType pipelineType, PipelineState* state) override; virtual void draw(UInt vertexCount, UInt startVertex) override; virtual void drawIndexed(UInt indexCount, UInt startIndex, UInt baseVertex) override; @@ -282,8 +284,11 @@ public: RefPtr<InputLayoutImpl> m_inputLayout; ComPtr<ID3D11DepthStencilState> m_depthStencilState; ComPtr<ID3D11RasterizerState> m_rasterizerState; + ComPtr<ID3D11BlendState> m_blendState; UINT m_stencilRef; + float m_blendColor[4]; + UINT m_sampleMask; }; class ComputePipelineStateImpl : public PipelineStateImpl @@ -1111,6 +1116,7 @@ Result D3D11Renderer::createInputLayout(const InputElementDesc* inputElementsIn, switch (inputElementsIn[ii].format) { case Format::RGBA_Float32: + case Format::RGBA_Unorm_UInt8: typeName = "float4"; break; case Format::RGB_Float32: @@ -1245,6 +1251,49 @@ void D3D11Renderer::setDepthStencilTarget(ResourceView* depthStencilView) m_targetBindingsDirty[int(PipelineType::Graphics)] = true; } +void D3D11Renderer::setViewports(UInt count, Viewport const* viewports) +{ + static const int kMaxViewports = D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX + 1; + assert(count <= kMaxViewports); + + D3D11_VIEWPORT dxViewports[kMaxViewports]; + for(UInt ii = 0; ii < count; ++ii) + { + auto& inViewport = viewports[ii]; + auto& dxViewport = dxViewports[ii]; + + dxViewport.TopLeftX = inViewport.originX; + dxViewport.TopLeftY = inViewport.originY; + dxViewport.Width = inViewport.extentX; + dxViewport.Height = inViewport.extentY; + dxViewport.MinDepth = inViewport.minZ; + dxViewport.MaxDepth = inViewport.maxZ; + } + + m_immediateContext->RSSetViewports(count, dxViewports); +} + +void D3D11Renderer::setScissorRects(UInt count, ScissorRect const* rects) +{ + static const int kMaxScissorRects = D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX + 1; + assert(count <= kMaxScissorRects); + + D3D11_RECT dxRects[kMaxScissorRects]; + for(UInt ii = 0; ii < count; ++ii) + { + auto& inRect = rects[ii]; + auto& dxRect = dxRects[ii]; + + dxRect.left = inRect.minX; + dxRect.top = inRect.minY; + dxRect.right = inRect.maxX; + dxRect.bottom = inRect.maxY; + } + + m_immediateContext->RSSetScissorRects(count, dxRects); +} + + void D3D11Renderer::setPipelineState(PipelineType pipelineType, PipelineState* state) { switch(pipelineType) @@ -1288,6 +1337,7 @@ void D3D11Renderer::setPipelineState(PipelineType pipelineType, PipelineState* s // OM + m_immediateContext->OMSetBlendState(stateImpl->m_blendState, stateImpl->m_blendColor, stateImpl->m_sampleMask); m_immediateContext->OMSetDepthStencilState(stateImpl->m_depthStencilState, stateImpl->m_stencilRef); m_currentGraphicsState = stateImpl; @@ -1409,6 +1459,82 @@ static D3D11_CULL_MODE translateCullMode(CullMode mode) } } +bool isBlendDisabled(AspectBlendDesc const& desc) +{ + return desc.op == BlendOp::Add + && desc.srcFactor == BlendFactor::One + && desc.dstFactor == BlendFactor::Zero; +} + + +bool isBlendDisabled(TargetBlendDesc const& desc) +{ + return isBlendDisabled(desc.color) + && isBlendDisabled(desc.alpha); +} + +D3D11_BLEND_OP translateBlendOp(BlendOp op) +{ + switch(op) + { + default: + assert(!"unimplemented"); + return (D3D11_BLEND_OP) -1; + +#define CASE(FROM, TO) case BlendOp::FROM: return D3D11_BLEND_OP_##TO + CASE(Add, ADD); + CASE(Subtract, SUBTRACT); + CASE(ReverseSubtract, REV_SUBTRACT); + CASE(Min, MIN); + CASE(Max, MAX); +#undef CASE + } +} + +D3D11_BLEND translateBlendFactor(BlendFactor factor) +{ + switch(factor) + { + default: + assert(!"unimplemented"); + return (D3D11_BLEND) -1; + +#define CASE(FROM, TO) case BlendFactor::FROM: return D3D11_BLEND_##TO + CASE(Zero, ZERO); + CASE(One, ONE); + CASE(SrcColor, SRC_COLOR); + CASE(InvSrcColor, INV_SRC_COLOR); + CASE(SrcAlpha, SRC_ALPHA); + CASE(InvSrcAlpha, INV_SRC_ALPHA); + CASE(DestAlpha, DEST_ALPHA); + CASE(InvDestAlpha, INV_DEST_ALPHA); + CASE(DestColor, DEST_COLOR); + CASE(InvDestColor, INV_DEST_ALPHA); + CASE(SrcAlphaSaturate, SRC_ALPHA_SAT); + CASE(BlendColor, BLEND_FACTOR); + CASE(InvBlendColor, INV_BLEND_FACTOR); + CASE(SecondarySrcColor, SRC1_COLOR); + CASE(InvSecondarySrcColor, INV_SRC1_COLOR); + CASE(SecondarySrcAlpha, SRC1_ALPHA); + CASE(InvSecondarySrcAlpha, INV_SRC1_ALPHA); +#undef CASE + } +} + +D3D11_COLOR_WRITE_ENABLE translateRenderTargetWriteMask(RenderTargetWriteMaskT mask) +{ + UINT result = 0; +#define CASE(FROM, TO) if(mask & RenderTargetWriteMask::Enable##FROM) result |= D3D11_COLOR_WRITE_ENABLE_##TO + + CASE(Red, RED); + CASE(Green, GREEN); + CASE(Blue, BLUE); + CASE(Alpha, ALPHA); + +#undef CASE + return D3D11_COLOR_WRITE_ENABLE(result); +} + Result D3D11Renderer::createGraphicsPipelineState(const GraphicsPipelineStateDesc& desc, PipelineState** outState) { auto programImpl = (ShaderProgramImpl*) desc.program; @@ -1458,14 +1584,81 @@ Result D3D11Renderer::createGraphicsPipelineState(const GraphicsPipelineStateDes } + ComPtr<ID3D11BlendState> blendState; + { + auto& srcDesc = desc.blend; + D3D11_BLEND_DESC dstDesc = {}; + + TargetBlendDesc defaultTargetBlendDesc; + + static const UInt kMaxTargets = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; + if(srcDesc.targetCount > kMaxTargets) return SLANG_FAIL; + + for(UInt ii = 0; ii < kMaxTargets; ++ii) + { + TargetBlendDesc const* srcTargetBlendDescPtr = nullptr; + if(ii < srcDesc.targetCount) + { + srcTargetBlendDescPtr = &srcDesc.targets[ii]; + } + else if(srcDesc.targetCount == 0) + { + srcTargetBlendDescPtr = &defaultTargetBlendDesc; + } + else + { + srcTargetBlendDescPtr = &srcDesc.targets[srcDesc.targetCount-1]; + } + + auto& srcTargetBlendDesc = *srcTargetBlendDescPtr; + auto& dstTargetBlendDesc = dstDesc.RenderTarget[ii]; + + if(isBlendDisabled(srcTargetBlendDesc)) + { + dstTargetBlendDesc.BlendEnable = false; + dstTargetBlendDesc.BlendOp = D3D11_BLEND_OP_ADD; + dstTargetBlendDesc.BlendOpAlpha = D3D11_BLEND_OP_ADD; + dstTargetBlendDesc.SrcBlend = D3D11_BLEND_ONE; + dstTargetBlendDesc.SrcBlendAlpha = D3D11_BLEND_ONE; + dstTargetBlendDesc.DestBlend = D3D11_BLEND_ZERO; + dstTargetBlendDesc.DestBlendAlpha = D3D11_BLEND_ZERO; + } + else + { + dstTargetBlendDesc.BlendEnable = true; + dstTargetBlendDesc.BlendOp = translateBlendOp(srcTargetBlendDesc.color.op); + dstTargetBlendDesc.BlendOpAlpha = translateBlendOp(srcTargetBlendDesc.alpha.op); + dstTargetBlendDesc.SrcBlend = translateBlendFactor(srcTargetBlendDesc.color.srcFactor); + dstTargetBlendDesc.SrcBlendAlpha = translateBlendFactor(srcTargetBlendDesc.alpha.srcFactor); + dstTargetBlendDesc.DestBlend = translateBlendFactor(srcTargetBlendDesc.color.dstFactor); + dstTargetBlendDesc.DestBlendAlpha = translateBlendFactor(srcTargetBlendDesc.alpha.dstFactor); + } + + dstTargetBlendDesc.RenderTargetWriteMask = translateRenderTargetWriteMask(srcTargetBlendDesc.writeMask); + } + + dstDesc.IndependentBlendEnable = srcDesc.targetCount > 1; + dstDesc.AlphaToCoverageEnable = srcDesc.alphaToCoverateEnable; + + SLANG_RETURN_ON_FAIL(m_device->CreateBlendState( + &dstDesc, + blendState.writeRef())); + } + RefPtr<GraphicsPipelineStateImpl> state = new GraphicsPipelineStateImpl(); state->m_program = programImpl; state->m_stencilRef = desc.depthStencil.stencilRef; state->m_depthStencilState = depthStencilState; state->m_rasterizerState = rasterizerState; + state->m_blendState = blendState; state->m_pipelineLayout = (PipelineLayoutImpl*) desc.pipelineLayout; state->m_inputLayout = (InputLayoutImpl*) desc.inputLayout; state->m_rtvCount = desc.renderTargetCount; + state->m_blendColor[0] = 0; + state->m_blendColor[1] = 0; + state->m_blendColor[2] = 0; + state->m_blendColor[3] = 0; + state->m_sampleMask = 0xFFFFFFFF; *outState = state.detach(); return SLANG_OK; |
