summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngine
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-11-06 06:46:17 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-11-06 06:46:17 +0000
commit4de58520987882e1daa162e31cabca3f334c20a8 (patch)
tree29ec4a5327f00f205ca4c370a5e1f9fd7dea5e4f /Graphics/GraphicsEngine
parentRefactored BufferBase (diff)
downloadDiligentCore-4de58520987882e1daa162e31cabca3f334c20a8.tar.gz
DiligentCore-4de58520987882e1daa162e31cabca3f334c20a8.zip
Refactored TextureBase
Diffstat (limited to 'Graphics/GraphicsEngine')
-rw-r--r--Graphics/GraphicsEngine/include/BufferBase.hpp52
-rw-r--r--Graphics/GraphicsEngine/include/TextureBase.hpp389
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceContext.h4
-rw-r--r--Graphics/GraphicsEngine/src/TextureBase.cpp228
4 files changed, 350 insertions, 323 deletions
diff --git a/Graphics/GraphicsEngine/include/BufferBase.hpp b/Graphics/GraphicsEngine/include/BufferBase.hpp
index 0ccbc0aa..f09e8fc5 100644
--- a/Graphics/GraphicsEngine/include/BufferBase.hpp
+++ b/Graphics/GraphicsEngine/include/BufferBase.hpp
@@ -138,30 +138,46 @@ public:
// Create default views for structured and raw buffers. For formatted buffers we do not know the view format, so
// cannot create views.
- if (this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS && (this->m_Desc.Mode == BUFFER_MODE_STRUCTURED || this->m_Desc.Mode == BUFFER_MODE_RAW))
+ auto CreateDefaultView = [&](BUFFER_VIEW_TYPE ViewType) //
{
BufferViewDesc ViewDesc;
- ViewDesc.ViewType = BUFFER_VIEW_UNORDERED_ACCESS;
- auto UAVName = FormatString("Default UAV of buffer '", this->m_Desc.Name, '\'');
- ViewDesc.Name = UAVName.c_str();
-
- IBufferView* pUAV = nullptr;
- CreateViewInternal(ViewDesc, &pUAV, true);
- m_pDefaultUAV.reset(static_cast<BufferViewImplType*>(pUAV));
- VERIFY(m_pDefaultUAV->GetDesc().ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Unexpected view type");
+ ViewDesc.ViewType = ViewType;
+
+ std::string ViewName;
+ switch (ViewType)
+ {
+ case BUFFER_VIEW_UNORDERED_ACCESS:
+ ViewName = "Default UAV of buffer '";
+ break;
+
+ case BUFFER_VIEW_SHADER_RESOURCE:
+ ViewName = "Default SRV of buffer '";
+ break;
+
+ default:
+ UNEXPECTED("Unexpected buffer view type");
+ }
+
+ ViewName += this->m_Desc.Name;
+ ViewName += '\'';
+ ViewDesc.Name = ViewName.c_str();
+
+ IBufferView* pView = nullptr;
+ CreateViewInternal(ViewDesc, &pView, true);
+ VERIFY(pView != nullptr, "Failed to create default view for buffer '", this->m_Desc.Name, "'");
+ VERIFY(pView->GetDesc().ViewType == ViewType, "Unexpected view type");
+
+ return static_cast<BufferViewImplType*>(pView);
+ };
+
+ if (this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS && (this->m_Desc.Mode == BUFFER_MODE_STRUCTURED || this->m_Desc.Mode == BUFFER_MODE_RAW))
+ {
+ m_pDefaultUAV.reset(CreateDefaultView(BUFFER_VIEW_UNORDERED_ACCESS));
}
if (this->m_Desc.BindFlags & BIND_SHADER_RESOURCE && (this->m_Desc.Mode == BUFFER_MODE_STRUCTURED || this->m_Desc.Mode == BUFFER_MODE_RAW))
{
- BufferViewDesc ViewDesc;
- ViewDesc.ViewType = BUFFER_VIEW_SHADER_RESOURCE;
- auto SRVName = FormatString("Default SRV of buffer '", this->m_Desc.Name, '\'');
- ViewDesc.Name = SRVName.c_str();
-
- IBufferView* pSRV = nullptr;
- CreateViewInternal(ViewDesc, &pSRV, true);
- m_pDefaultSRV.reset(static_cast<BufferViewImplType*>(pSRV));
- VERIFY(m_pDefaultSRV->GetDesc().ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Unexpected view type");
+ m_pDefaultSRV.reset(CreateDefaultView(BUFFER_VIEW_SHADER_RESOURCE));
}
}
diff --git a/Graphics/GraphicsEngine/include/TextureBase.hpp b/Graphics/GraphicsEngine/include/TextureBase.hpp
index 559df1ea..ddd1a378 100644
--- a/Graphics/GraphicsEngine/include/TextureBase.hpp
+++ b/Graphics/GraphicsEngine/include/TextureBase.hpp
@@ -44,9 +44,19 @@ namespace Diligent
struct CopyTextureAttribs;
-void ValidateTextureDesc(const TextureDesc& TexDesc);
+/// Validates texture description and throws an exception in case of an error.
+void ValidateTextureDesc(const TextureDesc& TexDesc) noexcept(false);
+
+/// Validates and corrects texture view description; throws an exception in case of an error.
+void ValidatedAndCorrectTextureViewDesc(const TextureDesc& TexDesc, TextureViewDesc& ViewDesc) noexcept(false);
+
+/// Validates update texture command paramters.
void ValidateUpdateTextureParams(const TextureDesc& TexDesc, Uint32 MipLevel, Uint32 Slice, const Box& DstBox, const TextureSubResData& SubresData);
+
+/// Validates copy texture command paramters.
void ValidateCopyTextureParams(const CopyTextureAttribs& CopyAttribs);
+
+/// Validates map texture command paramters.
void ValidateMapTextureParams(const TextureDesc& TexDesc,
Uint32 MipLevel,
Uint32 ArraySlice,
@@ -88,10 +98,10 @@ public:
#ifdef DILIGENT_DEBUG
m_dbgTexViewObjAllocator(TexViewObjAllocator),
#endif
- m_pDefaultSRV(nullptr, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>(TexViewObjAllocator)),
- m_pDefaultRTV(nullptr, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>(TexViewObjAllocator)),
- m_pDefaultDSV(nullptr, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>(TexViewObjAllocator)),
- m_pDefaultUAV(nullptr, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>(TexViewObjAllocator))
+ m_pDefaultSRV{nullptr, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>(TexViewObjAllocator)},
+ m_pDefaultRTV{nullptr, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>(TexViewObjAllocator)},
+ m_pDefaultDSV{nullptr, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>(TexViewObjAllocator)},
+ m_pDefaultUAV{nullptr, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>(TexViewObjAllocator)}
{
if (this->m_Desc.MipLevels == 0)
{
@@ -161,7 +171,78 @@ public:
/// - Creates default unordered access view addressing the entire texture if Diligent::BIND_UNORDERED_ACCESS flag is set.
///
/// The function calls CreateViewInternal().
- void CreateDefaultViews();
+ void CreateDefaultViews()
+ {
+ const auto& TexFmtAttribs = GetTextureFormatAttribs(this->m_Desc.Format);
+ if (TexFmtAttribs.ComponentType == COMPONENT_TYPE_UNDEFINED)
+ {
+ // Cannot create default view for TYPELESS formats
+ return;
+ }
+
+ auto CreateDefaultView = [&](TEXTURE_VIEW_TYPE ViewType) //
+ {
+ TextureViewDesc ViewDesc;
+ ViewDesc.ViewType = ViewType;
+
+ std::string ViewName;
+ switch (ViewType)
+ {
+ case TEXTURE_VIEW_SHADER_RESOURCE:
+ if ((this->m_Desc.MiscFlags & MISC_TEXTURE_FLAG_GENERATE_MIPS) != 0)
+ ViewDesc.Flags |= TEXTURE_VIEW_FLAG_ALLOW_MIP_MAP_GENERATION;
+ ViewName = "Default SRV of texture '";
+ break;
+
+ case TEXTURE_VIEW_RENDER_TARGET:
+ ViewName = "Default RTV of texture '";
+ break;
+
+ case TEXTURE_VIEW_DEPTH_STENCIL:
+ ViewName = "Default DSV of texture '";
+ break;
+
+ case TEXTURE_VIEW_UNORDERED_ACCESS:
+ ViewDesc.AccessFlags = UAV_ACCESS_FLAG_READ_WRITE;
+
+ ViewName = "Default UAV of texture '";
+ break;
+
+ default:
+ UNEXPECTED("Unexpected texture type");
+ }
+ ViewName += this->m_Desc.Name;
+ ViewName += '\'';
+ ViewDesc.Name = ViewName.c_str();
+
+ ITextureView* pView = nullptr;
+ CreateViewInternal(ViewDesc, &pView, true);
+ VERIFY(pView != nullptr, "Failed to create default view for texture '", this->m_Desc.Name, "'");
+ VERIFY(pView->GetDesc().ViewType == ViewType, "Unexpected view type");
+
+ return static_cast<TTextureViewImpl*>(pView);
+ };
+
+ if (this->m_Desc.BindFlags & BIND_SHADER_RESOURCE)
+ {
+ m_pDefaultSRV.reset(CreateDefaultView(TEXTURE_VIEW_SHADER_RESOURCE));
+ }
+
+ if (this->m_Desc.BindFlags & BIND_RENDER_TARGET)
+ {
+ m_pDefaultRTV.reset(CreateDefaultView(TEXTURE_VIEW_RENDER_TARGET));
+ }
+
+ if (this->m_Desc.BindFlags & BIND_DEPTH_STENCIL)
+ {
+ m_pDefaultDSV.reset(CreateDefaultView(TEXTURE_VIEW_DEPTH_STENCIL));
+ }
+
+ if (this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS)
+ {
+ m_pDefaultUAV.reset(CreateDefaultView(TEXTURE_VIEW_UNORDERED_ACCESS));
+ }
+ }
virtual void DILIGENT_CALL_TYPE SetState(RESOURCE_STATE State) override final
{
@@ -223,303 +304,7 @@ protected:
/// Default UAV addressing the entire texture
std::unique_ptr<TTextureViewImpl, STDDeleter<TTextureViewImpl, TTexViewObjAllocator>> m_pDefaultUAV;
- void CorrectTextureViewDesc(struct TextureViewDesc& ViewDesc);
-
RESOURCE_STATE m_State = RESOURCE_STATE_UNKNOWN;
};
-
-template <class BaseInterface, class TRenderDeviceImpl, class TTextureViewImpl, class TTexViewObjAllocator>
-void TextureBase<BaseInterface, TRenderDeviceImpl, TTextureViewImpl, TTexViewObjAllocator>::CorrectTextureViewDesc(struct TextureViewDesc& ViewDesc)
-{
-#define TEX_VIEW_VALIDATION_ERROR(...) LOG_ERROR_AND_THROW("\n Failed to create texture view '", (ViewDesc.Name ? ViewDesc.Name : ""), "' for texture '", this->m_Desc.Name, "': ", ##__VA_ARGS__)
-
- if (!(ViewDesc.ViewType > TEXTURE_VIEW_UNDEFINED && ViewDesc.ViewType < TEXTURE_VIEW_NUM_VIEWS))
- TEX_VIEW_VALIDATION_ERROR("Texture view type is not specified");
-
- if (ViewDesc.MostDetailedMip >= this->m_Desc.MipLevels)
- TEX_VIEW_VALIDATION_ERROR("Most detailed mip (", ViewDesc.MostDetailedMip, ") is out of range. The texture has only ", this->m_Desc.MipLevels, " mip ", (this->m_Desc.MipLevels > 1 ? "levels." : "level."));
-
- if (ViewDesc.NumMipLevels != REMAINING_MIP_LEVELS && ViewDesc.MostDetailedMip + ViewDesc.NumMipLevels > this->m_Desc.MipLevels)
- TEX_VIEW_VALIDATION_ERROR("Most detailed mip (", ViewDesc.MostDetailedMip, ") and number of mip levels in the view (", ViewDesc.NumMipLevels, ") is out of range. The texture has only ", this->m_Desc.MipLevels, " mip ", (this->m_Desc.MipLevels > 1 ? "levels." : "level."));
-
- if (ViewDesc.Format == TEX_FORMAT_UNKNOWN)
- ViewDesc.Format = GetDefaultTextureViewFormat(this->m_Desc.Format, ViewDesc.ViewType, this->m_Desc.BindFlags);
-
- if (ViewDesc.TextureDim == RESOURCE_DIM_UNDEFINED)
- {
- if (this->m_Desc.Type == RESOURCE_DIM_TEX_CUBE || this->m_Desc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY)
- {
- switch (ViewDesc.ViewType)
- {
- case TEXTURE_VIEW_SHADER_RESOURCE:
- ViewDesc.TextureDim = this->m_Desc.Type;
- break;
-
- case TEXTURE_VIEW_RENDER_TARGET:
- case TEXTURE_VIEW_DEPTH_STENCIL:
- case TEXTURE_VIEW_UNORDERED_ACCESS:
- ViewDesc.TextureDim = RESOURCE_DIM_TEX_2D_ARRAY;
- break;
-
- default: UNEXPECTED("Unexpected view type");
- }
- }
- else
- {
- ViewDesc.TextureDim = this->m_Desc.Type;
- }
- }
-
- switch (this->m_Desc.Type)
- {
- case RESOURCE_DIM_TEX_1D:
- if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_1D)
- {
- TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture 1D view: only Texture 1D is allowed");
- }
- break;
-
- case RESOURCE_DIM_TEX_1D_ARRAY:
- if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_1D_ARRAY &&
- ViewDesc.TextureDim != RESOURCE_DIM_TEX_1D)
- {
- TEX_VIEW_VALIDATION_ERROR("Incorrect view type for Texture 1D Array: only Texture 1D or Texture 1D Array are allowed");
- }
- break;
-
- case RESOURCE_DIM_TEX_2D:
- if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY &&
- ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D)
- {
- TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture 2D view: only Texture 2D or Texture 2D Array are allowed");
- }
- break;
-
- case RESOURCE_DIM_TEX_2D_ARRAY:
- if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY &&
- ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D)
- {
- TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture 2D Array view: only Texture 2D or Texture 2D Array are allowed");
- }
- break;
-
- case RESOURCE_DIM_TEX_3D:
- if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_3D)
- {
- TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture 3D view: only Texture 3D is allowed");
- }
- break;
-
- case RESOURCE_DIM_TEX_CUBE:
- if (ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE)
- {
- if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D &&
- ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY &&
- ViewDesc.TextureDim != RESOURCE_DIM_TEX_CUBE)
- {
- TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture cube SRV: Texture 2D, Texture 2D array or Texture Cube is allowed");
- }
- }
- else
- {
- if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D &&
- ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY)
- {
- TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture cube non-shader resource view: Texture 2D or Texture 2D array is allowed");
- }
- }
- break;
-
- case RESOURCE_DIM_TEX_CUBE_ARRAY:
- if (ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE)
- {
- if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D &&
- ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY &&
- ViewDesc.TextureDim != RESOURCE_DIM_TEX_CUBE &&
- ViewDesc.TextureDim != RESOURCE_DIM_TEX_CUBE_ARRAY)
- {
- TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture cube array SRV: Texture 2D, Texture 2D array, Texture Cube or Texture Cube Array is allowed");
- }
- }
- else
- {
- if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D &&
- ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY)
- {
- TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture cube array non-shader resource view: Texture 2D or Texture 2D array is allowed");
- }
- }
- break;
-
- default:
- UNEXPECTED("Unexpected texture type");
- break;
- }
-
- if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE)
- {
- if (ViewDesc.ViewType != TEXTURE_VIEW_SHADER_RESOURCE)
- TEX_VIEW_VALIDATION_ERROR("Unexpected view type: SRV is expected");
- if (ViewDesc.NumArraySlices != 6 && ViewDesc.NumArraySlices != 0 && ViewDesc.NumArraySlices != REMAINING_ARRAY_SLICES)
- TEX_VIEW_VALIDATION_ERROR("Texture cube SRV is expected to have 6 array slices, while ", ViewDesc.NumArraySlices, " is provided");
- if (ViewDesc.FirstArraySlice != 0)
- TEX_VIEW_VALIDATION_ERROR("First slice (", ViewDesc.FirstArraySlice, ") must be 0 for non-array texture cube SRV");
- }
- if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE_ARRAY)
- {
- if (ViewDesc.ViewType != TEXTURE_VIEW_SHADER_RESOURCE)
- TEX_VIEW_VALIDATION_ERROR("Unexpected view type: SRV is expected");
- if (ViewDesc.NumArraySlices != REMAINING_ARRAY_SLICES && (ViewDesc.NumArraySlices % 6) != 0)
- TEX_VIEW_VALIDATION_ERROR("Number of slices in texture cube array SRV is expected to be multiple of 6. ", ViewDesc.NumArraySlices, " slices is provided.");
- }
-
- if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_1D ||
- ViewDesc.TextureDim == RESOURCE_DIM_TEX_2D)
- {
- if (ViewDesc.FirstArraySlice != 0)
- TEX_VIEW_VALIDATION_ERROR("First slice (", ViewDesc.FirstArraySlice, ") must be 0 for non-array texture 1D/2D views");
-
- if (ViewDesc.NumArraySlices != REMAINING_ARRAY_SLICES && ViewDesc.NumArraySlices > 1)
- TEX_VIEW_VALIDATION_ERROR("Number of slices in the view (", ViewDesc.NumArraySlices, ") must be 1 (or 0) for non-array texture 1D/2D views");
- }
- else if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_1D_ARRAY ||
- ViewDesc.TextureDim == RESOURCE_DIM_TEX_2D_ARRAY ||
- ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE ||
- ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE_ARRAY)
- {
- if (ViewDesc.FirstArraySlice >= this->m_Desc.ArraySize)
- TEX_VIEW_VALIDATION_ERROR("First array slice (", ViewDesc.FirstArraySlice, ") exceeds the number of slices in the texture array (", this->m_Desc.ArraySize, ")");
-
- if (ViewDesc.NumArraySlices != REMAINING_ARRAY_SLICES && ViewDesc.FirstArraySlice + ViewDesc.NumArraySlices > this->m_Desc.ArraySize)
- TEX_VIEW_VALIDATION_ERROR("First slice (", ViewDesc.FirstArraySlice, ") and number of slices in the view (", ViewDesc.NumArraySlices, ") specify more slices than target texture has (", this->m_Desc.ArraySize, ")");
- }
- else if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_3D)
- {
- auto MipDepth = this->m_Desc.Depth >> ViewDesc.MostDetailedMip;
- if (ViewDesc.FirstDepthSlice + ViewDesc.NumDepthSlices > MipDepth)
- TEX_VIEW_VALIDATION_ERROR("First slice (", ViewDesc.FirstDepthSlice, ") and number of slices in the view (", ViewDesc.NumDepthSlices, ") specify more slices than target 3D texture mip level has (", MipDepth, ")");
- }
- else
- {
- UNEXPECTED("Unexpected texture dimension");
- }
-
- if (GetTextureFormatAttribs(ViewDesc.Format).IsTypeless)
- {
- TEX_VIEW_VALIDATION_ERROR("Texture view format (", GetTextureFormatAttribs(ViewDesc.Format).Name, ") cannot be typeless");
- }
-
- if ((ViewDesc.Flags & TEXTURE_VIEW_FLAG_ALLOW_MIP_MAP_GENERATION) != 0)
- {
- if ((this->m_Desc.MiscFlags & MISC_TEXTURE_FLAG_GENERATE_MIPS) == 0)
- TEX_VIEW_VALIDATION_ERROR("TEXTURE_VIEW_FLAG_ALLOW_MIP_MAP_GENERATION flag can only set if the texture was created with MISC_TEXTURE_FLAG_GENERATE_MIPS flag");
-
- if (ViewDesc.ViewType != TEXTURE_VIEW_SHADER_RESOURCE)
- TEX_VIEW_VALIDATION_ERROR("TEXTURE_VIEW_FLAG_ALLOW_MIP_MAP_GENERATION flag can only be used with TEXTURE_VIEW_SHADER_RESOURCE view type");
- }
-
-#undef TEX_VIEW_VALIDATION_ERROR
-
- if (ViewDesc.NumMipLevels == 0 || ViewDesc.NumMipLevels == REMAINING_MIP_LEVELS)
- {
- if (ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE)
- ViewDesc.NumMipLevels = this->m_Desc.MipLevels - ViewDesc.MostDetailedMip;
- else
- ViewDesc.NumMipLevels = 1;
- }
-
- if (ViewDesc.NumArraySlices == 0 || ViewDesc.NumArraySlices == REMAINING_ARRAY_SLICES)
- {
- if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_1D_ARRAY ||
- ViewDesc.TextureDim == RESOURCE_DIM_TEX_2D_ARRAY ||
- ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE ||
- ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE_ARRAY)
- ViewDesc.NumArraySlices = this->m_Desc.ArraySize - ViewDesc.FirstArraySlice;
- else if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_3D)
- {
- auto MipDepth = this->m_Desc.Depth >> ViewDesc.MostDetailedMip;
- ViewDesc.NumDepthSlices = MipDepth - ViewDesc.FirstDepthSlice;
- }
- else
- ViewDesc.NumArraySlices = 1;
- }
-
- if ((ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET) &&
- (ViewDesc.Format == TEX_FORMAT_R8_SNORM || ViewDesc.Format == TEX_FORMAT_RG8_SNORM || ViewDesc.Format == TEX_FORMAT_RGBA8_SNORM ||
- ViewDesc.Format == TEX_FORMAT_R16_SNORM || ViewDesc.Format == TEX_FORMAT_RG16_SNORM || ViewDesc.Format == TEX_FORMAT_RGBA16_SNORM))
- {
- const auto* FmtName = GetTextureFormatAttribs(ViewDesc.Format).Name;
- LOG_WARNING_MESSAGE(FmtName, " render target view is created.\n"
- "There might be an issue in OpenGL driver on NVidia hardware: when rendering to SNORM textures, all negative values are clamped to zero.\n"
- "Use UNORM format instead.");
- }
-}
-
-template <class BaseInterface, class TRenderDeviceImpl, class TTextureViewImpl, class TTexViewObjAllocator>
-void TextureBase<BaseInterface, TRenderDeviceImpl, TTextureViewImpl, TTexViewObjAllocator>::CreateDefaultViews()
-{
- const auto& TexFmtAttribs = GetTextureFormatAttribs(this->m_Desc.Format);
- if (TexFmtAttribs.ComponentType == COMPONENT_TYPE_UNDEFINED)
- {
- // Cannot create default view for TYPELESS formats
- return;
- }
-
- if (this->m_Desc.BindFlags & BIND_SHADER_RESOURCE)
- {
- TextureViewDesc ViewDesc;
- ViewDesc.ViewType = TEXTURE_VIEW_SHADER_RESOURCE;
- auto ViewName = FormatString("Default SRV of texture '", this->m_Desc.Name, "'");
- ViewDesc.Name = ViewName.c_str();
-
- ITextureView* pSRV = nullptr;
- if ((this->m_Desc.MiscFlags & MISC_TEXTURE_FLAG_GENERATE_MIPS) != 0)
- ViewDesc.Flags |= TEXTURE_VIEW_FLAG_ALLOW_MIP_MAP_GENERATION;
- CreateViewInternal(ViewDesc, &pSRV, true);
- m_pDefaultSRV.reset(static_cast<TTextureViewImpl*>(pSRV));
- VERIFY(m_pDefaultSRV->GetDesc().ViewType == TEXTURE_VIEW_SHADER_RESOURCE, "Unexpected view type");
- }
-
- if (this->m_Desc.BindFlags & BIND_RENDER_TARGET)
- {
- TextureViewDesc ViewDesc;
- ViewDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET;
- auto ViewName = FormatString("Default RTV of texture '", this->m_Desc.Name, "'");
- ViewDesc.Name = ViewName.c_str();
-
- ITextureView* pRTV = nullptr;
- CreateViewInternal(ViewDesc, &pRTV, true);
- m_pDefaultRTV.reset(static_cast<TTextureViewImpl*>(pRTV));
- VERIFY(m_pDefaultRTV->GetDesc().ViewType == TEXTURE_VIEW_RENDER_TARGET, "Unexpected view type");
- }
-
- if (this->m_Desc.BindFlags & BIND_DEPTH_STENCIL)
- {
- TextureViewDesc ViewDesc;
- ViewDesc.ViewType = TEXTURE_VIEW_DEPTH_STENCIL;
- auto ViewName = FormatString("Default DSV of texture '", this->m_Desc.Name, "'");
- ViewDesc.Name = ViewName.c_str();
-
- ITextureView* pDSV = nullptr;
- CreateViewInternal(ViewDesc, &pDSV, true);
- m_pDefaultDSV.reset(static_cast<TTextureViewImpl*>(pDSV));
- VERIFY(m_pDefaultDSV->GetDesc().ViewType == TEXTURE_VIEW_DEPTH_STENCIL, "Unexpected view type");
- }
-
- if (this->m_Desc.BindFlags & BIND_UNORDERED_ACCESS)
- {
- TextureViewDesc ViewDesc;
- ViewDesc.ViewType = TEXTURE_VIEW_UNORDERED_ACCESS;
- auto ViewName = FormatString("Default UAV of texture '", this->m_Desc.Name, "'");
- ViewDesc.Name = ViewName.c_str();
-
- ViewDesc.AccessFlags = UAV_ACCESS_FLAG_READ_WRITE;
- ITextureView* pUAV = nullptr;
- CreateViewInternal(ViewDesc, &pUAV, true);
- m_pDefaultUAV.reset(static_cast<TTextureViewImpl*>(pUAV));
- VERIFY(m_pDefaultUAV->GetDesc().ViewType == TEXTURE_VIEW_UNORDERED_ACCESS, "Unexpected view type");
- }
-}
-
} // namespace Diligent
diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h
index d19021f1..de0ce74f 100644
--- a/Graphics/GraphicsEngine/interface/DeviceContext.h
+++ b/Graphics/GraphicsEngine/interface/DeviceContext.h
@@ -1190,8 +1190,8 @@ struct TraceRaysAttribs
typedef struct TraceRaysAttribs TraceRaysAttribs;
-static const Uint32 REMAINING_MIP_LEVELS = 0xFFFFFFFFU;
-static const Uint32 REMAINING_ARRAY_SLICES = 0xFFFFFFFFU;
+static const Uint32 REMAINING_MIP_LEVELS = ~0u;
+static const Uint32 REMAINING_ARRAY_SLICES = ~0u;
/// Resource state transition barrier description
struct StateTransitionDesc
diff --git a/Graphics/GraphicsEngine/src/TextureBase.cpp b/Graphics/GraphicsEngine/src/TextureBase.cpp
index cd31242f..0ecfc538 100644
--- a/Graphics/GraphicsEngine/src/TextureBase.cpp
+++ b/Graphics/GraphicsEngine/src/TextureBase.cpp
@@ -32,7 +32,7 @@
namespace Diligent
{
-void ValidateTextureDesc(const TextureDesc& Desc)
+void ValidateTextureDesc(const TextureDesc& Desc) noexcept(false)
{
#define LOG_TEXTURE_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Texture '", (Desc.Name ? Desc.Name : ""), "': ", ##__VA_ARGS__)
@@ -311,4 +311,230 @@ void ValidateMapTextureParams(const TextureDesc& TexDesc,
}
}
+void ValidatedAndCorrectTextureViewDesc(const TextureDesc& TexDesc, TextureViewDesc& ViewDesc) noexcept(false)
+{
+#define TEX_VIEW_VALIDATION_ERROR(...) LOG_ERROR_AND_THROW("\n Failed to create texture view '", (ViewDesc.Name ? ViewDesc.Name : ""), "' for texture '", TexDesc.Name, "': ", ##__VA_ARGS__)
+
+ if (!(ViewDesc.ViewType > TEXTURE_VIEW_UNDEFINED && ViewDesc.ViewType < TEXTURE_VIEW_NUM_VIEWS))
+ TEX_VIEW_VALIDATION_ERROR("Texture view type is not specified");
+
+ if (ViewDesc.MostDetailedMip >= TexDesc.MipLevels)
+ TEX_VIEW_VALIDATION_ERROR("Most detailed mip (", ViewDesc.MostDetailedMip, ") is out of range. The texture has only ", TexDesc.MipLevels, " mip ", (TexDesc.MipLevels > 1 ? "levels." : "level."));
+
+ if (ViewDesc.NumMipLevels != REMAINING_MIP_LEVELS && ViewDesc.MostDetailedMip + ViewDesc.NumMipLevels > TexDesc.MipLevels)
+ TEX_VIEW_VALIDATION_ERROR("Most detailed mip (", ViewDesc.MostDetailedMip, ") and number of mip levels in the view (", ViewDesc.NumMipLevels, ") is out of range. The texture has only ", TexDesc.MipLevels, " mip ", (TexDesc.MipLevels > 1 ? "levels." : "level."));
+
+ if (ViewDesc.Format == TEX_FORMAT_UNKNOWN)
+ ViewDesc.Format = GetDefaultTextureViewFormat(TexDesc.Format, ViewDesc.ViewType, TexDesc.BindFlags);
+
+ if (ViewDesc.TextureDim == RESOURCE_DIM_UNDEFINED)
+ {
+ if (TexDesc.Type == RESOURCE_DIM_TEX_CUBE || TexDesc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY)
+ {
+ switch (ViewDesc.ViewType)
+ {
+ case TEXTURE_VIEW_SHADER_RESOURCE:
+ ViewDesc.TextureDim = TexDesc.Type;
+ break;
+
+ case TEXTURE_VIEW_RENDER_TARGET:
+ case TEXTURE_VIEW_DEPTH_STENCIL:
+ case TEXTURE_VIEW_UNORDERED_ACCESS:
+ ViewDesc.TextureDim = RESOURCE_DIM_TEX_2D_ARRAY;
+ break;
+
+ default: UNEXPECTED("Unexpected view type");
+ }
+ }
+ else
+ {
+ ViewDesc.TextureDim = TexDesc.Type;
+ }
+ }
+
+ switch (TexDesc.Type)
+ {
+ case RESOURCE_DIM_TEX_1D:
+ if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_1D)
+ {
+ TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture 1D view: only Texture 1D is allowed");
+ }
+ break;
+
+ case RESOURCE_DIM_TEX_1D_ARRAY:
+ if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_1D_ARRAY &&
+ ViewDesc.TextureDim != RESOURCE_DIM_TEX_1D)
+ {
+ TEX_VIEW_VALIDATION_ERROR("Incorrect view type for Texture 1D Array: only Texture 1D or Texture 1D Array are allowed");
+ }
+ break;
+
+ case RESOURCE_DIM_TEX_2D:
+ if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY &&
+ ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D)
+ {
+ TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture 2D view: only Texture 2D or Texture 2D Array are allowed");
+ }
+ break;
+
+ case RESOURCE_DIM_TEX_2D_ARRAY:
+ if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY &&
+ ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D)
+ {
+ TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture 2D Array view: only Texture 2D or Texture 2D Array are allowed");
+ }
+ break;
+
+ case RESOURCE_DIM_TEX_3D:
+ if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_3D)
+ {
+ TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture 3D view: only Texture 3D is allowed");
+ }
+ break;
+
+ case RESOURCE_DIM_TEX_CUBE:
+ if (ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE)
+ {
+ if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D &&
+ ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY &&
+ ViewDesc.TextureDim != RESOURCE_DIM_TEX_CUBE)
+ {
+ TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture cube SRV: Texture 2D, Texture 2D array or Texture Cube is allowed");
+ }
+ }
+ else
+ {
+ if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D &&
+ ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY)
+ {
+ TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture cube non-shader resource view: Texture 2D or Texture 2D array is allowed");
+ }
+ }
+ break;
+
+ case RESOURCE_DIM_TEX_CUBE_ARRAY:
+ if (ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE)
+ {
+ if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D &&
+ ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY &&
+ ViewDesc.TextureDim != RESOURCE_DIM_TEX_CUBE &&
+ ViewDesc.TextureDim != RESOURCE_DIM_TEX_CUBE_ARRAY)
+ {
+ TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture cube array SRV: Texture 2D, Texture 2D array, Texture Cube or Texture Cube Array is allowed");
+ }
+ }
+ else
+ {
+ if (ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D &&
+ ViewDesc.TextureDim != RESOURCE_DIM_TEX_2D_ARRAY)
+ {
+ TEX_VIEW_VALIDATION_ERROR("Incorrect texture type for Texture cube array non-shader resource view: Texture 2D or Texture 2D array is allowed");
+ }
+ }
+ break;
+
+ default:
+ UNEXPECTED("Unexpected texture type");
+ break;
+ }
+
+ if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE)
+ {
+ if (ViewDesc.ViewType != TEXTURE_VIEW_SHADER_RESOURCE)
+ TEX_VIEW_VALIDATION_ERROR("Unexpected view type: SRV is expected");
+ if (ViewDesc.NumArraySlices != 6 && ViewDesc.NumArraySlices != 0 && ViewDesc.NumArraySlices != REMAINING_ARRAY_SLICES)
+ TEX_VIEW_VALIDATION_ERROR("Texture cube SRV is expected to have 6 array slices, while ", ViewDesc.NumArraySlices, " is provided");
+ if (ViewDesc.FirstArraySlice != 0)
+ TEX_VIEW_VALIDATION_ERROR("First slice (", ViewDesc.FirstArraySlice, ") must be 0 for non-array texture cube SRV");
+ }
+ if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE_ARRAY)
+ {
+ if (ViewDesc.ViewType != TEXTURE_VIEW_SHADER_RESOURCE)
+ TEX_VIEW_VALIDATION_ERROR("Unexpected view type: SRV is expected");
+ if (ViewDesc.NumArraySlices != REMAINING_ARRAY_SLICES && (ViewDesc.NumArraySlices % 6) != 0)
+ TEX_VIEW_VALIDATION_ERROR("Number of slices in texture cube array SRV is expected to be multiple of 6. ", ViewDesc.NumArraySlices, " slices is provided.");
+ }
+
+ if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_1D ||
+ ViewDesc.TextureDim == RESOURCE_DIM_TEX_2D)
+ {
+ if (ViewDesc.FirstArraySlice != 0)
+ TEX_VIEW_VALIDATION_ERROR("First slice (", ViewDesc.FirstArraySlice, ") must be 0 for non-array texture 1D/2D views");
+
+ if (ViewDesc.NumArraySlices != REMAINING_ARRAY_SLICES && ViewDesc.NumArraySlices > 1)
+ TEX_VIEW_VALIDATION_ERROR("Number of slices in the view (", ViewDesc.NumArraySlices, ") must be 1 (or 0) for non-array texture 1D/2D views");
+ }
+ else if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_1D_ARRAY ||
+ ViewDesc.TextureDim == RESOURCE_DIM_TEX_2D_ARRAY ||
+ ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE ||
+ ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE_ARRAY)
+ {
+ if (ViewDesc.FirstArraySlice >= TexDesc.ArraySize)
+ TEX_VIEW_VALIDATION_ERROR("First array slice (", ViewDesc.FirstArraySlice, ") exceeds the number of slices in the texture array (", TexDesc.ArraySize, ")");
+
+ if (ViewDesc.NumArraySlices != REMAINING_ARRAY_SLICES && ViewDesc.FirstArraySlice + ViewDesc.NumArraySlices > TexDesc.ArraySize)
+ TEX_VIEW_VALIDATION_ERROR("First slice (", ViewDesc.FirstArraySlice, ") and number of slices in the view (", ViewDesc.NumArraySlices, ") specify more slices than target texture has (", TexDesc.ArraySize, ")");
+ }
+ else if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_3D)
+ {
+ auto MipDepth = TexDesc.Depth >> ViewDesc.MostDetailedMip;
+ if (ViewDesc.FirstDepthSlice + ViewDesc.NumDepthSlices > MipDepth)
+ TEX_VIEW_VALIDATION_ERROR("First slice (", ViewDesc.FirstDepthSlice, ") and number of slices in the view (", ViewDesc.NumDepthSlices, ") specify more slices than target 3D texture mip level has (", MipDepth, ")");
+ }
+ else
+ {
+ UNEXPECTED("Unexpected texture dimension");
+ }
+
+ if (GetTextureFormatAttribs(ViewDesc.Format).IsTypeless)
+ {
+ TEX_VIEW_VALIDATION_ERROR("Texture view format (", GetTextureFormatAttribs(ViewDesc.Format).Name, ") cannot be typeless");
+ }
+
+ if ((ViewDesc.Flags & TEXTURE_VIEW_FLAG_ALLOW_MIP_MAP_GENERATION) != 0)
+ {
+ if ((TexDesc.MiscFlags & MISC_TEXTURE_FLAG_GENERATE_MIPS) == 0)
+ TEX_VIEW_VALIDATION_ERROR("TEXTURE_VIEW_FLAG_ALLOW_MIP_MAP_GENERATION flag can only set if the texture was created with MISC_TEXTURE_FLAG_GENERATE_MIPS flag");
+
+ if (ViewDesc.ViewType != TEXTURE_VIEW_SHADER_RESOURCE)
+ TEX_VIEW_VALIDATION_ERROR("TEXTURE_VIEW_FLAG_ALLOW_MIP_MAP_GENERATION flag can only be used with TEXTURE_VIEW_SHADER_RESOURCE view type");
+ }
+
+#undef TEX_VIEW_VALIDATION_ERROR
+
+ if (ViewDesc.NumMipLevels == 0 || ViewDesc.NumMipLevels == REMAINING_MIP_LEVELS)
+ {
+ if (ViewDesc.ViewType == TEXTURE_VIEW_SHADER_RESOURCE)
+ ViewDesc.NumMipLevels = TexDesc.MipLevels - ViewDesc.MostDetailedMip;
+ else
+ ViewDesc.NumMipLevels = 1;
+ }
+
+ if (ViewDesc.NumArraySlices == 0 || ViewDesc.NumArraySlices == REMAINING_ARRAY_SLICES)
+ {
+ if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_1D_ARRAY ||
+ ViewDesc.TextureDim == RESOURCE_DIM_TEX_2D_ARRAY ||
+ ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE ||
+ ViewDesc.TextureDim == RESOURCE_DIM_TEX_CUBE_ARRAY)
+ ViewDesc.NumArraySlices = TexDesc.ArraySize - ViewDesc.FirstArraySlice;
+ else if (ViewDesc.TextureDim == RESOURCE_DIM_TEX_3D)
+ {
+ auto MipDepth = TexDesc.Depth >> ViewDesc.MostDetailedMip;
+ ViewDesc.NumDepthSlices = MipDepth - ViewDesc.FirstDepthSlice;
+ }
+ else
+ ViewDesc.NumArraySlices = 1;
+ }
+
+ if ((ViewDesc.ViewType == TEXTURE_VIEW_RENDER_TARGET) &&
+ (ViewDesc.Format == TEX_FORMAT_R8_SNORM || ViewDesc.Format == TEX_FORMAT_RG8_SNORM || ViewDesc.Format == TEX_FORMAT_RGBA8_SNORM ||
+ ViewDesc.Format == TEX_FORMAT_R16_SNORM || ViewDesc.Format == TEX_FORMAT_RG16_SNORM || ViewDesc.Format == TEX_FORMAT_RGBA16_SNORM))
+ {
+ const auto* FmtName = GetTextureFormatAttribs(ViewDesc.Format).Name;
+ LOG_WARNING_MESSAGE(FmtName, " render target view is created.\n"
+ "There might be an issue in OpenGL driver on NVidia hardware: when rendering to SNORM textures, all negative values are clamped to zero.\n"
+ "Use UNORM format instead.");
+ }
+}
+
} // namespace Diligent