From 01ceccf51532e469ab81c5cffc12704530c31e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 10 Sep 2015 16:32:37 -0700 Subject: [PATCH] D3D11: Find discard instruction to enable/disable fragment shader when writing into FB without color attachment. --- src/renderer_d3d11.cpp | 39 +++++++++++++++++++++++++++++++++++++-- src/renderer_d3d11.h | 3 +++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 0e5f3266..0b33640a 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -3443,6 +3443,39 @@ BX_PRAGMA_DIAGNOSTIC_POP(); BufferD3D11::create(_size, _data, _flags, stride, true); } + static bool hasDiscard(const void* _code, uint32_t _size) + { + bx::MemoryReader rd(_code, _size); + + DxbcContext dxbc; + read(&rd, dxbc); + + struct FindDiscard + { + FindDiscard() + : m_found(false) + { + } + + static void find(uint32_t /*_offset*/, const DxbcInstruction& _instruction, void* _userData) + { + FindDiscard& out = *reinterpret_cast(_userData); + if (_instruction.opcode == DxbcOpcode::DISCARD) + { + out.m_found = true; + return; + } + } + + bool m_found; + + } find; + + parse(dxbc.shader, FindDiscard::find, &find); + + return find.m_found; + } + void ShaderD3D11::create(const Memory* _mem) { bx::MemoryReader reader(_mem->data, _mem->size); @@ -3559,6 +3592,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (BGFX_CHUNK_MAGIC_FSH == magic) { + m_hasDiscard = hasDiscard(code, shaderSize); DX_CHECK(s_renderD3D11->m_device->CreatePixelShader(code, shaderSize, NULL, &m_pixelShader) ); BGFX_FATAL(NULL != m_ptr, bgfx::Fatal::InvalidShader, "Failed to create fragment shader."); } @@ -4682,9 +4716,10 @@ BX_PRAGMA_DIAGNOSTIC_POP(); deviceCtx->VSSetShader(vsh->m_vertexShader, NULL, 0); deviceCtx->VSSetConstantBuffers(0, 1, &vsh->m_buffer); - if (NULL != m_currentColor) + const ShaderD3D11* fsh = program.m_fsh; + if (NULL != m_currentColor + || fsh->m_hasDiscard) { - const ShaderD3D11* fsh = program.m_fsh; deviceCtx->PSSetShader(fsh->m_pixelShader, NULL, 0); deviceCtx->PSSetConstantBuffers(0, 1, &fsh->m_buffer); } diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h index 65b67669..e209a1e8 100644 --- a/src/renderer_d3d11.h +++ b/src/renderer_d3d11.h @@ -28,6 +28,7 @@ BX_PRAGMA_DIAGNOSTIC_POP() #include "renderer.h" #include "renderer_d3d.h" +#include "shader_dxbc.h" #include "ovr.h" #include "renderdoc.h" @@ -112,6 +113,7 @@ namespace bgfx { namespace d3d11 , m_hash(0) , m_numUniforms(0) , m_numPredefined(0) + , m_hasDiscard(false) { } @@ -161,6 +163,7 @@ namespace bgfx { namespace d3d11 uint16_t m_numUniforms; uint8_t m_numPredefined; + bool m_hasDiscard; }; struct ProgramD3D11