summaryrefslogtreecommitdiff
path: root/tools/gfx/metal/metal-command-encoder.cpp
diff options
context:
space:
mode:
authorskallweitNV <64953474+skallweitNV@users.noreply.github.com>2024-06-06 18:08:38 +0200
committerGitHub <noreply@github.com>2024-06-06 09:08:38 -0700
commit8ea3854d94eb1ff213be716a38493d601784810b (patch)
tree071be96574be4afa54afe0a1fe0d66f10eb2cd80 /tools/gfx/metal/metal-command-encoder.cpp
parent40d48bf1742cf21cc1ad3dd00d11fb04f37e512f (diff)
work on gfx metal backend (#4287)
* implement sampler state * implement input layout * implement fence object * buffer implementation * texture implementation * cleanup * add adapter enumeration * supported formats and allocation info * work on device and implement readBufferResource * skeleton for transient resource heap * initial work on command queue / buffers / encoders * fix uploading initial buffer data * implement buffer resource view * string utility functions * wip query pool implementation * cleanup * swapchain * wip * remove plain buffer view * extend gfxGetDeviceTypeName with metal * basic support for resource binding with compute shaders * needed for metal bindings * replace assert(0) with SLANG_UNIMPLEMENTED_X
Diffstat (limited to 'tools/gfx/metal/metal-command-encoder.cpp')
-rw-r--r--tools/gfx/metal/metal-command-encoder.cpp190
1 files changed, 133 insertions, 57 deletions
diff --git a/tools/gfx/metal/metal-command-encoder.cpp b/tools/gfx/metal/metal-command-encoder.cpp
index 1e74733d1..f1e834400 100644
--- a/tools/gfx/metal/metal-command-encoder.cpp
+++ b/tools/gfx/metal/metal-command-encoder.cpp
@@ -10,6 +10,7 @@
#include "metal-shader-program.h"
#include "metal-shader-table.h"
#include "metal-texture.h"
+#include "metal-util.h"
#include "metal-helper-functions.h"
@@ -24,37 +25,46 @@ namespace metal
void PipelineCommandEncoder::init(CommandBufferImpl* commandBuffer)
{
m_commandBuffer = commandBuffer;
- m_device = commandBuffer->m_renderer;
- m_metalCommandBuffer = m_commandBuffer->m_commandBuffer;
+ m_metalCommandBuffer = m_commandBuffer->m_commandBuffer.get();
}
-void ResourceCommandEncoder::copyBuffer(
- IBufferResource* dst, Offset dstOffset, IBufferResource* src, Offset srcOffset, Size size)
+void PipelineCommandEncoder::endEncodingImpl()
{
+ m_commandBuffer->endMetalCommandEncoder();
}
-void ResourceCommandEncoder::uploadBufferData(
- IBufferResource* buffer, Offset offset, Size size, void* data)
-{
-}
-
-void ResourceCommandEncoder::textureBarrier(
- GfxCount count, ITextureResource* const* textures, ResourceState src, ResourceState dst)
+Result PipelineCommandEncoder::setPipelineStateImpl(IPipelineState* state, IShaderObject** outRootObject)
{
+ m_currentPipeline = static_cast<PipelineStateImpl*>(state);
+ // m_commandBuffer->m_mutableRootShaderObject = nullptr;
+ SLANG_RETURN_ON_FAIL(m_commandBuffer->m_rootObject.init(
+ m_commandBuffer->m_device,
+ m_currentPipeline->getProgram<ShaderProgramImpl>()->m_rootObjectLayout));
+ *outRootObject = &m_commandBuffer->m_rootObject;
+ return SLANG_OK;
}
-// TODO: Change size_t to Count?
-void ResourceCommandEncoder::bufferBarrier(
- GfxCount count, IBufferResource* const* buffers, ResourceState src, ResourceState dst)
+void ResourceCommandEncoder::endEncoding()
{
+ PipelineCommandEncoder::endEncodingImpl();
}
-void ResourceCommandEncoder::endEncoding()
+void ResourceCommandEncoder::writeTimestamp(IQueryPool* queryPool, GfxIndex index)
{
+ auto encoder = m_commandBuffer->getMetalBlitCommandEncoder();
+ encoder->sampleCountersInBuffer(static_cast<QueryPoolImpl*>(queryPool)->m_counterSampleBuffer.get(), index, true);
}
-void ResourceCommandEncoder::writeTimestamp(IQueryPool* queryPool, GfxIndex index)
+void ResourceCommandEncoder::copyBuffer(
+ IBufferResource* dst, Offset dstOffset, IBufferResource* src, Offset srcOffset, Size size)
{
+ auto encoder = m_commandBuffer->getMetalBlitCommandEncoder();
+ encoder->copyFromBuffer(
+ static_cast<BufferResourceImpl*>(src)->m_buffer.get(),
+ srcOffset,
+ static_cast<BufferResourceImpl*>(dst)->m_buffer.get(),
+ dstOffset,
+ size);
}
void ResourceCommandEncoder::copyTexture(
@@ -68,6 +78,62 @@ void ResourceCommandEncoder::copyTexture(
ITextureResource::Offset3D srcOffset,
ITextureResource::Extents extent)
{
+ auto encoder = m_commandBuffer->getMetalBlitCommandEncoder();
+
+ if (dstSubresource.layerCount == 0 && dstSubresource.mipLevelCount == 0 && srcSubresource.layerCount == 0 && srcSubresource.mipLevelCount == 0)
+ {
+ encoder->copyFromTexture(
+ static_cast<TextureResourceImpl*>(src)->m_texture.get(),
+ static_cast<TextureResourceImpl*>(dst)->m_texture.get());
+ }
+ else
+ {
+ for (GfxIndex layer = 0; layer < dstSubresource.layerCount; layer++)
+ {
+ encoder->copyFromTexture(
+ static_cast<TextureResourceImpl*>(src)->m_texture.get(),
+ srcSubresource.baseArrayLayer + layer,
+ srcSubresource.mipLevel,
+ MTL::Origin(srcOffset.x, srcOffset.y, srcOffset.z),
+ MTL::Size(extent.width, extent.height, extent.depth),
+ static_cast<TextureResourceImpl*>(dst)->m_texture.get(),
+ dstSubresource.baseArrayLayer + layer,
+ dstSubresource.mipLevel,
+ MTL::Origin(dstOffset.x, dstOffset.y, dstOffset.z));
+ }
+ }
+}
+
+void ResourceCommandEncoder::copyTextureToBuffer(
+ IBufferResource* dst,
+ Offset dstOffset,
+ Size dstSize,
+ Size dstRowStride,
+ ITextureResource* src,
+ ResourceState srcState,
+ SubresourceRange srcSubresource,
+ ITextureResource::Offset3D srcOffset,
+ ITextureResource::Extents extent)
+{
+ assert(srcSubresource.mipLevelCount <= 1);
+
+ auto encoder = m_commandBuffer->getMetalBlitCommandEncoder();
+ encoder->copyFromTexture(
+ static_cast<TextureResourceImpl*>(src)->m_texture.get(),
+ srcSubresource.baseArrayLayer,
+ srcSubresource.mipLevel,
+ MTL::Origin(srcOffset.x, srcOffset.y, srcOffset.z),
+ MTL::Size(extent.width, extent.height, extent.depth),
+ static_cast<BufferResourceImpl*>(dst)->m_buffer.get(),
+ dstOffset,
+ dstRowStride,
+ dstSize);
+}
+
+void ResourceCommandEncoder::uploadBufferData(
+ IBufferResource* buffer, Offset offset, Size size, void* data)
+{
+ SLANG_UNIMPLEMENTED_X("uploadBufferData");
}
void ResourceCommandEncoder::uploadTextureData(
@@ -78,12 +144,34 @@ void ResourceCommandEncoder::uploadTextureData(
ITextureResource::SubresourceData* subResourceData,
GfxCount subResourceDataCount)
{
+ SLANG_UNIMPLEMENTED_X("uploadTextureData");
}
+void ResourceCommandEncoder::bufferBarrier(
+ GfxCount count, IBufferResource* const* buffers, ResourceState src, ResourceState dst)
+{
+ // We use automatic hazard tracking for now, no need for barriers.
+}
+
+void ResourceCommandEncoder::textureBarrier(
+ GfxCount count, ITextureResource* const* textures, ResourceState src, ResourceState dst)
+{
+ // We use automatic hazard tracking for now, no need for barriers.
+}
+
+void ResourceCommandEncoder::textureSubresourceBarrier(
+ ITextureResource* texture,
+ SubresourceRange subresourceRange,
+ ResourceState src,
+ ResourceState dst)
+{
+ // We use automatic hazard tracking for now, no need for barriers.
+}
void ResourceCommandEncoder::clearResourceView(
IResourceView* view, ClearValue* clearValue, ClearResourceViewFlags::Enum flags)
{
+ SLANG_UNIMPLEMENTED_X("clearResourceView");
}
void ResourceCommandEncoder::resolveResource(
@@ -94,41 +182,29 @@ void ResourceCommandEncoder::resolveResource(
ResourceState destState,
SubresourceRange destRange)
{
+ SLANG_UNIMPLEMENTED_X("resolveResource");
}
void ResourceCommandEncoder::resolveQuery(
IQueryPool* queryPool, GfxIndex index, GfxCount count, IBufferResource* buffer, Offset offset)
{
-}
-
-void ResourceCommandEncoder::copyTextureToBuffer(
- IBufferResource* dst,
- Offset dstOffset,
- Size dstSize,
- Size dstRowStride,
- ITextureResource* src,
- ResourceState srcState,
- SubresourceRange srcSubresource,
- ITextureResource::Offset3D srcOffset,
- ITextureResource::Extents extent)
-{
- assert(srcSubresource.mipLevelCount <= 1);
-}
-
-void ResourceCommandEncoder::textureSubresourceBarrier(
- ITextureResource* texture,
- SubresourceRange subresourceRange,
- ResourceState src,
- ResourceState dst)
-{
+ auto encoder = m_commandBuffer->getMetalBlitCommandEncoder();
+ encoder->resolveCounters(
+ static_cast<QueryPoolImpl*>(queryPool)->m_counterSampleBuffer.get(),
+ NS::Range(index, count),
+ static_cast<BufferResourceImpl*>(buffer)->m_buffer.get(),
+ offset);
}
void ResourceCommandEncoder::beginDebugEvent(const char* name, float rgbColor[3])
{
+ NS::SharedPtr<NS::String> string = MetalUtil::createString(name);
+ m_commandBuffer->m_commandBuffer->pushDebugGroup(string.get());
}
void ResourceCommandEncoder::endDebugEvent()
{
+ m_commandBuffer->m_commandBuffer->popDebugGroup();
}
void RenderCommandEncoder::beginPass(IRenderPassLayout* renderPass, IFramebuffer* framebuffer)
@@ -145,7 +221,7 @@ void RenderCommandEncoder::beginPass(IRenderPassLayout* renderPass, IFramebuffer
if (rpd->depthAttachment() && false)
{
TextureResourceViewImpl* depthView = static_cast<TextureResourceViewImpl*>(fb->depthStencilView.get());
- rpd->depthAttachment()->setTexture(depthView->m_texture->m_texture);
+ rpd->depthAttachment()->setTexture(depthView->m_texture->m_texture.get());
}
const int colorTargetCount = fb->renderTargetViews.getCount();
for (int i = 0; i < colorTargetCount; ++i)
@@ -153,15 +229,7 @@ void RenderCommandEncoder::beginPass(IRenderPassLayout* renderPass, IFramebuffer
TextureResourceViewImpl* texView = static_cast<TextureResourceViewImpl*>(fb->renderTargetViews[i].get());
MTL::Texture* tex = nullptr;
assert(texView->m_texture);
- if (texView->m_texture->m_isCurrentDrawable)
- {
- CA::MetalDrawable* drawable = static_cast<CA::MetalDrawable*>(fb->m_renderer->m_drawable);
- tex = drawable->texture();
- }
- else
- {
- tex = texView->m_texture->m_texture;
- }
+ tex = texView->m_texture->m_texture.get();
rpd->colorAttachments()->object(i)->setTexture(tex);
rpd->colorAttachments()->object(i)->setClearColor(MTL::ClearColor(0.2, 0.4, 0.9, 1.0));
}
@@ -181,7 +249,7 @@ Result RenderCommandEncoder::bindPipeline(
{
m_currentPipeline = static_cast<PipelineStateImpl*>(pipelineState);
// Initialize the root object
- SLANG_RETURN_ON_FAIL(m_commandBuffer->m_rootObject.init(m_commandBuffer->m_renderer,
+ SLANG_RETURN_ON_FAIL(m_commandBuffer->m_rootObject.init(m_commandBuffer->m_device,
m_currentPipeline->getProgram<ShaderProgramImpl>()->m_rootObjectLayout));
*outRootObject = &m_commandBuffer->m_rootObject;
//if (pPipelineState->m_renderState == nullptr) return SLANG_ERROR_INVALID_PARAMETER;
@@ -249,8 +317,8 @@ void RenderCommandEncoder::setVertexBuffers(
BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(buffers[i]);
if (buffer)
{
- MTL::Buffer* vertexBuffers = {buffer->m_buffer};
- m_encoder->setVertexBuffer(buffer->m_buffer, offsets[i], slotIndex);
+ MTL::Buffer* vertexBuffers = {buffer->m_buffer.get()};
+ m_encoder->setVertexBuffer(buffer->m_buffer.get(), offsets[i], slotIndex);
// ...
}
}
@@ -369,12 +437,15 @@ Result RenderCommandEncoder::drawMeshTasks(int x, int y, int z)
return SLANG_E_NOT_IMPLEMENTED;
}
-void ComputeCommandEncoder::endEncoding() { }
+void ComputeCommandEncoder::endEncoding()
+{
+ ResourceCommandEncoder::endEncoding();
+}
Result ComputeCommandEncoder::bindPipeline(
IPipelineState* pipelineState, IShaderObject** outRootObject)
{
- return SLANG_E_NOT_IMPLEMENTED;
+ return setPipelineStateImpl(pipelineState, outRootObject);
}
Result ComputeCommandEncoder::bindPipelineWithRootObject(
@@ -386,10 +457,15 @@ Result ComputeCommandEncoder::bindPipelineWithRootObject(
Result ComputeCommandEncoder::dispatchCompute(int x, int y, int z)
{
auto pipeline = static_cast<PipelineStateImpl*>(m_currentPipeline.Ptr());
- if (!pipeline)
- {
- return SLANG_FAIL;
- }
+ pipeline->ensureAPIPipelineStateCreated();
+
+ auto metalComputeCommandEncoder = m_commandBuffer->getMetalComputeCommandEncoder();
+ metalComputeCommandEncoder->setComputePipelineState(pipeline->m_computePipelineState.get());
+ ComputeBindingContext bindingContext;
+ bindingContext.init(m_commandBuffer->m_device, metalComputeCommandEncoder);
+ auto program = static_cast<ShaderProgramImpl*>(m_currentPipeline->m_program.get());
+ m_commandBuffer->m_rootObject.bindAsRoot(&bindingContext, program->m_rootObjectLayout);
+ metalComputeCommandEncoder->dispatchThreadgroups(MTL::Size(x, y, z), pipeline->m_threadGroupSize);
// Also create descriptor sets based on the given pipeline layout
return SLANG_E_NOT_IMPLEMENTED;