D3D11: Find discard instruction to enable/disable fragment shader when writing into FB without color attachment.

This commit is contained in:
Branimir Karadžić 2015-09-10 16:32:37 -07:00
parent 05490b53ca
commit 01ceccf515
2 changed files with 40 additions and 2 deletions

View file

@ -3443,6 +3443,39 @@ BX_PRAGMA_DIAGNOSTIC_POP();
BufferD3D11::create(_size, _data, _flags, stride, true); 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<FindDiscard*>(_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) void ShaderD3D11::create(const Memory* _mem)
{ {
bx::MemoryReader reader(_mem->data, _mem->size); bx::MemoryReader reader(_mem->data, _mem->size);
@ -3559,6 +3592,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
if (BGFX_CHUNK_MAGIC_FSH == magic) if (BGFX_CHUNK_MAGIC_FSH == magic)
{ {
m_hasDiscard = hasDiscard(code, shaderSize);
DX_CHECK(s_renderD3D11->m_device->CreatePixelShader(code, shaderSize, NULL, &m_pixelShader) ); 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."); 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->VSSetShader(vsh->m_vertexShader, NULL, 0);
deviceCtx->VSSetConstantBuffers(0, 1, &vsh->m_buffer); 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->PSSetShader(fsh->m_pixelShader, NULL, 0);
deviceCtx->PSSetConstantBuffers(0, 1, &fsh->m_buffer); deviceCtx->PSSetConstantBuffers(0, 1, &fsh->m_buffer);
} }

View file

@ -28,6 +28,7 @@ BX_PRAGMA_DIAGNOSTIC_POP()
#include "renderer.h" #include "renderer.h"
#include "renderer_d3d.h" #include "renderer_d3d.h"
#include "shader_dxbc.h"
#include "ovr.h" #include "ovr.h"
#include "renderdoc.h" #include "renderdoc.h"
@ -112,6 +113,7 @@ namespace bgfx { namespace d3d11
, m_hash(0) , m_hash(0)
, m_numUniforms(0) , m_numUniforms(0)
, m_numPredefined(0) , m_numPredefined(0)
, m_hasDiscard(false)
{ {
} }
@ -161,6 +163,7 @@ namespace bgfx { namespace d3d11
uint16_t m_numUniforms; uint16_t m_numUniforms;
uint8_t m_numPredefined; uint8_t m_numPredefined;
bool m_hasDiscard;
}; };
struct ProgramD3D11 struct ProgramD3D11