From 38ad2d5cb659074ad9b4bde16bcbf71481719b94 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 26 Jan 2020 13:44:37 -0800 Subject: Renamed .h -> .hpp in GraphicsEngine, GraphicsEngineD3DBase, GraphicsEningeD3D11, and GraphicsEningeD3D12 projects --- Graphics/GraphicsEngineD3DBase/CMakeLists.txt | 20 +- Graphics/GraphicsEngineD3DBase/include/D3DErrors.h | 114 ---- .../GraphicsEngineD3DBase/include/D3DErrors.hpp | 114 ++++ .../include/D3DShaderResourceLoader.h | 306 ----------- .../include/D3DShaderResourceLoader.hpp | 306 +++++++++++ .../include/D3DTypeConversionImpl.h | 589 --------------------- .../include/D3DTypeConversionImpl.hpp | 589 +++++++++++++++++++++ .../include/D3DViewDescConversionImpl.h | 344 ------------ .../include/D3DViewDescConversionImpl.hpp | 344 ++++++++++++ .../include/EngineFactoryD3DBase.h | 229 -------- .../include/EngineFactoryD3DBase.hpp | 229 ++++++++ .../include/RenderDeviceD3DBase.h | 182 ------- .../include/RenderDeviceD3DBase.hpp | 182 +++++++ .../GraphicsEngineD3DBase/include/ShaderD3DBase.h | 50 -- .../include/ShaderD3DBase.hpp | 50 ++ .../include/ShaderResources.h | 587 -------------------- .../include/ShaderResources.hpp | 587 ++++++++++++++++++++ .../include/ShaderVariableD3DBase.h | 89 ---- .../include/ShaderVariableD3DBase.hpp | 89 ++++ .../include/SwapChainD3DBase.h | 248 --------- .../include/SwapChainD3DBase.hpp | 248 +++++++++ .../GraphicsEngineD3DBase/src/ShaderD3DBase.cpp | 4 +- .../GraphicsEngineD3DBase/src/ShaderResources.cpp | 4 +- 23 files changed, 2752 insertions(+), 2752 deletions(-) delete mode 100644 Graphics/GraphicsEngineD3DBase/include/D3DErrors.h create mode 100644 Graphics/GraphicsEngineD3DBase/include/D3DErrors.hpp delete mode 100644 Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h create mode 100644 Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.hpp delete mode 100644 Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.h create mode 100644 Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.hpp delete mode 100644 Graphics/GraphicsEngineD3DBase/include/D3DViewDescConversionImpl.h create mode 100644 Graphics/GraphicsEngineD3DBase/include/D3DViewDescConversionImpl.hpp delete mode 100644 Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h create mode 100644 Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.hpp delete mode 100644 Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.h create mode 100644 Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.hpp delete mode 100644 Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.h create mode 100644 Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.hpp delete mode 100644 Graphics/GraphicsEngineD3DBase/include/ShaderResources.h create mode 100644 Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp delete mode 100644 Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.h create mode 100644 Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.hpp delete mode 100644 Graphics/GraphicsEngineD3DBase/include/SwapChainD3DBase.h create mode 100644 Graphics/GraphicsEngineD3DBase/include/SwapChainD3DBase.hpp (limited to 'Graphics/GraphicsEngineD3DBase') diff --git a/Graphics/GraphicsEngineD3DBase/CMakeLists.txt b/Graphics/GraphicsEngineD3DBase/CMakeLists.txt index 2a4daae2..a60f000f 100644 --- a/Graphics/GraphicsEngineD3DBase/CMakeLists.txt +++ b/Graphics/GraphicsEngineD3DBase/CMakeLists.txt @@ -3,18 +3,18 @@ cmake_minimum_required (VERSION 3.10) project(Diligent-GraphicsEngineD3DBase CXX) set(INCLUDE - include/D3DErrors.h - include/D3DShaderResourceLoader.h - include/D3DTypeConversionImpl.h - include/D3DViewDescConversionImpl.h + include/D3DErrors.hpp + include/D3DShaderResourceLoader.hpp + include/D3DTypeConversionImpl.hpp + include/D3DViewDescConversionImpl.hpp include/DXGITypeConversions.h - include/EngineFactoryD3DBase.h + include/EngineFactoryD3DBase.hpp include/HLSLDefinitions.fxh - include/RenderDeviceD3DBase.h - include/ShaderD3DBase.h - include/ShaderResources.h - include/ShaderVariableD3DBase.h - include/SwapChainD3DBase.h + include/RenderDeviceD3DBase.hpp + include/ShaderD3DBase.hpp + include/ShaderResources.hpp + include/ShaderVariableD3DBase.hpp + include/SwapChainD3DBase.hpp ) set(INTERFACE diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DErrors.h b/Graphics/GraphicsEngineD3DBase/include/D3DErrors.h deleted file mode 100644 index 51863b7a..00000000 --- a/Graphics/GraphicsEngineD3DBase/include/D3DErrors.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include - -#include "Errors.h" - -/// \file -/// Declaration of Diligent::ComErrorDesc class - -namespace Diligent -{ - -/// Helper class that provides description of a COM error -class ComErrorDesc -{ -public: - ComErrorDesc(HRESULT hr) - { - auto NumCharsWritten = FormatMessageA( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - hr, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - m_Msg, - _countof(m_Msg), - NULL); - - if (NumCharsWritten == 0) - { - strcpy_s(m_Msg, _countof(m_Msg), "Unknown error"); - } - else - { - auto nLen = strlen(m_Msg); - if (nLen > 1 && m_Msg[nLen - 1] == '\n') - { - m_Msg[nLen - 1] = 0; - if (m_Msg[nLen - 2] == '\r') - { - m_Msg[nLen - 2] = 0; - } - } - } - } - - const char* Get() { return m_Msg; } - -private: - char m_Msg[4096]; -}; - -} // namespace Diligent - - -#define CHECK_D3D_RESULT_THROW(Expr, Message) \ - do \ - { \ - HRESULT _hr_ = Expr; \ - if (FAILED(_hr_)) \ - { \ - ComErrorDesc ErrDesc(_hr_); \ - LOG_ERROR_AND_THROW(Message, "\nHRESULT Desc: ", ErrDesc.Get()); \ - } \ - } while (false) - -#define CHECK_D3D_RESULT_THROW_EX(Expr, ...) \ - do \ - { \ - HRESULT _hr_ = Expr; \ - if (FAILED(_hr_)) \ - { \ - auto msg = Diligent::FormatString(__VA_ARGS__); \ - ComErrorDesc ErrDesc(_hr_); \ - LOG_ERROR_AND_THROW(msg, "\nHRESULT Desc: ", ErrDesc.Get()); \ - } \ - } while (false) - -#define LOG_D3D_ERROR(Expr, Message) \ - do \ - { \ - HRESULT _hr_ = Expr; \ - if (FAILED(_hr_)) \ - { \ - ComErrorDesc ErrDesc(_hr_); \ - LOG_ERROR_MESSAGE(Message, "\nHRESULT Desc: ", ErrDesc.Get()); \ - } \ - } while (false) diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DErrors.hpp b/Graphics/GraphicsEngineD3DBase/include/D3DErrors.hpp new file mode 100644 index 00000000..51863b7a --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/D3DErrors.hpp @@ -0,0 +1,114 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include + +#include "Errors.h" + +/// \file +/// Declaration of Diligent::ComErrorDesc class + +namespace Diligent +{ + +/// Helper class that provides description of a COM error +class ComErrorDesc +{ +public: + ComErrorDesc(HRESULT hr) + { + auto NumCharsWritten = FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + hr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + m_Msg, + _countof(m_Msg), + NULL); + + if (NumCharsWritten == 0) + { + strcpy_s(m_Msg, _countof(m_Msg), "Unknown error"); + } + else + { + auto nLen = strlen(m_Msg); + if (nLen > 1 && m_Msg[nLen - 1] == '\n') + { + m_Msg[nLen - 1] = 0; + if (m_Msg[nLen - 2] == '\r') + { + m_Msg[nLen - 2] = 0; + } + } + } + } + + const char* Get() { return m_Msg; } + +private: + char m_Msg[4096]; +}; + +} // namespace Diligent + + +#define CHECK_D3D_RESULT_THROW(Expr, Message) \ + do \ + { \ + HRESULT _hr_ = Expr; \ + if (FAILED(_hr_)) \ + { \ + ComErrorDesc ErrDesc(_hr_); \ + LOG_ERROR_AND_THROW(Message, "\nHRESULT Desc: ", ErrDesc.Get()); \ + } \ + } while (false) + +#define CHECK_D3D_RESULT_THROW_EX(Expr, ...) \ + do \ + { \ + HRESULT _hr_ = Expr; \ + if (FAILED(_hr_)) \ + { \ + auto msg = Diligent::FormatString(__VA_ARGS__); \ + ComErrorDesc ErrDesc(_hr_); \ + LOG_ERROR_AND_THROW(msg, "\nHRESULT Desc: ", ErrDesc.Get()); \ + } \ + } while (false) + +#define LOG_D3D_ERROR(Expr, Message) \ + do \ + { \ + HRESULT _hr_ = Expr; \ + if (FAILED(_hr_)) \ + { \ + ComErrorDesc ErrDesc(_hr_); \ + LOG_ERROR_MESSAGE(Message, "\nHRESULT Desc: ", ErrDesc.Get()); \ + } \ + } while (false) diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h b/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h deleted file mode 100644 index 64e08580..00000000 --- a/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.h +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include -#include - -#include "Shader.h" -#include "StringTools.h" - -/// \file -/// D3D shader resource loading - -namespace Diligent -{ - -struct D3DShaderResourceCounters -{ - Uint32 NumCBs = 0; - Uint32 NumTexSRVs = 0; - Uint32 NumTexUAVs = 0; - Uint32 NumBufSRVs = 0; - Uint32 NumBufUAVs = 0; - Uint32 NumSamplers = 0; -}; - -template -void LoadD3DShaderResources(ID3DBlob* pShaderByteCode, - THandleShaderDesc HandleShaderDesc, - TOnResourcesCounted OnResourcesCounted, - TOnNewCB OnNewCB, - TOnNewTexUAV OnNewTexUAV, - TOnNewBuffUAV OnNewBuffUAV, - TOnNewBuffSRV OnNewBuffSRV, - TOnNewSampler OnNewSampler, - TOnNewTexSRV OnNewTexSRV) -{ - CComPtr pShaderReflection; - - auto hr = D3DReflect(pShaderByteCode->GetBufferPointer(), pShaderByteCode->GetBufferSize(), __uuidof(pShaderReflection), reinterpret_cast(static_cast(&pShaderReflection))); - CHECK_D3D_RESULT_THROW(hr, "Failed to get the shader reflection"); - - D3D_SHADER_DESC shaderDesc = {}; - pShaderReflection->GetDesc(&shaderDesc); - - HandleShaderDesc(shaderDesc); - - std::vector> Resources(STD_ALLOCATOR_RAW_MEM(D3DShaderResourceAttribs, GetRawAllocator(), "Allocator for vector")); - Resources.reserve(shaderDesc.BoundResources); - std::unordered_set ResourceNamesTmpPool; - - D3DShaderResourceCounters RC; - - size_t ResourceNamesPoolSize = 0; - // Number of resources to skip (used for array resources) - UINT SkipCount = 1; - for (UINT Res = 0; Res < shaderDesc.BoundResources; Res += SkipCount) - { - D3D_SHADER_INPUT_BIND_DESC BindingDesc = {}; - pShaderReflection->GetResourceBindingDesc(Res, &BindingDesc); - - std::string Name(BindingDesc.Name); - - SkipCount = 1; - - UINT BindCount = BindingDesc.BindCount; - - // Handle arrays - // For shader models 5_0 and before, every resource array element is enumerated individually. - // For instance, if the following texture array is defined in the shader: - // - // Texture2D g_tex2DDiffuse[4]; - // - // The reflection system will enumerate 4 resources with the following names: - // "g_tex2DDiffuse[0]" - // "g_tex2DDiffuse[1]" - // "g_tex2DDiffuse[2]" - // "g_tex2DDiffuse[3]" - // - // Notice that if some array element is not used by the shader, it will not be enumerated - - auto OpenBracketPos = Name.find('['); - if (String::npos != OpenBracketPos) - { - VERIFY(BindCount == 1, "When array elements are enumerated individually, BindCount is expected to always be 1"); - - // Name == "g_tex2DDiffuse[0]" - // ^ - // OpenBracketPos - Name.erase(OpenBracketPos, Name.length() - OpenBracketPos); - // Name == "g_tex2DDiffuse" - VERIFY_EXPR(Name.length() == OpenBracketPos); -#ifdef _DEBUG - for (const auto& ExistingRes : Resources) - { - VERIFY(Name.compare(ExistingRes.Name) != 0, "Resource with the same name has already been enumerated. All array elements are expected to be enumerated one after another"); - } -#endif - for (UINT ArrElem = Res + 1; ArrElem < shaderDesc.BoundResources; ++ArrElem) - { - D3D_SHADER_INPUT_BIND_DESC ArrElemBindingDesc = {}; - pShaderReflection->GetResourceBindingDesc(ArrElem, &ArrElemBindingDesc); - - // Make sure this case is handled correctly: - // "g_tex2DDiffuse[.]" != "g_tex2DDiffuse2[.]" - if (strncmp(Name.c_str(), ArrElemBindingDesc.Name, OpenBracketPos) == 0 && ArrElemBindingDesc.Name[OpenBracketPos] == '[') - { - //g_tex2DDiffuse[2] - // ^ - UINT Ind = atoi(ArrElemBindingDesc.Name + OpenBracketPos + 1); - BindCount = std::max(BindCount, Ind + 1); - VERIFY(ArrElemBindingDesc.BindPoint == BindingDesc.BindPoint + Ind, - "Array elements are expected to use contigous bind points.\n", - BindingDesc.Name, " uses slot ", BindingDesc.BindPoint, ", so ", ArrElemBindingDesc.Name, - " is expected to use slot ", BindingDesc.BindPoint + Ind, " while ", ArrElemBindingDesc.BindPoint, - " is actually used"); - - // Note that skip count may not necessarily be the same as BindCount. - // If some array elements are not used by the shader, the reflection system skips them - ++SkipCount; - } - else - { - break; - } - } - } - - switch (BindingDesc.Type) - { - // clang-format off - case D3D_SIT_CBUFFER: ++RC.NumCBs; break; - case D3D_SIT_TBUFFER: UNSUPPORTED( "TBuffers are not supported" ); break; - case D3D_SIT_TEXTURE: ++(BindingDesc.Dimension == D3D_SRV_DIMENSION_BUFFER ? RC.NumBufSRVs : RC.NumTexSRVs); break; - case D3D_SIT_SAMPLER: ++RC.NumSamplers; break; - case D3D_SIT_UAV_RWTYPED: ++(BindingDesc.Dimension == D3D_SRV_DIMENSION_BUFFER ? RC.NumBufUAVs : RC.NumTexUAVs); break; - case D3D_SIT_STRUCTURED: ++RC.NumBufSRVs; break; - case D3D_SIT_UAV_RWSTRUCTURED: ++RC.NumBufUAVs; break; - case D3D_SIT_BYTEADDRESS: ++RC.NumBufSRVs; break; - case D3D_SIT_UAV_RWBYTEADDRESS: ++RC.NumBufUAVs; break; - case D3D_SIT_UAV_APPEND_STRUCTURED: UNSUPPORTED( "Append structured buffers are not supported" ); break; - case D3D_SIT_UAV_CONSUME_STRUCTURED: UNSUPPORTED( "Consume structured buffers are not supported" ); break; - case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: UNSUPPORTED( "RW structured buffers with counter are not supported" ); break; - // clang-format on - default: UNEXPECTED("Unexpected resource type"); - } - ResourceNamesPoolSize += Name.length() + 1; - auto it = ResourceNamesTmpPool.emplace(std::move(Name)); - Resources.emplace_back( - it.first->c_str(), - BindingDesc.BindPoint, - BindCount, - BindingDesc.Type, - BindingDesc.Dimension, - D3DShaderResourceAttribs::InvalidSamplerId); - } - - OnResourcesCounted(RC, ResourceNamesPoolSize); - - std::vector> TexSRVInds(STD_ALLOCATOR_RAW_MEM(size_t, GetRawAllocator(), "Allocator for vector")); - TexSRVInds.reserve(RC.NumTexSRVs); - - for (size_t ResInd = 0; ResInd < Resources.size(); ++ResInd) - { - const auto& Res = Resources[ResInd]; - switch (Res.GetInputType()) - { - case D3D_SIT_CBUFFER: - { - OnNewCB(Res); - break; - } - - case D3D_SIT_TBUFFER: - { - UNSUPPORTED("TBuffers are not supported"); - break; - } - - case D3D_SIT_TEXTURE: - { - if (Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER) - { - OnNewBuffSRV(Res); - } - else - { - // Texture SRVs must be processed all samplers are initialized - TexSRVInds.push_back(ResInd); - } - break; - } - - case D3D_SIT_SAMPLER: - { - OnNewSampler(Res); - break; - } - - case D3D_SIT_UAV_RWTYPED: - { - if (Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER) - { - OnNewBuffUAV(Res); - } - else - { - OnNewTexUAV(Res); - } - break; - } - - case D3D_SIT_STRUCTURED: - { - OnNewBuffSRV(Res); - break; - } - - case D3D_SIT_UAV_RWSTRUCTURED: - { - OnNewBuffUAV(Res); - break; - } - - case D3D_SIT_BYTEADDRESS: - { - OnNewBuffSRV(Res); - break; - } - - case D3D_SIT_UAV_RWBYTEADDRESS: - { - OnNewBuffUAV(Res); - break; - } - - case D3D_SIT_UAV_APPEND_STRUCTURED: - { - UNSUPPORTED("Append structured buffers are not supported"); - break; - } - - case D3D_SIT_UAV_CONSUME_STRUCTURED: - { - UNSUPPORTED("Consume structured buffers are not supported"); - break; - } - - case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: - { - UNSUPPORTED("RW structured buffers with counter are not supported"); - break; - } - - default: - { - UNEXPECTED("Unexpected resource input type"); - } - } - } - - // Process texture SRVs. We need to do this after all samplers are initialized - for (auto TexSRVInd : TexSRVInds) - { - OnNewTexSRV(Resources[TexSRVInd]); - } -} - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.hpp b/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.hpp new file mode 100644 index 00000000..64e08580 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/D3DShaderResourceLoader.hpp @@ -0,0 +1,306 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include +#include + +#include "Shader.h" +#include "StringTools.h" + +/// \file +/// D3D shader resource loading + +namespace Diligent +{ + +struct D3DShaderResourceCounters +{ + Uint32 NumCBs = 0; + Uint32 NumTexSRVs = 0; + Uint32 NumTexUAVs = 0; + Uint32 NumBufSRVs = 0; + Uint32 NumBufUAVs = 0; + Uint32 NumSamplers = 0; +}; + +template +void LoadD3DShaderResources(ID3DBlob* pShaderByteCode, + THandleShaderDesc HandleShaderDesc, + TOnResourcesCounted OnResourcesCounted, + TOnNewCB OnNewCB, + TOnNewTexUAV OnNewTexUAV, + TOnNewBuffUAV OnNewBuffUAV, + TOnNewBuffSRV OnNewBuffSRV, + TOnNewSampler OnNewSampler, + TOnNewTexSRV OnNewTexSRV) +{ + CComPtr pShaderReflection; + + auto hr = D3DReflect(pShaderByteCode->GetBufferPointer(), pShaderByteCode->GetBufferSize(), __uuidof(pShaderReflection), reinterpret_cast(static_cast(&pShaderReflection))); + CHECK_D3D_RESULT_THROW(hr, "Failed to get the shader reflection"); + + D3D_SHADER_DESC shaderDesc = {}; + pShaderReflection->GetDesc(&shaderDesc); + + HandleShaderDesc(shaderDesc); + + std::vector> Resources(STD_ALLOCATOR_RAW_MEM(D3DShaderResourceAttribs, GetRawAllocator(), "Allocator for vector")); + Resources.reserve(shaderDesc.BoundResources); + std::unordered_set ResourceNamesTmpPool; + + D3DShaderResourceCounters RC; + + size_t ResourceNamesPoolSize = 0; + // Number of resources to skip (used for array resources) + UINT SkipCount = 1; + for (UINT Res = 0; Res < shaderDesc.BoundResources; Res += SkipCount) + { + D3D_SHADER_INPUT_BIND_DESC BindingDesc = {}; + pShaderReflection->GetResourceBindingDesc(Res, &BindingDesc); + + std::string Name(BindingDesc.Name); + + SkipCount = 1; + + UINT BindCount = BindingDesc.BindCount; + + // Handle arrays + // For shader models 5_0 and before, every resource array element is enumerated individually. + // For instance, if the following texture array is defined in the shader: + // + // Texture2D g_tex2DDiffuse[4]; + // + // The reflection system will enumerate 4 resources with the following names: + // "g_tex2DDiffuse[0]" + // "g_tex2DDiffuse[1]" + // "g_tex2DDiffuse[2]" + // "g_tex2DDiffuse[3]" + // + // Notice that if some array element is not used by the shader, it will not be enumerated + + auto OpenBracketPos = Name.find('['); + if (String::npos != OpenBracketPos) + { + VERIFY(BindCount == 1, "When array elements are enumerated individually, BindCount is expected to always be 1"); + + // Name == "g_tex2DDiffuse[0]" + // ^ + // OpenBracketPos + Name.erase(OpenBracketPos, Name.length() - OpenBracketPos); + // Name == "g_tex2DDiffuse" + VERIFY_EXPR(Name.length() == OpenBracketPos); +#ifdef _DEBUG + for (const auto& ExistingRes : Resources) + { + VERIFY(Name.compare(ExistingRes.Name) != 0, "Resource with the same name has already been enumerated. All array elements are expected to be enumerated one after another"); + } +#endif + for (UINT ArrElem = Res + 1; ArrElem < shaderDesc.BoundResources; ++ArrElem) + { + D3D_SHADER_INPUT_BIND_DESC ArrElemBindingDesc = {}; + pShaderReflection->GetResourceBindingDesc(ArrElem, &ArrElemBindingDesc); + + // Make sure this case is handled correctly: + // "g_tex2DDiffuse[.]" != "g_tex2DDiffuse2[.]" + if (strncmp(Name.c_str(), ArrElemBindingDesc.Name, OpenBracketPos) == 0 && ArrElemBindingDesc.Name[OpenBracketPos] == '[') + { + //g_tex2DDiffuse[2] + // ^ + UINT Ind = atoi(ArrElemBindingDesc.Name + OpenBracketPos + 1); + BindCount = std::max(BindCount, Ind + 1); + VERIFY(ArrElemBindingDesc.BindPoint == BindingDesc.BindPoint + Ind, + "Array elements are expected to use contigous bind points.\n", + BindingDesc.Name, " uses slot ", BindingDesc.BindPoint, ", so ", ArrElemBindingDesc.Name, + " is expected to use slot ", BindingDesc.BindPoint + Ind, " while ", ArrElemBindingDesc.BindPoint, + " is actually used"); + + // Note that skip count may not necessarily be the same as BindCount. + // If some array elements are not used by the shader, the reflection system skips them + ++SkipCount; + } + else + { + break; + } + } + } + + switch (BindingDesc.Type) + { + // clang-format off + case D3D_SIT_CBUFFER: ++RC.NumCBs; break; + case D3D_SIT_TBUFFER: UNSUPPORTED( "TBuffers are not supported" ); break; + case D3D_SIT_TEXTURE: ++(BindingDesc.Dimension == D3D_SRV_DIMENSION_BUFFER ? RC.NumBufSRVs : RC.NumTexSRVs); break; + case D3D_SIT_SAMPLER: ++RC.NumSamplers; break; + case D3D_SIT_UAV_RWTYPED: ++(BindingDesc.Dimension == D3D_SRV_DIMENSION_BUFFER ? RC.NumBufUAVs : RC.NumTexUAVs); break; + case D3D_SIT_STRUCTURED: ++RC.NumBufSRVs; break; + case D3D_SIT_UAV_RWSTRUCTURED: ++RC.NumBufUAVs; break; + case D3D_SIT_BYTEADDRESS: ++RC.NumBufSRVs; break; + case D3D_SIT_UAV_RWBYTEADDRESS: ++RC.NumBufUAVs; break; + case D3D_SIT_UAV_APPEND_STRUCTURED: UNSUPPORTED( "Append structured buffers are not supported" ); break; + case D3D_SIT_UAV_CONSUME_STRUCTURED: UNSUPPORTED( "Consume structured buffers are not supported" ); break; + case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: UNSUPPORTED( "RW structured buffers with counter are not supported" ); break; + // clang-format on + default: UNEXPECTED("Unexpected resource type"); + } + ResourceNamesPoolSize += Name.length() + 1; + auto it = ResourceNamesTmpPool.emplace(std::move(Name)); + Resources.emplace_back( + it.first->c_str(), + BindingDesc.BindPoint, + BindCount, + BindingDesc.Type, + BindingDesc.Dimension, + D3DShaderResourceAttribs::InvalidSamplerId); + } + + OnResourcesCounted(RC, ResourceNamesPoolSize); + + std::vector> TexSRVInds(STD_ALLOCATOR_RAW_MEM(size_t, GetRawAllocator(), "Allocator for vector")); + TexSRVInds.reserve(RC.NumTexSRVs); + + for (size_t ResInd = 0; ResInd < Resources.size(); ++ResInd) + { + const auto& Res = Resources[ResInd]; + switch (Res.GetInputType()) + { + case D3D_SIT_CBUFFER: + { + OnNewCB(Res); + break; + } + + case D3D_SIT_TBUFFER: + { + UNSUPPORTED("TBuffers are not supported"); + break; + } + + case D3D_SIT_TEXTURE: + { + if (Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER) + { + OnNewBuffSRV(Res); + } + else + { + // Texture SRVs must be processed all samplers are initialized + TexSRVInds.push_back(ResInd); + } + break; + } + + case D3D_SIT_SAMPLER: + { + OnNewSampler(Res); + break; + } + + case D3D_SIT_UAV_RWTYPED: + { + if (Res.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER) + { + OnNewBuffUAV(Res); + } + else + { + OnNewTexUAV(Res); + } + break; + } + + case D3D_SIT_STRUCTURED: + { + OnNewBuffSRV(Res); + break; + } + + case D3D_SIT_UAV_RWSTRUCTURED: + { + OnNewBuffUAV(Res); + break; + } + + case D3D_SIT_BYTEADDRESS: + { + OnNewBuffSRV(Res); + break; + } + + case D3D_SIT_UAV_RWBYTEADDRESS: + { + OnNewBuffUAV(Res); + break; + } + + case D3D_SIT_UAV_APPEND_STRUCTURED: + { + UNSUPPORTED("Append structured buffers are not supported"); + break; + } + + case D3D_SIT_UAV_CONSUME_STRUCTURED: + { + UNSUPPORTED("Consume structured buffers are not supported"); + break; + } + + case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: + { + UNSUPPORTED("RW structured buffers with counter are not supported"); + break; + } + + default: + { + UNEXPECTED("Unexpected resource input type"); + } + } + } + + // Process texture SRVs. We need to do this after all samplers are initialized + for (auto TexSRVInd : TexSRVInds) + { + OnNewTexSRV(Resources[TexSRVInd]); + } +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.h b/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.h deleted file mode 100644 index 0e2c684d..00000000 --- a/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.h +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include - -/// \file -/// Implementation of D3D type conversions - -/// This file must be included after D3D11TypeDefinitions.h or D3D12TypeDefinitions.h - -namespace Diligent -{ - -template -inline D3D_COMPARISON_FUNC ComparisonFuncToD3DComparisonFunc(COMPARISON_FUNCTION Func) -{ - // D3D12_COMPARISON_FUNC is equal to D3D11_COMPARISON_FUNC - switch (Func) - { - // clang-format off - case COMPARISON_FUNC_UNKNOWN: UNEXPECTED("Comparison function is not specified" ); return D3D_COMPARISON_FUNC_ALWAYS; - case COMPARISON_FUNC_NEVER: return D3D_COMPARISON_FUNC_NEVER; - case COMPARISON_FUNC_LESS: return D3D_COMPARISON_FUNC_LESS; - case COMPARISON_FUNC_EQUAL: return D3D_COMPARISON_FUNC_EQUAL; - case COMPARISON_FUNC_LESS_EQUAL: return D3D_COMPARISON_FUNC_LESS_EQUAL; - case COMPARISON_FUNC_GREATER: return D3D_COMPARISON_FUNC_GREATER; - case COMPARISON_FUNC_NOT_EQUAL: return D3D_COMPARISON_FUNC_NOT_EQUAL; - case COMPARISON_FUNC_GREATER_EQUAL: return D3D_COMPARISON_FUNC_GREATER_EQUAL; - case COMPARISON_FUNC_ALWAYS: return D3D_COMPARISON_FUNC_ALWAYS; - default: UNEXPECTED("Unknown comparison function" ); return D3D_COMPARISON_FUNC_ALWAYS; - // clang-format on - } -} - - -template -D3D_TEXTURE_ADDRESS_MODE TexAddressModeToD3DAddressMode(TEXTURE_ADDRESS_MODE Mode) -{ - switch (Mode) - { - // clang-format off - case TEXTURE_ADDRESS_UNKNOWN: UNEXPECTED("Texture address mode is not specified" ); return D3D_TEXTURE_ADDRESS_CLAMP; - case TEXTURE_ADDRESS_WRAP: return D3D_TEXTURE_ADDRESS_WRAP; - case TEXTURE_ADDRESS_MIRROR: return D3D_TEXTURE_ADDRESS_MIRROR; - case TEXTURE_ADDRESS_CLAMP: return D3D_TEXTURE_ADDRESS_CLAMP; - case TEXTURE_ADDRESS_BORDER: return D3D_TEXTURE_ADDRESS_BORDER; - case TEXTURE_ADDRESS_MIRROR_ONCE: return D3D_TEXTURE_ADDRESS_MIRROR_ONCE; - default: UNEXPECTED("Unknown texture address mode" ); return D3D_TEXTURE_ADDRESS_CLAMP; - // clang-format on - } -} - -template -D3D_PRIM_TOPOLOGY TopologyToD3DTopology(PRIMITIVE_TOPOLOGY Topology) -{ - static bool bIsInit = false; - static std::array d3dPrimTopology = {}; - if (!bIsInit) - { - // clang-format off - d3dPrimTopology[PRIMITIVE_TOPOLOGY_UNDEFINED] = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_TRIANGLE_LIST] = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP] = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_POINT_LIST] = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_LINE_LIST] = D3D_PRIMITIVE_TOPOLOGY_LINELIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST; - d3dPrimTopology[PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST; - // clang-format on - bIsInit = true; - } - - VERIFY_EXPR(Topology >= PRIMITIVE_TOPOLOGY_UNDEFINED && Topology < PRIMITIVE_TOPOLOGY_NUM_TOPOLOGIES); - return d3dPrimTopology[Topology]; -} - - -// ================= Rasterizer state attributes conversion functions ================= - -template -D3D_FILL_MODE FillModeToD3DFillMode(FILL_MODE FillMode) -{ - // D3D12_FILL_MODE is identical tp D3D11_FILL_MODE - static bool bIsInit = false; - static std::array d3dFillModes = {}; - if (!bIsInit) - { - d3dFillModes[FILL_MODE_WIREFRAME] = D3D_FILL_MODE_WIREFRAME; - d3dFillModes[FILL_MODE_SOLID] = D3D_FILL_MODE_SOLID; - - bIsInit = true; - } - if (FILL_MODE_UNDEFINED < FillMode && FillMode < FILL_MODE_NUM_MODES) - { - auto d3dFillMode = d3dFillModes[FillMode]; - VERIFY(d3dFillMode != 0, "Incorrect fill mode"); - return d3dFillMode; - } - else - { - UNEXPECTED("Incorrect fill mode (", FillMode, ")"); - return static_cast(0); - } -} - -template -D3D_CULL_MODE CullModeToD3DCullMode(CULL_MODE CullMode) -{ - // D3D_CULL_MODE is identical to D3D11_CULL_MODE - static bool bIsInit = false; - static std::array d3dCullModes = {}; - if (!bIsInit) - { - d3dCullModes[CULL_MODE_NONE] = D3D_CULL_MODE_NONE; - d3dCullModes[CULL_MODE_FRONT] = D3D_CULL_MODE_FRONT; - d3dCullModes[CULL_MODE_BACK] = D3D_CULL_MODE_BACK; - - bIsInit = true; - } - - if (CULL_MODE_UNDEFINED < CullMode && CullMode < CULL_MODE_NUM_MODES) - { - auto d3dCullMode = d3dCullModes[CullMode]; - VERIFY(d3dCullMode != 0, "Incorrect cull mode"); - return d3dCullMode; - } - else - { - UNEXPECTED("Incorrect cull mode (", CullMode, ")"); - return static_cast(0); - } -} - -template -void RasterizerStateDesc_To_D3D_RASTERIZER_DESC(const RasterizerStateDesc& RasterizerDesc, D3D_RASTERIZER_DESC& d3dRSDesc) -{ - d3dRSDesc.FillMode = FillModeToD3DFillMode(RasterizerDesc.FillMode); - d3dRSDesc.CullMode = CullModeToD3DCullMode(RasterizerDesc.CullMode); - d3dRSDesc.FrontCounterClockwise = RasterizerDesc.FrontCounterClockwise ? TRUE : FALSE; - d3dRSDesc.DepthBias = RasterizerDesc.DepthBias; - d3dRSDesc.DepthBiasClamp = RasterizerDesc.DepthBiasClamp; - d3dRSDesc.SlopeScaledDepthBias = RasterizerDesc.SlopeScaledDepthBias; - d3dRSDesc.DepthClipEnable = RasterizerDesc.DepthClipEnable ? TRUE : FALSE; - - //d3d12RSDesc.ScissorEnable = RSDesc.ScissorEnable ? TRUE : FALSE; - - d3dRSDesc.AntialiasedLineEnable = RasterizerDesc.AntialiasedLineEnable ? TRUE : FALSE; - d3dRSDesc.MultisampleEnable = d3dRSDesc.AntialiasedLineEnable; -} - - - -// ================= Blend state attributes conversion functions ================= - -template -D3D_BLEND BlendFactorToD3DBlend(BLEND_FACTOR bf) -{ - // D3D11_BLEND and D3D12_BLEND are identical - - // Note that this code is safe for multithreaded environments since - // bIsInit is set to true only AFTER the entire map is initialized. - static bool bIsInit = false; - static std::array D3DBlend = {}; - if (!bIsInit) - { - // In a multithreaded environment, several threads can potentially enter - // this block. This is not a problem since they will just initialize the - // memory with the same values more than once - - // clang-format off - D3DBlend[BLEND_FACTOR_ZERO ] = D3D_BLEND_ZERO; - D3DBlend[BLEND_FACTOR_ONE ] = D3D_BLEND_ONE; - D3DBlend[BLEND_FACTOR_SRC_COLOR ] = D3D_BLEND_SRC_COLOR; - D3DBlend[BLEND_FACTOR_INV_SRC_COLOR ] = D3D_BLEND_INV_SRC_COLOR; - D3DBlend[BLEND_FACTOR_SRC_ALPHA ] = D3D_BLEND_SRC_ALPHA; - D3DBlend[BLEND_FACTOR_INV_SRC_ALPHA ] = D3D_BLEND_INV_SRC_ALPHA; - D3DBlend[BLEND_FACTOR_DEST_ALPHA ] = D3D_BLEND_DEST_ALPHA; - D3DBlend[BLEND_FACTOR_INV_DEST_ALPHA ] = D3D_BLEND_INV_DEST_ALPHA; - D3DBlend[BLEND_FACTOR_DEST_COLOR ] = D3D_BLEND_DEST_COLOR; - D3DBlend[BLEND_FACTOR_INV_DEST_COLOR ] = D3D_BLEND_INV_DEST_COLOR; - D3DBlend[BLEND_FACTOR_SRC_ALPHA_SAT ] = D3D_BLEND_SRC_ALPHA_SAT; - D3DBlend[BLEND_FACTOR_BLEND_FACTOR ] = D3D_BLEND_BLEND_FACTOR; - D3DBlend[BLEND_FACTOR_INV_BLEND_FACTOR] = D3D_BLEND_INV_BLEND_FACTOR; - D3DBlend[BLEND_FACTOR_SRC1_COLOR ] = D3D_BLEND_SRC1_COLOR; - D3DBlend[BLEND_FACTOR_INV_SRC1_COLOR ] = D3D_BLEND_INV_SRC1_COLOR; - D3DBlend[BLEND_FACTOR_SRC1_ALPHA ] = D3D_BLEND_SRC1_ALPHA; - D3DBlend[BLEND_FACTOR_INV_SRC1_ALPHA ] = D3D_BLEND_INV_SRC1_ALPHA; - // clang-format on - - bIsInit = true; - } - if (bf > BLEND_FACTOR_UNDEFINED && bf < BLEND_FACTOR_NUM_FACTORS) - { - auto d3dbf = D3DBlend[bf]; - VERIFY(d3dbf != 0, "Incorrect blend factor"); - return d3dbf; - } - else - { - UNEXPECTED("Incorrect blend factor (", bf, ")"); - return static_cast(0); - } -} - -template -D3D_BLEND_OP BlendOperationToD3DBlendOp(BLEND_OPERATION BlendOp) -{ - // D3D12_BLEND_OP and D3D11_BLEND_OP are identical - - static bool bIsInit = false; - static std::array D3DBlendOp = {}; - if (!bIsInit) - { - // clang-format off - D3DBlendOp[BLEND_OPERATION_ADD ] = D3D_BLEND_OP_ADD; - D3DBlendOp[BLEND_OPERATION_SUBTRACT ] = D3D_BLEND_OP_SUBTRACT; - D3DBlendOp[BLEND_OPERATION_REV_SUBTRACT] = D3D_BLEND_OP_REV_SUBTRACT; - D3DBlendOp[BLEND_OPERATION_MIN ] = D3D_BLEND_OP_MIN; - D3DBlendOp[BLEND_OPERATION_MAX ] = D3D_BLEND_OP_MAX; - // clang-format on - - bIsInit = true; - } - - if (BlendOp > BLEND_OPERATION_UNDEFINED && BlendOp < BLEND_OPERATION_NUM_OPERATIONS) - { - auto d3dbop = D3DBlendOp[BlendOp]; - VERIFY(d3dbop != 0, "Incorrect blend operation"); - return d3dbop; - } - else - { - UNEXPECTED("Incorrect blend operation (", BlendOp, ")"); - return static_cast(0); - } -} - -template -void BlendStateDescToD3DBlendDesc(const BlendStateDesc& BSDesc, D3D_BLEND_DESC& d3d12BlendDesc) -{ - // D3D_BLEND_DESC and D3D11_BLEND_DESC structures are identical - d3d12BlendDesc.AlphaToCoverageEnable = BSDesc.AlphaToCoverageEnable ? TRUE : FALSE; - d3d12BlendDesc.IndependentBlendEnable = BSDesc.IndependentBlendEnable ? TRUE : FALSE; - VERIFY(MAX_RENDER_TARGETS >= 8, "Number of render targets is expected to be at least 8"); - for (int i = 0; i < 8; ++i) - { - const auto& SrcRTDesc = BSDesc.RenderTargets[i]; - auto& DstRTDesc = d3d12BlendDesc.RenderTarget[i]; - DstRTDesc.BlendEnable = SrcRTDesc.BlendEnable ? TRUE : FALSE; - - DstRTDesc.SrcBlend = BlendFactorToD3DBlend(SrcRTDesc.SrcBlend); - DstRTDesc.DestBlend = BlendFactorToD3DBlend(SrcRTDesc.DestBlend); - DstRTDesc.BlendOp = BlendOperationToD3DBlendOp(SrcRTDesc.BlendOp); - - DstRTDesc.SrcBlendAlpha = BlendFactorToD3DBlend(SrcRTDesc.SrcBlendAlpha); - DstRTDesc.DestBlendAlpha = BlendFactorToD3DBlend(SrcRTDesc.DestBlendAlpha); - DstRTDesc.BlendOpAlpha = BlendOperationToD3DBlendOp(SrcRTDesc.BlendOpAlpha); - - DstRTDesc.RenderTargetWriteMask = - ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_RED) ? D3D_COLOR_WRITE_ENABLE_RED : 0) | - ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_GREEN) ? D3D_COLOR_WRITE_ENABLE_GREEN : 0) | - ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_BLUE) ? D3D_COLOR_WRITE_ENABLE_BLUE : 0) | - ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_ALPHA) ? D3D_COLOR_WRITE_ENABLE_ALPHA : 0); - } -} - - - -// ====================== Depth-stencil state attributes conversion functions ====================== - -template -D3D_STENCIL_OP StencilOpToD3DStencilOp(STENCIL_OP StencilOp) -{ - static bool bIsInit = false; - static std::array StOpToD3DStOpMap = {}; - if (!bIsInit) - { - // clang-format off - StOpToD3DStOpMap[STENCIL_OP_KEEP ] = D3D_STENCIL_OP_KEEP; - StOpToD3DStOpMap[STENCIL_OP_ZERO ] = D3D_STENCIL_OP_ZERO; - StOpToD3DStOpMap[STENCIL_OP_REPLACE ] = D3D_STENCIL_OP_REPLACE; - StOpToD3DStOpMap[STENCIL_OP_INCR_SAT ] = D3D_STENCIL_OP_INCR_SAT; - StOpToD3DStOpMap[STENCIL_OP_DECR_SAT ] = D3D_STENCIL_OP_DECR_SAT; - StOpToD3DStOpMap[STENCIL_OP_INVERT ] = D3D_STENCIL_OP_INVERT; - StOpToD3DStOpMap[STENCIL_OP_INCR_WRAP] = D3D_STENCIL_OP_INCR; - StOpToD3DStOpMap[STENCIL_OP_DECR_WRAP] = D3D_STENCIL_OP_DECR; - // clang-format on - - bIsInit = true; - } - - if (StencilOp > STENCIL_OP_UNDEFINED && StencilOp < STENCIL_OP_NUM_OPS) - { - auto d3dStencilOp = StOpToD3DStOpMap[StencilOp]; - VERIFY(d3dStencilOp != 0, "Unexpected stencil op"); - return d3dStencilOp; - } - else - { - UNEXPECTED("Stencil operation (", StencilOp, ") is out of allowed range [1, ", STENCIL_OP_NUM_OPS - 1, "]"); - return static_cast(0); - } -} - -template -D3D_DEPTH_STENCILOP_DESC StencilOpDescToD3DStencilOpDesc(const StencilOpDesc& StOpDesc) -{ - // D3D12_DEPTH_STENCILOP_DESC is identical to D3D11_DEPTH_STENCILOP_DESC - D3D_DEPTH_STENCILOP_DESC D3DStOpDesc; - D3DStOpDesc.StencilFailOp = StencilOpToD3DStencilOp(StOpDesc.StencilFailOp); - D3DStOpDesc.StencilDepthFailOp = StencilOpToD3DStencilOp(StOpDesc.StencilDepthFailOp); - D3DStOpDesc.StencilPassOp = StencilOpToD3DStencilOp(StOpDesc.StencilPassOp); - D3DStOpDesc.StencilFunc = ComparisonFuncToD3DComparisonFunc(StOpDesc.StencilFunc); - return D3DStOpDesc; -} - -template -void DepthStencilStateDesc_To_D3D_DEPTH_STENCIL_DESC(const DepthStencilStateDesc& DepthStencilDesc, D3D_DEPTH_STENCIL_DESC& d3dDSSDesc) -{ - // D3D_DEPTH_STENCIL_DESC is identical to D3D11_DEPTH_STENCIL_DESC - d3dDSSDesc.DepthEnable = DepthStencilDesc.DepthEnable ? TRUE : FALSE; - d3dDSSDesc.DepthWriteMask = DepthStencilDesc.DepthWriteEnable ? D3D_DEPTH_WRITE_MASK_ALL : D3D_DEPTH_WRITE_MASK_ZERO; - d3dDSSDesc.DepthFunc = ComparisonFuncToD3DComparisonFunc(DepthStencilDesc.DepthFunc); - d3dDSSDesc.StencilEnable = DepthStencilDesc.StencilEnable ? TRUE : FALSE; - d3dDSSDesc.StencilReadMask = DepthStencilDesc.StencilReadMask; - d3dDSSDesc.StencilWriteMask = DepthStencilDesc.StencilWriteMask; - d3dDSSDesc.FrontFace = StencilOpDescToD3DStencilOpDesc(DepthStencilDesc.FrontFace); - d3dDSSDesc.BackFace = StencilOpDescToD3DStencilOpDesc(DepthStencilDesc.BackFace); -} - - - -template -void LayoutElements_To_D3D_INPUT_ELEMENT_DESCs(const InputLayoutDesc& InputLayout, - std::vector>& D3DInputElements) -{ - // D3D12_INPUT_ELEMENT_DESC and D3D11_INPUT_ELEMENT_DESC are identical - D3DInputElements.resize(InputLayout.NumElements); - for (Uint32 iElem = 0; iElem < InputLayout.NumElements; ++iElem) - { - const auto& CurrElem = InputLayout.LayoutElements[iElem]; - auto& D3DElem = D3DInputElements[iElem]; - D3DElem.SemanticName = CurrElem.HLSLSemantic; - D3DElem.SemanticIndex = CurrElem.InputIndex; - D3DElem.AlignedByteOffset = CurrElem.RelativeOffset; - D3DElem.InputSlot = CurrElem.BufferSlot; - D3DElem.Format = TypeToDXGI_Format(CurrElem.ValueType, CurrElem.NumComponents, CurrElem.IsNormalized); - D3DElem.InputSlotClass = (CurrElem.Frequency == INPUT_ELEMENT_FREQUENCY_PER_VERTEX) ? D3D_INPUT_CLASSIFICATION_PER_VERTEX_DATA : D3D_INPUT_CLASSIFICATION_PER_INSTANCE_DATA; - D3DElem.InstanceDataStepRate = (CurrElem.Frequency == INPUT_ELEMENT_FREQUENCY_PER_VERTEX) ? 0 : CurrElem.InstanceDataStepRate; - } -} - - -template -D3D_FILTER FilterTypeToD3DFilter(FILTER_TYPE MinFilter, FILTER_TYPE MagFilter, FILTER_TYPE MipFilter) -{ - switch (MinFilter) - { - // Regular filters - case FILTER_TYPE_POINT: - if (MagFilter == FILTER_TYPE_POINT) - { - if (MipFilter == FILTER_TYPE_POINT) - return D3D_FILTER_MIN_MAG_MIP_POINT; - else if (MipFilter == FILTER_TYPE_LINEAR) - return D3D_FILTER_MIN_MAG_POINT_MIP_LINEAR; - } - else if (MagFilter == FILTER_TYPE_LINEAR) - { - if (MipFilter == FILTER_TYPE_POINT) - return D3D_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; - else if (MipFilter == FILTER_TYPE_LINEAR) - return D3D_FILTER_MIN_POINT_MAG_MIP_LINEAR; - } - break; - - case FILTER_TYPE_LINEAR: - if (MagFilter == FILTER_TYPE_POINT) - { - if (MipFilter == FILTER_TYPE_POINT) - return D3D_FILTER_MIN_LINEAR_MAG_MIP_POINT; - else if (MipFilter == FILTER_TYPE_LINEAR) - return D3D_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; - } - else if (MagFilter == FILTER_TYPE_LINEAR) - { - if (MipFilter == FILTER_TYPE_POINT) - return D3D_FILTER_MIN_MAG_LINEAR_MIP_POINT; - else if (MipFilter == FILTER_TYPE_LINEAR) - return D3D_FILTER_MIN_MAG_MIP_LINEAR; - } - break; - - case FILTER_TYPE_ANISOTROPIC: - VERIFY(MagFilter == FILTER_TYPE_ANISOTROPIC && MipFilter == FILTER_TYPE_ANISOTROPIC, - "For anistropic filtering, all filters must be anisotropic"); - return D3D_FILTER_ANISOTROPIC; - break; - - - - // Comparison filters - case FILTER_TYPE_COMPARISON_POINT: - if (MagFilter == FILTER_TYPE_COMPARISON_POINT) - { - if (MipFilter == FILTER_TYPE_COMPARISON_POINT) - return D3D_FILTER_COMPARISON_MIN_MAG_MIP_POINT; - else if (MipFilter == FILTER_TYPE_COMPARISON_LINEAR) - return D3D_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR; - } - else if (MagFilter == FILTER_TYPE_COMPARISON_LINEAR) - { - if (MipFilter == FILTER_TYPE_COMPARISON_POINT) - return D3D_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT; - else if (MipFilter == FILTER_TYPE_COMPARISON_LINEAR) - return D3D_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR; - } - break; - - case FILTER_TYPE_COMPARISON_LINEAR: - if (MagFilter == FILTER_TYPE_COMPARISON_POINT) - { - if (MipFilter == FILTER_TYPE_COMPARISON_POINT) - return D3D_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT; - else if (MipFilter == FILTER_TYPE_COMPARISON_LINEAR) - return D3D_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR; - } - else if (MagFilter == FILTER_TYPE_COMPARISON_LINEAR) - { - if (MipFilter == FILTER_TYPE_COMPARISON_POINT) - return D3D_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; - else if (MipFilter == FILTER_TYPE_COMPARISON_LINEAR) - return D3D_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; - } - break; - - case FILTER_TYPE_COMPARISON_ANISOTROPIC: - VERIFY(MagFilter == FILTER_TYPE_COMPARISON_ANISOTROPIC && MipFilter == FILTER_TYPE_COMPARISON_ANISOTROPIC, - "For comparison anistropic filtering, all filters must be anisotropic"); - return D3D_FILTER_COMPARISON_ANISOTROPIC; - break; - - - - // Minimum filters - case FILTER_TYPE_MINIMUM_POINT: - if (MagFilter == FILTER_TYPE_MINIMUM_POINT) - { - if (MipFilter == FILTER_TYPE_MINIMUM_POINT) - return D3D_FILTER_MINIMUM_MIN_MAG_MIP_POINT; - else if (MipFilter == FILTER_TYPE_MINIMUM_LINEAR) - return D3D_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR; - } - else if (MagFilter == FILTER_TYPE_MINIMUM_LINEAR) - { - if (MipFilter == FILTER_TYPE_MINIMUM_POINT) - return D3D_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT; - else if (MipFilter == FILTER_TYPE_MINIMUM_LINEAR) - return D3D_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR; - } - break; - - case FILTER_TYPE_MINIMUM_LINEAR: - if (MagFilter == FILTER_TYPE_MINIMUM_POINT) - { - if (MipFilter == FILTER_TYPE_MINIMUM_POINT) - return D3D_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT; - else if (MipFilter == FILTER_TYPE_MINIMUM_LINEAR) - return D3D_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR; - } - else if (MagFilter == FILTER_TYPE_MINIMUM_LINEAR) - { - if (MipFilter == FILTER_TYPE_MINIMUM_POINT) - return D3D_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT; - else if (MipFilter == FILTER_TYPE_MINIMUM_LINEAR) - return D3D_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR; - } - break; - - case FILTER_TYPE_MINIMUM_ANISOTROPIC: - VERIFY(MagFilter == FILTER_TYPE_MINIMUM_ANISOTROPIC && MipFilter == FILTER_TYPE_MINIMUM_ANISOTROPIC, - "For minimum anistropic filtering, all filters must be anisotropic"); - return D3D_FILTER_MINIMUM_ANISOTROPIC; - break; - - - - // Maximum filters - case FILTER_TYPE_MAXIMUM_POINT: - if (MagFilter == FILTER_TYPE_MAXIMUM_POINT) - { - if (MipFilter == FILTER_TYPE_MAXIMUM_POINT) - return D3D_FILTER_MAXIMUM_MIN_MAG_MIP_POINT; - else if (MipFilter == FILTER_TYPE_MAXIMUM_LINEAR) - return D3D_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR; - } - else if (MagFilter == FILTER_TYPE_MAXIMUM_LINEAR) - { - if (MipFilter == FILTER_TYPE_MAXIMUM_POINT) - return D3D_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT; - else if (MipFilter == FILTER_TYPE_MAXIMUM_LINEAR) - return D3D_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR; - } - break; - - case FILTER_TYPE_MAXIMUM_LINEAR: - if (MagFilter == FILTER_TYPE_MAXIMUM_POINT) - { - if (MipFilter == FILTER_TYPE_MAXIMUM_POINT) - return D3D_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT; - else if (MipFilter == FILTER_TYPE_MAXIMUM_LINEAR) - return D3D_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR; - } - else if (MagFilter == FILTER_TYPE_MAXIMUM_LINEAR) - { - if (MipFilter == FILTER_TYPE_MAXIMUM_POINT) - return D3D_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT; - else if (MipFilter == FILTER_TYPE_MAXIMUM_LINEAR) - return D3D_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR; - } - break; - - case FILTER_TYPE_MAXIMUM_ANISOTROPIC: - VERIFY(MagFilter == FILTER_TYPE_MAXIMUM_ANISOTROPIC && MipFilter == FILTER_TYPE_MAXIMUM_ANISOTROPIC, - "For maximum anistropic filtering, all filters must be anisotropic"); - return D3D_FILTER_MAXIMUM_ANISOTROPIC; - break; - } - - UNEXPECTED("Unsupported filter combination"); - return D3D_FILTER_MIN_MAG_MIP_POINT; -} - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.hpp b/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.hpp new file mode 100644 index 00000000..0e2c684d --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.hpp @@ -0,0 +1,589 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include + +/// \file +/// Implementation of D3D type conversions + +/// This file must be included after D3D11TypeDefinitions.h or D3D12TypeDefinitions.h + +namespace Diligent +{ + +template +inline D3D_COMPARISON_FUNC ComparisonFuncToD3DComparisonFunc(COMPARISON_FUNCTION Func) +{ + // D3D12_COMPARISON_FUNC is equal to D3D11_COMPARISON_FUNC + switch (Func) + { + // clang-format off + case COMPARISON_FUNC_UNKNOWN: UNEXPECTED("Comparison function is not specified" ); return D3D_COMPARISON_FUNC_ALWAYS; + case COMPARISON_FUNC_NEVER: return D3D_COMPARISON_FUNC_NEVER; + case COMPARISON_FUNC_LESS: return D3D_COMPARISON_FUNC_LESS; + case COMPARISON_FUNC_EQUAL: return D3D_COMPARISON_FUNC_EQUAL; + case COMPARISON_FUNC_LESS_EQUAL: return D3D_COMPARISON_FUNC_LESS_EQUAL; + case COMPARISON_FUNC_GREATER: return D3D_COMPARISON_FUNC_GREATER; + case COMPARISON_FUNC_NOT_EQUAL: return D3D_COMPARISON_FUNC_NOT_EQUAL; + case COMPARISON_FUNC_GREATER_EQUAL: return D3D_COMPARISON_FUNC_GREATER_EQUAL; + case COMPARISON_FUNC_ALWAYS: return D3D_COMPARISON_FUNC_ALWAYS; + default: UNEXPECTED("Unknown comparison function" ); return D3D_COMPARISON_FUNC_ALWAYS; + // clang-format on + } +} + + +template +D3D_TEXTURE_ADDRESS_MODE TexAddressModeToD3DAddressMode(TEXTURE_ADDRESS_MODE Mode) +{ + switch (Mode) + { + // clang-format off + case TEXTURE_ADDRESS_UNKNOWN: UNEXPECTED("Texture address mode is not specified" ); return D3D_TEXTURE_ADDRESS_CLAMP; + case TEXTURE_ADDRESS_WRAP: return D3D_TEXTURE_ADDRESS_WRAP; + case TEXTURE_ADDRESS_MIRROR: return D3D_TEXTURE_ADDRESS_MIRROR; + case TEXTURE_ADDRESS_CLAMP: return D3D_TEXTURE_ADDRESS_CLAMP; + case TEXTURE_ADDRESS_BORDER: return D3D_TEXTURE_ADDRESS_BORDER; + case TEXTURE_ADDRESS_MIRROR_ONCE: return D3D_TEXTURE_ADDRESS_MIRROR_ONCE; + default: UNEXPECTED("Unknown texture address mode" ); return D3D_TEXTURE_ADDRESS_CLAMP; + // clang-format on + } +} + +template +D3D_PRIM_TOPOLOGY TopologyToD3DTopology(PRIMITIVE_TOPOLOGY Topology) +{ + static bool bIsInit = false; + static std::array d3dPrimTopology = {}; + if (!bIsInit) + { + // clang-format off + d3dPrimTopology[PRIMITIVE_TOPOLOGY_UNDEFINED] = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_TRIANGLE_LIST] = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP] = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_POINT_LIST] = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_LINE_LIST] = D3D_PRIMITIVE_TOPOLOGY_LINELIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST; + d3dPrimTopology[PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST] = D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST; + // clang-format on + bIsInit = true; + } + + VERIFY_EXPR(Topology >= PRIMITIVE_TOPOLOGY_UNDEFINED && Topology < PRIMITIVE_TOPOLOGY_NUM_TOPOLOGIES); + return d3dPrimTopology[Topology]; +} + + +// ================= Rasterizer state attributes conversion functions ================= + +template +D3D_FILL_MODE FillModeToD3DFillMode(FILL_MODE FillMode) +{ + // D3D12_FILL_MODE is identical tp D3D11_FILL_MODE + static bool bIsInit = false; + static std::array d3dFillModes = {}; + if (!bIsInit) + { + d3dFillModes[FILL_MODE_WIREFRAME] = D3D_FILL_MODE_WIREFRAME; + d3dFillModes[FILL_MODE_SOLID] = D3D_FILL_MODE_SOLID; + + bIsInit = true; + } + if (FILL_MODE_UNDEFINED < FillMode && FillMode < FILL_MODE_NUM_MODES) + { + auto d3dFillMode = d3dFillModes[FillMode]; + VERIFY(d3dFillMode != 0, "Incorrect fill mode"); + return d3dFillMode; + } + else + { + UNEXPECTED("Incorrect fill mode (", FillMode, ")"); + return static_cast(0); + } +} + +template +D3D_CULL_MODE CullModeToD3DCullMode(CULL_MODE CullMode) +{ + // D3D_CULL_MODE is identical to D3D11_CULL_MODE + static bool bIsInit = false; + static std::array d3dCullModes = {}; + if (!bIsInit) + { + d3dCullModes[CULL_MODE_NONE] = D3D_CULL_MODE_NONE; + d3dCullModes[CULL_MODE_FRONT] = D3D_CULL_MODE_FRONT; + d3dCullModes[CULL_MODE_BACK] = D3D_CULL_MODE_BACK; + + bIsInit = true; + } + + if (CULL_MODE_UNDEFINED < CullMode && CullMode < CULL_MODE_NUM_MODES) + { + auto d3dCullMode = d3dCullModes[CullMode]; + VERIFY(d3dCullMode != 0, "Incorrect cull mode"); + return d3dCullMode; + } + else + { + UNEXPECTED("Incorrect cull mode (", CullMode, ")"); + return static_cast(0); + } +} + +template +void RasterizerStateDesc_To_D3D_RASTERIZER_DESC(const RasterizerStateDesc& RasterizerDesc, D3D_RASTERIZER_DESC& d3dRSDesc) +{ + d3dRSDesc.FillMode = FillModeToD3DFillMode(RasterizerDesc.FillMode); + d3dRSDesc.CullMode = CullModeToD3DCullMode(RasterizerDesc.CullMode); + d3dRSDesc.FrontCounterClockwise = RasterizerDesc.FrontCounterClockwise ? TRUE : FALSE; + d3dRSDesc.DepthBias = RasterizerDesc.DepthBias; + d3dRSDesc.DepthBiasClamp = RasterizerDesc.DepthBiasClamp; + d3dRSDesc.SlopeScaledDepthBias = RasterizerDesc.SlopeScaledDepthBias; + d3dRSDesc.DepthClipEnable = RasterizerDesc.DepthClipEnable ? TRUE : FALSE; + + //d3d12RSDesc.ScissorEnable = RSDesc.ScissorEnable ? TRUE : FALSE; + + d3dRSDesc.AntialiasedLineEnable = RasterizerDesc.AntialiasedLineEnable ? TRUE : FALSE; + d3dRSDesc.MultisampleEnable = d3dRSDesc.AntialiasedLineEnable; +} + + + +// ================= Blend state attributes conversion functions ================= + +template +D3D_BLEND BlendFactorToD3DBlend(BLEND_FACTOR bf) +{ + // D3D11_BLEND and D3D12_BLEND are identical + + // Note that this code is safe for multithreaded environments since + // bIsInit is set to true only AFTER the entire map is initialized. + static bool bIsInit = false; + static std::array D3DBlend = {}; + if (!bIsInit) + { + // In a multithreaded environment, several threads can potentially enter + // this block. This is not a problem since they will just initialize the + // memory with the same values more than once + + // clang-format off + D3DBlend[BLEND_FACTOR_ZERO ] = D3D_BLEND_ZERO; + D3DBlend[BLEND_FACTOR_ONE ] = D3D_BLEND_ONE; + D3DBlend[BLEND_FACTOR_SRC_COLOR ] = D3D_BLEND_SRC_COLOR; + D3DBlend[BLEND_FACTOR_INV_SRC_COLOR ] = D3D_BLEND_INV_SRC_COLOR; + D3DBlend[BLEND_FACTOR_SRC_ALPHA ] = D3D_BLEND_SRC_ALPHA; + D3DBlend[BLEND_FACTOR_INV_SRC_ALPHA ] = D3D_BLEND_INV_SRC_ALPHA; + D3DBlend[BLEND_FACTOR_DEST_ALPHA ] = D3D_BLEND_DEST_ALPHA; + D3DBlend[BLEND_FACTOR_INV_DEST_ALPHA ] = D3D_BLEND_INV_DEST_ALPHA; + D3DBlend[BLEND_FACTOR_DEST_COLOR ] = D3D_BLEND_DEST_COLOR; + D3DBlend[BLEND_FACTOR_INV_DEST_COLOR ] = D3D_BLEND_INV_DEST_COLOR; + D3DBlend[BLEND_FACTOR_SRC_ALPHA_SAT ] = D3D_BLEND_SRC_ALPHA_SAT; + D3DBlend[BLEND_FACTOR_BLEND_FACTOR ] = D3D_BLEND_BLEND_FACTOR; + D3DBlend[BLEND_FACTOR_INV_BLEND_FACTOR] = D3D_BLEND_INV_BLEND_FACTOR; + D3DBlend[BLEND_FACTOR_SRC1_COLOR ] = D3D_BLEND_SRC1_COLOR; + D3DBlend[BLEND_FACTOR_INV_SRC1_COLOR ] = D3D_BLEND_INV_SRC1_COLOR; + D3DBlend[BLEND_FACTOR_SRC1_ALPHA ] = D3D_BLEND_SRC1_ALPHA; + D3DBlend[BLEND_FACTOR_INV_SRC1_ALPHA ] = D3D_BLEND_INV_SRC1_ALPHA; + // clang-format on + + bIsInit = true; + } + if (bf > BLEND_FACTOR_UNDEFINED && bf < BLEND_FACTOR_NUM_FACTORS) + { + auto d3dbf = D3DBlend[bf]; + VERIFY(d3dbf != 0, "Incorrect blend factor"); + return d3dbf; + } + else + { + UNEXPECTED("Incorrect blend factor (", bf, ")"); + return static_cast(0); + } +} + +template +D3D_BLEND_OP BlendOperationToD3DBlendOp(BLEND_OPERATION BlendOp) +{ + // D3D12_BLEND_OP and D3D11_BLEND_OP are identical + + static bool bIsInit = false; + static std::array D3DBlendOp = {}; + if (!bIsInit) + { + // clang-format off + D3DBlendOp[BLEND_OPERATION_ADD ] = D3D_BLEND_OP_ADD; + D3DBlendOp[BLEND_OPERATION_SUBTRACT ] = D3D_BLEND_OP_SUBTRACT; + D3DBlendOp[BLEND_OPERATION_REV_SUBTRACT] = D3D_BLEND_OP_REV_SUBTRACT; + D3DBlendOp[BLEND_OPERATION_MIN ] = D3D_BLEND_OP_MIN; + D3DBlendOp[BLEND_OPERATION_MAX ] = D3D_BLEND_OP_MAX; + // clang-format on + + bIsInit = true; + } + + if (BlendOp > BLEND_OPERATION_UNDEFINED && BlendOp < BLEND_OPERATION_NUM_OPERATIONS) + { + auto d3dbop = D3DBlendOp[BlendOp]; + VERIFY(d3dbop != 0, "Incorrect blend operation"); + return d3dbop; + } + else + { + UNEXPECTED("Incorrect blend operation (", BlendOp, ")"); + return static_cast(0); + } +} + +template +void BlendStateDescToD3DBlendDesc(const BlendStateDesc& BSDesc, D3D_BLEND_DESC& d3d12BlendDesc) +{ + // D3D_BLEND_DESC and D3D11_BLEND_DESC structures are identical + d3d12BlendDesc.AlphaToCoverageEnable = BSDesc.AlphaToCoverageEnable ? TRUE : FALSE; + d3d12BlendDesc.IndependentBlendEnable = BSDesc.IndependentBlendEnable ? TRUE : FALSE; + VERIFY(MAX_RENDER_TARGETS >= 8, "Number of render targets is expected to be at least 8"); + for (int i = 0; i < 8; ++i) + { + const auto& SrcRTDesc = BSDesc.RenderTargets[i]; + auto& DstRTDesc = d3d12BlendDesc.RenderTarget[i]; + DstRTDesc.BlendEnable = SrcRTDesc.BlendEnable ? TRUE : FALSE; + + DstRTDesc.SrcBlend = BlendFactorToD3DBlend(SrcRTDesc.SrcBlend); + DstRTDesc.DestBlend = BlendFactorToD3DBlend(SrcRTDesc.DestBlend); + DstRTDesc.BlendOp = BlendOperationToD3DBlendOp(SrcRTDesc.BlendOp); + + DstRTDesc.SrcBlendAlpha = BlendFactorToD3DBlend(SrcRTDesc.SrcBlendAlpha); + DstRTDesc.DestBlendAlpha = BlendFactorToD3DBlend(SrcRTDesc.DestBlendAlpha); + DstRTDesc.BlendOpAlpha = BlendOperationToD3DBlendOp(SrcRTDesc.BlendOpAlpha); + + DstRTDesc.RenderTargetWriteMask = + ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_RED) ? D3D_COLOR_WRITE_ENABLE_RED : 0) | + ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_GREEN) ? D3D_COLOR_WRITE_ENABLE_GREEN : 0) | + ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_BLUE) ? D3D_COLOR_WRITE_ENABLE_BLUE : 0) | + ((SrcRTDesc.RenderTargetWriteMask & COLOR_MASK_ALPHA) ? D3D_COLOR_WRITE_ENABLE_ALPHA : 0); + } +} + + + +// ====================== Depth-stencil state attributes conversion functions ====================== + +template +D3D_STENCIL_OP StencilOpToD3DStencilOp(STENCIL_OP StencilOp) +{ + static bool bIsInit = false; + static std::array StOpToD3DStOpMap = {}; + if (!bIsInit) + { + // clang-format off + StOpToD3DStOpMap[STENCIL_OP_KEEP ] = D3D_STENCIL_OP_KEEP; + StOpToD3DStOpMap[STENCIL_OP_ZERO ] = D3D_STENCIL_OP_ZERO; + StOpToD3DStOpMap[STENCIL_OP_REPLACE ] = D3D_STENCIL_OP_REPLACE; + StOpToD3DStOpMap[STENCIL_OP_INCR_SAT ] = D3D_STENCIL_OP_INCR_SAT; + StOpToD3DStOpMap[STENCIL_OP_DECR_SAT ] = D3D_STENCIL_OP_DECR_SAT; + StOpToD3DStOpMap[STENCIL_OP_INVERT ] = D3D_STENCIL_OP_INVERT; + StOpToD3DStOpMap[STENCIL_OP_INCR_WRAP] = D3D_STENCIL_OP_INCR; + StOpToD3DStOpMap[STENCIL_OP_DECR_WRAP] = D3D_STENCIL_OP_DECR; + // clang-format on + + bIsInit = true; + } + + if (StencilOp > STENCIL_OP_UNDEFINED && StencilOp < STENCIL_OP_NUM_OPS) + { + auto d3dStencilOp = StOpToD3DStOpMap[StencilOp]; + VERIFY(d3dStencilOp != 0, "Unexpected stencil op"); + return d3dStencilOp; + } + else + { + UNEXPECTED("Stencil operation (", StencilOp, ") is out of allowed range [1, ", STENCIL_OP_NUM_OPS - 1, "]"); + return static_cast(0); + } +} + +template +D3D_DEPTH_STENCILOP_DESC StencilOpDescToD3DStencilOpDesc(const StencilOpDesc& StOpDesc) +{ + // D3D12_DEPTH_STENCILOP_DESC is identical to D3D11_DEPTH_STENCILOP_DESC + D3D_DEPTH_STENCILOP_DESC D3DStOpDesc; + D3DStOpDesc.StencilFailOp = StencilOpToD3DStencilOp(StOpDesc.StencilFailOp); + D3DStOpDesc.StencilDepthFailOp = StencilOpToD3DStencilOp(StOpDesc.StencilDepthFailOp); + D3DStOpDesc.StencilPassOp = StencilOpToD3DStencilOp(StOpDesc.StencilPassOp); + D3DStOpDesc.StencilFunc = ComparisonFuncToD3DComparisonFunc(StOpDesc.StencilFunc); + return D3DStOpDesc; +} + +template +void DepthStencilStateDesc_To_D3D_DEPTH_STENCIL_DESC(const DepthStencilStateDesc& DepthStencilDesc, D3D_DEPTH_STENCIL_DESC& d3dDSSDesc) +{ + // D3D_DEPTH_STENCIL_DESC is identical to D3D11_DEPTH_STENCIL_DESC + d3dDSSDesc.DepthEnable = DepthStencilDesc.DepthEnable ? TRUE : FALSE; + d3dDSSDesc.DepthWriteMask = DepthStencilDesc.DepthWriteEnable ? D3D_DEPTH_WRITE_MASK_ALL : D3D_DEPTH_WRITE_MASK_ZERO; + d3dDSSDesc.DepthFunc = ComparisonFuncToD3DComparisonFunc(DepthStencilDesc.DepthFunc); + d3dDSSDesc.StencilEnable = DepthStencilDesc.StencilEnable ? TRUE : FALSE; + d3dDSSDesc.StencilReadMask = DepthStencilDesc.StencilReadMask; + d3dDSSDesc.StencilWriteMask = DepthStencilDesc.StencilWriteMask; + d3dDSSDesc.FrontFace = StencilOpDescToD3DStencilOpDesc(DepthStencilDesc.FrontFace); + d3dDSSDesc.BackFace = StencilOpDescToD3DStencilOpDesc(DepthStencilDesc.BackFace); +} + + + +template +void LayoutElements_To_D3D_INPUT_ELEMENT_DESCs(const InputLayoutDesc& InputLayout, + std::vector>& D3DInputElements) +{ + // D3D12_INPUT_ELEMENT_DESC and D3D11_INPUT_ELEMENT_DESC are identical + D3DInputElements.resize(InputLayout.NumElements); + for (Uint32 iElem = 0; iElem < InputLayout.NumElements; ++iElem) + { + const auto& CurrElem = InputLayout.LayoutElements[iElem]; + auto& D3DElem = D3DInputElements[iElem]; + D3DElem.SemanticName = CurrElem.HLSLSemantic; + D3DElem.SemanticIndex = CurrElem.InputIndex; + D3DElem.AlignedByteOffset = CurrElem.RelativeOffset; + D3DElem.InputSlot = CurrElem.BufferSlot; + D3DElem.Format = TypeToDXGI_Format(CurrElem.ValueType, CurrElem.NumComponents, CurrElem.IsNormalized); + D3DElem.InputSlotClass = (CurrElem.Frequency == INPUT_ELEMENT_FREQUENCY_PER_VERTEX) ? D3D_INPUT_CLASSIFICATION_PER_VERTEX_DATA : D3D_INPUT_CLASSIFICATION_PER_INSTANCE_DATA; + D3DElem.InstanceDataStepRate = (CurrElem.Frequency == INPUT_ELEMENT_FREQUENCY_PER_VERTEX) ? 0 : CurrElem.InstanceDataStepRate; + } +} + + +template +D3D_FILTER FilterTypeToD3DFilter(FILTER_TYPE MinFilter, FILTER_TYPE MagFilter, FILTER_TYPE MipFilter) +{ + switch (MinFilter) + { + // Regular filters + case FILTER_TYPE_POINT: + if (MagFilter == FILTER_TYPE_POINT) + { + if (MipFilter == FILTER_TYPE_POINT) + return D3D_FILTER_MIN_MAG_MIP_POINT; + else if (MipFilter == FILTER_TYPE_LINEAR) + return D3D_FILTER_MIN_MAG_POINT_MIP_LINEAR; + } + else if (MagFilter == FILTER_TYPE_LINEAR) + { + if (MipFilter == FILTER_TYPE_POINT) + return D3D_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; + else if (MipFilter == FILTER_TYPE_LINEAR) + return D3D_FILTER_MIN_POINT_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_LINEAR: + if (MagFilter == FILTER_TYPE_POINT) + { + if (MipFilter == FILTER_TYPE_POINT) + return D3D_FILTER_MIN_LINEAR_MAG_MIP_POINT; + else if (MipFilter == FILTER_TYPE_LINEAR) + return D3D_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + } + else if (MagFilter == FILTER_TYPE_LINEAR) + { + if (MipFilter == FILTER_TYPE_POINT) + return D3D_FILTER_MIN_MAG_LINEAR_MIP_POINT; + else if (MipFilter == FILTER_TYPE_LINEAR) + return D3D_FILTER_MIN_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_ANISOTROPIC: + VERIFY(MagFilter == FILTER_TYPE_ANISOTROPIC && MipFilter == FILTER_TYPE_ANISOTROPIC, + "For anistropic filtering, all filters must be anisotropic"); + return D3D_FILTER_ANISOTROPIC; + break; + + + + // Comparison filters + case FILTER_TYPE_COMPARISON_POINT: + if (MagFilter == FILTER_TYPE_COMPARISON_POINT) + { + if (MipFilter == FILTER_TYPE_COMPARISON_POINT) + return D3D_FILTER_COMPARISON_MIN_MAG_MIP_POINT; + else if (MipFilter == FILTER_TYPE_COMPARISON_LINEAR) + return D3D_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR; + } + else if (MagFilter == FILTER_TYPE_COMPARISON_LINEAR) + { + if (MipFilter == FILTER_TYPE_COMPARISON_POINT) + return D3D_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT; + else if (MipFilter == FILTER_TYPE_COMPARISON_LINEAR) + return D3D_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_COMPARISON_LINEAR: + if (MagFilter == FILTER_TYPE_COMPARISON_POINT) + { + if (MipFilter == FILTER_TYPE_COMPARISON_POINT) + return D3D_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT; + else if (MipFilter == FILTER_TYPE_COMPARISON_LINEAR) + return D3D_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + } + else if (MagFilter == FILTER_TYPE_COMPARISON_LINEAR) + { + if (MipFilter == FILTER_TYPE_COMPARISON_POINT) + return D3D_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; + else if (MipFilter == FILTER_TYPE_COMPARISON_LINEAR) + return D3D_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_COMPARISON_ANISOTROPIC: + VERIFY(MagFilter == FILTER_TYPE_COMPARISON_ANISOTROPIC && MipFilter == FILTER_TYPE_COMPARISON_ANISOTROPIC, + "For comparison anistropic filtering, all filters must be anisotropic"); + return D3D_FILTER_COMPARISON_ANISOTROPIC; + break; + + + + // Minimum filters + case FILTER_TYPE_MINIMUM_POINT: + if (MagFilter == FILTER_TYPE_MINIMUM_POINT) + { + if (MipFilter == FILTER_TYPE_MINIMUM_POINT) + return D3D_FILTER_MINIMUM_MIN_MAG_MIP_POINT; + else if (MipFilter == FILTER_TYPE_MINIMUM_LINEAR) + return D3D_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR; + } + else if (MagFilter == FILTER_TYPE_MINIMUM_LINEAR) + { + if (MipFilter == FILTER_TYPE_MINIMUM_POINT) + return D3D_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT; + else if (MipFilter == FILTER_TYPE_MINIMUM_LINEAR) + return D3D_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_MINIMUM_LINEAR: + if (MagFilter == FILTER_TYPE_MINIMUM_POINT) + { + if (MipFilter == FILTER_TYPE_MINIMUM_POINT) + return D3D_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT; + else if (MipFilter == FILTER_TYPE_MINIMUM_LINEAR) + return D3D_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + } + else if (MagFilter == FILTER_TYPE_MINIMUM_LINEAR) + { + if (MipFilter == FILTER_TYPE_MINIMUM_POINT) + return D3D_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT; + else if (MipFilter == FILTER_TYPE_MINIMUM_LINEAR) + return D3D_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_MINIMUM_ANISOTROPIC: + VERIFY(MagFilter == FILTER_TYPE_MINIMUM_ANISOTROPIC && MipFilter == FILTER_TYPE_MINIMUM_ANISOTROPIC, + "For minimum anistropic filtering, all filters must be anisotropic"); + return D3D_FILTER_MINIMUM_ANISOTROPIC; + break; + + + + // Maximum filters + case FILTER_TYPE_MAXIMUM_POINT: + if (MagFilter == FILTER_TYPE_MAXIMUM_POINT) + { + if (MipFilter == FILTER_TYPE_MAXIMUM_POINT) + return D3D_FILTER_MAXIMUM_MIN_MAG_MIP_POINT; + else if (MipFilter == FILTER_TYPE_MAXIMUM_LINEAR) + return D3D_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR; + } + else if (MagFilter == FILTER_TYPE_MAXIMUM_LINEAR) + { + if (MipFilter == FILTER_TYPE_MAXIMUM_POINT) + return D3D_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT; + else if (MipFilter == FILTER_TYPE_MAXIMUM_LINEAR) + return D3D_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_MAXIMUM_LINEAR: + if (MagFilter == FILTER_TYPE_MAXIMUM_POINT) + { + if (MipFilter == FILTER_TYPE_MAXIMUM_POINT) + return D3D_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT; + else if (MipFilter == FILTER_TYPE_MAXIMUM_LINEAR) + return D3D_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + } + else if (MagFilter == FILTER_TYPE_MAXIMUM_LINEAR) + { + if (MipFilter == FILTER_TYPE_MAXIMUM_POINT) + return D3D_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT; + else if (MipFilter == FILTER_TYPE_MAXIMUM_LINEAR) + return D3D_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR; + } + break; + + case FILTER_TYPE_MAXIMUM_ANISOTROPIC: + VERIFY(MagFilter == FILTER_TYPE_MAXIMUM_ANISOTROPIC && MipFilter == FILTER_TYPE_MAXIMUM_ANISOTROPIC, + "For maximum anistropic filtering, all filters must be anisotropic"); + return D3D_FILTER_MAXIMUM_ANISOTROPIC; + break; + } + + UNEXPECTED("Unsupported filter combination"); + return D3D_FILTER_MIN_MAG_MIP_POINT; +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DViewDescConversionImpl.h b/Graphics/GraphicsEngineD3DBase/include/D3DViewDescConversionImpl.h deleted file mode 100644 index 5f6939a8..00000000 --- a/Graphics/GraphicsEngineD3DBase/include/D3DViewDescConversionImpl.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Implementation of D3D type conversions - -/// This file must be included after D3D11TypeDefinitions.h or D3D12TypeDefinitions.h - -#include "DXGITypeConversions.h" - -namespace Diligent -{ - -template -void TextureViewDesc_to_D3D_SRV_DESC(const TextureViewDesc& SRVDesc, D3D_SHADER_RESOURCE_VIEW_DESC& d3dSRVDesc, Uint32 SampleCount) -{ - memset(&d3dSRVDesc, 0, sizeof(d3dSRVDesc)); - d3dSRVDesc.Format = TexFormatToDXGI_Format(SRVDesc.Format, BIND_SHADER_RESOURCE); - - switch (SRVDesc.TextureDim) - { - case RESOURCE_DIM_TEX_1D: - d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1D; - d3dSRVDesc.Texture1D.MipLevels = SRVDesc.NumMipLevels; - d3dSRVDesc.Texture1D.MostDetailedMip = SRVDesc.MostDetailedMip; - break; - - case RESOURCE_DIM_TEX_1D_ARRAY: - d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1DARRAY; - d3dSRVDesc.Texture1DArray.ArraySize = SRVDesc.NumArraySlices; - d3dSRVDesc.Texture1DArray.FirstArraySlice = SRVDesc.FirstArraySlice; - d3dSRVDesc.Texture1DArray.MipLevels = SRVDesc.NumMipLevels; - d3dSRVDesc.Texture1DArray.MostDetailedMip = SRVDesc.MostDetailedMip; - break; - - case RESOURCE_DIM_TEX_2D: - if (SampleCount > 1) - { - d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DMS; - d3dSRVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; - } - else - { - d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D; - d3dSRVDesc.Texture2D.MipLevels = SRVDesc.NumMipLevels; - d3dSRVDesc.Texture2D.MostDetailedMip = SRVDesc.MostDetailedMip; - } - break; - - case RESOURCE_DIM_TEX_2D_ARRAY: - if (SampleCount > 1) - { - d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY; - d3dSRVDesc.Texture2DMSArray.ArraySize = SRVDesc.NumArraySlices; - d3dSRVDesc.Texture2DMSArray.FirstArraySlice = SRVDesc.FirstArraySlice; - } - else - { - d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DARRAY; - d3dSRVDesc.Texture2DArray.ArraySize = SRVDesc.NumArraySlices; - d3dSRVDesc.Texture2DArray.FirstArraySlice = SRVDesc.FirstArraySlice; - d3dSRVDesc.Texture2DArray.MipLevels = SRVDesc.NumMipLevels; - d3dSRVDesc.Texture2DArray.MostDetailedMip = SRVDesc.MostDetailedMip; - } - break; - - case RESOURCE_DIM_TEX_3D: - d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE3D; - d3dSRVDesc.Texture3D.MipLevels = SRVDesc.NumMipLevels; - d3dSRVDesc.Texture3D.MostDetailedMip = SRVDesc.MostDetailedMip; - break; - - case RESOURCE_DIM_TEX_CUBE: - d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBE; - d3dSRVDesc.TextureCube.MipLevels = SRVDesc.NumMipLevels; - d3dSRVDesc.TextureCube.MostDetailedMip = SRVDesc.MostDetailedMip; - break; - - case RESOURCE_DIM_TEX_CUBE_ARRAY: - d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBEARRAY; - d3dSRVDesc.TextureCubeArray.MipLevels = SRVDesc.NumMipLevels; - d3dSRVDesc.TextureCubeArray.MostDetailedMip = SRVDesc.MostDetailedMip; - d3dSRVDesc.TextureCubeArray.First2DArrayFace = SRVDesc.FirstArraySlice; - d3dSRVDesc.TextureCubeArray.NumCubes = SRVDesc.NumArraySlices / 6; - break; - - default: - UNEXPECTED("Unexpected view type"); - } -} - -template -void TextureViewDesc_to_D3D_RTV_DESC(const TextureViewDesc& RTVDesc, D3D_RENDER_TARGET_VIEW_DESC& d3dRTVDesc, Uint32 SampleCount) -{ - memset(&d3dRTVDesc, 0, sizeof(d3dRTVDesc)); - d3dRTVDesc.Format = TexFormatToDXGI_Format(RTVDesc.Format, BIND_RENDER_TARGET); - - switch (RTVDesc.TextureDim) - { - case RESOURCE_DIM_TEX_1D: - d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE1D; - d3dRTVDesc.Texture1D.MipSlice = RTVDesc.MostDetailedMip; - break; - - case RESOURCE_DIM_TEX_1D_ARRAY: - d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE1DARRAY; - d3dRTVDesc.Texture1DArray.ArraySize = RTVDesc.NumArraySlices; - d3dRTVDesc.Texture1DArray.FirstArraySlice = RTVDesc.FirstArraySlice; - d3dRTVDesc.Texture1DArray.MipSlice = RTVDesc.MostDetailedMip; - break; - - - case RESOURCE_DIM_TEX_2D: - if (SampleCount > 1) - { - d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE2DMS; - d3dRTVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; - } - else - { - d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE2D; - d3dRTVDesc.Texture2D.MipSlice = RTVDesc.MostDetailedMip; - } - break; - - case RESOURCE_DIM_TEX_2D_ARRAY: - if (SampleCount > 1) - { - d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE2DMSARRAY; - d3dRTVDesc.Texture2DMSArray.ArraySize = RTVDesc.NumArraySlices; - d3dRTVDesc.Texture2DMSArray.FirstArraySlice = RTVDesc.FirstArraySlice; - } - else - { - d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE2DARRAY; - d3dRTVDesc.Texture2DArray.ArraySize = RTVDesc.NumArraySlices; - d3dRTVDesc.Texture2DArray.FirstArraySlice = RTVDesc.FirstArraySlice; - d3dRTVDesc.Texture2DArray.MipSlice = RTVDesc.MostDetailedMip; - } - break; - - case RESOURCE_DIM_TEX_3D: - d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE3D; - d3dRTVDesc.Texture3D.FirstWSlice = RTVDesc.FirstDepthSlice; - d3dRTVDesc.Texture3D.WSize = RTVDesc.NumDepthSlices; - d3dRTVDesc.Texture3D.MipSlice = RTVDesc.MostDetailedMip; - break; - - default: - UNEXPECTED("Unexpected view type"); - } -} - -template -void TextureViewDesc_to_D3D_DSV_DESC(const TextureViewDesc& DSVDesc, D3D_DEPTH_STENCIL_VIEW_DESC& d3dDSVDesc, Uint32 SampleCount) -{ - memset(&d3dDSVDesc, 0, sizeof(d3dDSVDesc)); - d3dDSVDesc.Format = TexFormatToDXGI_Format(DSVDesc.Format, BIND_DEPTH_STENCIL); - - switch (DSVDesc.TextureDim) - { - case RESOURCE_DIM_TEX_1D: - d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE1D; - d3dDSVDesc.Texture1D.MipSlice = DSVDesc.MostDetailedMip; - break; - - case RESOURCE_DIM_TEX_1D_ARRAY: - d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE1DARRAY; - d3dDSVDesc.Texture1DArray.ArraySize = DSVDesc.NumArraySlices; - d3dDSVDesc.Texture1DArray.FirstArraySlice = DSVDesc.FirstArraySlice; - d3dDSVDesc.Texture1DArray.MipSlice = DSVDesc.MostDetailedMip; - break; - - - case RESOURCE_DIM_TEX_2D: - if (SampleCount > 1) - { - d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE2DMS; - d3dDSVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; - } - else - { - d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE2D; - d3dDSVDesc.Texture2D.MipSlice = DSVDesc.MostDetailedMip; - } - break; - - case RESOURCE_DIM_TEX_2D_ARRAY: - if (SampleCount > 1) - { - d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE2DMSARRAY; - d3dDSVDesc.Texture2DMSArray.ArraySize = DSVDesc.NumArraySlices; - d3dDSVDesc.Texture2DMSArray.FirstArraySlice = DSVDesc.FirstArraySlice; - } - else - { - d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE2DARRAY; - d3dDSVDesc.Texture2DArray.ArraySize = DSVDesc.NumArraySlices; - d3dDSVDesc.Texture2DArray.FirstArraySlice = DSVDesc.FirstArraySlice; - d3dDSVDesc.Texture2DArray.MipSlice = DSVDesc.MostDetailedMip; - } - break; - - case RESOURCE_DIM_TEX_3D: - LOG_ERROR_AND_THROW("Depth stencil views are not supported for 3D textures"); - break; - - default: - UNEXPECTED("Unexpected view type"); - } -} - -template -void TextureViewDesc_to_D3D_UAV_DESC(const TextureViewDesc& UAVDesc, D3D_UNORDERED_ACCESS_VIEW_DESC& d3dUAVDesc) -{ - memset(&d3dUAVDesc, 0, sizeof(d3dUAVDesc)); - d3dUAVDesc.Format = TexFormatToDXGI_Format(UAVDesc.Format, BIND_UNORDERED_ACCESS); - - switch (UAVDesc.TextureDim) - { - case RESOURCE_DIM_TEX_1D: - d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE1D; - d3dUAVDesc.Texture1D.MipSlice = UAVDesc.MostDetailedMip; - break; - - case RESOURCE_DIM_TEX_1D_ARRAY: - d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE1DARRAY; - d3dUAVDesc.Texture1DArray.ArraySize = UAVDesc.NumArraySlices; - d3dUAVDesc.Texture1DArray.FirstArraySlice = UAVDesc.FirstArraySlice; - d3dUAVDesc.Texture1DArray.MipSlice = UAVDesc.MostDetailedMip; - break; - - case RESOURCE_DIM_TEX_2D: - d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE2D; - d3dUAVDesc.Texture2D.MipSlice = UAVDesc.MostDetailedMip; - break; - - case RESOURCE_DIM_TEX_2D_ARRAY: - d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE2DARRAY; - d3dUAVDesc.Texture2DArray.ArraySize = UAVDesc.NumArraySlices; - d3dUAVDesc.Texture2DArray.FirstArraySlice = UAVDesc.FirstArraySlice; - d3dUAVDesc.Texture2DArray.MipSlice = UAVDesc.MostDetailedMip; - break; - - case RESOURCE_DIM_TEX_3D: - d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE3D; - d3dUAVDesc.Texture3D.FirstWSlice = UAVDesc.FirstDepthSlice; - d3dUAVDesc.Texture3D.WSize = UAVDesc.NumDepthSlices; - d3dUAVDesc.Texture3D.MipSlice = UAVDesc.MostDetailedMip; - break; - - default: - UNEXPECTED("Unexpected view type"); - } -} - -template -void BufferViewDesc_to_D3D_SRV_DESC(const BufferDesc& BuffDesc, const BufferViewDesc& SRVDesc, D3D_UNORDERED_ACCESS_VIEW_DESC& d3dSRVDesc) -{ - VERIFY(SRVDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Incorrect view type: shader resource is expected"); - - memset(&d3dSRVDesc, 0, sizeof(d3dSRVDesc)); - const auto& BuffFmt = SRVDesc.Format; - if (BuffDesc.Mode == BUFFER_MODE_FORMATTED || BuffDesc.Mode == BUFFER_MODE_RAW && BuffFmt.ValueType != VT_UNDEFINED) - d3dSRVDesc.Format = TypeToDXGI_Format(BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized); - - Uint32 ElementByteStride = 0; - if (BuffDesc.Mode == BUFFER_MODE_FORMATTED || BuffDesc.Mode == BUFFER_MODE_STRUCTURED || BuffDesc.Mode == BUFFER_MODE_RAW && BuffFmt.ValueType != VT_UNDEFINED) - ElementByteStride = BuffDesc.ElementByteStride; - else if (BuffDesc.Mode == BUFFER_MODE_RAW && BuffFmt.ValueType == VT_UNDEFINED) - ElementByteStride = 4; - - if (ElementByteStride != 0) - { - DEV_CHECK_ERR((SRVDesc.ByteOffset % ElementByteStride) == 0, "Byte offest (", SRVDesc.ByteOffset, ") is not multiple of element byte stride (", ElementByteStride, ")"); - DEV_CHECK_ERR((SRVDesc.ByteWidth % ElementByteStride) == 0, "Byte width (", SRVDesc.ByteWidth, ")is not multiple of element byte stride (", ElementByteStride, ")"); - d3dSRVDesc.Buffer.FirstElement = SRVDesc.ByteOffset / ElementByteStride; - d3dSRVDesc.Buffer.NumElements = SRVDesc.ByteWidth / ElementByteStride; - } - d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_BUFFER; -} - -template -void BufferViewDesc_to_D3D_UAV_DESC(const BufferDesc& BuffDesc, const BufferViewDesc& UAVDesc, D3D_UNORDERED_ACCESS_VIEW_DESC& d3dUAVDesc) -{ - VERIFY(UAVDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Incorrect view type: unordered access is expected"); - - memset(&d3dUAVDesc, 0, sizeof(d3dUAVDesc)); - const auto& BuffFmt = UAVDesc.Format; - if (BuffDesc.Mode == BUFFER_MODE_FORMATTED || BuffDesc.Mode == BUFFER_MODE_RAW && BuffFmt.ValueType != VT_UNDEFINED) - d3dUAVDesc.Format = TypeToDXGI_Format(BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized); - - Uint32 ElementByteStride = 0; - if (BuffDesc.Mode == BUFFER_MODE_FORMATTED || BuffDesc.Mode == BUFFER_MODE_STRUCTURED || BuffDesc.Mode == BUFFER_MODE_RAW && BuffFmt.ValueType != VT_UNDEFINED) - ElementByteStride = BuffDesc.ElementByteStride; - else if (BuffDesc.Mode == BUFFER_MODE_RAW && BuffFmt.ValueType == VT_UNDEFINED) - ElementByteStride = 4; - - if (ElementByteStride != 0) - { - DEV_CHECK_ERR((UAVDesc.ByteOffset % ElementByteStride) == 0, "Byte offest (", UAVDesc.ByteOffset, ") is not multiple of element byte stride (", ElementByteStride, ")"); - DEV_CHECK_ERR((UAVDesc.ByteWidth % ElementByteStride) == 0, "Byte width (", UAVDesc.ByteWidth, ")is not multiple of element byte stride (", ElementByteStride, ")"); - d3dUAVDesc.Buffer.FirstElement = UAVDesc.ByteOffset / ElementByteStride; - d3dUAVDesc.Buffer.NumElements = UAVDesc.ByteWidth / ElementByteStride; - } - - if (BuffDesc.Mode == BUFFER_MODE_RAW && UAVDesc.Format.ValueType == VT_UNDEFINED) - { - d3dUAVDesc.Format = DXGI_FORMAT_R32_TYPELESS; - d3dUAVDesc.Buffer.Flags = D3D_BUFFER_UAV_FLAG_RAW; - } - else - d3dUAVDesc.Buffer.Flags = D3D_BUFFER_UAV_FLAG_NONE; - - d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_BUFFER; -} - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DViewDescConversionImpl.hpp b/Graphics/GraphicsEngineD3DBase/include/D3DViewDescConversionImpl.hpp new file mode 100644 index 00000000..5f6939a8 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/D3DViewDescConversionImpl.hpp @@ -0,0 +1,344 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of D3D type conversions + +/// This file must be included after D3D11TypeDefinitions.h or D3D12TypeDefinitions.h + +#include "DXGITypeConversions.h" + +namespace Diligent +{ + +template +void TextureViewDesc_to_D3D_SRV_DESC(const TextureViewDesc& SRVDesc, D3D_SHADER_RESOURCE_VIEW_DESC& d3dSRVDesc, Uint32 SampleCount) +{ + memset(&d3dSRVDesc, 0, sizeof(d3dSRVDesc)); + d3dSRVDesc.Format = TexFormatToDXGI_Format(SRVDesc.Format, BIND_SHADER_RESOURCE); + + switch (SRVDesc.TextureDim) + { + case RESOURCE_DIM_TEX_1D: + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1D; + d3dSRVDesc.Texture1D.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.Texture1D.MostDetailedMip = SRVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_1D_ARRAY: + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1DARRAY; + d3dSRVDesc.Texture1DArray.ArraySize = SRVDesc.NumArraySlices; + d3dSRVDesc.Texture1DArray.FirstArraySlice = SRVDesc.FirstArraySlice; + d3dSRVDesc.Texture1DArray.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.Texture1DArray.MostDetailedMip = SRVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_2D: + if (SampleCount > 1) + { + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DMS; + d3dSRVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; + } + else + { + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D; + d3dSRVDesc.Texture2D.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.Texture2D.MostDetailedMip = SRVDesc.MostDetailedMip; + } + break; + + case RESOURCE_DIM_TEX_2D_ARRAY: + if (SampleCount > 1) + { + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY; + d3dSRVDesc.Texture2DMSArray.ArraySize = SRVDesc.NumArraySlices; + d3dSRVDesc.Texture2DMSArray.FirstArraySlice = SRVDesc.FirstArraySlice; + } + else + { + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DARRAY; + d3dSRVDesc.Texture2DArray.ArraySize = SRVDesc.NumArraySlices; + d3dSRVDesc.Texture2DArray.FirstArraySlice = SRVDesc.FirstArraySlice; + d3dSRVDesc.Texture2DArray.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.Texture2DArray.MostDetailedMip = SRVDesc.MostDetailedMip; + } + break; + + case RESOURCE_DIM_TEX_3D: + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE3D; + d3dSRVDesc.Texture3D.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.Texture3D.MostDetailedMip = SRVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_CUBE: + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBE; + d3dSRVDesc.TextureCube.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.TextureCube.MostDetailedMip = SRVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_CUBE_ARRAY: + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBEARRAY; + d3dSRVDesc.TextureCubeArray.MipLevels = SRVDesc.NumMipLevels; + d3dSRVDesc.TextureCubeArray.MostDetailedMip = SRVDesc.MostDetailedMip; + d3dSRVDesc.TextureCubeArray.First2DArrayFace = SRVDesc.FirstArraySlice; + d3dSRVDesc.TextureCubeArray.NumCubes = SRVDesc.NumArraySlices / 6; + break; + + default: + UNEXPECTED("Unexpected view type"); + } +} + +template +void TextureViewDesc_to_D3D_RTV_DESC(const TextureViewDesc& RTVDesc, D3D_RENDER_TARGET_VIEW_DESC& d3dRTVDesc, Uint32 SampleCount) +{ + memset(&d3dRTVDesc, 0, sizeof(d3dRTVDesc)); + d3dRTVDesc.Format = TexFormatToDXGI_Format(RTVDesc.Format, BIND_RENDER_TARGET); + + switch (RTVDesc.TextureDim) + { + case RESOURCE_DIM_TEX_1D: + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE1D; + d3dRTVDesc.Texture1D.MipSlice = RTVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_1D_ARRAY: + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE1DARRAY; + d3dRTVDesc.Texture1DArray.ArraySize = RTVDesc.NumArraySlices; + d3dRTVDesc.Texture1DArray.FirstArraySlice = RTVDesc.FirstArraySlice; + d3dRTVDesc.Texture1DArray.MipSlice = RTVDesc.MostDetailedMip; + break; + + + case RESOURCE_DIM_TEX_2D: + if (SampleCount > 1) + { + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE2DMS; + d3dRTVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; + } + else + { + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE2D; + d3dRTVDesc.Texture2D.MipSlice = RTVDesc.MostDetailedMip; + } + break; + + case RESOURCE_DIM_TEX_2D_ARRAY: + if (SampleCount > 1) + { + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE2DMSARRAY; + d3dRTVDesc.Texture2DMSArray.ArraySize = RTVDesc.NumArraySlices; + d3dRTVDesc.Texture2DMSArray.FirstArraySlice = RTVDesc.FirstArraySlice; + } + else + { + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE2DARRAY; + d3dRTVDesc.Texture2DArray.ArraySize = RTVDesc.NumArraySlices; + d3dRTVDesc.Texture2DArray.FirstArraySlice = RTVDesc.FirstArraySlice; + d3dRTVDesc.Texture2DArray.MipSlice = RTVDesc.MostDetailedMip; + } + break; + + case RESOURCE_DIM_TEX_3D: + d3dRTVDesc.ViewDimension = D3D_RTV_DIMENSION_TEXTURE3D; + d3dRTVDesc.Texture3D.FirstWSlice = RTVDesc.FirstDepthSlice; + d3dRTVDesc.Texture3D.WSize = RTVDesc.NumDepthSlices; + d3dRTVDesc.Texture3D.MipSlice = RTVDesc.MostDetailedMip; + break; + + default: + UNEXPECTED("Unexpected view type"); + } +} + +template +void TextureViewDesc_to_D3D_DSV_DESC(const TextureViewDesc& DSVDesc, D3D_DEPTH_STENCIL_VIEW_DESC& d3dDSVDesc, Uint32 SampleCount) +{ + memset(&d3dDSVDesc, 0, sizeof(d3dDSVDesc)); + d3dDSVDesc.Format = TexFormatToDXGI_Format(DSVDesc.Format, BIND_DEPTH_STENCIL); + + switch (DSVDesc.TextureDim) + { + case RESOURCE_DIM_TEX_1D: + d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE1D; + d3dDSVDesc.Texture1D.MipSlice = DSVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_1D_ARRAY: + d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE1DARRAY; + d3dDSVDesc.Texture1DArray.ArraySize = DSVDesc.NumArraySlices; + d3dDSVDesc.Texture1DArray.FirstArraySlice = DSVDesc.FirstArraySlice; + d3dDSVDesc.Texture1DArray.MipSlice = DSVDesc.MostDetailedMip; + break; + + + case RESOURCE_DIM_TEX_2D: + if (SampleCount > 1) + { + d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE2DMS; + d3dDSVDesc.Texture2DMS.UnusedField_NothingToDefine = 0; + } + else + { + d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE2D; + d3dDSVDesc.Texture2D.MipSlice = DSVDesc.MostDetailedMip; + } + break; + + case RESOURCE_DIM_TEX_2D_ARRAY: + if (SampleCount > 1) + { + d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE2DMSARRAY; + d3dDSVDesc.Texture2DMSArray.ArraySize = DSVDesc.NumArraySlices; + d3dDSVDesc.Texture2DMSArray.FirstArraySlice = DSVDesc.FirstArraySlice; + } + else + { + d3dDSVDesc.ViewDimension = D3D_DSV_DIMENSION_TEXTURE2DARRAY; + d3dDSVDesc.Texture2DArray.ArraySize = DSVDesc.NumArraySlices; + d3dDSVDesc.Texture2DArray.FirstArraySlice = DSVDesc.FirstArraySlice; + d3dDSVDesc.Texture2DArray.MipSlice = DSVDesc.MostDetailedMip; + } + break; + + case RESOURCE_DIM_TEX_3D: + LOG_ERROR_AND_THROW("Depth stencil views are not supported for 3D textures"); + break; + + default: + UNEXPECTED("Unexpected view type"); + } +} + +template +void TextureViewDesc_to_D3D_UAV_DESC(const TextureViewDesc& UAVDesc, D3D_UNORDERED_ACCESS_VIEW_DESC& d3dUAVDesc) +{ + memset(&d3dUAVDesc, 0, sizeof(d3dUAVDesc)); + d3dUAVDesc.Format = TexFormatToDXGI_Format(UAVDesc.Format, BIND_UNORDERED_ACCESS); + + switch (UAVDesc.TextureDim) + { + case RESOURCE_DIM_TEX_1D: + d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE1D; + d3dUAVDesc.Texture1D.MipSlice = UAVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_1D_ARRAY: + d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE1DARRAY; + d3dUAVDesc.Texture1DArray.ArraySize = UAVDesc.NumArraySlices; + d3dUAVDesc.Texture1DArray.FirstArraySlice = UAVDesc.FirstArraySlice; + d3dUAVDesc.Texture1DArray.MipSlice = UAVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_2D: + d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE2D; + d3dUAVDesc.Texture2D.MipSlice = UAVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_2D_ARRAY: + d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE2DARRAY; + d3dUAVDesc.Texture2DArray.ArraySize = UAVDesc.NumArraySlices; + d3dUAVDesc.Texture2DArray.FirstArraySlice = UAVDesc.FirstArraySlice; + d3dUAVDesc.Texture2DArray.MipSlice = UAVDesc.MostDetailedMip; + break; + + case RESOURCE_DIM_TEX_3D: + d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_TEXTURE3D; + d3dUAVDesc.Texture3D.FirstWSlice = UAVDesc.FirstDepthSlice; + d3dUAVDesc.Texture3D.WSize = UAVDesc.NumDepthSlices; + d3dUAVDesc.Texture3D.MipSlice = UAVDesc.MostDetailedMip; + break; + + default: + UNEXPECTED("Unexpected view type"); + } +} + +template +void BufferViewDesc_to_D3D_SRV_DESC(const BufferDesc& BuffDesc, const BufferViewDesc& SRVDesc, D3D_UNORDERED_ACCESS_VIEW_DESC& d3dSRVDesc) +{ + VERIFY(SRVDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Incorrect view type: shader resource is expected"); + + memset(&d3dSRVDesc, 0, sizeof(d3dSRVDesc)); + const auto& BuffFmt = SRVDesc.Format; + if (BuffDesc.Mode == BUFFER_MODE_FORMATTED || BuffDesc.Mode == BUFFER_MODE_RAW && BuffFmt.ValueType != VT_UNDEFINED) + d3dSRVDesc.Format = TypeToDXGI_Format(BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized); + + Uint32 ElementByteStride = 0; + if (BuffDesc.Mode == BUFFER_MODE_FORMATTED || BuffDesc.Mode == BUFFER_MODE_STRUCTURED || BuffDesc.Mode == BUFFER_MODE_RAW && BuffFmt.ValueType != VT_UNDEFINED) + ElementByteStride = BuffDesc.ElementByteStride; + else if (BuffDesc.Mode == BUFFER_MODE_RAW && BuffFmt.ValueType == VT_UNDEFINED) + ElementByteStride = 4; + + if (ElementByteStride != 0) + { + DEV_CHECK_ERR((SRVDesc.ByteOffset % ElementByteStride) == 0, "Byte offest (", SRVDesc.ByteOffset, ") is not multiple of element byte stride (", ElementByteStride, ")"); + DEV_CHECK_ERR((SRVDesc.ByteWidth % ElementByteStride) == 0, "Byte width (", SRVDesc.ByteWidth, ")is not multiple of element byte stride (", ElementByteStride, ")"); + d3dSRVDesc.Buffer.FirstElement = SRVDesc.ByteOffset / ElementByteStride; + d3dSRVDesc.Buffer.NumElements = SRVDesc.ByteWidth / ElementByteStride; + } + d3dSRVDesc.ViewDimension = D3D_SRV_DIMENSION_BUFFER; +} + +template +void BufferViewDesc_to_D3D_UAV_DESC(const BufferDesc& BuffDesc, const BufferViewDesc& UAVDesc, D3D_UNORDERED_ACCESS_VIEW_DESC& d3dUAVDesc) +{ + VERIFY(UAVDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Incorrect view type: unordered access is expected"); + + memset(&d3dUAVDesc, 0, sizeof(d3dUAVDesc)); + const auto& BuffFmt = UAVDesc.Format; + if (BuffDesc.Mode == BUFFER_MODE_FORMATTED || BuffDesc.Mode == BUFFER_MODE_RAW && BuffFmt.ValueType != VT_UNDEFINED) + d3dUAVDesc.Format = TypeToDXGI_Format(BuffFmt.ValueType, BuffFmt.NumComponents, BuffFmt.IsNormalized); + + Uint32 ElementByteStride = 0; + if (BuffDesc.Mode == BUFFER_MODE_FORMATTED || BuffDesc.Mode == BUFFER_MODE_STRUCTURED || BuffDesc.Mode == BUFFER_MODE_RAW && BuffFmt.ValueType != VT_UNDEFINED) + ElementByteStride = BuffDesc.ElementByteStride; + else if (BuffDesc.Mode == BUFFER_MODE_RAW && BuffFmt.ValueType == VT_UNDEFINED) + ElementByteStride = 4; + + if (ElementByteStride != 0) + { + DEV_CHECK_ERR((UAVDesc.ByteOffset % ElementByteStride) == 0, "Byte offest (", UAVDesc.ByteOffset, ") is not multiple of element byte stride (", ElementByteStride, ")"); + DEV_CHECK_ERR((UAVDesc.ByteWidth % ElementByteStride) == 0, "Byte width (", UAVDesc.ByteWidth, ")is not multiple of element byte stride (", ElementByteStride, ")"); + d3dUAVDesc.Buffer.FirstElement = UAVDesc.ByteOffset / ElementByteStride; + d3dUAVDesc.Buffer.NumElements = UAVDesc.ByteWidth / ElementByteStride; + } + + if (BuffDesc.Mode == BUFFER_MODE_RAW && UAVDesc.Format.ValueType == VT_UNDEFINED) + { + d3dUAVDesc.Format = DXGI_FORMAT_R32_TYPELESS; + d3dUAVDesc.Buffer.Flags = D3D_BUFFER_UAV_FLAG_RAW; + } + else + d3dUAVDesc.Buffer.Flags = D3D_BUFFER_UAV_FLAG_NONE; + + d3dUAVDesc.ViewDimension = D3D_UAV_DIMENSION_BUFFER; +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h deleted file mode 100644 index e2f04091..00000000 --- a/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include "DXGITypeConversions.h" -#include "EngineFactoryBase.h" - -/// \file -/// Implementation of the Diligent::EngineFactoryD3DBase template class - -namespace Diligent -{ - -template -class EngineFactoryD3DBase : public EngineFactoryBase -{ -public: - using TEngineFactoryBase = EngineFactoryBase; - - EngineFactoryD3DBase(const INTERFACE_ID& FactoryIID) : - TEngineFactoryBase{FactoryIID} - {} - - - virtual void EnumerateAdapters(DIRECT3D_FEATURE_LEVEL MinFeatureLevel, - Uint32& NumAdapters, - AdapterAttribs* Adapters) override - { - auto DXGIAdapters = FindCompatibleAdapters(MinFeatureLevel); - - if (Adapters == nullptr) - NumAdapters = static_cast(DXGIAdapters.size()); - else - { - NumAdapters = std::min(NumAdapters, static_cast(DXGIAdapters.size())); - for (Uint32 adapter = 0; adapter < NumAdapters; ++adapter) - { - IDXGIAdapter1* pDXIAdapter = DXGIAdapters[adapter]; - DXGI_ADAPTER_DESC1 AdapterDesc; - pDXIAdapter->GetDesc1(&AdapterDesc); - - auto& Attribs = Adapters[adapter]; - - Attribs.AdapterType = (AdapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) ? ADAPTER_TYPE_SOFTWARE : ADAPTER_TYPE_HARDWARE; - WideCharToMultiByte(CP_ACP, 0, AdapterDesc.Description, -1, Attribs.Description, _countof(Attribs.Description), NULL, FALSE); - Attribs.DedicatedVideoMemory = AdapterDesc.DedicatedVideoMemory; - Attribs.DedicatedSystemMemory = AdapterDesc.DedicatedSystemMemory; - Attribs.SharedSystemMemory = AdapterDesc.SharedSystemMemory; - Attribs.VendorId = AdapterDesc.VendorId; - Attribs.DeviceId = AdapterDesc.DeviceId; - - Attribs.NumOutputs = 0; - CComPtr pOutput; - while (pDXIAdapter->EnumOutputs(Attribs.NumOutputs, &pOutput) != DXGI_ERROR_NOT_FOUND) - { - ++Attribs.NumOutputs; - pOutput.Release(); - }; - } - } - } - - - virtual void EnumerateDisplayModes(DIRECT3D_FEATURE_LEVEL MinFeatureLevel, - Uint32 AdapterId, - Uint32 OutputId, - TEXTURE_FORMAT Format, - Uint32& NumDisplayModes, - DisplayModeAttribs* DisplayModes) override - { - auto DXGIAdapters = FindCompatibleAdapters(MinFeatureLevel); - if (AdapterId >= DXGIAdapters.size()) - { - LOG_ERROR("Incorrect adapter id ", AdapterId); - return; - } - - IDXGIAdapter1* pDXIAdapter = DXGIAdapters[AdapterId]; - - DXGI_FORMAT DXIGFormat = TexFormatToDXGI_Format(Format); - CComPtr pOutput; - if (pDXIAdapter->EnumOutputs(OutputId, &pOutput) == DXGI_ERROR_NOT_FOUND) - { - DXGI_ADAPTER_DESC1 AdapterDesc; - pDXIAdapter->GetDesc1(&AdapterDesc); - char DescriptionMB[_countof(AdapterDesc.Description)]; - WideCharToMultiByte(CP_ACP, 0, AdapterDesc.Description, -1, DescriptionMB, _countof(DescriptionMB), NULL, FALSE); - LOG_ERROR_MESSAGE("Failed to enumerate output ", OutputId, " of adapter ", AdapterId, " (", DescriptionMB, ')'); - return; - } - - UINT numModes = 0; - // Get the number of elements - auto hr = pOutput->GetDisplayModeList(DXIGFormat, 0, &numModes, NULL); - if (DisplayModes != nullptr) - { - // Get the list - std::vector DXIDisplayModes(numModes); - hr = pOutput->GetDisplayModeList(DXIGFormat, 0, &numModes, DXIDisplayModes.data()); - for (Uint32 m = 0; m < std::min(NumDisplayModes, numModes); ++m) - { - const auto& SrcMode = DXIDisplayModes[m]; - auto& DstMode = DisplayModes[m]; - DstMode.Width = SrcMode.Width; - DstMode.Height = SrcMode.Height; - DstMode.Format = DXGI_FormatToTexFormat(SrcMode.Format); - DstMode.RefreshRateNumerator = SrcMode.RefreshRate.Numerator; - DstMode.RefreshRateDenominator = SrcMode.RefreshRate.Denominator; - DstMode.Scaling = static_cast(SrcMode.Scaling); - DstMode.ScanlineOrder = static_cast(SrcMode.ScanlineOrdering); - } - NumDisplayModes = std::min(NumDisplayModes, numModes); - } - else - { - NumDisplayModes = numModes; - } - } - - - std::vector> FindCompatibleAdapters(DIRECT3D_FEATURE_LEVEL MinFeatureLevel) - { - std::vector> DXGIAdapters; - - CComPtr pFactory; - if (FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory2), (void**)&pFactory))) - { - LOG_ERROR_MESSAGE("Failed to create DXGI Factory"); - return std::move(DXGIAdapters); - } - - CComPtr pDXIAdapter; - - auto d3dFeatureLevel = GetD3DFeatureLevel(MinFeatureLevel); - UINT adapter = 0; - for (; pFactory->EnumAdapters1(adapter, &pDXIAdapter) != DXGI_ERROR_NOT_FOUND; ++adapter, pDXIAdapter.Release()) - { - DXGI_ADAPTER_DESC1 AdapterDesc; - pDXIAdapter->GetDesc1(&AdapterDesc); - bool IsCompatibleAdapter = CheckAdapterCompatibility(pDXIAdapter, d3dFeatureLevel); - if (IsCompatibleAdapter) - { - DXGIAdapters.emplace_back(std::move(pDXIAdapter)); - } - } - - return std::move(DXGIAdapters); - } - - -protected: - static D3D_FEATURE_LEVEL GetD3DFeatureLevel(DIRECT3D_FEATURE_LEVEL FeatureLevel) - { - switch (FeatureLevel) - { - case DIRECT3D_FEATURE_LEVEL_10_0: return D3D_FEATURE_LEVEL_10_0; - case DIRECT3D_FEATURE_LEVEL_10_1: return D3D_FEATURE_LEVEL_10_1; - case DIRECT3D_FEATURE_LEVEL_11_0: return D3D_FEATURE_LEVEL_11_0; - case DIRECT3D_FEATURE_LEVEL_11_1: return D3D_FEATURE_LEVEL_11_1; -#if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT >= _WIN32_WINNT_WIN10) - case DIRECT3D_FEATURE_LEVEL_12_0: return D3D_FEATURE_LEVEL_12_0; - case DIRECT3D_FEATURE_LEVEL_12_1: return D3D_FEATURE_LEVEL_12_1; -#endif - - default: - UNEXPECTED("Unknown DIRECT3D_FEATURE_LEVEL ", static_cast(FeatureLevel)); - return D3D_FEATURE_LEVEL_11_0; - } - } - -private: - template - bool CheckAdapterCompatibility(IDXGIAdapter1* pDXGIAdapter, - D3D_FEATURE_LEVEL FeatureLevels); - - template <> - bool CheckAdapterCompatibility(IDXGIAdapter1* pDXGIAdapter, - D3D_FEATURE_LEVEL FeatureLevel) - { - auto hr = D3D11CreateDevice( - nullptr, - D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device. - 0, - 0, // Flags. - &FeatureLevel, // Feature levels. - 1, // Number of feature levels - D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps. - nullptr, // No need to keep the D3D device reference. - nullptr, // Feature level of the created adapter. - nullptr // No need to keep the D3D device context reference. - ); - return SUCCEEDED(hr); - } - - template <> - bool CheckAdapterCompatibility(IDXGIAdapter1* pDXGIAdapter, - D3D_FEATURE_LEVEL FeatureLevel) - { - auto hr = D3D12CreateDevice(pDXGIAdapter, FeatureLevel, _uuidof(ID3D12Device), nullptr); - return SUCCEEDED(hr); - } -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.hpp b/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.hpp new file mode 100644 index 00000000..1e610f62 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.hpp @@ -0,0 +1,229 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "DXGITypeConversions.h" +#include "EngineFactoryBase.hpp" + +/// \file +/// Implementation of the Diligent::EngineFactoryD3DBase template class + +namespace Diligent +{ + +template +class EngineFactoryD3DBase : public EngineFactoryBase +{ +public: + using TEngineFactoryBase = EngineFactoryBase; + + EngineFactoryD3DBase(const INTERFACE_ID& FactoryIID) : + TEngineFactoryBase{FactoryIID} + {} + + + virtual void EnumerateAdapters(DIRECT3D_FEATURE_LEVEL MinFeatureLevel, + Uint32& NumAdapters, + AdapterAttribs* Adapters) override + { + auto DXGIAdapters = FindCompatibleAdapters(MinFeatureLevel); + + if (Adapters == nullptr) + NumAdapters = static_cast(DXGIAdapters.size()); + else + { + NumAdapters = std::min(NumAdapters, static_cast(DXGIAdapters.size())); + for (Uint32 adapter = 0; adapter < NumAdapters; ++adapter) + { + IDXGIAdapter1* pDXIAdapter = DXGIAdapters[adapter]; + DXGI_ADAPTER_DESC1 AdapterDesc; + pDXIAdapter->GetDesc1(&AdapterDesc); + + auto& Attribs = Adapters[adapter]; + + Attribs.AdapterType = (AdapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) ? ADAPTER_TYPE_SOFTWARE : ADAPTER_TYPE_HARDWARE; + WideCharToMultiByte(CP_ACP, 0, AdapterDesc.Description, -1, Attribs.Description, _countof(Attribs.Description), NULL, FALSE); + Attribs.DedicatedVideoMemory = AdapterDesc.DedicatedVideoMemory; + Attribs.DedicatedSystemMemory = AdapterDesc.DedicatedSystemMemory; + Attribs.SharedSystemMemory = AdapterDesc.SharedSystemMemory; + Attribs.VendorId = AdapterDesc.VendorId; + Attribs.DeviceId = AdapterDesc.DeviceId; + + Attribs.NumOutputs = 0; + CComPtr pOutput; + while (pDXIAdapter->EnumOutputs(Attribs.NumOutputs, &pOutput) != DXGI_ERROR_NOT_FOUND) + { + ++Attribs.NumOutputs; + pOutput.Release(); + }; + } + } + } + + + virtual void EnumerateDisplayModes(DIRECT3D_FEATURE_LEVEL MinFeatureLevel, + Uint32 AdapterId, + Uint32 OutputId, + TEXTURE_FORMAT Format, + Uint32& NumDisplayModes, + DisplayModeAttribs* DisplayModes) override + { + auto DXGIAdapters = FindCompatibleAdapters(MinFeatureLevel); + if (AdapterId >= DXGIAdapters.size()) + { + LOG_ERROR("Incorrect adapter id ", AdapterId); + return; + } + + IDXGIAdapter1* pDXIAdapter = DXGIAdapters[AdapterId]; + + DXGI_FORMAT DXIGFormat = TexFormatToDXGI_Format(Format); + CComPtr pOutput; + if (pDXIAdapter->EnumOutputs(OutputId, &pOutput) == DXGI_ERROR_NOT_FOUND) + { + DXGI_ADAPTER_DESC1 AdapterDesc; + pDXIAdapter->GetDesc1(&AdapterDesc); + char DescriptionMB[_countof(AdapterDesc.Description)]; + WideCharToMultiByte(CP_ACP, 0, AdapterDesc.Description, -1, DescriptionMB, _countof(DescriptionMB), NULL, FALSE); + LOG_ERROR_MESSAGE("Failed to enumerate output ", OutputId, " of adapter ", AdapterId, " (", DescriptionMB, ')'); + return; + } + + UINT numModes = 0; + // Get the number of elements + auto hr = pOutput->GetDisplayModeList(DXIGFormat, 0, &numModes, NULL); + if (DisplayModes != nullptr) + { + // Get the list + std::vector DXIDisplayModes(numModes); + hr = pOutput->GetDisplayModeList(DXIGFormat, 0, &numModes, DXIDisplayModes.data()); + for (Uint32 m = 0; m < std::min(NumDisplayModes, numModes); ++m) + { + const auto& SrcMode = DXIDisplayModes[m]; + auto& DstMode = DisplayModes[m]; + DstMode.Width = SrcMode.Width; + DstMode.Height = SrcMode.Height; + DstMode.Format = DXGI_FormatToTexFormat(SrcMode.Format); + DstMode.RefreshRateNumerator = SrcMode.RefreshRate.Numerator; + DstMode.RefreshRateDenominator = SrcMode.RefreshRate.Denominator; + DstMode.Scaling = static_cast(SrcMode.Scaling); + DstMode.ScanlineOrder = static_cast(SrcMode.ScanlineOrdering); + } + NumDisplayModes = std::min(NumDisplayModes, numModes); + } + else + { + NumDisplayModes = numModes; + } + } + + + std::vector> FindCompatibleAdapters(DIRECT3D_FEATURE_LEVEL MinFeatureLevel) + { + std::vector> DXGIAdapters; + + CComPtr pFactory; + if (FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory2), (void**)&pFactory))) + { + LOG_ERROR_MESSAGE("Failed to create DXGI Factory"); + return std::move(DXGIAdapters); + } + + CComPtr pDXIAdapter; + + auto d3dFeatureLevel = GetD3DFeatureLevel(MinFeatureLevel); + UINT adapter = 0; + for (; pFactory->EnumAdapters1(adapter, &pDXIAdapter) != DXGI_ERROR_NOT_FOUND; ++adapter, pDXIAdapter.Release()) + { + DXGI_ADAPTER_DESC1 AdapterDesc; + pDXIAdapter->GetDesc1(&AdapterDesc); + bool IsCompatibleAdapter = CheckAdapterCompatibility(pDXIAdapter, d3dFeatureLevel); + if (IsCompatibleAdapter) + { + DXGIAdapters.emplace_back(std::move(pDXIAdapter)); + } + } + + return std::move(DXGIAdapters); + } + + +protected: + static D3D_FEATURE_LEVEL GetD3DFeatureLevel(DIRECT3D_FEATURE_LEVEL FeatureLevel) + { + switch (FeatureLevel) + { + case DIRECT3D_FEATURE_LEVEL_10_0: return D3D_FEATURE_LEVEL_10_0; + case DIRECT3D_FEATURE_LEVEL_10_1: return D3D_FEATURE_LEVEL_10_1; + case DIRECT3D_FEATURE_LEVEL_11_0: return D3D_FEATURE_LEVEL_11_0; + case DIRECT3D_FEATURE_LEVEL_11_1: return D3D_FEATURE_LEVEL_11_1; +#if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT >= _WIN32_WINNT_WIN10) + case DIRECT3D_FEATURE_LEVEL_12_0: return D3D_FEATURE_LEVEL_12_0; + case DIRECT3D_FEATURE_LEVEL_12_1: return D3D_FEATURE_LEVEL_12_1; +#endif + + default: + UNEXPECTED("Unknown DIRECT3D_FEATURE_LEVEL ", static_cast(FeatureLevel)); + return D3D_FEATURE_LEVEL_11_0; + } + } + +private: + template + bool CheckAdapterCompatibility(IDXGIAdapter1* pDXGIAdapter, + D3D_FEATURE_LEVEL FeatureLevels); + + template <> + bool CheckAdapterCompatibility(IDXGIAdapter1* pDXGIAdapter, + D3D_FEATURE_LEVEL FeatureLevel) + { + auto hr = D3D11CreateDevice( + nullptr, + D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device. + 0, + 0, // Flags. + &FeatureLevel, // Feature levels. + 1, // Number of feature levels + D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps. + nullptr, // No need to keep the D3D device reference. + nullptr, // Feature level of the created adapter. + nullptr // No need to keep the D3D device context reference. + ); + return SUCCEEDED(hr); + } + + template <> + bool CheckAdapterCompatibility(IDXGIAdapter1* pDXGIAdapter, + D3D_FEATURE_LEVEL FeatureLevel) + { + auto hr = D3D12CreateDevice(pDXGIAdapter, FeatureLevel, _uuidof(ID3D12Device), nullptr); + return SUCCEEDED(hr); + } +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.h deleted file mode 100644 index a1f0f601..00000000 --- a/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Implementation of the Diligent::RenderDeviceBase template class and related structures - -#include "RenderDeviceBase.h" - -namespace Diligent -{ - -/// Base implementation of a D3D render device - -template -class RenderDeviceD3DBase : public RenderDeviceBase -{ -public: - RenderDeviceD3DBase(IReferenceCounters* pRefCounters, - IMemoryAllocator& RawMemAllocator, - IEngineFactory* pEngineFactory, - Uint32 NumDeferredContexts, - const DeviceObjectSizes& ObjectSizes) : - RenderDeviceBase{pRefCounters, RawMemAllocator, pEngineFactory, NumDeferredContexts, ObjectSizes} - { - // Flag texture formats always supported in D3D11 and D3D12 - - // clang-format off -#define FLAG_FORMAT(Fmt, IsSupported) m_TextureFormatsInfo[Fmt].Supported=IsSupported - - FLAG_FORMAT(TEX_FORMAT_RGBA32_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RGBA32_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA32_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA32_SINT, true); - FLAG_FORMAT(TEX_FORMAT_RGB32_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RGB32_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_RGB32_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RGB32_SINT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA16_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RGBA16_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA16_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_RGBA16_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA16_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_RGBA16_SINT, true); - FLAG_FORMAT(TEX_FORMAT_RG32_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RG32_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_RG32_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RG32_SINT, true); - FLAG_FORMAT(TEX_FORMAT_R32G8X24_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_D32_FLOAT_S8X24_UINT, true); - FLAG_FORMAT(TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_X32_TYPELESS_G8X24_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RGB10A2_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RGB10A2_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_RGB10A2_UINT, true); - FLAG_FORMAT(TEX_FORMAT_R11G11B10_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RGBA8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_RGBA8_UNORM_SRGB, true); - FLAG_FORMAT(TEX_FORMAT_RGBA8_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RGBA8_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_RGBA8_SINT, true); - FLAG_FORMAT(TEX_FORMAT_RG16_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RG16_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_RG16_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_RG16_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RG16_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_RG16_SINT, true); - FLAG_FORMAT(TEX_FORMAT_R32_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_D32_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_R32_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_R32_UINT, true); - FLAG_FORMAT(TEX_FORMAT_R32_SINT, true); - FLAG_FORMAT(TEX_FORMAT_R24G8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_D24_UNORM_S8_UINT, true); - FLAG_FORMAT(TEX_FORMAT_R24_UNORM_X8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_X24_TYPELESS_G8_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RG8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_RG8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_RG8_UINT, true); - FLAG_FORMAT(TEX_FORMAT_RG8_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_RG8_SINT, true); - FLAG_FORMAT(TEX_FORMAT_R16_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_R16_FLOAT, true); - FLAG_FORMAT(TEX_FORMAT_D16_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_R16_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_R16_UINT, true); - FLAG_FORMAT(TEX_FORMAT_R16_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_R16_SINT, true); - FLAG_FORMAT(TEX_FORMAT_R8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_R8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_R8_UINT, true); - FLAG_FORMAT(TEX_FORMAT_R8_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_R8_SINT, true); - FLAG_FORMAT(TEX_FORMAT_A8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_R1_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_RGB9E5_SHAREDEXP, true); - FLAG_FORMAT(TEX_FORMAT_RG8_B8G8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_G8R8_G8B8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC1_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC1_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC1_UNORM_SRGB, true); - FLAG_FORMAT(TEX_FORMAT_BC2_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC2_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC2_UNORM_SRGB, true); - FLAG_FORMAT(TEX_FORMAT_BC3_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC3_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC3_UNORM_SRGB, true); - FLAG_FORMAT(TEX_FORMAT_BC4_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC4_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC4_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC5_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC5_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC5_SNORM, true); - FLAG_FORMAT(TEX_FORMAT_B5G6R5_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_B5G5R5A1_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BGRA8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BGRX8_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BGRA8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BGRA8_UNORM_SRGB, true); - FLAG_FORMAT(TEX_FORMAT_BGRX8_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BGRX8_UNORM_SRGB, true); - FLAG_FORMAT(TEX_FORMAT_BC6H_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC6H_UF16, true); - FLAG_FORMAT(TEX_FORMAT_BC6H_SF16, true); - FLAG_FORMAT(TEX_FORMAT_BC7_TYPELESS, true); - FLAG_FORMAT(TEX_FORMAT_BC7_UNORM, true); - FLAG_FORMAT(TEX_FORMAT_BC7_UNORM_SRGB, true); -#undef FLAG_FORMAT - // clang-format on - - auto& Features = this->m_DeviceCaps.Features; - - Features.SeparablePrograms = True; - Features.IndirectRendering = True; - Features.WireframeFill = True; - Features.MultithreadedResourceCreation = True; - Features.ComputeShaders = True; - Features.GeometryShaders = True; - Features.Tessellation = True; - Features.OcclusionQueries = True; - Features.BinaryOcclusionQueries = True; - Features.TimestampQueries = True; - Features.PipelineStatisticsQueries = True; - Features.DepthBiasClamp = True; - Features.DepthClamp = True; - Features.IndependentBlend = True; - Features.DualSourceBlend = True; - Features.MultiViewport = True; - Features.TextureCompressionBC = True; - Features.PixelUAVWritesAndAtomics = True; - Features.TextureUAVExtendedFormats = True; - } -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.hpp b/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.hpp new file mode 100644 index 00000000..5b11dabc --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.hpp @@ -0,0 +1,182 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of the Diligent::RenderDeviceBase template class and related structures + +#include "RenderDeviceBase.hpp" + +namespace Diligent +{ + +/// Base implementation of a D3D render device + +template +class RenderDeviceD3DBase : public RenderDeviceBase +{ +public: + RenderDeviceD3DBase(IReferenceCounters* pRefCounters, + IMemoryAllocator& RawMemAllocator, + IEngineFactory* pEngineFactory, + Uint32 NumDeferredContexts, + const DeviceObjectSizes& ObjectSizes) : + RenderDeviceBase{pRefCounters, RawMemAllocator, pEngineFactory, NumDeferredContexts, ObjectSizes} + { + // Flag texture formats always supported in D3D11 and D3D12 + + // clang-format off +#define FLAG_FORMAT(Fmt, IsSupported) m_TextureFormatsInfo[Fmt].Supported=IsSupported + + FLAG_FORMAT(TEX_FORMAT_RGBA32_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGBA32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA32_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA32_SINT, true); + FLAG_FORMAT(TEX_FORMAT_RGB32_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGB32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RGB32_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGB32_SINT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGBA16_SINT, true); + FLAG_FORMAT(TEX_FORMAT_RG32_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RG32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RG32_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RG32_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R32G8X24_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_D32_FLOAT_S8X24_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R32_FLOAT_X8X24_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_X32_TYPELESS_G8X24_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGB10A2_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGB10A2_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGB10A2_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R11G11B10_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGBA8_SINT, true); + FLAG_FORMAT(TEX_FORMAT_RG16_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RG16_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_RG16_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RG16_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RG16_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_RG16_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R32_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_D32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_R32_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_R32_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R32_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R24G8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_D24_UNORM_S8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R24_UNORM_X8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_X24_TYPELESS_G8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RG8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_RG8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RG8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_RG8_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_RG8_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R16_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_R16_FLOAT, true); + FLAG_FORMAT(TEX_FORMAT_D16_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R16_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R16_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R16_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_R16_SINT, true); + FLAG_FORMAT(TEX_FORMAT_R8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_R8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R8_UINT, true); + FLAG_FORMAT(TEX_FORMAT_R8_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_R8_SINT, true); + FLAG_FORMAT(TEX_FORMAT_A8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R1_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_RGB9E5_SHAREDEXP, true); + FLAG_FORMAT(TEX_FORMAT_RG8_B8G8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_G8R8_G8B8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC1_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC1_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC1_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BC2_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC2_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC2_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BC3_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC3_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC3_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BC4_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC4_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC4_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC5_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC5_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC5_SNORM, true); + FLAG_FORMAT(TEX_FORMAT_B5G6R5_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_B5G5R5A1_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BGRA8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BGRX8_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BGRA8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BGRA8_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BGRX8_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BGRX8_UNORM_SRGB, true); + FLAG_FORMAT(TEX_FORMAT_BC6H_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC6H_UF16, true); + FLAG_FORMAT(TEX_FORMAT_BC6H_SF16, true); + FLAG_FORMAT(TEX_FORMAT_BC7_TYPELESS, true); + FLAG_FORMAT(TEX_FORMAT_BC7_UNORM, true); + FLAG_FORMAT(TEX_FORMAT_BC7_UNORM_SRGB, true); +#undef FLAG_FORMAT + // clang-format on + + auto& Features = this->m_DeviceCaps.Features; + + Features.SeparablePrograms = True; + Features.IndirectRendering = True; + Features.WireframeFill = True; + Features.MultithreadedResourceCreation = True; + Features.ComputeShaders = True; + Features.GeometryShaders = True; + Features.Tessellation = True; + Features.OcclusionQueries = True; + Features.BinaryOcclusionQueries = True; + Features.TimestampQueries = True; + Features.PipelineStatisticsQueries = True; + Features.DepthBiasClamp = True; + Features.DepthClamp = True; + Features.IndependentBlend = True; + Features.DualSourceBlend = True; + Features.MultiViewport = True; + Features.TextureCompressionBC = True; + Features.PixelUAVWritesAndAtomics = True; + Features.TextureUAVExtendedFormats = True; + } +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.h deleted file mode 100644 index e7b61f59..00000000 --- a/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include - -#include "Shader.h" - -/// \file -/// Base implementation of a D3D shader - -namespace Diligent -{ - -/// Base implementation of a D3D shader -class ShaderD3DBase -{ -public: - ShaderD3DBase(const ShaderCreateInfo& ShaderCI, const char* ShaderModel); - -protected: - CComPtr m_pShaderByteCode; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.hpp b/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.hpp new file mode 100644 index 00000000..e7b61f59 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.hpp @@ -0,0 +1,50 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include + +#include "Shader.h" + +/// \file +/// Base implementation of a D3D shader + +namespace Diligent +{ + +/// Base implementation of a D3D shader +class ShaderD3DBase +{ +public: + ShaderD3DBase(const ShaderCreateInfo& ShaderCI, const char* ShaderModel); + +protected: + CComPtr m_pShaderByteCode; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h deleted file mode 100644 index 343c4177..00000000 --- a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h +++ /dev/null @@ -1,587 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::ShaderResources class -/// See http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resources/ - -// ShaderResources class uses continuous chunk of memory to store all resources, as follows: -// -// -// m_MemoryBuffer m_TexSRVOffset m_TexUAVOffset m_BufSRVOffset m_BufUAVOffset m_SamplersOffset m_MemorySize -// | | | | | | | | -// | CB[0] ... CB[Ncb-1] | TexSRV[0] ... TexSRV[Ntsrv-1] | TexUAV[0] ... TexUAV[Ntuav-1] | BufSRV[0] ... BufSRV[Nbsrv-1] | BufUAV[0] ... BufUAV[Nbuav-1] | Sam[0] ... Sam[Nsam-1] | Resource Names | -// -// Ncb - number of constant buffers -// Ntsrv - number of texture SRVs -// Ntuav - number of texture UAVs -// Nbsrv - number of buffer SRVs -// Nbuav - number of buffer UAVs -// Nsam - number of samplers -// -// -// If texture SRV is assigned a sampler, it is cross-referenced through SamplerOrTexSRVId: -// -// _____________________SamplerOrTexSRVId___________________ -// | | -// | V -// | CBs | ... TexSRV[n] ... | TexUAVs | BufSRVs | BufUAVs | Sam[0] ... Sam[SamplerId] ... | -// A | -// '---------------------SamplerOrTexSRVId-------------------' -// - -#include - -#define NOMINMAX -#include - -#include "ShaderD3D.h" -#include "STDAllocator.h" -#include "HashUtils.h" -#include "StringPool.h" -#include "D3DShaderResourceLoader.h" -#include "PipelineState.h" - -namespace Diligent -{ - -// sizeof(D3DShaderResourceAttribs) == 16 (x64) -struct D3DShaderResourceAttribs -{ - // clang-format off - -/* 0 */ const char* const Name; - -/* 8 */ const Uint16 BindPoint; -/*10 */ const Uint16 BindCount; - -private: - // 4 4 24 - // bit | 0 1 2 3 | 4 5 6 7 | 8 9 10 ... 31 | - // | | | | - // | InputType | SRV Dim | SamplerOrTexSRVIdBits | - static constexpr const Uint32 ShaderInputTypeBits = 4; - static constexpr const Uint32 SRVDimBits = 4; - static constexpr const Uint32 SamplerOrTexSRVIdBits = 24; - static_assert(ShaderInputTypeBits + SRVDimBits + SamplerOrTexSRVIdBits == 32, "Attributes are better be packed into 32 bits"); - - static_assert(D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER < (1 << ShaderInputTypeBits), "Not enough bits to represent D3D_SHADER_INPUT_TYPE"); - static_assert(D3D_SRV_DIMENSION_BUFFEREX < (1 << SRVDimBits), "Not enough bits to represent D3D_SRV_DIMENSION"); - - // We need to use Uint32 instead of the actual type for reliability and correctness. - // There originally was a problem when the type of InputType was D3D_SHADER_INPUT_TYPE: - // the value of D3D_SIT_UAV_RWBYTEADDRESS (8) was interpreted as -8 (as the underlying enum type - // is signed) causing errors -/*12.0*/ const Uint32 InputType : ShaderInputTypeBits; // Max value: D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER == 11 -/*12.4*/ const Uint32 SRVDimension : SRVDimBits; // Max value: D3D_SRV_DIMENSION_BUFFEREX == 11 -/*13.0*/ Uint32 SamplerOrTexSRVId : SamplerOrTexSRVIdBits; // Max value: 2^24-1 -/*16 */ // End of structure - - // clang-format on - -public: - static constexpr const Uint32 InvalidSamplerId = (1 << SamplerOrTexSRVIdBits) - 1; - static constexpr const Uint32 InvalidTexSRVId = (1 << SamplerOrTexSRVIdBits) - 1; - static constexpr const Uint16 InvalidBindPoint = std::numeric_limits::max(); - static constexpr const Uint16 MaxBindPoint = InvalidBindPoint - 1; - static constexpr const Uint16 MaxBindCount = std::numeric_limits::max(); - - - D3DShaderResourceAttribs(const char* _Name, - UINT _BindPoint, - UINT _BindCount, - D3D_SHADER_INPUT_TYPE _InputType, - D3D_SRV_DIMENSION _SRVDimension, - Uint32 _SamplerId) noexcept : - // clang-format off - Name {_Name}, - BindPoint {static_cast (_BindPoint) }, - BindCount {static_cast (_BindCount) }, - InputType {static_cast (_InputType) }, - SRVDimension {static_cast(_SRVDimension)}, - SamplerOrTexSRVId {_SamplerId} - // clang-format on - { -#ifdef _DEBUG - // clang-format off - VERIFY(_BindPoint <= MaxBindPoint || _BindPoint == InvalidBindPoint, "Bind Point is out of allowed range"); - VERIFY(_BindCount <= MaxBindCount, "Bind Count is out of allowed range"); - VERIFY(_InputType < (1 << ShaderInputTypeBits), "Shader input type is out of expected range"); - VERIFY(_SRVDimension < (1 << SRVDimBits), "SRV dimensions is out of expected range"); - VERIFY(_SamplerId < (1 << SamplerOrTexSRVIdBits), "SamplerOrTexSRVId is out of representable range"); - // clang-format on - - if (_InputType == D3D_SIT_TEXTURE && _SRVDimension != D3D_SRV_DIMENSION_BUFFER) - VERIFY_EXPR(GetCombinedSamplerId() == _SamplerId); - else - VERIFY(_SamplerId == InvalidSamplerId, "Only texture SRV can be assigned a valid texture sampler"); -#endif - } - - D3DShaderResourceAttribs(StringPool& NamesPool, const D3DShaderResourceAttribs& rhs, Uint32 SamplerId) noexcept : - // clang-format off - D3DShaderResourceAttribs - { - NamesPool.CopyString(rhs.Name), - rhs.BindPoint, - rhs.BindCount, - rhs.GetInputType(), - rhs.GetSRVDimension(), - SamplerId - } - // clang-format on - { - VERIFY(GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER, "Only texture SRV can be assigned a texture sampler"); - } - - D3DShaderResourceAttribs(StringPool& NamesPool, const D3DShaderResourceAttribs& rhs) noexcept : - // clang-format off - D3DShaderResourceAttribs - { - NamesPool.CopyString(rhs.Name), - rhs.BindPoint, - rhs.BindCount, - rhs.GetInputType(), - rhs.GetSRVDimension(), - rhs.SamplerOrTexSRVId - } - // clang-format on - { - } - - // clang-format off - D3DShaderResourceAttribs (const D3DShaderResourceAttribs& rhs) = delete; - D3DShaderResourceAttribs ( D3DShaderResourceAttribs&& rhs) = default; // Required for vector - D3DShaderResourceAttribs& operator = (const D3DShaderResourceAttribs& rhs) = delete; - D3DShaderResourceAttribs& operator = ( D3DShaderResourceAttribs&& rhs) = delete; - // clang-format on - - D3D_SHADER_INPUT_TYPE GetInputType() const - { - return static_cast(InputType); - } - - D3D_SRV_DIMENSION GetSRVDimension() const - { - return static_cast(SRVDimension); - } - - bool IsCombinedWithSampler() const - { - return GetCombinedSamplerId() != InvalidSamplerId; - } - - bool IsCombinedWithTexSRV() const - { - return GetCombinedTexSRVId() != InvalidTexSRVId; - } - - bool IsValidBindPoint() const - { - return BindPoint != InvalidBindPoint; - } - - String GetPrintName(Uint32 ArrayInd) const - { - VERIFY_EXPR(ArrayInd < BindCount); - if (BindCount > 1) - return String(Name) + '[' + std::to_string(ArrayInd) + ']'; - else - return Name; - } - - bool IsCompatibleWith(const D3DShaderResourceAttribs& Attribs) const - { - return BindPoint == Attribs.BindPoint && - BindCount == Attribs.BindCount && - InputType == Attribs.InputType && - SRVDimension == Attribs.SRVDimension && - SamplerOrTexSRVId == Attribs.SamplerOrTexSRVId; - } - - size_t GetHash() const - { - return ComputeHash(BindPoint, BindCount, InputType, SRVDimension, SamplerOrTexSRVId); - } - - HLSLShaderResourceDesc GetHLSLResourceDesc() const; - -private: - friend class ShaderResources; - - Uint32 GetCombinedSamplerId() const - { - VERIFY(GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER, "Invalid input type: D3D_SIT_TEXTURE is expected"); - return SamplerOrTexSRVId; - } - - void SetTexSRVId(Uint32 TexSRVId) - { - VERIFY(GetInputType() == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected"); - VERIFY(TexSRVId < (1 << SamplerOrTexSRVIdBits), "TexSRVId (", TexSRVId, ") is out of representable range"); - SamplerOrTexSRVId = TexSRVId; - } - - Uint32 GetCombinedTexSRVId() const - { - VERIFY(GetInputType() == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected"); - return SamplerOrTexSRVId; - } -}; -static_assert(sizeof(D3DShaderResourceAttribs) == sizeof(void*) + sizeof(Uint32) * 2, "Unexpected sizeof(D3DShaderResourceAttribs)"); - - -/// Diligent::ShaderResources class -class ShaderResources -{ -public: - ShaderResources(SHADER_TYPE ShaderType) noexcept : - m_ShaderType{ShaderType} - { - } - - // clang-format off - ShaderResources (const ShaderResources&) = delete; - ShaderResources ( ShaderResources&&) = delete; - ShaderResources& operator = (const ShaderResources&) = delete; - ShaderResources& operator = ( ShaderResources&&) = delete; - // clang-format on - - ~ShaderResources(); - - // clang-format off - Uint32 GetNumCBs() const noexcept { return (m_TexSRVOffset - 0); } - Uint32 GetNumTexSRV() const noexcept { return (m_TexUAVOffset - m_TexSRVOffset); } - Uint32 GetNumTexUAV() const noexcept { return (m_BufSRVOffset - m_TexUAVOffset); } - Uint32 GetNumBufSRV() const noexcept { return (m_BufUAVOffset - m_BufSRVOffset); } - Uint32 GetNumBufUAV() const noexcept { return (m_SamplersOffset - m_BufUAVOffset); } - Uint32 GetNumSamplers() const noexcept { return (m_TotalResources - m_SamplersOffset); } - Uint32 GetTotalResources()const noexcept { return m_TotalResources; } - - const D3DShaderResourceAttribs& GetCB (Uint32 n)const noexcept { return GetResAttribs(n, GetNumCBs(), 0); } - const D3DShaderResourceAttribs& GetTexSRV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); } - const D3DShaderResourceAttribs& GetTexUAV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); } - const D3DShaderResourceAttribs& GetBufSRV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); } - const D3DShaderResourceAttribs& GetBufUAV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); } - const D3DShaderResourceAttribs& GetSampler(Uint32 n)const noexcept { return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); } - // clang-format on - - const D3DShaderResourceAttribs& GetCombinedSampler(const D3DShaderResourceAttribs& TexSRV) const noexcept - { - VERIFY(TexSRV.IsCombinedWithSampler(), "This texture SRV is not combined with any sampler"); - return GetSampler(TexSRV.GetCombinedSamplerId()); - } - - const D3DShaderResourceAttribs& GetCombinedTextureSRV(const D3DShaderResourceAttribs& Sampler) const noexcept - { - VERIFY(Sampler.IsCombinedWithTexSRV(), "This sampler is not combined with any texture SRV"); - return GetTexSRV(Sampler.GetCombinedTexSRVId()); - } - - SHADER_TYPE GetShaderType() const noexcept { return m_ShaderType; } - - HLSLShaderResourceDesc GetHLSLShaderResourceDesc(Uint32 Index) const; - - template - void ProcessResources(THandleCB HandleCB, - THandleSampler HandleSampler, - THandleTexSRV HandleTexSRV, - THandleTexUAV HandleTexUAV, - THandleBufSRV HandleBufSRV, - THandleBufUAV HandleBufUAV) const - { - for (Uint32 n = 0; n < GetNumCBs(); ++n) - { - const auto& CB = GetCB(n); - HandleCB(CB, n); - } - - for (Uint32 n = 0; n < GetNumSamplers(); ++n) - { - const auto& Sampler = GetSampler(n); - HandleSampler(Sampler, n); - } - - for (Uint32 n = 0; n < GetNumTexSRV(); ++n) - { - const auto& TexSRV = GetTexSRV(n); - HandleTexSRV(TexSRV, n); - } - - for (Uint32 n = 0; n < GetNumTexUAV(); ++n) - { - const auto& TexUAV = GetTexUAV(n); - HandleTexUAV(TexUAV, n); - } - - for (Uint32 n = 0; n < GetNumBufSRV(); ++n) - { - const auto& BufSRV = GetBufSRV(n); - HandleBufSRV(BufSRV, n); - } - - for (Uint32 n = 0; n < GetNumBufUAV(); ++n) - { - const auto& BufUAV = GetBufUAV(n); - HandleBufUAV(BufUAV, n); - } - } - - bool IsCompatibleWith(const ShaderResources& Resources) const; - bool IsUsingCombinedTextureSamplers() const { return m_SamplerSuffix != nullptr; } - const char* GetCombinedSamplerSuffix() const { return m_SamplerSuffix; } - const Char* GetShaderName() const { return m_ShaderName; } - - size_t GetHash() const; - - SHADER_RESOURCE_VARIABLE_TYPE FindVariableType(const D3DShaderResourceAttribs& ResourceAttribs, - const PipelineResourceLayoutDesc& ResourceLayout) const; - - Int32 FindStaticSampler(const D3DShaderResourceAttribs& ResourceAttribs, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - bool LogStaticSamplerArrayError) const; - - D3DShaderResourceCounters CountResources(const PipelineResourceLayoutDesc& ResourceLayout, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - bool CountStaticSamplers) const noexcept; -#ifdef DEVELOPMENT - static void DvpVerifyResourceLayout(const PipelineResourceLayoutDesc& ResourceLayout, - const ShaderResources* const pShaderResources[], - Uint32 NumShaders); -#endif - - void GetShaderModel(Uint32& Major, Uint32& Minor) const - { - Major = (m_ShaderVersion & 0x000000F0) >> 4; - Minor = (m_ShaderVersion & 0x0000000F); - } - -protected: - template - void Initialize(ID3DBlob* pShaderByteCode, - TNewResourceHandler NewResHandler, - const Char* ShaderName, - const Char* SamplerSuffix); - - - __forceinline D3DShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset) noexcept - { - VERIFY(n < NumResources, "Resource index (", n, ") is out of range. Resource array size: ", NumResources); - VERIFY_EXPR(Offset + n < m_TotalResources); - return reinterpret_cast(m_MemoryBuffer.get())[Offset + n]; - } - - __forceinline const D3DShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset) const noexcept - { - VERIFY(n < NumResources, "Resource index (", n, ") is out of range. Resource array size: ", NumResources); - VERIFY_EXPR(Offset + n < m_TotalResources); - return reinterpret_cast(m_MemoryBuffer.get())[Offset + n]; - } - - // clang-format off - D3DShaderResourceAttribs& GetCB(Uint32 n) noexcept { return GetResAttribs(n, GetNumCBs(), 0); } - D3DShaderResourceAttribs& GetTexSRV(Uint32 n) noexcept { return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); } - D3DShaderResourceAttribs& GetTexUAV(Uint32 n) noexcept { return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); } - D3DShaderResourceAttribs& GetBufSRV(Uint32 n) noexcept { return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); } - D3DShaderResourceAttribs& GetBufUAV(Uint32 n) noexcept { return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); } - D3DShaderResourceAttribs& GetSampler(Uint32 n) noexcept { return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); } - // clang-format on - -private: - void AllocateMemory(IMemoryAllocator& Allocator, - const D3DShaderResourceCounters& ResCounters, - size_t ResourceNamesPoolSize); - - Uint32 FindAssignedSamplerId(const D3DShaderResourceAttribs& TexSRV, const char* SamplerSuffix) const; - - // Memory buffer that holds all resources as continuous chunk of memory: - // | CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | Resource Names | - // - - std::unique_ptr> m_MemoryBuffer; - - StringPool m_ResourceNames; - const char* m_SamplerSuffix = nullptr; // The suffix and the shader name - const char* m_ShaderName = nullptr; // are put into the m_ResourceNames - - // Offsets in elements of D3DShaderResourceAttribs - typedef Uint16 OffsetType; - OffsetType m_TexSRVOffset = 0; - OffsetType m_TexUAVOffset = 0; - OffsetType m_BufSRVOffset = 0; - OffsetType m_BufUAVOffset = 0; - OffsetType m_SamplersOffset = 0; - OffsetType m_TotalResources = 0; - - const SHADER_TYPE m_ShaderType; - - Uint32 m_ShaderVersion = 0; -}; - - -template -void ShaderResources::Initialize(ID3DBlob* pShaderByteCode, - TNewResourceHandler NewResHandler, - const Char* ShaderName, - const Char* CombinedSamplerSuffix) -{ - Uint32 CurrCB = 0, CurrTexSRV = 0, CurrTexUAV = 0, CurrBufSRV = 0, CurrBufUAV = 0, CurrSampler = 0; - LoadD3DShaderResources( - pShaderByteCode, - - [&](const D3D_SHADER_DESC& d3dShaderDesc) // - { - m_ShaderVersion = d3dShaderDesc.Version; - }, - - [&](const D3DShaderResourceCounters& ResCounters, size_t ResourceNamesPoolSize) // - { - VERIFY_EXPR(ShaderName != nullptr); - ResourceNamesPoolSize += strlen(ShaderName) + 1; - - if (CombinedSamplerSuffix != nullptr) - ResourceNamesPoolSize += strlen(CombinedSamplerSuffix) + 1; - - AllocateMemory(GetRawAllocator(), ResCounters, ResourceNamesPoolSize); - }, - - [&](const D3DShaderResourceAttribs& CBAttribs) // - { - VERIFY_EXPR(CBAttribs.GetInputType() == D3D_SIT_CBUFFER); - auto* pNewCB = new (&GetCB(CurrCB++)) D3DShaderResourceAttribs(m_ResourceNames, CBAttribs); - NewResHandler.OnNewCB(*pNewCB); - }, - - [&](const D3DShaderResourceAttribs& TexUAV) // - { - VERIFY_EXPR(TexUAV.GetInputType() == D3D_SIT_UAV_RWTYPED && TexUAV.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER); - auto* pNewTexUAV = new (&GetTexUAV(CurrTexUAV++)) D3DShaderResourceAttribs(m_ResourceNames, TexUAV); - NewResHandler.OnNewTexUAV(*pNewTexUAV); - }, - - [&](const D3DShaderResourceAttribs& BuffUAV) // - { - VERIFY_EXPR(BuffUAV.GetInputType() == D3D_SIT_UAV_RWTYPED && BuffUAV.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER || BuffUAV.GetInputType() == D3D_SIT_UAV_RWSTRUCTURED || BuffUAV.GetInputType() == D3D_SIT_UAV_RWBYTEADDRESS); - auto* pNewBufUAV = new (&GetBufUAV(CurrBufUAV++)) D3DShaderResourceAttribs(m_ResourceNames, BuffUAV); - NewResHandler.OnNewBuffUAV(*pNewBufUAV); - }, - - [&](const D3DShaderResourceAttribs& BuffSRV) // - { - VERIFY_EXPR(BuffSRV.GetInputType() == D3D_SIT_TEXTURE && BuffSRV.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER || BuffSRV.GetInputType() == D3D_SIT_STRUCTURED || BuffSRV.GetInputType() == D3D_SIT_BYTEADDRESS); - auto* pNewBuffSRV = new (&GetBufSRV(CurrBufSRV++)) D3DShaderResourceAttribs(m_ResourceNames, BuffSRV); - NewResHandler.OnNewBuffSRV(*pNewBuffSRV); - }, - - [&](const D3DShaderResourceAttribs& SamplerAttribs) // - { - VERIFY_EXPR(SamplerAttribs.GetInputType() == D3D_SIT_SAMPLER); - auto* pNewSampler = new (&GetSampler(CurrSampler++)) D3DShaderResourceAttribs(m_ResourceNames, SamplerAttribs); - NewResHandler.OnNewSampler(*pNewSampler); - }, - - [&](const D3DShaderResourceAttribs& TexAttribs) // - { - VERIFY_EXPR(TexAttribs.GetInputType() == D3D_SIT_TEXTURE && TexAttribs.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER); - VERIFY(CurrSampler == GetNumSamplers(), "All samplers must be initialized before texture SRVs"); - - auto SamplerId = CombinedSamplerSuffix != nullptr ? FindAssignedSamplerId(TexAttribs, CombinedSamplerSuffix) : D3DShaderResourceAttribs::InvalidSamplerId; - auto* pNewTexSRV = new (&GetTexSRV(CurrTexSRV)) D3DShaderResourceAttribs(m_ResourceNames, TexAttribs, SamplerId); - if (SamplerId != D3DShaderResourceAttribs::InvalidSamplerId) - { - GetSampler(SamplerId).SetTexSRVId(CurrTexSRV); - } - ++CurrTexSRV; - NewResHandler.OnNewTexSRV(*pNewTexSRV); - } // - ); - - m_ShaderName = m_ResourceNames.CopyString(ShaderName); - - if (CombinedSamplerSuffix != nullptr) - { - m_SamplerSuffix = m_ResourceNames.CopyString(CombinedSamplerSuffix); - -#ifdef DEVELOPMENT - for (Uint32 n = 0; n < GetNumSamplers(); ++n) - { - const auto& Sampler = GetSampler(n); - if (!Sampler.IsCombinedWithTexSRV()) - LOG_ERROR_MESSAGE("Shader '", ShaderName, "' uses combined texture samplers, but sampler '", Sampler.Name, "' is not assigned to any texture"); - } -#endif - } - - VERIFY_EXPR(m_ResourceNames.GetRemainingSize() == 0); - // clang-format off - VERIFY(CurrCB == GetNumCBs(), "Not all CBs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called"); - VERIFY(CurrTexSRV == GetNumTexSRV(), "Not all Tex SRVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); - VERIFY(CurrTexUAV == GetNumTexUAV(), "Not all Tex UAVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); - VERIFY(CurrBufSRV == GetNumBufSRV(), "Not all Buf SRVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); - VERIFY(CurrBufUAV == GetNumBufUAV(), "Not all Buf UAVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); - VERIFY(CurrSampler == GetNumSamplers(), "Not all Samplers are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); - // clang-format on -} - -} // namespace Diligent - -namespace std -{ - -template <> -struct hash -{ - size_t operator()(const Diligent::D3DShaderResourceAttribs& Attribs) const - { - return Attribs.GetHash(); - } -}; - -template <> -struct hash -{ - size_t operator()(const Diligent::ShaderResources& Res) const - { - return Res.GetHash(); - } -}; - -} // namespace std diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp new file mode 100644 index 00000000..a2ed64dd --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp @@ -0,0 +1,587 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResources class +/// See http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resources/ + +// ShaderResources class uses continuous chunk of memory to store all resources, as follows: +// +// +// m_MemoryBuffer m_TexSRVOffset m_TexUAVOffset m_BufSRVOffset m_BufUAVOffset m_SamplersOffset m_MemorySize +// | | | | | | | | +// | CB[0] ... CB[Ncb-1] | TexSRV[0] ... TexSRV[Ntsrv-1] | TexUAV[0] ... TexUAV[Ntuav-1] | BufSRV[0] ... BufSRV[Nbsrv-1] | BufUAV[0] ... BufUAV[Nbuav-1] | Sam[0] ... Sam[Nsam-1] | Resource Names | +// +// Ncb - number of constant buffers +// Ntsrv - number of texture SRVs +// Ntuav - number of texture UAVs +// Nbsrv - number of buffer SRVs +// Nbuav - number of buffer UAVs +// Nsam - number of samplers +// +// +// If texture SRV is assigned a sampler, it is cross-referenced through SamplerOrTexSRVId: +// +// _____________________SamplerOrTexSRVId___________________ +// | | +// | V +// | CBs | ... TexSRV[n] ... | TexUAVs | BufSRVs | BufUAVs | Sam[0] ... Sam[SamplerId] ... | +// A | +// '---------------------SamplerOrTexSRVId-------------------' +// + +#include + +#define NOMINMAX +#include + +#include "ShaderD3D.h" +#include "STDAllocator.h" +#include "HashUtils.h" +#include "StringPool.h" +#include "D3DShaderResourceLoader.hpp" +#include "PipelineState.h" + +namespace Diligent +{ + +// sizeof(D3DShaderResourceAttribs) == 16 (x64) +struct D3DShaderResourceAttribs +{ + // clang-format off + +/* 0 */ const char* const Name; + +/* 8 */ const Uint16 BindPoint; +/*10 */ const Uint16 BindCount; + +private: + // 4 4 24 + // bit | 0 1 2 3 | 4 5 6 7 | 8 9 10 ... 31 | + // | | | | + // | InputType | SRV Dim | SamplerOrTexSRVIdBits | + static constexpr const Uint32 ShaderInputTypeBits = 4; + static constexpr const Uint32 SRVDimBits = 4; + static constexpr const Uint32 SamplerOrTexSRVIdBits = 24; + static_assert(ShaderInputTypeBits + SRVDimBits + SamplerOrTexSRVIdBits == 32, "Attributes are better be packed into 32 bits"); + + static_assert(D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER < (1 << ShaderInputTypeBits), "Not enough bits to represent D3D_SHADER_INPUT_TYPE"); + static_assert(D3D_SRV_DIMENSION_BUFFEREX < (1 << SRVDimBits), "Not enough bits to represent D3D_SRV_DIMENSION"); + + // We need to use Uint32 instead of the actual type for reliability and correctness. + // There originally was a problem when the type of InputType was D3D_SHADER_INPUT_TYPE: + // the value of D3D_SIT_UAV_RWBYTEADDRESS (8) was interpreted as -8 (as the underlying enum type + // is signed) causing errors +/*12.0*/ const Uint32 InputType : ShaderInputTypeBits; // Max value: D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER == 11 +/*12.4*/ const Uint32 SRVDimension : SRVDimBits; // Max value: D3D_SRV_DIMENSION_BUFFEREX == 11 +/*13.0*/ Uint32 SamplerOrTexSRVId : SamplerOrTexSRVIdBits; // Max value: 2^24-1 +/*16 */ // End of structure + + // clang-format on + +public: + static constexpr const Uint32 InvalidSamplerId = (1 << SamplerOrTexSRVIdBits) - 1; + static constexpr const Uint32 InvalidTexSRVId = (1 << SamplerOrTexSRVIdBits) - 1; + static constexpr const Uint16 InvalidBindPoint = std::numeric_limits::max(); + static constexpr const Uint16 MaxBindPoint = InvalidBindPoint - 1; + static constexpr const Uint16 MaxBindCount = std::numeric_limits::max(); + + + D3DShaderResourceAttribs(const char* _Name, + UINT _BindPoint, + UINT _BindCount, + D3D_SHADER_INPUT_TYPE _InputType, + D3D_SRV_DIMENSION _SRVDimension, + Uint32 _SamplerId) noexcept : + // clang-format off + Name {_Name}, + BindPoint {static_cast (_BindPoint) }, + BindCount {static_cast (_BindCount) }, + InputType {static_cast (_InputType) }, + SRVDimension {static_cast(_SRVDimension)}, + SamplerOrTexSRVId {_SamplerId} + // clang-format on + { +#ifdef _DEBUG + // clang-format off + VERIFY(_BindPoint <= MaxBindPoint || _BindPoint == InvalidBindPoint, "Bind Point is out of allowed range"); + VERIFY(_BindCount <= MaxBindCount, "Bind Count is out of allowed range"); + VERIFY(_InputType < (1 << ShaderInputTypeBits), "Shader input type is out of expected range"); + VERIFY(_SRVDimension < (1 << SRVDimBits), "SRV dimensions is out of expected range"); + VERIFY(_SamplerId < (1 << SamplerOrTexSRVIdBits), "SamplerOrTexSRVId is out of representable range"); + // clang-format on + + if (_InputType == D3D_SIT_TEXTURE && _SRVDimension != D3D_SRV_DIMENSION_BUFFER) + VERIFY_EXPR(GetCombinedSamplerId() == _SamplerId); + else + VERIFY(_SamplerId == InvalidSamplerId, "Only texture SRV can be assigned a valid texture sampler"); +#endif + } + + D3DShaderResourceAttribs(StringPool& NamesPool, const D3DShaderResourceAttribs& rhs, Uint32 SamplerId) noexcept : + // clang-format off + D3DShaderResourceAttribs + { + NamesPool.CopyString(rhs.Name), + rhs.BindPoint, + rhs.BindCount, + rhs.GetInputType(), + rhs.GetSRVDimension(), + SamplerId + } + // clang-format on + { + VERIFY(GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER, "Only texture SRV can be assigned a texture sampler"); + } + + D3DShaderResourceAttribs(StringPool& NamesPool, const D3DShaderResourceAttribs& rhs) noexcept : + // clang-format off + D3DShaderResourceAttribs + { + NamesPool.CopyString(rhs.Name), + rhs.BindPoint, + rhs.BindCount, + rhs.GetInputType(), + rhs.GetSRVDimension(), + rhs.SamplerOrTexSRVId + } + // clang-format on + { + } + + // clang-format off + D3DShaderResourceAttribs (const D3DShaderResourceAttribs& rhs) = delete; + D3DShaderResourceAttribs ( D3DShaderResourceAttribs&& rhs) = default; // Required for vector + D3DShaderResourceAttribs& operator = (const D3DShaderResourceAttribs& rhs) = delete; + D3DShaderResourceAttribs& operator = ( D3DShaderResourceAttribs&& rhs) = delete; + // clang-format on + + D3D_SHADER_INPUT_TYPE GetInputType() const + { + return static_cast(InputType); + } + + D3D_SRV_DIMENSION GetSRVDimension() const + { + return static_cast(SRVDimension); + } + + bool IsCombinedWithSampler() const + { + return GetCombinedSamplerId() != InvalidSamplerId; + } + + bool IsCombinedWithTexSRV() const + { + return GetCombinedTexSRVId() != InvalidTexSRVId; + } + + bool IsValidBindPoint() const + { + return BindPoint != InvalidBindPoint; + } + + String GetPrintName(Uint32 ArrayInd) const + { + VERIFY_EXPR(ArrayInd < BindCount); + if (BindCount > 1) + return String(Name) + '[' + std::to_string(ArrayInd) + ']'; + else + return Name; + } + + bool IsCompatibleWith(const D3DShaderResourceAttribs& Attribs) const + { + return BindPoint == Attribs.BindPoint && + BindCount == Attribs.BindCount && + InputType == Attribs.InputType && + SRVDimension == Attribs.SRVDimension && + SamplerOrTexSRVId == Attribs.SamplerOrTexSRVId; + } + + size_t GetHash() const + { + return ComputeHash(BindPoint, BindCount, InputType, SRVDimension, SamplerOrTexSRVId); + } + + HLSLShaderResourceDesc GetHLSLResourceDesc() const; + +private: + friend class ShaderResources; + + Uint32 GetCombinedSamplerId() const + { + VERIFY(GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER, "Invalid input type: D3D_SIT_TEXTURE is expected"); + return SamplerOrTexSRVId; + } + + void SetTexSRVId(Uint32 TexSRVId) + { + VERIFY(GetInputType() == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected"); + VERIFY(TexSRVId < (1 << SamplerOrTexSRVIdBits), "TexSRVId (", TexSRVId, ") is out of representable range"); + SamplerOrTexSRVId = TexSRVId; + } + + Uint32 GetCombinedTexSRVId() const + { + VERIFY(GetInputType() == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected"); + return SamplerOrTexSRVId; + } +}; +static_assert(sizeof(D3DShaderResourceAttribs) == sizeof(void*) + sizeof(Uint32) * 2, "Unexpected sizeof(D3DShaderResourceAttribs)"); + + +/// Diligent::ShaderResources class +class ShaderResources +{ +public: + ShaderResources(SHADER_TYPE ShaderType) noexcept : + m_ShaderType{ShaderType} + { + } + + // clang-format off + ShaderResources (const ShaderResources&) = delete; + ShaderResources ( ShaderResources&&) = delete; + ShaderResources& operator = (const ShaderResources&) = delete; + ShaderResources& operator = ( ShaderResources&&) = delete; + // clang-format on + + ~ShaderResources(); + + // clang-format off + Uint32 GetNumCBs() const noexcept { return (m_TexSRVOffset - 0); } + Uint32 GetNumTexSRV() const noexcept { return (m_TexUAVOffset - m_TexSRVOffset); } + Uint32 GetNumTexUAV() const noexcept { return (m_BufSRVOffset - m_TexUAVOffset); } + Uint32 GetNumBufSRV() const noexcept { return (m_BufUAVOffset - m_BufSRVOffset); } + Uint32 GetNumBufUAV() const noexcept { return (m_SamplersOffset - m_BufUAVOffset); } + Uint32 GetNumSamplers() const noexcept { return (m_TotalResources - m_SamplersOffset); } + Uint32 GetTotalResources()const noexcept { return m_TotalResources; } + + const D3DShaderResourceAttribs& GetCB (Uint32 n)const noexcept { return GetResAttribs(n, GetNumCBs(), 0); } + const D3DShaderResourceAttribs& GetTexSRV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); } + const D3DShaderResourceAttribs& GetTexUAV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); } + const D3DShaderResourceAttribs& GetBufSRV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); } + const D3DShaderResourceAttribs& GetBufUAV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); } + const D3DShaderResourceAttribs& GetSampler(Uint32 n)const noexcept { return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); } + // clang-format on + + const D3DShaderResourceAttribs& GetCombinedSampler(const D3DShaderResourceAttribs& TexSRV) const noexcept + { + VERIFY(TexSRV.IsCombinedWithSampler(), "This texture SRV is not combined with any sampler"); + return GetSampler(TexSRV.GetCombinedSamplerId()); + } + + const D3DShaderResourceAttribs& GetCombinedTextureSRV(const D3DShaderResourceAttribs& Sampler) const noexcept + { + VERIFY(Sampler.IsCombinedWithTexSRV(), "This sampler is not combined with any texture SRV"); + return GetTexSRV(Sampler.GetCombinedTexSRVId()); + } + + SHADER_TYPE GetShaderType() const noexcept { return m_ShaderType; } + + HLSLShaderResourceDesc GetHLSLShaderResourceDesc(Uint32 Index) const; + + template + void ProcessResources(THandleCB HandleCB, + THandleSampler HandleSampler, + THandleTexSRV HandleTexSRV, + THandleTexUAV HandleTexUAV, + THandleBufSRV HandleBufSRV, + THandleBufUAV HandleBufUAV) const + { + for (Uint32 n = 0; n < GetNumCBs(); ++n) + { + const auto& CB = GetCB(n); + HandleCB(CB, n); + } + + for (Uint32 n = 0; n < GetNumSamplers(); ++n) + { + const auto& Sampler = GetSampler(n); + HandleSampler(Sampler, n); + } + + for (Uint32 n = 0; n < GetNumTexSRV(); ++n) + { + const auto& TexSRV = GetTexSRV(n); + HandleTexSRV(TexSRV, n); + } + + for (Uint32 n = 0; n < GetNumTexUAV(); ++n) + { + const auto& TexUAV = GetTexUAV(n); + HandleTexUAV(TexUAV, n); + } + + for (Uint32 n = 0; n < GetNumBufSRV(); ++n) + { + const auto& BufSRV = GetBufSRV(n); + HandleBufSRV(BufSRV, n); + } + + for (Uint32 n = 0; n < GetNumBufUAV(); ++n) + { + const auto& BufUAV = GetBufUAV(n); + HandleBufUAV(BufUAV, n); + } + } + + bool IsCompatibleWith(const ShaderResources& Resources) const; + bool IsUsingCombinedTextureSamplers() const { return m_SamplerSuffix != nullptr; } + const char* GetCombinedSamplerSuffix() const { return m_SamplerSuffix; } + const Char* GetShaderName() const { return m_ShaderName; } + + size_t GetHash() const; + + SHADER_RESOURCE_VARIABLE_TYPE FindVariableType(const D3DShaderResourceAttribs& ResourceAttribs, + const PipelineResourceLayoutDesc& ResourceLayout) const; + + Int32 FindStaticSampler(const D3DShaderResourceAttribs& ResourceAttribs, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + bool LogStaticSamplerArrayError) const; + + D3DShaderResourceCounters CountResources(const PipelineResourceLayoutDesc& ResourceLayout, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + bool CountStaticSamplers) const noexcept; +#ifdef DEVELOPMENT + static void DvpVerifyResourceLayout(const PipelineResourceLayoutDesc& ResourceLayout, + const ShaderResources* const pShaderResources[], + Uint32 NumShaders); +#endif + + void GetShaderModel(Uint32& Major, Uint32& Minor) const + { + Major = (m_ShaderVersion & 0x000000F0) >> 4; + Minor = (m_ShaderVersion & 0x0000000F); + } + +protected: + template + void Initialize(ID3DBlob* pShaderByteCode, + TNewResourceHandler NewResHandler, + const Char* ShaderName, + const Char* SamplerSuffix); + + + __forceinline D3DShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset) noexcept + { + VERIFY(n < NumResources, "Resource index (", n, ") is out of range. Resource array size: ", NumResources); + VERIFY_EXPR(Offset + n < m_TotalResources); + return reinterpret_cast(m_MemoryBuffer.get())[Offset + n]; + } + + __forceinline const D3DShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset) const noexcept + { + VERIFY(n < NumResources, "Resource index (", n, ") is out of range. Resource array size: ", NumResources); + VERIFY_EXPR(Offset + n < m_TotalResources); + return reinterpret_cast(m_MemoryBuffer.get())[Offset + n]; + } + + // clang-format off + D3DShaderResourceAttribs& GetCB(Uint32 n) noexcept { return GetResAttribs(n, GetNumCBs(), 0); } + D3DShaderResourceAttribs& GetTexSRV(Uint32 n) noexcept { return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); } + D3DShaderResourceAttribs& GetTexUAV(Uint32 n) noexcept { return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); } + D3DShaderResourceAttribs& GetBufSRV(Uint32 n) noexcept { return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); } + D3DShaderResourceAttribs& GetBufUAV(Uint32 n) noexcept { return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); } + D3DShaderResourceAttribs& GetSampler(Uint32 n) noexcept { return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); } + // clang-format on + +private: + void AllocateMemory(IMemoryAllocator& Allocator, + const D3DShaderResourceCounters& ResCounters, + size_t ResourceNamesPoolSize); + + Uint32 FindAssignedSamplerId(const D3DShaderResourceAttribs& TexSRV, const char* SamplerSuffix) const; + + // Memory buffer that holds all resources as continuous chunk of memory: + // | CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | Resource Names | + // + + std::unique_ptr> m_MemoryBuffer; + + StringPool m_ResourceNames; + const char* m_SamplerSuffix = nullptr; // The suffix and the shader name + const char* m_ShaderName = nullptr; // are put into the m_ResourceNames + + // Offsets in elements of D3DShaderResourceAttribs + typedef Uint16 OffsetType; + OffsetType m_TexSRVOffset = 0; + OffsetType m_TexUAVOffset = 0; + OffsetType m_BufSRVOffset = 0; + OffsetType m_BufUAVOffset = 0; + OffsetType m_SamplersOffset = 0; + OffsetType m_TotalResources = 0; + + const SHADER_TYPE m_ShaderType; + + Uint32 m_ShaderVersion = 0; +}; + + +template +void ShaderResources::Initialize(ID3DBlob* pShaderByteCode, + TNewResourceHandler NewResHandler, + const Char* ShaderName, + const Char* CombinedSamplerSuffix) +{ + Uint32 CurrCB = 0, CurrTexSRV = 0, CurrTexUAV = 0, CurrBufSRV = 0, CurrBufUAV = 0, CurrSampler = 0; + LoadD3DShaderResources( + pShaderByteCode, + + [&](const D3D_SHADER_DESC& d3dShaderDesc) // + { + m_ShaderVersion = d3dShaderDesc.Version; + }, + + [&](const D3DShaderResourceCounters& ResCounters, size_t ResourceNamesPoolSize) // + { + VERIFY_EXPR(ShaderName != nullptr); + ResourceNamesPoolSize += strlen(ShaderName) + 1; + + if (CombinedSamplerSuffix != nullptr) + ResourceNamesPoolSize += strlen(CombinedSamplerSuffix) + 1; + + AllocateMemory(GetRawAllocator(), ResCounters, ResourceNamesPoolSize); + }, + + [&](const D3DShaderResourceAttribs& CBAttribs) // + { + VERIFY_EXPR(CBAttribs.GetInputType() == D3D_SIT_CBUFFER); + auto* pNewCB = new (&GetCB(CurrCB++)) D3DShaderResourceAttribs(m_ResourceNames, CBAttribs); + NewResHandler.OnNewCB(*pNewCB); + }, + + [&](const D3DShaderResourceAttribs& TexUAV) // + { + VERIFY_EXPR(TexUAV.GetInputType() == D3D_SIT_UAV_RWTYPED && TexUAV.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER); + auto* pNewTexUAV = new (&GetTexUAV(CurrTexUAV++)) D3DShaderResourceAttribs(m_ResourceNames, TexUAV); + NewResHandler.OnNewTexUAV(*pNewTexUAV); + }, + + [&](const D3DShaderResourceAttribs& BuffUAV) // + { + VERIFY_EXPR(BuffUAV.GetInputType() == D3D_SIT_UAV_RWTYPED && BuffUAV.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER || BuffUAV.GetInputType() == D3D_SIT_UAV_RWSTRUCTURED || BuffUAV.GetInputType() == D3D_SIT_UAV_RWBYTEADDRESS); + auto* pNewBufUAV = new (&GetBufUAV(CurrBufUAV++)) D3DShaderResourceAttribs(m_ResourceNames, BuffUAV); + NewResHandler.OnNewBuffUAV(*pNewBufUAV); + }, + + [&](const D3DShaderResourceAttribs& BuffSRV) // + { + VERIFY_EXPR(BuffSRV.GetInputType() == D3D_SIT_TEXTURE && BuffSRV.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER || BuffSRV.GetInputType() == D3D_SIT_STRUCTURED || BuffSRV.GetInputType() == D3D_SIT_BYTEADDRESS); + auto* pNewBuffSRV = new (&GetBufSRV(CurrBufSRV++)) D3DShaderResourceAttribs(m_ResourceNames, BuffSRV); + NewResHandler.OnNewBuffSRV(*pNewBuffSRV); + }, + + [&](const D3DShaderResourceAttribs& SamplerAttribs) // + { + VERIFY_EXPR(SamplerAttribs.GetInputType() == D3D_SIT_SAMPLER); + auto* pNewSampler = new (&GetSampler(CurrSampler++)) D3DShaderResourceAttribs(m_ResourceNames, SamplerAttribs); + NewResHandler.OnNewSampler(*pNewSampler); + }, + + [&](const D3DShaderResourceAttribs& TexAttribs) // + { + VERIFY_EXPR(TexAttribs.GetInputType() == D3D_SIT_TEXTURE && TexAttribs.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER); + VERIFY(CurrSampler == GetNumSamplers(), "All samplers must be initialized before texture SRVs"); + + auto SamplerId = CombinedSamplerSuffix != nullptr ? FindAssignedSamplerId(TexAttribs, CombinedSamplerSuffix) : D3DShaderResourceAttribs::InvalidSamplerId; + auto* pNewTexSRV = new (&GetTexSRV(CurrTexSRV)) D3DShaderResourceAttribs(m_ResourceNames, TexAttribs, SamplerId); + if (SamplerId != D3DShaderResourceAttribs::InvalidSamplerId) + { + GetSampler(SamplerId).SetTexSRVId(CurrTexSRV); + } + ++CurrTexSRV; + NewResHandler.OnNewTexSRV(*pNewTexSRV); + } // + ); + + m_ShaderName = m_ResourceNames.CopyString(ShaderName); + + if (CombinedSamplerSuffix != nullptr) + { + m_SamplerSuffix = m_ResourceNames.CopyString(CombinedSamplerSuffix); + +#ifdef DEVELOPMENT + for (Uint32 n = 0; n < GetNumSamplers(); ++n) + { + const auto& Sampler = GetSampler(n); + if (!Sampler.IsCombinedWithTexSRV()) + LOG_ERROR_MESSAGE("Shader '", ShaderName, "' uses combined texture samplers, but sampler '", Sampler.Name, "' is not assigned to any texture"); + } +#endif + } + + VERIFY_EXPR(m_ResourceNames.GetRemainingSize() == 0); + // clang-format off + VERIFY(CurrCB == GetNumCBs(), "Not all CBs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called"); + VERIFY(CurrTexSRV == GetNumTexSRV(), "Not all Tex SRVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrTexUAV == GetNumTexUAV(), "Not all Tex UAVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrBufSRV == GetNumBufSRV(), "Not all Buf SRVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrBufUAV == GetNumBufUAV(), "Not all Buf UAVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); + VERIFY(CurrSampler == GetNumSamplers(), "Not all Samplers are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" ); + // clang-format on +} + +} // namespace Diligent + +namespace std +{ + +template <> +struct hash +{ + size_t operator()(const Diligent::D3DShaderResourceAttribs& Attribs) const + { + return Attribs.GetHash(); + } +}; + +template <> +struct hash +{ + size_t operator()(const Diligent::ShaderResources& Res) const + { + return Res.GetHash(); + } +}; + +} // namespace std diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.h deleted file mode 100644 index 3c566b20..00000000 --- a/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include "ShaderResourceVariableBase.h" -#include "ShaderResourceVariableD3D.h" - -/// \file -/// Declaration of Diligent::ShaderVariableD3DBase class - -namespace Diligent -{ - -struct D3DVariableIDComparator -{ - bool operator()(const INTERFACE_ID& IID) const - { - return IID == IID_ShaderResourceVariableD3D || IID == IID_ShaderResourceVariable || IID == IID_Unknown; - } -}; - -template -struct ShaderVariableD3DBase : public ShaderVariableBase -{ - using TBase = ShaderVariableBase; - - ShaderVariableD3DBase(TShaderResourceLayout& ParentResLayout, - const D3DShaderResourceAttribs& Attribs, - SHADER_RESOURCE_VARIABLE_TYPE VariableType) : - // clang-format off - TBase {ParentResLayout}, - m_Attribs {Attribs }, - m_VariableType {VariableType } - // clang-format on - { - } - - virtual SHADER_RESOURCE_VARIABLE_TYPE GetType() const override final - { - return m_VariableType; - } - - virtual void GetResourceDesc(ShaderResourceDesc& ResourceDesc) const override final - { - ResourceDesc = GetHLSLResourceDesc(); - } - - virtual HLSLShaderResourceDesc GetHLSLResourceDesc() const override final - { - return m_Attribs.GetHLSLResourceDesc(); - } - - virtual Uint32 GetIndex() const override final - { - return m_ParentResLayout.GetVariableIndex(*this); - } - - const D3DShaderResourceAttribs& m_Attribs; - -protected: - const SHADER_RESOURCE_VARIABLE_TYPE m_VariableType; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.hpp b/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.hpp new file mode 100644 index 00000000..c89610f9 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderVariableD3DBase.hpp @@ -0,0 +1,89 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "ShaderResourceVariableBase.hpp" +#include "ShaderResourceVariableD3D.h" + +/// \file +/// Declaration of Diligent::ShaderVariableD3DBase class + +namespace Diligent +{ + +struct D3DVariableIDComparator +{ + bool operator()(const INTERFACE_ID& IID) const + { + return IID == IID_ShaderResourceVariableD3D || IID == IID_ShaderResourceVariable || IID == IID_Unknown; + } +}; + +template +struct ShaderVariableD3DBase : public ShaderVariableBase +{ + using TBase = ShaderVariableBase; + + ShaderVariableD3DBase(TShaderResourceLayout& ParentResLayout, + const D3DShaderResourceAttribs& Attribs, + SHADER_RESOURCE_VARIABLE_TYPE VariableType) : + // clang-format off + TBase {ParentResLayout}, + m_Attribs {Attribs }, + m_VariableType {VariableType } + // clang-format on + { + } + + virtual SHADER_RESOURCE_VARIABLE_TYPE GetType() const override final + { + return m_VariableType; + } + + virtual void GetResourceDesc(ShaderResourceDesc& ResourceDesc) const override final + { + ResourceDesc = GetHLSLResourceDesc(); + } + + virtual HLSLShaderResourceDesc GetHLSLResourceDesc() const override final + { + return m_Attribs.GetHLSLResourceDesc(); + } + + virtual Uint32 GetIndex() const override final + { + return m_ParentResLayout.GetVariableIndex(*this); + } + + const D3DShaderResourceAttribs& m_Attribs; + +protected: + const SHADER_RESOURCE_VARIABLE_TYPE m_VariableType; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/SwapChainD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/SwapChainD3DBase.h deleted file mode 100644 index a3b091d2..00000000 --- a/Graphics/GraphicsEngineD3DBase/include/SwapChainD3DBase.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include "SwapChainBase.h" - -/// \file -/// Base implementation of a D3D swap chain - -namespace Diligent -{ - -/// Base implementation of a D3D swap chain -template -class SwapChainD3DBase : public SwapChainBase -{ -public: - using TBase = SwapChainBase; - SwapChainD3DBase(IReferenceCounters* pRefCounters, - IRenderDevice* pDevice, - IDeviceContext* pDeviceContext, - const SwapChainDesc& SCDesc, - const FullScreenModeDesc& FSDesc, - void* pNativeWndHandle) : - // clang-format off - TBase{pRefCounters, pDevice, pDeviceContext, SCDesc}, - m_FSDesc {FSDesc}, - m_pNativeWndHandle {pNativeWndHandle} - // clang-format on - {} - - ~SwapChainD3DBase() - { - if (m_pSwapChain) - { - // Swap chain must be in windowed mode when it is destroyed - // https://msdn.microsoft.com/en-us/library/windows/desktop/bb205075(v=vs.85).aspx#Destroying - BOOL IsFullScreen = FALSE; - m_pSwapChain->GetFullscreenState(&IsFullScreen, nullptr); - if (IsFullScreen) - m_pSwapChain->SetFullscreenState(FALSE, nullptr); - } - } - -protected: - virtual void UpdateSwapChain(bool CreateNew) = 0; - - void CreateDXGISwapChain(IUnknown* pD3D11DeviceOrD3D12CmdQueue) - { -#if PLATFORM_WIN32 - auto hWnd = reinterpret_cast(m_pNativeWndHandle); - if (m_SwapChainDesc.Width == 0 || m_SwapChainDesc.Height == 0) - { - RECT rc; - if (m_FSDesc.Fullscreen) - { - const HWND hDesktop = GetDesktopWindow(); - GetWindowRect(hDesktop, &rc); - } - else - { - GetClientRect(hWnd, &rc); - } - m_SwapChainDesc.Width = rc.right - rc.left; - m_SwapChainDesc.Height = rc.bottom - rc.top; - } -#endif - - auto DXGIColorBuffFmt = TexFormatToDXGI_Format(m_SwapChainDesc.ColorBufferFormat); - - DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; - - swapChainDesc.Width = m_SwapChainDesc.Width; - swapChainDesc.Height = m_SwapChainDesc.Height; - // Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD) only support the following Formats: - // - DXGI_FORMAT_R16G16B16A16_FLOAT - // - DXGI_FORMAT_B8G8R8A8_UNORM - // - DXGI_FORMAT_R8G8B8A8_UNORM - // - DXGI_FORMAT_R10G10B10A2_UNORM - // If RGBA8_UNORM_SRGB swap chain is required, we will create RGBA8_UNORM swap chain, but - // create RGBA8_UNORM_SRGB render target view - switch (DXGIColorBuffFmt) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - break; - - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - break; - - default: - swapChainDesc.Format = DXGIColorBuffFmt; - } - - swapChainDesc.Stereo = FALSE; - - // Multi-sampled swap chains are not supported anymore. CreateSwapChainForHwnd() fails when sample count is not 1 - // for any swap effect. - swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.SampleDesc.Quality = 0; - - DEV_CHECK_ERR(m_SwapChainDesc.Usage != 0, "No swap chain usage flags defined"); - swapChainDesc.BufferUsage = 0; - if (m_SwapChainDesc.Usage & SWAP_CHAIN_USAGE_RENDER_TARGET) - swapChainDesc.BufferUsage |= DXGI_USAGE_RENDER_TARGET_OUTPUT; - if (m_SwapChainDesc.Usage & SWAP_CHAIN_USAGE_SHADER_INPUT) - swapChainDesc.BufferUsage |= DXGI_USAGE_SHADER_INPUT; - //if (m_SwapChainDesc.Usage & SWAP_CHAIN_USAGE_COPY_SOURCE) - // ; - - swapChainDesc.BufferCount = m_SwapChainDesc.BufferCount; - swapChainDesc.Scaling = DXGI_SCALING_NONE; - -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) - // DXGI_SCALING_NONE is supported starting with Windows 8 - if (!IsWindows8OrGreater()) - swapChainDesc.Scaling = DXGI_SCALING_STRETCH; -#endif - - // DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL is the flip presentation model, where the contents of the back - // buffer is preserved after the call to Present. This flag cannot be used with multisampling. - // The only swap effect that supports multisampling is DXGI_SWAP_EFFECT_DISCARD. - // Windows Store apps must use DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL or DXGI_SWAP_EFFECT_FLIP_DISCARD. - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; - - swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Transparency behavior is not specified - - // DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH enables an application to switch modes by calling - // IDXGISwapChain::ResizeTarget(). When switching from windowed to fullscreen mode, the display - // mode (or monitor resolution) will be changed to match the dimensions of the application window. - swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; - - CComPtr pSwapChain1; - CComPtr factory; - HRESULT hr = CreateDXGIFactory1(__uuidof(factory), reinterpret_cast(static_cast(&factory))); - CHECK_D3D_RESULT_THROW(hr, "Failed to create DXGI factory"); - -#if PLATFORM_WIN32 - - DXGI_SWAP_CHAIN_FULLSCREEN_DESC FullScreenDesc = {}; - - FullScreenDesc.Windowed = m_FSDesc.Fullscreen ? FALSE : TRUE; - FullScreenDesc.RefreshRate.Numerator = m_FSDesc.RefreshRateNumerator; - FullScreenDesc.RefreshRate.Denominator = m_FSDesc.RefreshRateDenominator; - FullScreenDesc.Scaling = static_cast(m_FSDesc.Scaling); - FullScreenDesc.ScanlineOrdering = static_cast(m_FSDesc.ScanlineOrder); - - hr = factory->CreateSwapChainForHwnd(pD3D11DeviceOrD3D12CmdQueue, hWnd, &swapChainDesc, &FullScreenDesc, nullptr, &pSwapChain1); - CHECK_D3D_RESULT_THROW(hr, "Failed to create Swap Chain"); - - { - // This is silly, but IDXGIFactory used for MakeWindowAssociation must be retrieved via - // calling IDXGISwapchain::GetParent first, otherwise it won't work - // https://www.gamedev.net/forums/topic/634235-dxgidisabling-altenter/?do=findComment&comment=4999990 - CComPtr pFactoryFromSC; - if (SUCCEEDED(pSwapChain1->GetParent(__uuidof(pFactoryFromSC), (void**)&pFactoryFromSC))) - { - // Do not allow the swap chain to handle Alt+Enter - pFactoryFromSC->MakeWindowAssociation(hWnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER); - } - } - -#elif PLATFORM_UNIVERSAL_WINDOWS - - if (m_FSDesc.Fullscreen) - LOG_WARNING_MESSAGE("UWP applications do not support fullscreen mode"); - - hr = factory->CreateSwapChainForCoreWindow( - pD3D11DeviceOrD3D12CmdQueue, - reinterpret_cast(m_pNativeWndHandle), - &swapChainDesc, - nullptr, - &pSwapChain1); - CHECK_D3D_RESULT_THROW(hr, "Failed to create DXGI swap chain"); - - // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and - // ensures that the application will only render after each VSync, minimizing power consumption. - //pDXGIDevice->SetMaximumFrameLatency( 1 ); - -#endif - - pSwapChain1->QueryInterface(__uuidof(m_pSwapChain), reinterpret_cast(static_cast(&m_pSwapChain))); - } - - virtual void SetFullscreenMode(const DisplayModeAttribs& DisplayMode) override final - { - if (m_pSwapChain) - { - // If we are already in fullscreen mode, we need to switch to windowed mode first, - // because a swap chain must be in windowed mode when it is released. - // https://msdn.microsoft.com/en-us/library/windows/desktop/bb205075(v=vs.85).aspx#Destroying - if (m_FSDesc.Fullscreen) - m_pSwapChain->SetFullscreenState(FALSE, nullptr); - m_FSDesc.Fullscreen = True; - m_FSDesc.RefreshRateNumerator = DisplayMode.RefreshRateNumerator; - m_FSDesc.RefreshRateDenominator = DisplayMode.RefreshRateDenominator; - m_FSDesc.Scaling = DisplayMode.Scaling; - m_FSDesc.ScanlineOrder = DisplayMode.ScanlineOrder; - m_SwapChainDesc.Width = DisplayMode.Width; - m_SwapChainDesc.Height = DisplayMode.Height; - if (DisplayMode.Format != TEX_FORMAT_UNKNOWN) - m_SwapChainDesc.ColorBufferFormat = DisplayMode.Format; - UpdateSwapChain(true); - } - } - - virtual void SetWindowedMode() override final - { - if (m_FSDesc.Fullscreen) - { - m_FSDesc.Fullscreen = False; - m_pSwapChain->SetFullscreenState(FALSE, nullptr); - } - } - - FullScreenModeDesc m_FSDesc; - CComPtr m_pSwapChain; - void* m_pNativeWndHandle; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/include/SwapChainD3DBase.hpp b/Graphics/GraphicsEngineD3DBase/include/SwapChainD3DBase.hpp new file mode 100644 index 00000000..70856a63 --- /dev/null +++ b/Graphics/GraphicsEngineD3DBase/include/SwapChainD3DBase.hpp @@ -0,0 +1,248 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include "SwapChainBase.hpp" + +/// \file +/// Base implementation of a D3D swap chain + +namespace Diligent +{ + +/// Base implementation of a D3D swap chain +template +class SwapChainD3DBase : public SwapChainBase +{ +public: + using TBase = SwapChainBase; + SwapChainD3DBase(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + IDeviceContext* pDeviceContext, + const SwapChainDesc& SCDesc, + const FullScreenModeDesc& FSDesc, + void* pNativeWndHandle) : + // clang-format off + TBase{pRefCounters, pDevice, pDeviceContext, SCDesc}, + m_FSDesc {FSDesc}, + m_pNativeWndHandle {pNativeWndHandle} + // clang-format on + {} + + ~SwapChainD3DBase() + { + if (m_pSwapChain) + { + // Swap chain must be in windowed mode when it is destroyed + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb205075(v=vs.85).aspx#Destroying + BOOL IsFullScreen = FALSE; + m_pSwapChain->GetFullscreenState(&IsFullScreen, nullptr); + if (IsFullScreen) + m_pSwapChain->SetFullscreenState(FALSE, nullptr); + } + } + +protected: + virtual void UpdateSwapChain(bool CreateNew) = 0; + + void CreateDXGISwapChain(IUnknown* pD3D11DeviceOrD3D12CmdQueue) + { +#if PLATFORM_WIN32 + auto hWnd = reinterpret_cast(m_pNativeWndHandle); + if (m_SwapChainDesc.Width == 0 || m_SwapChainDesc.Height == 0) + { + RECT rc; + if (m_FSDesc.Fullscreen) + { + const HWND hDesktop = GetDesktopWindow(); + GetWindowRect(hDesktop, &rc); + } + else + { + GetClientRect(hWnd, &rc); + } + m_SwapChainDesc.Width = rc.right - rc.left; + m_SwapChainDesc.Height = rc.bottom - rc.top; + } +#endif + + auto DXGIColorBuffFmt = TexFormatToDXGI_Format(m_SwapChainDesc.ColorBufferFormat); + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; + + swapChainDesc.Width = m_SwapChainDesc.Width; + swapChainDesc.Height = m_SwapChainDesc.Height; + // Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD) only support the following Formats: + // - DXGI_FORMAT_R16G16B16A16_FLOAT + // - DXGI_FORMAT_B8G8R8A8_UNORM + // - DXGI_FORMAT_R8G8B8A8_UNORM + // - DXGI_FORMAT_R10G10B10A2_UNORM + // If RGBA8_UNORM_SRGB swap chain is required, we will create RGBA8_UNORM swap chain, but + // create RGBA8_UNORM_SRGB render target view + switch (DXGIColorBuffFmt) + { + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + break; + + default: + swapChainDesc.Format = DXGIColorBuffFmt; + } + + swapChainDesc.Stereo = FALSE; + + // Multi-sampled swap chains are not supported anymore. CreateSwapChainForHwnd() fails when sample count is not 1 + // for any swap effect. + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + + DEV_CHECK_ERR(m_SwapChainDesc.Usage != 0, "No swap chain usage flags defined"); + swapChainDesc.BufferUsage = 0; + if (m_SwapChainDesc.Usage & SWAP_CHAIN_USAGE_RENDER_TARGET) + swapChainDesc.BufferUsage |= DXGI_USAGE_RENDER_TARGET_OUTPUT; + if (m_SwapChainDesc.Usage & SWAP_CHAIN_USAGE_SHADER_INPUT) + swapChainDesc.BufferUsage |= DXGI_USAGE_SHADER_INPUT; + //if (m_SwapChainDesc.Usage & SWAP_CHAIN_USAGE_COPY_SOURCE) + // ; + + swapChainDesc.BufferCount = m_SwapChainDesc.BufferCount; + swapChainDesc.Scaling = DXGI_SCALING_NONE; + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + // DXGI_SCALING_NONE is supported starting with Windows 8 + if (!IsWindows8OrGreater()) + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; +#endif + + // DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL is the flip presentation model, where the contents of the back + // buffer is preserved after the call to Present. This flag cannot be used with multisampling. + // The only swap effect that supports multisampling is DXGI_SWAP_EFFECT_DISCARD. + // Windows Store apps must use DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL or DXGI_SWAP_EFFECT_FLIP_DISCARD. + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Transparency behavior is not specified + + // DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH enables an application to switch modes by calling + // IDXGISwapChain::ResizeTarget(). When switching from windowed to fullscreen mode, the display + // mode (or monitor resolution) will be changed to match the dimensions of the application window. + swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + + CComPtr pSwapChain1; + CComPtr factory; + HRESULT hr = CreateDXGIFactory1(__uuidof(factory), reinterpret_cast(static_cast(&factory))); + CHECK_D3D_RESULT_THROW(hr, "Failed to create DXGI factory"); + +#if PLATFORM_WIN32 + + DXGI_SWAP_CHAIN_FULLSCREEN_DESC FullScreenDesc = {}; + + FullScreenDesc.Windowed = m_FSDesc.Fullscreen ? FALSE : TRUE; + FullScreenDesc.RefreshRate.Numerator = m_FSDesc.RefreshRateNumerator; + FullScreenDesc.RefreshRate.Denominator = m_FSDesc.RefreshRateDenominator; + FullScreenDesc.Scaling = static_cast(m_FSDesc.Scaling); + FullScreenDesc.ScanlineOrdering = static_cast(m_FSDesc.ScanlineOrder); + + hr = factory->CreateSwapChainForHwnd(pD3D11DeviceOrD3D12CmdQueue, hWnd, &swapChainDesc, &FullScreenDesc, nullptr, &pSwapChain1); + CHECK_D3D_RESULT_THROW(hr, "Failed to create Swap Chain"); + + { + // This is silly, but IDXGIFactory used for MakeWindowAssociation must be retrieved via + // calling IDXGISwapchain::GetParent first, otherwise it won't work + // https://www.gamedev.net/forums/topic/634235-dxgidisabling-altenter/?do=findComment&comment=4999990 + CComPtr pFactoryFromSC; + if (SUCCEEDED(pSwapChain1->GetParent(__uuidof(pFactoryFromSC), (void**)&pFactoryFromSC))) + { + // Do not allow the swap chain to handle Alt+Enter + pFactoryFromSC->MakeWindowAssociation(hWnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER); + } + } + +#elif PLATFORM_UNIVERSAL_WINDOWS + + if (m_FSDesc.Fullscreen) + LOG_WARNING_MESSAGE("UWP applications do not support fullscreen mode"); + + hr = factory->CreateSwapChainForCoreWindow( + pD3D11DeviceOrD3D12CmdQueue, + reinterpret_cast(m_pNativeWndHandle), + &swapChainDesc, + nullptr, + &pSwapChain1); + CHECK_D3D_RESULT_THROW(hr, "Failed to create DXGI swap chain"); + + // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and + // ensures that the application will only render after each VSync, minimizing power consumption. + //pDXGIDevice->SetMaximumFrameLatency( 1 ); + +#endif + + pSwapChain1->QueryInterface(__uuidof(m_pSwapChain), reinterpret_cast(static_cast(&m_pSwapChain))); + } + + virtual void SetFullscreenMode(const DisplayModeAttribs& DisplayMode) override final + { + if (m_pSwapChain) + { + // If we are already in fullscreen mode, we need to switch to windowed mode first, + // because a swap chain must be in windowed mode when it is released. + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb205075(v=vs.85).aspx#Destroying + if (m_FSDesc.Fullscreen) + m_pSwapChain->SetFullscreenState(FALSE, nullptr); + m_FSDesc.Fullscreen = True; + m_FSDesc.RefreshRateNumerator = DisplayMode.RefreshRateNumerator; + m_FSDesc.RefreshRateDenominator = DisplayMode.RefreshRateDenominator; + m_FSDesc.Scaling = DisplayMode.Scaling; + m_FSDesc.ScanlineOrder = DisplayMode.ScanlineOrder; + m_SwapChainDesc.Width = DisplayMode.Width; + m_SwapChainDesc.Height = DisplayMode.Height; + if (DisplayMode.Format != TEX_FORMAT_UNKNOWN) + m_SwapChainDesc.ColorBufferFormat = DisplayMode.Format; + UpdateSwapChain(true); + } + } + + virtual void SetWindowedMode() override final + { + if (m_FSDesc.Fullscreen) + { + m_FSDesc.Fullscreen = False; + m_pSwapChain->SetFullscreenState(FALSE, nullptr); + } + } + + FullScreenModeDesc m_FSDesc; + CComPtr m_pSwapChain; + void* m_pNativeWndHandle; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp index 07cd4536..20fe247e 100644 --- a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp +++ b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp @@ -28,11 +28,11 @@ #include #include -#include "D3DErrors.h" +#include "D3DErrors.hpp" #include "DataBlobImpl.h" #include "RefCntAutoPtr.h" #include -#include "ShaderD3DBase.h" +#include "ShaderD3DBase.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp index 34742425..b56fa540 100644 --- a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp +++ b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp @@ -28,9 +28,9 @@ #include "pch.h" #include "EngineMemory.h" #include "StringTools.h" -#include "ShaderResources.h" +#include "ShaderResources.hpp" #include "HashUtils.h" -#include "ShaderResourceVariableBase.h" +#include "ShaderResourceVariableBase.hpp" #include "Align.h" namespace Diligent -- cgit v1.2.3