diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 0b33640a..6b57be17 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -2966,8 +2966,20 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void clearQuad(ClearQuad& _clearQuad, const Rect& _rect, const Clear& _clear, const float _palette[][4]) { - uint32_t width = getBufferWidth(); - uint32_t height = getBufferHeight(); + uint32_t width; + uint32_t height; + + if (isValid(m_fbh) ) + { + const FrameBufferD3D11& fb = m_frameBuffers[m_fbh.idx]; + width = fb.m_width; + height = fb.m_height; + } + else + { + width = getBufferWidth(); + height = getBufferHeight(); + } if (0 == _rect.m_x && 0 == _rect.m_y @@ -3443,35 +3455,38 @@ BX_PRAGMA_DIAGNOSTIC_POP(); BufferD3D11::create(_size, _data, _flags, stride, true); } - static bool hasDiscard(const void* _code, uint32_t _size) + static bool hasDepthOp(const void* _code, uint32_t _size) { bx::MemoryReader rd(_code, _size); DxbcContext dxbc; read(&rd, dxbc); - struct FindDiscard + struct FindDepthOp { - FindDiscard() + FindDepthOp() : m_found(false) { } - static void find(uint32_t /*_offset*/, const DxbcInstruction& _instruction, void* _userData) + static bool find(uint32_t /*_offset*/, const DxbcInstruction& _instruction, void* _userData) { - FindDiscard& out = *reinterpret_cast(_userData); - if (_instruction.opcode == DxbcOpcode::DISCARD) + FindDepthOp& out = *reinterpret_cast(_userData); + if (_instruction.opcode == DxbcOpcode::DISCARD + || (0 != _instruction.numOperands && DxbcOperandType::OutputDepth == _instruction.operand[0].type) ) { out.m_found = true; - return; + return false; } + + return true; } bool m_found; } find; - parse(dxbc.shader, FindDiscard::find, &find); + parse(dxbc.shader, FindDepthOp::find, &find); return find.m_found; } @@ -3592,7 +3607,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (BGFX_CHUNK_MAGIC_FSH == magic) { - m_hasDiscard = hasDiscard(code, shaderSize); + m_hasDepthOp = hasDepthOp(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."); } @@ -4052,6 +4067,9 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void FrameBufferD3D11::postReset() { + m_width = 0; + m_height = 0; + if (0 < m_numTh) { m_num = 0; @@ -4061,6 +4079,32 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (isValid(handle) ) { const TextureD3D11& texture = s_renderD3D11->m_textures[handle.idx]; + + if (0 == m_width) + { + switch (texture.m_type) + { + case TextureD3D11::Texture2D: + case TextureD3D11::TextureCube: + { + D3D11_TEXTURE2D_DESC desc; + texture.m_texture2d->GetDesc(&desc); + m_width = desc.Width; + m_height = desc.Height; + } + break; + + case TextureD3D11::Texture3D: + { + D3D11_TEXTURE3D_DESC desc; + texture.m_texture3d->GetDesc(&desc); + m_width = desc.Width; + m_height = desc.Height; + } + break; + } + } + if (isDepth( (TextureFormat::Enum)texture.m_textureFormat) ) { BX_CHECK(NULL == m_dsv, "Frame buffer already has depth-stencil attached."); @@ -4718,7 +4762,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); const ShaderD3D11* fsh = program.m_fsh; if (NULL != m_currentColor - || fsh->m_hasDiscard) + || fsh->m_hasDepthOp) { 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 e209a1e8..359f9368 100644 --- a/src/renderer_d3d11.h +++ b/src/renderer_d3d11.h @@ -113,7 +113,7 @@ namespace bgfx { namespace d3d11 , m_hash(0) , m_numUniforms(0) , m_numPredefined(0) - , m_hasDiscard(false) + , m_hasDepthOp(false) { } @@ -163,7 +163,7 @@ namespace bgfx { namespace d3d11 uint16_t m_numUniforms; uint8_t m_numPredefined; - bool m_hasDiscard; + bool m_hasDepthOp; }; struct ProgramD3D11 @@ -231,25 +231,27 @@ namespace bgfx { namespace d3d11 union { - ID3D11Resource* m_ptr; + ID3D11Resource* m_ptr; ID3D11Texture2D* m_texture2d; ID3D11Texture3D* m_texture3d; }; - ID3D11ShaderResourceView* m_srv; + ID3D11ShaderResourceView* m_srv; ID3D11UnorderedAccessView* m_uav; ID3D11SamplerState* m_sampler; uint32_t m_flags; - uint8_t m_type; - uint8_t m_requestedFormat; - uint8_t m_textureFormat; - uint8_t m_numMips; + uint8_t m_type; + uint8_t m_requestedFormat; + uint8_t m_textureFormat; + uint8_t m_numMips; }; struct FrameBufferD3D11 { FrameBufferD3D11() : m_dsv(NULL) + , m_width(0) + , m_height(0) , m_denseIdx(UINT16_MAX) , m_num(0) , m_numTh(0) @@ -268,6 +270,8 @@ namespace bgfx { namespace d3d11 ID3D11ShaderResourceView* m_srv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1]; ID3D11DepthStencilView* m_dsv; IDXGISwapChain* m_swapChain; + uint32_t m_width; + uint32_t m_height; uint16_t m_denseIdx; uint8_t m_num; uint8_t m_numTh; diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 7ce32b6f..7050cc2c 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -2422,8 +2422,20 @@ data.NumQualityLevels = 0; void clearQuad(const Rect& _rect, const Clear& _clear, const float _palette[][4]) { - uint32_t width = m_scd.BufferDesc.Width; - uint32_t height = m_scd.BufferDesc.Height; + uint32_t width; + uint32_t height; + + if (isValid(m_fbh) ) + { + const FrameBufferD3D12& fb = m_frameBuffers[m_fbh.idx]; + width = fb.m_width; + height = fb.m_height; + } + else + { + width = m_scd.BufferDesc.Width; + height = m_scd.BufferDesc.Height; + } if (0 == _rect.m_x && 0 == _rect.m_y @@ -4038,6 +4050,8 @@ data.NumQualityLevels = 0; uint32_t fbhIdx = (uint32_t)(this - s_renderD3D12->m_frameBuffers); rtvDescriptor.ptr += (BX_COUNTOF(s_renderD3D12->m_backBufferColor) + fbhIdx * BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) * rtvDescriptorSize; + m_width = 0; + m_height = 0; m_depth.idx = bgfx::invalidHandle; m_num = 0; for (uint32_t ii = 0; ii < m_numTh; ++ii) @@ -4046,6 +4060,14 @@ data.NumQualityLevels = 0; if (isValid(handle) ) { const TextureD3D12& texture = s_renderD3D12->m_textures[handle.idx]; + + if (0 == m_width) + { + D3D12_RESOURCE_DESC desc = texture.m_ptr->GetDesc(); + m_width = uint32_t(desc.Width); + m_height = uint32_t(desc.Height); + } + if (isDepth( (TextureFormat::Enum)texture.m_textureFormat) ) { BX_CHECK(!isValid(m_depth), ""); diff --git a/src/renderer_d3d12.h b/src/renderer_d3d12.h index a5488683..563db929 100644 --- a/src/renderer_d3d12.h +++ b/src/renderer_d3d12.h @@ -283,6 +283,8 @@ namespace bgfx { namespace d3d12 { FrameBufferD3D12() : m_swapChain(NULL) + , m_width(0) + , m_height(0) , m_denseIdx(UINT16_MAX) , m_num(0) , m_numTh(0) @@ -301,6 +303,8 @@ namespace bgfx { namespace d3d12 TextureHandle m_texture[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; TextureHandle m_depth; IDXGISwapChain* m_swapChain; + uint32_t m_width; + uint32_t m_height; uint16_t m_denseIdx; uint8_t m_num; uint8_t m_numTh; diff --git a/src/shader_dxbc.cpp b/src/shader_dxbc.cpp index d59af86e..5d8d9609 100644 --- a/src/shader_dxbc.cpp +++ b/src/shader_dxbc.cpp @@ -1884,7 +1884,11 @@ namespace bgfx uint32_t size = read(&reader, instruction); BX_CHECK(size/4 == instruction.length, "read %d, expected %d", size/4, instruction.length); BX_UNUSED(size); - _fn(token * sizeof(uint32_t), instruction, _userData); + bool cont = _fn(token * sizeof(uint32_t), instruction, _userData); + if (!cont) + { + return; + } token += instruction.length; } diff --git a/src/shader_dxbc.h b/src/shader_dxbc.h index 710ac87f..52590981 100644 --- a/src/shader_dxbc.h +++ b/src/shader_dxbc.h @@ -575,7 +575,7 @@ namespace bgfx int32_t read(bx::ReaderSeekerI* _reader, DxbcShader& _shader); int32_t write(bx::WriterI* _writer, const DxbcShader& _shader); - typedef void (*DxbcParseFn)(uint32_t _offset, const DxbcInstruction& _instruction, void* _userData); + typedef bool (*DxbcParseFn)(uint32_t _offset, const DxbcInstruction& _instruction, void* _userData); void parse(const DxbcShader& _src, DxbcParseFn _fn, void* _userData); typedef void (*DxbcFilterFn)(DxbcInstruction& _instruction, void* _userData);