summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-10-01 00:01:15 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-10-01 00:01:15 +0000
commit3941b472dedd0836b5e4970460fbf0e38a42e4e4 (patch)
treefc4d0002e0c17cab1f09f4f1955e80c2b5fa4ce0
parentUpdated Metal interfaces plus a number of misc fixes (diff)
downloadDiligentCore-3941b472dedd0836b5e4970460fbf0e38a42e4e4.tar.gz
DiligentCore-3941b472dedd0836b5e4970460fbf0e38a42e4e4.zip
A number of updates to support Metal backend
-rw-r--r--CMakeLists.txt3
-rw-r--r--Common/interface/RefCntAutoPtr.hpp2
-rw-r--r--Graphics/GraphicsAccessories/interface/GraphicsAccessories.hpp5
-rw-r--r--Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp36
-rw-r--r--Graphics/GraphicsEngine/interface/GraphicsTypes.h4
-rw-r--r--Graphics/GraphicsEngineMetal/interface/BufferMtl.h4
-rw-r--r--Graphics/GraphicsEngineMetal/interface/TextureMtl.h4
-rw-r--r--Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp8
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp14
-rw-r--r--Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp38
-rw-r--r--Tests/DiligentCoreAPITest/CMakeLists.txt3
-rw-r--r--Tests/DiligentCoreAPITest/include/Metal/TestingEnvironmentMtl.hpp2
-rw-r--r--Tests/DiligentCoreAPITest/src/Metal/TestingEnvironmentMtl.mm5
13 files changed, 80 insertions, 48 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 01fe74e4..2caa523f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,6 +7,9 @@ include(GNUInstallDirs)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+# Generate XCode schema files
+set(CMAKE_XCODE_GENERATE_SCHEME TRUE)
+
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
message(STATUS "CMAKE_BUILD_TYPE is not specified, default to Debug. Note that this is only relevant for single-configuration generators (such as Makefile Generators and Ninja).")
diff --git a/Common/interface/RefCntAutoPtr.hpp b/Common/interface/RefCntAutoPtr.hpp
index 7cf13e15..140c01d5 100644
--- a/Common/interface/RefCntAutoPtr.hpp
+++ b/Common/interface/RefCntAutoPtr.hpp
@@ -220,7 +220,7 @@ public:
const T* operator->() const noexcept { return m_pObject; }
template <typename InterfaceType>
- RefCntAutoPtr<InterfaceType> Cast(const INTERFACE_ID& IID)
+ RefCntAutoPtr<InterfaceType> Cast(const INTERFACE_ID& IID) const
{
return RefCntAutoPtr<InterfaceType>{m_pObject, IID};
}
diff --git a/Graphics/GraphicsAccessories/interface/GraphicsAccessories.hpp b/Graphics/GraphicsAccessories/interface/GraphicsAccessories.hpp
index 0e834f0b..47ded2c1 100644
--- a/Graphics/GraphicsAccessories/interface/GraphicsAccessories.hpp
+++ b/Graphics/GraphicsAccessories/interface/GraphicsAccessories.hpp
@@ -471,4 +471,9 @@ bool IsConsistentShaderType(SHADER_TYPE ShaderType, PIPELINE_TYPE Pipelin
Int32 GetShaderTypePipelineIndex(SHADER_TYPE ShaderType, PIPELINE_TYPE PipelineType);
SHADER_TYPE GetShaderTypeFromPipelineIndex(Int32 Index, PIPELINE_TYPE PipelineType);
+Uint32 GetStagingTextureSubresOffset(const TextureDesc& TexDesc,
+ Uint32 ArraySlice,
+ Uint32 MipLevel,
+ Uint32 Alignment);
+
} // namespace Diligent
diff --git a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp
index 6229ff2b..193a4989 100644
--- a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp
+++ b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp
@@ -1395,4 +1395,40 @@ SHADER_TYPE GetShaderTypeFromPipelineIndex(Int32 Index, PIPELINE_TYPE PipelineTy
}
}
+
+Uint32 GetStagingTextureSubresOffset(const TextureDesc& TexDesc,
+ Uint32 ArraySlice,
+ Uint32 MipLevel,
+ Uint32 Alignment)
+{
+ VERIFY_EXPR(ArraySlice < TexDesc.ArraySize && MipLevel < TexDesc.MipLevels || ArraySlice == TexDesc.ArraySize && MipLevel == 0);
+
+ Uint32 Offset = 0;
+ if (ArraySlice > 0)
+ {
+ Uint32 ArraySliceSize = 0;
+ for (Uint32 mip = 0; mip < TexDesc.MipLevels; ++mip)
+ {
+ auto MipInfo = GetMipLevelProperties(TexDesc, mip);
+ ArraySliceSize += Align(MipInfo.MipSize, Alignment);
+ }
+
+ Offset = ArraySliceSize;
+ if (TexDesc.Type == RESOURCE_DIM_TEX_1D_ARRAY ||
+ TexDesc.Type == RESOURCE_DIM_TEX_2D_ARRAY ||
+ TexDesc.Type == RESOURCE_DIM_TEX_CUBE ||
+ TexDesc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY)
+ Offset *= ArraySlice;
+ }
+
+ for (Uint32 mip = 0; mip < MipLevel; ++mip)
+ {
+ auto MipInfo = GetMipLevelProperties(TexDesc, mip);
+ Offset += Align(MipInfo.MipSize, Alignment);
+ }
+
+ return Offset;
+}
+
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h
index 93295972..e8263232 100644
--- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h
+++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h
@@ -1743,6 +1743,10 @@ struct DeviceCaps
{
return DevType == RENDER_DEVICE_TYPE_VULKAN;
}
+ bool IsMetalDevice()const
+ {
+ return DevType == RENDER_DEVICE_TYPE_METAL;
+ }
struct NDCAttribs
{
diff --git a/Graphics/GraphicsEngineMetal/interface/BufferMtl.h b/Graphics/GraphicsEngineMetal/interface/BufferMtl.h
index 1ed88a5c..7f4a0a61 100644
--- a/Graphics/GraphicsEngineMetal/interface/BufferMtl.h
+++ b/Graphics/GraphicsEngineMetal/interface/BufferMtl.h
@@ -41,8 +41,8 @@ static const INTERFACE_ID IID_BufferMtl =
class IBufferMtl : public IBuffer
{
public:
- /// Returns a pointer to Metal buffer (MTLBuffer)
- virtual void* GetMtlBuffer() const = 0;
+ /// Returns a pointer to a Metal buffer (MTLBuffer).
+ virtual void* GetMtlResource() const = 0;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineMetal/interface/TextureMtl.h b/Graphics/GraphicsEngineMetal/interface/TextureMtl.h
index da2db211..bced9bb7 100644
--- a/Graphics/GraphicsEngineMetal/interface/TextureMtl.h
+++ b/Graphics/GraphicsEngineMetal/interface/TextureMtl.h
@@ -41,6 +41,10 @@ static const INTERFACE_ID IID_TextureMtl =
class ITextureMtl : public ITexture
{
public:
+ /// Returns a pointer to a Metal resource.
+ /// For a staging texture, this will be a pointer to a MTLStorageModeShared buffer (MTLBuffer).
+ /// For all other texture types, this will be a pointer to Metal texture object (MTLTexture).
+ virtual void* GetMtlResource() const = 0;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp
index 39eb7ec1..b04babec 100644
--- a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp
@@ -42,8 +42,6 @@ namespace Diligent
class FixedBlockMemoryAllocator;
-Uint32 GetStagingDataOffset(const TextureDesc& TexDesc, Uint32 ArraySlice, Uint32 MipLevel, Uint32 Alignment = 4);
-
/// Texture object implementation in Vulkan backend.
class TextureVkImpl final : public TextureBase<ITextureVk, RenderDeviceVkImpl, TextureViewVkImpl, FixedBlockMemoryAllocator>
{
@@ -101,6 +99,12 @@ public:
void InvalidateStagingRange(VkDeviceSize Offset, VkDeviceSize Size);
+ // bufferOffset must be a multiple of 4 (18.4)
+ // If the calling command's VkImage parameter is a compressed image, bufferOffset
+ // must be a multiple of the compressed texel block size in bytes (18.4). This
+ // is automatically guaranteed as MipWidth and MipHeight are rounded to block size.
+ static constexpr Uint32 StagingDataAlignment = 4;
+
protected:
void CreateViewInternal(const struct TextureViewDesc& ViewDesc, ITextureView** ppView, bool bIsDefaultView) override;
//void PrepareVkInitData(const TextureData &InitData, Uint32 NumSubresources, std::vector<Vk_SUBRESOURCE_DATA> &VkInitData);
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index cd5d0901..f14e7f9c 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -1634,7 +1634,7 @@ void DeviceContextVkImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs)
DEV_CHECK_ERR((SrcTexDesc.CPUAccessFlags & CPU_ACCESS_WRITE), "Attempting to copy from staging texture that was not created with CPU_ACCESS_WRITE flag");
DEV_CHECK_ERR(pSrcTexVk->GetState() == RESOURCE_STATE_COPY_SOURCE, "Source staging texture must permanently be in RESOURCE_STATE_COPY_SOURCE state");
- auto SrcBufferOffset = GetStagingDataOffset(SrcTexDesc, CopyAttribs.SrcSlice, CopyAttribs.SrcMipLevel);
+ auto SrcBufferOffset = GetStagingTextureSubresOffset(SrcTexDesc, CopyAttribs.SrcSlice, CopyAttribs.SrcMipLevel, TextureVkImpl::StagingDataAlignment);
auto SrcMipLevelAttribs = GetMipLevelProperties(SrcTexDesc, CopyAttribs.SrcMipLevel);
// address of (x,y,z) = region->bufferOffset + (((z * imageHeight) + y) * rowLength + x) * texelBlockSize; (18.4.1)
SrcBufferOffset +=
@@ -1667,8 +1667,10 @@ void DeviceContextVkImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs)
DEV_CHECK_ERR((DstTexDesc.CPUAccessFlags & CPU_ACCESS_READ), "Attempting to copy to staging texture that was not created with CPU_ACCESS_READ flag");
DEV_CHECK_ERR(pDstTexVk->GetState() == RESOURCE_STATE_COPY_DEST, "Destination staging texture must permanently be in RESOURCE_STATE_COPY_DEST state");
- auto DstBufferOffset = GetStagingDataOffset(DstTexDesc, CopyAttribs.DstSlice, CopyAttribs.DstMipLevel);
- auto DstMipLevelAttribs = GetMipLevelProperties(DstTexDesc, CopyAttribs.DstMipLevel);
+ auto DstBufferOffset =
+ GetStagingTextureSubresOffset(DstTexDesc, CopyAttribs.DstSlice, CopyAttribs.DstMipLevel,
+ TextureVkImpl::StagingDataAlignment);
+ const auto DstMipLevelAttribs = GetMipLevelProperties(DstTexDesc, CopyAttribs.DstMipLevel);
// address of (x,y,z) = region->bufferOffset + (((z * imageHeight) + y) * rowLength + x) * texelBlockSize; (18.4.1)
DstBufferOffset +=
// For compressed-block formats, RowSize is the size of one compressed row.
@@ -2007,8 +2009,10 @@ void DeviceContextVkImpl::MapTextureSubresource(ITexture* pTextu
}
else if (TexDesc.Usage == USAGE_STAGING)
{
- auto SubresourceOffset = GetStagingDataOffset(TexDesc, ArraySlice, MipLevel);
- auto MipLevelAttribs = GetMipLevelProperties(TexDesc, MipLevel);
+ auto SubresourceOffset =
+ GetStagingTextureSubresOffset(TexDesc, ArraySlice, MipLevel,
+ TextureVkImpl::StagingDataAlignment);
+ const auto MipLevelAttribs = GetMipLevelProperties(TexDesc, MipLevel);
// address of (x,y,z) = region->bufferOffset + (((z * imageHeight) + y) * rowLength + x) * texelBlockSize; (18.4.1)
auto MapStartOffset = SubresourceOffset +
// For compressed-block formats, RowSize is the size of one compressed row.
diff --git a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
index ca04f900..8a37df0c 100644
--- a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp
@@ -408,7 +408,7 @@ TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters,
VkStagingBuffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
VkStagingBuffCI.pNext = nullptr;
VkStagingBuffCI.flags = 0;
- VkStagingBuffCI.size = GetStagingDataOffset(m_Desc, m_Desc.ArraySize, 0);
+ VkStagingBuffCI.size = GetStagingTextureSubresOffset(m_Desc, m_Desc.ArraySize, 0, StagingDataAlignment);
// clang-format off
DEV_CHECK_ERR((m_Desc.CPUAccessFlags & (CPU_ACCESS_READ | CPU_ACCESS_WRITE)) == CPU_ACCESS_READ ||
@@ -470,42 +470,6 @@ TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters,
VERIFY_EXPR(IsInKnownState());
}
-Uint32 GetStagingDataOffset(const TextureDesc& TexDesc, Uint32 ArraySlice, Uint32 MipLevel, Uint32 Alignment)
-{
- VERIFY_EXPR(ArraySlice < TexDesc.ArraySize && MipLevel < TexDesc.MipLevels || ArraySlice == TexDesc.ArraySize && MipLevel == 0);
-
- Uint32 Offset = 0;
- if (ArraySlice > 0)
- {
- Uint32 ArraySliceSize = 0;
- for (Uint32 mip = 0; mip < TexDesc.MipLevels; ++mip)
- {
- auto MipInfo = GetMipLevelProperties(TexDesc, mip);
- // bufferOffset must be a multiple of 4 (18.4)
- // If the calling command's VkImage parameter is a compressed image, bufferOffset
- // must be a multiple of the compressed texel block size in bytes (18.4). This
- // is automatically guaranteed as MipWidth and MipHeight are rounded to block size
- ArraySliceSize += Align(MipInfo.MipSize, Alignment);
- }
-
- Offset = ArraySliceSize;
- if (TexDesc.Type == RESOURCE_DIM_TEX_1D_ARRAY ||
- TexDesc.Type == RESOURCE_DIM_TEX_2D_ARRAY ||
- TexDesc.Type == RESOURCE_DIM_TEX_CUBE ||
- TexDesc.Type == RESOURCE_DIM_TEX_CUBE_ARRAY)
- Offset *= ArraySlice;
- }
-
- for (Uint32 mip = 0; mip < MipLevel; ++mip)
- {
- auto MipInfo = GetMipLevelProperties(TexDesc, mip);
- // bufferOffset must be a multiple of 4 (18.4)
- Offset += Align(MipInfo.MipSize, Alignment);
- }
-
- return Offset;
-}
-
TextureVkImpl::TextureVkImpl(IReferenceCounters* pRefCounters,
FixedBlockMemoryAllocator& TexViewObjAllocator,
RenderDeviceVkImpl* pDeviceVk,
diff --git a/Tests/DiligentCoreAPITest/CMakeLists.txt b/Tests/DiligentCoreAPITest/CMakeLists.txt
index fb3aeb37..b2a5c2fb 100644
--- a/Tests/DiligentCoreAPITest/CMakeLists.txt
+++ b/Tests/DiligentCoreAPITest/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 3.6)
+cmake_minimum_required (VERSION 3.17)
project(DiligentCoreAPITest)
@@ -159,6 +159,7 @@ PRIVATE
set_target_properties(DiligentCoreAPITest
PROPERTIES
VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/assets"
+ XCODE_SCHEME_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/assets"
)
if(PLATFORM_WIN32)
diff --git a/Tests/DiligentCoreAPITest/include/Metal/TestingEnvironmentMtl.hpp b/Tests/DiligentCoreAPITest/include/Metal/TestingEnvironmentMtl.hpp
index 3a214c81..80cc7f53 100644
--- a/Tests/DiligentCoreAPITest/include/Metal/TestingEnvironmentMtl.hpp
+++ b/Tests/DiligentCoreAPITest/include/Metal/TestingEnvironmentMtl.hpp
@@ -48,6 +48,8 @@ public:
virtual void Reset() override final;
+ void* GetMtlDevice() const;
+
private:
};
diff --git a/Tests/DiligentCoreAPITest/src/Metal/TestingEnvironmentMtl.mm b/Tests/DiligentCoreAPITest/src/Metal/TestingEnvironmentMtl.mm
index 6b50bee5..90f5ebcc 100644
--- a/Tests/DiligentCoreAPITest/src/Metal/TestingEnvironmentMtl.mm
+++ b/Tests/DiligentCoreAPITest/src/Metal/TestingEnvironmentMtl.mm
@@ -68,6 +68,11 @@ TestingEnvironment* CreateTestingEnvironmentMtl(RENDER_DEVICE_TYPE deviceType,
return new TestingEnvironmentMtl{deviceType, AdapterType, AdapterId, SCDesc};
}
+void* TestingEnvironmentMtl::GetMtlDevice() const
+{
+ return m_pDevice.Cast<IRenderDeviceMtl>(IID_RenderDeviceMtl)->GetMtlDevice();
+}
+
} // namespace Testing
} // namespace Diligent