summaryrefslogtreecommitdiffstats
path: root/tools/gfx
diff options
context:
space:
mode:
authorlucy96chen <47800040+lucy96chen@users.noreply.github.com>2021-12-08 11:38:14 -0800
committerGitHub <noreply@github.com>2021-12-08 11:38:14 -0800
commit9606401e1de1002e3ad070bc5c6384fa5bc4d9ff (patch)
tree7a557a14fadf5220a34f6df9faf1a5535100743f /tools/gfx
parent90d8af888b40c83b33f9f0c037bd2ab8c19a35f4 (diff)
D3D12 and Vulkan to CUDA Texture Sharing (#2038)
Diffstat (limited to 'tools/gfx')
-rw-r--r--tools/gfx/cuda/render-cuda.cpp232
-rw-r--r--tools/gfx/d3d12/render-d3d12.cpp17
-rw-r--r--tools/gfx/debug-layer.cpp16
-rw-r--r--tools/gfx/debug-layer.h5
-rw-r--r--tools/gfx/renderer-shared.cpp14
-rw-r--r--tools/gfx/renderer-shared.h6
-rw-r--r--tools/gfx/vulkan/render-vk.cpp162
7 files changed, 351 insertions, 101 deletions
diff --git a/tools/gfx/cuda/render-cuda.cpp b/tools/gfx/cuda/render-cuda.cpp
index 7abf51ef3..b97fc819c 100644
--- a/tools/gfx/cuda/render-cuda.cpp
+++ b/tools/gfx/cuda/render-cuda.cpp
@@ -242,6 +242,8 @@ public:
CUarray m_cudaArray = CUarray();
CUmipmappedArray m_cudaMipMappedArray = CUmipmappedArray();
+ void* m_cudaExternalMemory = nullptr;
+
RefPtr<CUDAContext> m_cudaContext;
virtual SLANG_NO_THROW Result SLANG_MCALL getNativeResourceHandle(InteropHandle* outHandle) override
@@ -1439,6 +1441,62 @@ public:
return SLANG_OK;
}
+ Result getCUDAFormat(Format format, CUarray_format* outFormat)
+ {
+ // TODO: Expand to cover all available formats that can be supported in CUDA
+ switch (format)
+ {
+ case Format::R32G32B32A32_FLOAT:
+ case Format::R32G32B32_FLOAT:
+ case Format::R32G32_FLOAT:
+ case Format::R32_FLOAT:
+ case Format::D32_FLOAT:
+ *outFormat = CU_AD_FORMAT_FLOAT;
+ return SLANG_OK;
+ case Format::R16G16B16A16_FLOAT:
+ case Format::R16G16_FLOAT:
+ case Format::R16_FLOAT:
+ *outFormat = CU_AD_FORMAT_HALF;
+ return SLANG_OK;
+ case Format::R32G32B32A32_UINT:
+ case Format::R32G32B32_UINT:
+ case Format::R32G32_UINT:
+ case Format::R32_UINT:
+ *outFormat = CU_AD_FORMAT_UNSIGNED_INT32;
+ return SLANG_OK;
+ case Format::R16G16B16A16_UINT:
+ case Format::R16G16_UINT:
+ case Format::R16_UINT:
+ *outFormat = CU_AD_FORMAT_UNSIGNED_INT16;
+ return SLANG_OK;
+ case Format::R8G8B8A8_UINT:
+ case Format::R8G8_UINT:
+ case Format::R8_UINT:
+ case Format::R8G8B8A8_UNORM:
+ *outFormat = CU_AD_FORMAT_UNSIGNED_INT8;
+ return SLANG_OK;
+ case Format::R32G32B32A32_SINT:
+ case Format::R32G32B32_SINT:
+ case Format::R32G32_SINT:
+ case Format::R32_SINT:
+ *outFormat = CU_AD_FORMAT_SIGNED_INT32;
+ return SLANG_OK;
+ case Format::R16G16B16A16_SINT:
+ case Format::R16G16_SINT:
+ case Format::R16_SINT:
+ *outFormat = CU_AD_FORMAT_SIGNED_INT16;
+ return SLANG_OK;
+ case Format::R8G8B8A8_SINT:
+ case Format::R8G8_SINT:
+ case Format::R8_SINT:
+ *outFormat = CU_AD_FORMAT_SIGNED_INT8;
+ return SLANG_OK;
+ default:
+ SLANG_ASSERT(!"Only support R32_FLOAT/R8G8B8A8_UNORM formats for now");
+ return SLANG_FAIL;
+ }
+ }
+
virtual SLANG_NO_THROW Result SLANG_MCALL createTextureResource(
const ITextureResource::Desc& desc,
const ITextureResource::SubresourceData* initData,
@@ -1489,45 +1547,34 @@ public:
{
CUarray_format format = CU_AD_FORMAT_FLOAT;
int numChannels = 0;
-
- switch (desc.format)
+
+ SLANG_RETURN_ON_FAIL(getCUDAFormat(desc.format, &format));
+ FormatInfo info;
+ gfxGetFormatInfo(desc.format, &info);
+ numChannels = info.channelCount;
+
+ switch (format)
{
- case Format::R32G32B32A32_FLOAT:
- case Format::R32G32B32_FLOAT:
- case Format::R32G32_FLOAT:
- case Format::R32_FLOAT:
- case Format::D32_FLOAT:
- {
- FormatInfo info;
- gfxGetFormatInfo(desc.format, &info);
- format = CU_AD_FORMAT_FLOAT;
- numChannels = info.channelCount;
- elementSize = sizeof(float) * numChannels;
- break;
- }
- case Format::R16G16B16A16_FLOAT:
- case Format::R16G16_FLOAT:
- case Format::R16_FLOAT:
- {
- FormatInfo info;
- gfxGetFormatInfo(desc.format, &info);
- format = CU_AD_FORMAT_HALF;
- numChannels = info.channelCount;
- elementSize = sizeof(uint16_t) * numChannels;
- break;
- }
- case Format::R8G8B8A8_UNORM:
- {
- format = CU_AD_FORMAT_UNSIGNED_INT8;
- numChannels = 4;
- elementSize = sizeof(uint32_t);
- break;
- }
+ case CU_AD_FORMAT_FLOAT:
+ {
+ elementSize = sizeof(float) * numChannels;
+ break;
+ }
+ case CU_AD_FORMAT_HALF:
+ {
+ elementSize = sizeof(uint16_t) * numChannels;
+ break;
+ }
+ case CU_AD_FORMAT_UNSIGNED_INT8:
+ {
+ elementSize = sizeof(uint32_t) * numChannels;
+ break;
+ }
default:
- {
- SLANG_ASSERT(!"Only support R32_FLOAT/R8G8B8A8_UNORM formats for now");
- return SLANG_FAIL;
- }
+ {
+ SLANG_ASSERT(!"Only support R32_FLOAT/R8G8B8A8_UNORM formats for now");
+ return SLANG_FAIL;
+ }
}
if (desc.numMipLevels > 1)
@@ -1951,6 +1998,83 @@ public:
return SLANG_OK;
}
+ virtual SLANG_NO_THROW Result SLANG_MCALL createTextureFromSharedHandle(
+ InteropHandle handle,
+ const ITextureResource::Desc& desc,
+ const size_t size,
+ ITextureResource** outResource) override
+ {
+ if (handle.handleValue == 0)
+ {
+ *outResource = nullptr;
+ return SLANG_OK;
+ }
+
+ RefPtr<TextureCUDAResource> resource = new TextureCUDAResource(desc);
+ resource->m_cudaContext = m_context;
+
+ // CUDA manages sharing of buffers through the idea of an
+ // "external memory" object, which represents the relationship
+ // with another API's objects. In order to create this external
+ // memory association, we first need to fill in a descriptor struct.
+ CUDA_EXTERNAL_MEMORY_HANDLE_DESC externalMemoryHandleDesc;
+ memset(&externalMemoryHandleDesc, 0, sizeof(externalMemoryHandleDesc));
+ switch (handle.api)
+ {
+ case InteropHandleAPI::D3D12:
+ externalMemoryHandleDesc.type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE;
+ break;
+ case InteropHandleAPI::Vulkan:
+ externalMemoryHandleDesc.type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32;
+ break;
+ default:
+ return SLANG_FAIL;
+ }
+ externalMemoryHandleDesc.handle.win32.handle = (void*)handle.handleValue;
+ externalMemoryHandleDesc.size = size;
+ externalMemoryHandleDesc.flags = cudaExternalMemoryDedicated;
+
+ CUexternalMemory externalMemory;
+ SLANG_CUDA_RETURN_ON_FAIL(cuImportExternalMemory(&externalMemory, &externalMemoryHandleDesc));
+ resource->m_cudaExternalMemory = externalMemory;
+
+ FormatInfo formatInfo;
+ SLANG_RETURN_ON_FAIL(gfxGetFormatInfo(desc.format, &formatInfo));
+ CUDA_ARRAY3D_DESCRIPTOR arrayDesc;
+ arrayDesc.Depth = desc.size.depth;
+ arrayDesc.Height = desc.size.height;
+ arrayDesc.Width = desc.size.width;
+ arrayDesc.NumChannels = formatInfo.channelCount;
+ getCUDAFormat(desc.format, &arrayDesc.Format);
+ arrayDesc.Flags = 0; // TODO: Flags? CUDA_ARRAY_LAYERED/SURFACE_LDST/CUBEMAP/TEXTURE_GATHER
+
+ CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC externalMemoryMipDesc;
+ memset(&externalMemoryMipDesc, 0, sizeof(externalMemoryMipDesc));
+ externalMemoryMipDesc.offset = 0;
+ externalMemoryMipDesc.arrayDesc = arrayDesc;
+ externalMemoryMipDesc.numLevels = desc.numMipLevels;
+
+ CUmipmappedArray mipArray;
+ SLANG_CUDA_RETURN_ON_FAIL(cuExternalMemoryGetMappedMipmappedArray(&mipArray, externalMemory, &externalMemoryMipDesc));
+ resource->m_cudaMipMappedArray = mipArray;
+
+ CUarray cuArray;
+ SLANG_CUDA_RETURN_ON_FAIL(cuMipmappedArrayGetLevel(&cuArray, mipArray, 0));
+ resource->m_cudaArray = cuArray;
+
+ CUDA_RESOURCE_DESC surfDesc;
+ memset(&surfDesc, 0, sizeof(surfDesc));
+ surfDesc.resType = CU_RESOURCE_TYPE_ARRAY;
+ surfDesc.res.array.hArray = cuArray;
+
+ CUsurfObject surface;
+ SLANG_CUDA_RETURN_ON_FAIL(cuSurfObjectCreate(&surface, &surfDesc));
+ resource->m_cudaSurfObj = surface;
+
+ returnComPtr(outResource, resource);
+ return SLANG_OK;
+ }
+
virtual SLANG_NO_THROW Result SLANG_MCALL createTextureView(
ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) override
{
@@ -2183,12 +2307,36 @@ public:
size_t* outRowPitch,
size_t* outPixelSize) override
{
- SLANG_UNUSED(texture);
- SLANG_UNUSED(outBlob);
- SLANG_UNUSED(outRowPitch);
- SLANG_UNUSED(outPixelSize);
+ auto textureImpl = static_cast<TextureCUDAResource*>(texture);
+ RefPtr<ListBlob> blob = new ListBlob();
- return SLANG_E_NOT_AVAILABLE;
+ auto desc = textureImpl->getDesc();
+ auto width = desc->size.width;
+ auto height = desc->size.height;
+ FormatInfo sizeInfo;
+ SLANG_RETURN_ON_FAIL(gfxGetFormatInfo(desc->format, &sizeInfo));
+ size_t pixelSize = sizeInfo.blockSizeInBytes / sizeInfo.pixelsPerBlock;
+ size_t rowPitch = width * pixelSize;
+ size_t size = height * rowPitch;
+ blob->m_data.setCount((Index)size);
+
+ CUDA_MEMCPY2D copyParam;
+ memset(&copyParam, 0, sizeof(copyParam));
+
+ copyParam.srcMemoryType = CU_MEMORYTYPE_ARRAY;
+ copyParam.srcArray = textureImpl->m_cudaArray;
+
+ copyParam.dstMemoryType = CU_MEMORYTYPE_HOST;
+ copyParam.dstHost = blob->m_data.getBuffer();
+ copyParam.dstPitch = rowPitch;
+ copyParam.WidthInBytes = copyParam.dstPitch;
+ copyParam.Height = height;
+ SLANG_CUDA_RETURN_ON_FAIL(cuMemcpy2D(&copyParam));
+
+ *outRowPitch = rowPitch;
+ *outPixelSize = pixelSize;
+ returnComPtr(outBlob, blob);
+ return SLANG_OK;
}
virtual SLANG_NO_THROW Result SLANG_MCALL readBufferResource(
diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp
index 371d22002..ebc894291 100644
--- a/tools/gfx/d3d12/render-d3d12.cpp
+++ b/tools/gfx/d3d12/render-d3d12.cpp
@@ -314,11 +314,19 @@ public:
virtual SLANG_NO_THROW Result SLANG_MCALL getSharedHandle(InteropHandle* outHandle) override
{
+ // Check if a shared handle already exists for this resource.
+ if (sharedHandle.handleValue != 0)
+ {
+ *outHandle = sharedHandle;
+ return SLANG_OK;
+ }
+
+ // If a shared handle doesn't exist, create one and store it.
ComPtr<ID3D12Device> pDevice;
auto pResource = m_resource.getResource();
pResource->GetDevice(IID_PPV_ARGS(pDevice.writeRef()));
SLANG_RETURN_ON_FAIL(pDevice->CreateSharedHandle(pResource, NULL, GENERIC_ALL, nullptr, (HANDLE*)&outHandle->handleValue));
- outHandle->api = InteropHandleAPI::Win32;
+ outHandle->api = InteropHandleAPI::D3D12;
return SLANG_OK;
}
};
@@ -5031,7 +5039,7 @@ Result D3D12Device::getTextureAllocationInfo(
TextureResource::Desc srcDesc = fixupTextureDesc(desc);
D3D12_RESOURCE_DESC resourceDesc = {};
setupResourceDesc(resourceDesc, srcDesc);
- auto allocInfo = m_device->GetResourceAllocationInfo(0xFF, 1, &resourceDesc);
+ auto allocInfo = m_device->GetResourceAllocationInfo(0, 1, &resourceDesc);
*outSize = (size_t)allocInfo.SizeInBytes;
*outAlignment = (size_t)allocInfo.Alignment;
return SLANG_OK;
@@ -5061,6 +5069,9 @@ Result D3D12Device::createTextureResource(const ITextureResource::Desc& descIn,
heapProps.CreationNodeMask = 1;
heapProps.VisibleNodeMask = 1;
+ D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE;
+ if (descIn.isShared) flags |= D3D12_HEAP_FLAG_SHARED;
+
D3D12_CLEAR_VALUE clearValue;
D3D12_CLEAR_VALUE* clearValuePtr = &clearValue;
if ((resourceDesc.Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET |
@@ -5075,7 +5086,7 @@ Result D3D12Device::createTextureResource(const ITextureResource::Desc& descIn,
SLANG_RETURN_ON_FAIL(texture->m_resource.initCommitted(
m_device,
heapProps,
- D3D12_HEAP_FLAG_NONE,
+ flags,
resourceDesc,
D3D12_RESOURCE_STATE_COPY_DEST,
clearValuePtr));
diff --git a/tools/gfx/debug-layer.cpp b/tools/gfx/debug-layer.cpp
index 470b63599..60e726243 100644
--- a/tools/gfx/debug-layer.cpp
+++ b/tools/gfx/debug-layer.cpp
@@ -370,6 +370,22 @@ Result DebugDevice::createTextureFromNativeHandle(
return result;
}
+Result DebugDevice::createTextureFromSharedHandle(
+ InteropHandle handle,
+ const ITextureResource::Desc& srcDesc,
+ const size_t size,
+ ITextureResource** outResource)
+{
+ SLANG_GFX_API_FUNC;
+
+ RefPtr<DebugTextureResource> outObject = new DebugTextureResource();
+ auto result = baseObject->createTextureFromSharedHandle(handle, srcDesc, size, outObject->baseObject.writeRef());
+ if (SLANG_FAILED(result))
+ return result;
+ returnComPtr(outResource, outObject);
+ return result;
+}
+
Result DebugDevice::createBufferResource(
const IBufferResource::Desc& desc,
const void* initData,
diff --git a/tools/gfx/debug-layer.h b/tools/gfx/debug-layer.h
index e0a97ee1c..71cf74260 100644
--- a/tools/gfx/debug-layer.h
+++ b/tools/gfx/debug-layer.h
@@ -60,6 +60,11 @@ public:
InteropHandle handle,
const ITextureResource::Desc& srcDesc,
ITextureResource** outResource) override;
+ virtual SLANG_NO_THROW Result SLANG_MCALL createTextureFromSharedHandle(
+ InteropHandle handle,
+ const ITextureResource::Desc& srcDesc,
+ const size_t size,
+ ITextureResource** outResource) override;
virtual SLANG_NO_THROW Result SLANG_MCALL createBufferResource(
const IBufferResource::Desc& desc,
const void* initData,
diff --git a/tools/gfx/renderer-shared.cpp b/tools/gfx/renderer-shared.cpp
index 101e02d47..df6ebd37e 100644
--- a/tools/gfx/renderer-shared.cpp
+++ b/tools/gfx/renderer-shared.cpp
@@ -365,6 +365,19 @@ SLANG_NO_THROW Result SLANG_MCALL RendererBase::createTextureFromNativeHandle(
return SLANG_E_NOT_AVAILABLE;
}
+SLANG_NO_THROW Result SLANG_MCALL RendererBase::createTextureFromSharedHandle(
+ InteropHandle handle,
+ const ITextureResource::Desc& srcDesc,
+ const size_t size,
+ ITextureResource** outResource)
+{
+ SLANG_UNUSED(handle);
+ SLANG_UNUSED(srcDesc);
+ SLANG_UNUSED(size);
+ SLANG_UNUSED(outResource);
+ return SLANG_E_NOT_AVAILABLE;
+}
+
SLANG_NO_THROW Result SLANG_MCALL RendererBase::createBufferFromNativeHandle(
InteropHandle handle,
const IBufferResource::Desc& srcDesc,
@@ -381,6 +394,7 @@ SLANG_NO_THROW Result SLANG_MCALL RendererBase::createBufferFromSharedHandle(
const IBufferResource::Desc& srcDesc,
IBufferResource** outResource)
{
+ SLANG_UNUSED(handle);
SLANG_UNUSED(srcDesc);
SLANG_UNUSED(outResource);
return SLANG_E_NOT_AVAILABLE;
diff --git a/tools/gfx/renderer-shared.h b/tools/gfx/renderer-shared.h
index e7ea1b7f5..7859f1ad9 100644
--- a/tools/gfx/renderer-shared.h
+++ b/tools/gfx/renderer-shared.h
@@ -1206,6 +1206,12 @@ public:
const ITextureResource::Desc& srcDesc,
ITextureResource** outResource) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW Result SLANG_MCALL createTextureFromSharedHandle(
+ InteropHandle handle,
+ const ITextureResource::Desc& srcDesc,
+ const size_t size,
+ ITextureResource** outResource) SLANG_OVERRIDE;
+
virtual SLANG_NO_THROW Result SLANG_MCALL createBufferFromNativeHandle(
InteropHandle handle,
const IBufferResource::Desc& srcDesc,
diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp
index 25609ec6e..b55c78ea0 100644
--- a/tools/gfx/vulkan/render-vk.cpp
+++ b/tools/gfx/vulkan/render-vk.cpp
@@ -381,6 +381,12 @@ public:
vkAPI.vkFreeMemory(vkAPI.m_device, m_imageMemory, nullptr);
vkAPI.vkDestroyImage(vkAPI.m_device, m_image, nullptr);
}
+ if (sharedHandle.handleValue != 0)
+ {
+#if SLANG_WINDOWS_FAMILY
+ CloseHandle((HANDLE)sharedHandle.handleValue);
+#endif
+ }
}
VkImage m_image = VK_NULL_HANDLE;
@@ -398,8 +404,31 @@ public:
virtual SLANG_NO_THROW Result SLANG_MCALL getSharedHandle(InteropHandle* outHandle) override
{
+ // Check if a shared handle already exists for this resource.
+ if (sharedHandle.handleValue != 0)
+ {
+ *outHandle = sharedHandle;
+ return SLANG_OK;
+ }
+
+ // If a shared handle doesn't exist, create one and store it.
+#if SLANG_WINDOWS_FAMILY
+ VkMemoryGetWin32HandleInfoKHR info = {};
+ info.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
+ info.pNext = nullptr;
+ info.memory = m_imageMemory;
+ info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
+
+ auto& api = m_device->m_api;
+ PFN_vkGetMemoryWin32HandleKHR vkCreateSharedHandle;
+ vkCreateSharedHandle = api.vkGetMemoryWin32HandleKHR;
+ if (!vkCreateSharedHandle)
+ {
+ return SLANG_FAIL;
+ }
+ SLANG_RETURN_ON_FAIL(vkCreateSharedHandle(m_device->m_device, &info, (HANDLE*)&outHandle->handleValue) != VK_SUCCESS);
+#endif
outHandle->api = InteropHandleAPI::Vulkan;
- outHandle->handleValue = 0;
return SLANG_OK;
}
};
@@ -5712,7 +5741,7 @@ Result VKDevice::Buffer::init(
exportMemoryAllocateInfo.pNext =
extMemHandleType & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
? &exportMemoryWin32HandleInfo
- : NULL;
+ : nullptr;
exportMemoryAllocateInfo.handleTypes = extMemHandleType;
allocateInfo.pNext = &exportMemoryAllocateInfo;
}
@@ -6921,78 +6950,99 @@ Result VKDevice::createTextureResource(const ITextureResource::Desc& descIn, con
RefPtr<TextureResourceImpl> texture(new TextureResourceImpl(desc, this));
texture->m_vkformat = format;
// Create the image
+
+ VkImageCreateInfo imageInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
+ switch (desc.type)
{
- VkImageCreateInfo imageInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
- switch (desc.type)
+ case IResource::Type::Texture1D:
{
- case IResource::Type::Texture1D:
- {
- imageInfo.imageType = VK_IMAGE_TYPE_1D;
- imageInfo.extent = VkExtent3D{ uint32_t(descIn.size.width), 1, 1 };
- break;
- }
- case IResource::Type::Texture2D:
- {
- imageInfo.imageType = VK_IMAGE_TYPE_2D;
- imageInfo.extent = VkExtent3D{ uint32_t(descIn.size.width), uint32_t(descIn.size.height), 1 };
- break;
- }
- case IResource::Type::TextureCube:
- {
- imageInfo.imageType = VK_IMAGE_TYPE_2D;
- imageInfo.extent = VkExtent3D{ uint32_t(descIn.size.width), uint32_t(descIn.size.height), 1 };
- imageInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
- break;
- }
- case IResource::Type::Texture3D:
- {
- // Can't have an array and 3d texture
- assert(desc.arraySize <= 1);
+ imageInfo.imageType = VK_IMAGE_TYPE_1D;
+ imageInfo.extent = VkExtent3D{ uint32_t(descIn.size.width), 1, 1 };
+ break;
+ }
+ case IResource::Type::Texture2D:
+ {
+ imageInfo.imageType = VK_IMAGE_TYPE_2D;
+ imageInfo.extent = VkExtent3D{ uint32_t(descIn.size.width), uint32_t(descIn.size.height), 1 };
+ break;
+ }
+ case IResource::Type::TextureCube:
+ {
+ imageInfo.imageType = VK_IMAGE_TYPE_2D;
+ imageInfo.extent = VkExtent3D{ uint32_t(descIn.size.width), uint32_t(descIn.size.height), 1 };
+ imageInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
+ break;
+ }
+ case IResource::Type::Texture3D:
+ {
+ // Can't have an array and 3d texture
+ assert(desc.arraySize <= 1);
- imageInfo.imageType = VK_IMAGE_TYPE_3D;
- imageInfo.extent = VkExtent3D{ uint32_t(descIn.size.width), uint32_t(descIn.size.height), uint32_t(descIn.size.depth) };
- break;
- }
- default:
- {
- assert(!"Unhandled type");
- return SLANG_FAIL;
- }
+ imageInfo.imageType = VK_IMAGE_TYPE_3D;
+ imageInfo.extent = VkExtent3D{ uint32_t(descIn.size.width), uint32_t(descIn.size.height), uint32_t(descIn.size.depth) };
+ break;
+ }
+ default:
+ {
+ assert(!"Unhandled type");
+ return SLANG_FAIL;
}
+ }
- imageInfo.mipLevels = desc.numMipLevels;
- imageInfo.arrayLayers = arraySize;
+ imageInfo.mipLevels = desc.numMipLevels;
+ imageInfo.arrayLayers = arraySize;
- imageInfo.format = format;
+ imageInfo.format = format;
- imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
- imageInfo.usage = _calcImageUsageFlags(desc.allowedStates, desc.cpuAccessFlags, initData);
- imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
+ imageInfo.usage = _calcImageUsageFlags(desc.allowedStates, desc.cpuAccessFlags, initData);
+ imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
- imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+ imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
- SLANG_VK_RETURN_ON_FAIL(m_api.vkCreateImage(m_device, &imageInfo, nullptr, &texture->m_image));
+ VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO };
+#if SLANG_WINDOWS_FAMILY
+ VkExternalMemoryHandleTypeFlags extMemoryHandleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
+ if (descIn.isShared)
+ {
+ externalMemoryImageCreateInfo.pNext = nullptr;
+ externalMemoryImageCreateInfo.handleTypes = extMemoryHandleType;
+ imageInfo.pNext = &externalMemoryImageCreateInfo;
}
+#endif
+ SLANG_VK_RETURN_ON_FAIL(m_api.vkCreateImage(m_device, &imageInfo, nullptr, &texture->m_image));
VkMemoryRequirements memRequirements;
m_api.vkGetImageMemoryRequirements(m_device, texture->m_image, &memRequirements);
// Allocate the memory
- {
- VkMemoryPropertyFlags reqMemoryProperties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
-
- VkMemoryAllocateInfo allocInfo = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
-
- int memoryTypeIndex = m_api.findMemoryTypeIndex(memRequirements.memoryTypeBits, reqMemoryProperties);
- assert(memoryTypeIndex >= 0);
-
- VkMemoryPropertyFlags actualMemoryProperites = m_api.m_deviceMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags;
+ VkMemoryPropertyFlags reqMemoryProperties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+ int memoryTypeIndex = m_api.findMemoryTypeIndex(memRequirements.memoryTypeBits, reqMemoryProperties);
+ assert(memoryTypeIndex >= 0);
- allocInfo.allocationSize = memRequirements.size;
- allocInfo.memoryTypeIndex = memoryTypeIndex;
+ VkMemoryPropertyFlags actualMemoryProperites = m_api.m_deviceMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags;
+ VkMemoryAllocateInfo allocInfo = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
+ allocInfo.allocationSize = memRequirements.size;
+ allocInfo.memoryTypeIndex = memoryTypeIndex;
+#if SLANG_WINDOWS_FAMILY
+ VkExportMemoryWin32HandleInfoKHR exportMemoryWin32HandleInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR };
+ VkExportMemoryAllocateInfoKHR exportMemoryAllocateInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR };
+ if (descIn.isShared)
+ {
+ exportMemoryWin32HandleInfo.pNext = nullptr;
+ exportMemoryWin32HandleInfo.pAttributes = nullptr;
+ exportMemoryWin32HandleInfo.dwAccess = DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE;
+ exportMemoryWin32HandleInfo.name = NULL;
- SLANG_VK_RETURN_ON_FAIL(m_api.vkAllocateMemory(m_device, &allocInfo, nullptr, &texture->m_imageMemory));
+ exportMemoryAllocateInfo.pNext =
+ extMemoryHandleType & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
+ ? &exportMemoryWin32HandleInfo
+ : nullptr;
+ exportMemoryAllocateInfo.handleTypes = extMemoryHandleType;
+ allocInfo.pNext = &exportMemoryAllocateInfo;
}
+#endif
+ SLANG_VK_RETURN_ON_FAIL(m_api.vkAllocateMemory(m_device, &allocInfo, nullptr, &texture->m_imageMemory));
// Bind the memory to the image
m_api.vkBindImageMemory(m_device, texture->m_image, texture->m_imageMemory, 0);