summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/gfx/metal/metal-command-buffer.cpp4
-rw-r--r--tools/gfx/metal/metal-command-encoder.cpp6
-rw-r--r--tools/gfx/metal/metal-device.cpp125
-rw-r--r--tools/gfx/metal/metal-pipeline-state.cpp13
-rw-r--r--tools/gfx/metal/metal-resource-views.h1
-rw-r--r--tools/gfx/metal/metal-shader-object.cpp2
-rw-r--r--tools/gfx/metal/metal-texture.h5
7 files changed, 103 insertions, 53 deletions
diff --git a/tools/gfx/metal/metal-command-buffer.cpp b/tools/gfx/metal/metal-command-buffer.cpp
index c54552ae4..3f9923bf8 100644
--- a/tools/gfx/metal/metal-command-buffer.cpp
+++ b/tools/gfx/metal/metal-command-buffer.cpp
@@ -77,7 +77,9 @@ void CommandBufferImpl::close()
Result CommandBufferImpl::getNativeHandle(InteropHandle* outHandle)
{
- return SLANG_E_NOT_IMPLEMENTED;
+ outHandle->api = InteropHandleAPI::Metal;
+ outHandle->handleValue = reinterpret_cast<intptr_t>(m_commandBuffer.get());
+ return SLANG_OK;
}
MTL::RenderCommandEncoder* CommandBufferImpl::getMetalRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDesc)
diff --git a/tools/gfx/metal/metal-command-encoder.cpp b/tools/gfx/metal/metal-command-encoder.cpp
index 3e0fbd1f6..fa1df263e 100644
--- a/tools/gfx/metal/metal-command-encoder.cpp
+++ b/tools/gfx/metal/metal-command-encoder.cpp
@@ -227,7 +227,7 @@ void RenderCommandEncoder::beginPass(IRenderPassLayout* renderPass, IFramebuffer
{
TextureResourceViewImpl* renderTargetView = m_framebuffer->m_renderTargetViews[i];
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = m_renderPassDesc->colorAttachments()->object(i);
- colorAttachment->setTexture(renderTargetView->m_texture->m_texture.get());
+ colorAttachment->setTexture(renderTargetView->m_textureView.get());
colorAttachment->setLevel(renderTargetView->m_desc.subresourceRange.mipLevel);
colorAttachment->setSlice(renderTargetView->m_desc.subresourceRange.baseArrayLayer);
}
@@ -239,14 +239,14 @@ void RenderCommandEncoder::beginPass(IRenderPassLayout* renderPass, IFramebuffer
if (MetalUtil::isDepthFormat(pixelFormat))
{
MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = m_renderPassDesc->depthAttachment();
- depthAttachment->setTexture(depthStencilView->m_texture->m_texture.get());
+ depthAttachment->setTexture(depthStencilView->m_textureView.get());
depthAttachment->setLevel(depthStencilView->m_desc.subresourceRange.mipLevel);
depthAttachment->setSlice(depthStencilView->m_desc.subresourceRange.baseArrayLayer);
}
if (MetalUtil::isStencilFormat(pixelFormat))
{
MTL::RenderPassStencilAttachmentDescriptor* stencilAttachment = m_renderPassDesc->stencilAttachment();
- stencilAttachment->setTexture(depthStencilView->m_texture->m_texture.get());
+ stencilAttachment->setTexture(depthStencilView->m_textureView.get());
stencilAttachment->setLevel(depthStencilView->m_desc.subresourceRange.mipLevel);
stencilAttachment->setSlice(depthStencilView->m_desc.subresourceRange.baseArrayLayer);
}
diff --git a/tools/gfx/metal/metal-device.cpp b/tools/gfx/metal/metal-device.cpp
index a4cf23da3..1be9d1019 100644
--- a/tools/gfx/metal/metal-device.cpp
+++ b/tools/gfx/metal/metal-device.cpp
@@ -292,6 +292,11 @@ Result DeviceImpl::createTextureResource(
TextureResource::Desc desc = fixupTextureDesc(descIn);
+ // Metal doesn't support mip-mapping for 1D textures
+ // However, we still need to use the provided mip level count when initializing the texture
+ Count initMipLevels = desc.numMipLevels;
+ desc.numMipLevels = desc.type == IResource::Type::Texture1D ? 1 : desc.numMipLevels;
+
const MTL::PixelFormat pixelFormat = MetalUtil::translatePixelFormat(desc.format);
if (pixelFormat == MTL::PixelFormat::PixelFormatInvalid)
{
@@ -316,29 +321,29 @@ Result DeviceImpl::createTextureResource(
break;
}
- NS::UInteger arrayLength = calcEffectiveArraySize(desc);
+ bool isArray = desc.arraySize > 0;
switch (desc.type)
{
case IResource::Type::Texture1D:
- textureDesc->setTextureType(arrayLength > 1 ? MTL::TextureType1DArray : MTL::TextureType1D);
+ textureDesc->setTextureType(isArray ? MTL::TextureType1DArray : MTL::TextureType1D);
textureDesc->setWidth(desc.size.width);
break;
case IResource::Type::Texture2D:
if (desc.sampleDesc.numSamples > 1)
{
- textureDesc->setTextureType(arrayLength > 1 ? MTL::TextureType2DMultisampleArray : MTL::TextureType2DMultisample);
+ textureDesc->setTextureType(isArray ? MTL::TextureType2DMultisampleArray : MTL::TextureType2DMultisample);
textureDesc->setSampleCount(desc.sampleDesc.numSamples);
}
else
{
- textureDesc->setTextureType(arrayLength > 1 ? MTL::TextureType2DArray : MTL::TextureType2D);
+ textureDesc->setTextureType(isArray ? MTL::TextureType2DArray : MTL::TextureType2D);
}
textureDesc->setWidth(descIn.size.width);
textureDesc->setHeight(descIn.size.height);
break;
case IResource::Type::TextureCube:
- textureDesc->setTextureType(arrayLength > 6 ? MTL::TextureTypeCubeArray : MTL::TextureTypeCube);
+ textureDesc->setTextureType(isArray ? MTL::TextureTypeCubeArray : MTL::TextureTypeCube);
textureDesc->setWidth(descIn.size.width);
textureDesc->setHeight(descIn.size.height);
break;
@@ -369,7 +374,7 @@ Result DeviceImpl::createTextureResource(
}
textureDesc->setMipmapLevelCount(desc.numMipLevels);
- textureDesc->setArrayLength(arrayLength);
+ textureDesc->setArrayLength(isArray ? desc.arraySize : 1);
textureDesc->setPixelFormat(pixelFormat);
textureDesc->setUsage(textureUsage);
textureDesc->setSampleCount(desc.sampleDesc.numSamples);
@@ -380,8 +385,52 @@ Result DeviceImpl::createTextureResource(
{
return SLANG_FAIL;
}
+ textureImpl->m_textureType = textureDesc->textureType();
+ textureImpl->m_pixelFormat = textureDesc->pixelFormat();
// TODO: handle initData
+ if (initData)
+ {
+ textureDesc->setStorageMode(MTL::StorageModeManaged);
+ textureDesc->setCpuCacheMode(MTL::CPUCacheModeDefaultCache);
+ NS::SharedPtr<MTL::Texture> stagingTexture = NS::TransferPtr(m_device->newTexture(textureDesc.get()));
+
+ MTL::CommandBuffer* commandBuffer = m_commandQueue->commandBuffer();
+ MTL::BlitCommandEncoder* encoder = commandBuffer->blitCommandEncoder();
+ if (!stagingTexture || !commandBuffer || !encoder)
+ {
+ return SLANG_FAIL;
+ }
+
+ Count sliceCount = isArray ? desc.arraySize : 1;
+ if (desc.type == IResource::Type::TextureCube)
+ {
+ sliceCount *= 6;
+ }
+
+ for (Index slice = 0; slice < sliceCount; ++slice)
+ {
+ MTL::Region region;
+ region.origin = MTL::Origin(0, 0, 0);
+ region.size = MTL::Size(desc.size.width, desc.size.height, desc.size.depth);
+ for (Index level = 0; level < initMipLevels; ++level)
+ {
+ if (level >= desc.numMipLevels)
+ continue;
+ const ITextureResource::SubresourceData& subresourceData = initData[slice * initMipLevels + level];
+ stagingTexture->replaceRegion(region, level, slice, subresourceData.data, subresourceData.strideY, subresourceData.strideZ);
+ encoder->synchronizeTexture(stagingTexture.get(), slice, level);
+ region.size.width = region.size.width > 0 ? Math::Max(1ul, region.size.width >> 1) : 0;
+ region.size.height = region.size.height > 0 ? Math::Max(1ul, region.size.height >> 1) : 0;
+ region.size.depth = region.size.depth > 0 ? Math::Max(1ul, region.size.depth >> 1) : 0;
+ }
+ }
+
+ encoder->copyFromTexture(stagingTexture.get(), textureImpl->m_texture.get());
+ encoder->endEncoding();
+ commandBuffer->commit();
+ commandBuffer->waitUntilCompleted();
+ }
returnComPtr(outResource, textureImpl);
return SLANG_OK;
@@ -461,52 +510,40 @@ Result DeviceImpl::createTextureView(
{
AUTORELEASEPOOL
- auto resourceImpl = static_cast<TextureResourceImpl*>(texture);
- RefPtr<TextureResourceViewImpl> view = new TextureResourceViewImpl(this);
- view->m_desc = desc;
- view->m_device = this;
- if (texture == nullptr)
+ auto textureImpl = static_cast<TextureResourceImpl*>(texture);
+ RefPtr<TextureResourceViewImpl> viewImpl = new TextureResourceViewImpl(this);
+ viewImpl->m_desc = desc;
+ viewImpl->m_device = this;
+ viewImpl->m_texture = textureImpl;
+ if (textureImpl == nullptr)
{
- view->m_texture = nullptr;
- returnComPtr(outView, view);
+ returnComPtr(outView, viewImpl);
return SLANG_OK;
}
- bool isArray = resourceImpl->getDesc()->arraySize > 1;
- MTL::PixelFormat pixelFormat = MetalUtil::translatePixelFormat(desc.format);
- NS::Range levelRange(desc.subresourceRange.baseArrayLayer, std::max(desc.subresourceRange.layerCount, 1));
- NS::Range sliceRange(desc.subresourceRange.mipLevel, std::max(desc.subresourceRange.mipLevelCount, 1));
- MTL::TextureType textureType;
- switch (resourceImpl->getType())
- {
- case IResource::Type::Texture1D:
- textureType = isArray ? MTL::TextureType1DArray : MTL::TextureType1D;
- break;
- case IResource::Type::Texture2D:
- textureType = isArray ? MTL::TextureType2DArray : MTL::TextureType2D;
- break;
- case IResource::Type::Texture3D:
+ const ITextureResource::Desc& textureDesc = *textureImpl->getDesc();
+ SubresourceRange sr = desc.subresourceRange;
+ sr.mipLevelCount = sr.mipLevelCount == 0 ? textureDesc.numMipLevels - sr.mipLevel : sr.mipLevelCount;
+ sr.layerCount = sr.layerCount == 0 ? textureDesc.arraySize - sr.baseArrayLayer : sr.layerCount;
+ if (sr.mipLevel == 0 && sr.mipLevelCount == textureDesc.numMipLevels &&
+ sr.baseArrayLayer == 0 && sr.layerCount == textureDesc.arraySize)
{
- if (isArray) SLANG_UNIMPLEMENTED_X("Metal does not support arrays of 3D textures.");
- textureType = MTL::TextureType3D;
- break;
- }
- case IResource::Type::TextureCube:
- textureType = isArray ? MTL::TextureTypeCube : MTL::TextureTypeCubeArray;
- break;
- default:
- SLANG_UNIMPLEMENTED_X("Unsupported texture type.");
- break;
+ viewImpl->m_textureView = textureImpl->m_texture;
+ returnComPtr(outView, viewImpl);
+ return SLANG_OK;
}
- ITextureResource::Desc newDesc = *texture->getDesc();
- newDesc.numMipLevels = levelRange.length;
- newDesc.arraySize = sliceRange.length;
- view->m_type = ResourceViewImpl::ViewType::Texture;
- view->m_texture = resourceImpl; //new TextureResourceImpl(newDesc, this);
- view->m_texture->m_texture = NS::TransferPtr(resourceImpl->m_texture->newTextureView(pixelFormat, textureType, levelRange, sliceRange));
- returnComPtr(outView, view);
+ MTL::PixelFormat pixelFormat = desc.format == Format::Unknown ? textureImpl->m_pixelFormat : MetalUtil::translatePixelFormat(desc.format);
+ NS::Range levelRange(sr.baseArrayLayer, sr.layerCount);
+ NS::Range sliceRange(sr.mipLevel, sr.mipLevelCount);
+ viewImpl->m_textureView = NS::TransferPtr(textureImpl->m_texture->newTextureView(pixelFormat, textureImpl->m_textureType, levelRange, sliceRange));
+ if (!viewImpl->m_textureView)
+ {
+ return SLANG_FAIL;
+ }
+
+ returnComPtr(outView, viewImpl);
return SLANG_OK;
}
diff --git a/tools/gfx/metal/metal-pipeline-state.cpp b/tools/gfx/metal/metal-pipeline-state.cpp
index 8daaeccda..b23aab2b9 100644
--- a/tools/gfx/metal/metal-pipeline-state.cpp
+++ b/tools/gfx/metal/metal-pipeline-state.cpp
@@ -212,7 +212,18 @@ Result PipelineStateImpl::ensureAPIPipelineStateCreated()
SLANG_NO_THROW Result SLANG_MCALL PipelineStateImpl::getNativeHandle(InteropHandle* outHandle)
{
- return SLANG_E_NOT_IMPLEMENTED;
+ switch (desc.type)
+ {
+ case PipelineType::Compute:
+ outHandle->api = InteropHandleAPI::Metal;
+ outHandle->handleValue = reinterpret_cast<intptr_t>(m_computePipelineState.get());
+ return SLANG_OK;
+ case PipelineType::Graphics:
+ outHandle->api = InteropHandleAPI::Metal;
+ outHandle->handleValue = reinterpret_cast<intptr_t>(m_renderPipelineState.get());
+ return SLANG_OK;
+ }
+ return SLANG_FAIL;
}
RayTracingPipelineStateImpl::RayTracingPipelineStateImpl(DeviceImpl* device)
diff --git a/tools/gfx/metal/metal-resource-views.h b/tools/gfx/metal/metal-resource-views.h
index 9a8e24ab5..89986f19d 100644
--- a/tools/gfx/metal/metal-resource-views.h
+++ b/tools/gfx/metal/metal-resource-views.h
@@ -41,6 +41,7 @@ public:
{}
~TextureResourceViewImpl();
RefPtr<TextureResourceImpl> m_texture;
+ NS::SharedPtr<MTL::Texture> m_textureView;
virtual SLANG_NO_THROW Result SLANG_MCALL getNativeHandle(InteropHandle* outHandle) override;
};
diff --git a/tools/gfx/metal/metal-shader-object.cpp b/tools/gfx/metal/metal-shader-object.cpp
index fde04f9ba..33e19bc6f 100644
--- a/tools/gfx/metal/metal-shader-object.cpp
+++ b/tools/gfx/metal/metal-shader-object.cpp
@@ -388,7 +388,7 @@ Result ShaderObjectImpl::bindAsValue(
for (uint32_t i = 0; i < count; ++i)
{
auto texture = m_textures[baseIndex + i];
- context->setTexture(texture ? texture->m_texture->m_texture.get() : nullptr, registerOffset + i);
+ context->setTexture(texture ? texture->m_textureView.get() : nullptr, registerOffset + i);
}
}
diff --git a/tools/gfx/metal/metal-texture.h b/tools/gfx/metal/metal-texture.h
index 8f8ab3576..aff49beb6 100644
--- a/tools/gfx/metal/metal-texture.h
+++ b/tools/gfx/metal/metal-texture.h
@@ -22,9 +22,8 @@ public:
BreakableReference<DeviceImpl> m_device;
NS::SharedPtr<MTL::Texture> m_texture;
- // TODO still needed?
- // MTL::PixelFormat m_metalFormat = MTL::PixelFormat::PixelFormatInvalid;
- // bool m_isWeakImageReference = false;
+ MTL::TextureType m_textureType;
+ MTL::PixelFormat m_pixelFormat;
virtual SLANG_NO_THROW Result SLANG_MCALL getNativeResourceHandle(InteropHandle* outHandle) override;