Format: src/backend/metal

This commit is contained in:
Corentin Wallez 2017-11-24 14:12:44 -05:00 committed by Corentin Wallez
parent 2d62a371ee
commit f58d84d488
29 changed files with 688 additions and 771 deletions

View File

@ -18,8 +18,7 @@
#include "backend/BlendState.h" #include "backend/BlendState.h"
#import <Metal/Metal.h> #import <Metal/Metal.h>
namespace backend { namespace backend { namespace metal {
namespace metal {
class BlendState : public BlendStateBase { class BlendState : public BlendStateBase {
public: public:
@ -28,7 +27,6 @@ namespace metal {
void ApplyBlendState(MTLRenderPipelineColorAttachmentDescriptor* descriptor) const; void ApplyBlendState(MTLRenderPipelineColorAttachmentDescriptor* descriptor) const;
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_BLENDSTATEMTL_H_ #endif // BACKEND_METAL_BLENDSTATEMTL_H_

View File

@ -16,8 +16,7 @@
#include "backend/metal/MetalBackend.h" #include "backend/metal/MetalBackend.h"
namespace backend { namespace backend { namespace metal {
namespace metal {
namespace { namespace {
@ -48,7 +47,8 @@ namespace metal {
case nxt::BlendFactor::BlendColor: case nxt::BlendFactor::BlendColor:
return alpha ? MTLBlendFactorBlendAlpha : MTLBlendFactorBlendColor; return alpha ? MTLBlendFactorBlendAlpha : MTLBlendFactorBlendColor;
case nxt::BlendFactor::OneMinusBlendColor: case nxt::BlendFactor::OneMinusBlendColor:
return alpha ? MTLBlendFactorOneMinusBlendAlpha : MTLBlendFactorOneMinusBlendColor; return alpha ? MTLBlendFactorOneMinusBlendAlpha
: MTLBlendFactorOneMinusBlendColor;
} }
} }
@ -68,14 +68,19 @@ namespace metal {
} }
MTLColorWriteMask MetalColorWriteMask(nxt::ColorWriteMask colorWriteMask) { MTLColorWriteMask MetalColorWriteMask(nxt::ColorWriteMask colorWriteMask) {
return ( return (((colorWriteMask & nxt::ColorWriteMask::Red) != nxt::ColorWriteMask::None
((colorWriteMask & nxt::ColorWriteMask::Red) != nxt::ColorWriteMask::None ? MTLColorWriteMaskRed : MTLColorWriteMaskNone) | ? MTLColorWriteMaskRed
((colorWriteMask & nxt::ColorWriteMask::Green) != nxt::ColorWriteMask::None ? MTLColorWriteMaskGreen : MTLColorWriteMaskNone) | : MTLColorWriteMaskNone) |
((colorWriteMask & nxt::ColorWriteMask::Blue) != nxt::ColorWriteMask::None ? MTLColorWriteMaskBlue : MTLColorWriteMaskNone) | ((colorWriteMask & nxt::ColorWriteMask::Green) != nxt::ColorWriteMask::None
((colorWriteMask & nxt::ColorWriteMask::Alpha) != nxt::ColorWriteMask::None ? MTLColorWriteMaskAlpha : MTLColorWriteMaskNone) ? MTLColorWriteMaskGreen
); : MTLColorWriteMaskNone) |
((colorWriteMask & nxt::ColorWriteMask::Blue) != nxt::ColorWriteMask::None
? MTLColorWriteMaskBlue
: MTLColorWriteMaskNone) |
((colorWriteMask & nxt::ColorWriteMask::Alpha) != nxt::ColorWriteMask::None
? MTLColorWriteMaskAlpha
: MTLColorWriteMaskNone));
} }
} }
BlendState::BlendState(BlendStateBuilder* builder) : BlendStateBase(builder) { BlendState::BlendState(BlendStateBuilder* builder) : BlendStateBase(builder) {
@ -92,5 +97,5 @@ namespace metal {
descriptor.alphaBlendOperation = MetalBlendOperation(info.alphaBlend.operation); descriptor.alphaBlendOperation = MetalBlendOperation(info.alphaBlend.operation);
descriptor.writeMask = MetalColorWriteMask(info.colorWriteMask); descriptor.writeMask = MetalColorWriteMask(info.colorWriteMask);
} }
}
} }} // namespace backend::metal

View File

@ -20,8 +20,7 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
namespace backend { namespace backend { namespace metal {
namespace metal {
class Device; class Device;
@ -38,7 +37,8 @@ namespace metal {
void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override; void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override;
void MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) override; void MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) override;
void UnmapImpl() override; void UnmapImpl() override;
void TransitionUsageImpl(nxt::BufferUsageBit currentUsage, nxt::BufferUsageBit targetUsage) override; void TransitionUsageImpl(nxt::BufferUsageBit currentUsage,
nxt::BufferUsageBit targetUsage) override;
id<MTLBuffer> mMtlBuffer = nil; id<MTLBuffer> mMtlBuffer = nil;
}; };
@ -67,7 +67,6 @@ namespace metal {
SerialQueue<Request> mInflightRequests; SerialQueue<Request> mInflightRequests;
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_BUFFERMTL_H_ #endif // BACKEND_METAL_BUFFERMTL_H_

View File

@ -17,12 +17,9 @@
#include "backend/metal/MetalBackend.h" #include "backend/metal/MetalBackend.h"
#include "backend/metal/ResourceUploader.h" #include "backend/metal/ResourceUploader.h"
namespace backend { namespace backend { namespace metal {
namespace metal {
Buffer::Buffer(BufferBuilder* builder)
: BufferBase(builder) {
Buffer::Buffer(BufferBuilder* builder) : BufferBase(builder) {
MTLResourceOptions storageMode; MTLResourceOptions storageMode;
if (GetAllowedUsage() & (nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::MapWrite)) { if (GetAllowedUsage() & (nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::MapWrite)) {
storageMode = MTLResourceStorageModeShared; storageMode = MTLResourceStorageModeShared;
@ -50,7 +47,8 @@ namespace metal {
void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) { void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) {
auto* uploader = ToBackend(GetDevice())->GetResourceUploader(); auto* uploader = ToBackend(GetDevice())->GetResourceUploader();
uploader->BufferSubData(mMtlBuffer, start * sizeof(uint32_t), count * sizeof(uint32_t), data); uploader->BufferSubData(mMtlBuffer, start * sizeof(uint32_t), count * sizeof(uint32_t),
data);
} }
void Buffer::MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t) { void Buffer::MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t) {
@ -65,12 +63,10 @@ namespace metal {
void Buffer::TransitionUsageImpl(nxt::BufferUsageBit, nxt::BufferUsageBit) { void Buffer::TransitionUsageImpl(nxt::BufferUsageBit, nxt::BufferUsageBit) {
} }
BufferView::BufferView(BufferViewBuilder* builder) BufferView::BufferView(BufferViewBuilder* builder) : BufferViewBase(builder) {
: BufferViewBase(builder) {
} }
MapReadRequestTracker::MapReadRequestTracker(Device* device) MapReadRequestTracker::MapReadRequestTracker(Device* device) : mDevice(device) {
: mDevice(device) {
} }
MapReadRequestTracker::~MapReadRequestTracker() { MapReadRequestTracker::~MapReadRequestTracker() {
@ -92,5 +88,5 @@ namespace metal {
} }
mInflightRequests.ClearUpTo(finishedSerial); mInflightRequests.ClearUpTo(finishedSerial);
} }
}
} }} // namespace backend::metal

View File

@ -19,8 +19,7 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
namespace backend { namespace backend { namespace metal {
namespace metal {
class Device; class Device;
@ -36,7 +35,6 @@ namespace metal {
CommandIterator mCommands; CommandIterator mCommands;
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_COMMANDBUFFERMTL_H_ #endif // BACKEND_METAL_COMMANDBUFFERMTL_H_

View File

@ -25,8 +25,7 @@
#include "backend/metal/SamplerMTL.h" #include "backend/metal/SamplerMTL.h"
#include "backend/metal/TextureMTL.h" #include "backend/metal/TextureMTL.h"
namespace backend { namespace backend { namespace metal {
namespace metal {
namespace { namespace {
struct CurrentEncoders { struct CurrentEncoders {
@ -77,7 +76,8 @@ namespace metal {
const auto& info = currentRenderPass->GetSubpassInfo(subpass); const auto& info = currentRenderPass->GetSubpassInfo(subpass);
MTLRenderPassDescriptor* descriptor = [MTLRenderPassDescriptor renderPassDescriptor]; MTLRenderPassDescriptor* descriptor =
[MTLRenderPassDescriptor renderPassDescriptor];
for (unsigned int location : IterateBitSet(info.colorAttachmentsSet)) { for (unsigned int location : IterateBitSet(info.colorAttachmentsSet)) {
uint32_t attachment = info.colorAttachments[location]; uint32_t attachment = info.colorAttachments[location];
const auto& attachmentInfo = currentRenderPass->GetAttachmentInfo(attachment); const auto& attachmentInfo = currentRenderPass->GetAttachmentInfo(attachment);
@ -90,7 +90,9 @@ namespace metal {
if (isFirstUse && shouldClearOnFirstUse) { if (isFirstUse && shouldClearOnFirstUse) {
auto clearValue = currentFramebuffer->GetClearColor(location); auto clearValue = currentFramebuffer->GetClearColor(location);
descriptor.colorAttachments[location].loadAction = MTLLoadActionClear; descriptor.colorAttachments[location].loadAction = MTLLoadActionClear;
descriptor.colorAttachments[location].clearColor = MTLClearColorMake(clearValue.color[0], clearValue.color[1], clearValue.color[2], clearValue.color[3]); descriptor.colorAttachments[location].clearColor =
MTLClearColorMake(clearValue.color[0], clearValue.color[1],
clearValue.color[2], clearValue.color[3]);
} else { } else {
descriptor.colorAttachments[location].loadAction = MTLLoadActionLoad; descriptor.colorAttachments[location].loadAction = MTLLoadActionLoad;
} }
@ -113,7 +115,8 @@ namespace metal {
descriptor.depthAttachment.texture = texture; descriptor.depthAttachment.texture = texture;
descriptor.depthAttachment.storeAction = MTLStoreActionStore; descriptor.depthAttachment.storeAction = MTLStoreActionStore;
bool shouldClearDepthOnFirstUse = attachmentInfo.depthLoadOp == nxt::LoadOp::Clear; bool shouldClearDepthOnFirstUse =
attachmentInfo.depthLoadOp == nxt::LoadOp::Clear;
if (isFirstUse && shouldClearDepthOnFirstUse) { if (isFirstUse && shouldClearDepthOnFirstUse) {
descriptor.depthAttachment.loadAction = MTLLoadActionClear; descriptor.depthAttachment.loadAction = MTLLoadActionClear;
descriptor.depthAttachment.clearDepth = clearValues.depth; descriptor.depthAttachment.clearDepth = clearValues.depth;
@ -126,7 +129,8 @@ namespace metal {
descriptor.stencilAttachment.texture = texture; descriptor.stencilAttachment.texture = texture;
descriptor.stencilAttachment.storeAction = MTLStoreActionStore; descriptor.stencilAttachment.storeAction = MTLStoreActionStore;
bool shouldClearStencilOnFirstUse = attachmentInfo.stencilLoadOp == nxt::LoadOp::Clear; bool shouldClearStencilOnFirstUse =
attachmentInfo.stencilLoadOp == nxt::LoadOp::Clear;
if (isFirstUse && shouldClearStencilOnFirstUse) { if (isFirstUse && shouldClearStencilOnFirstUse) {
descriptor.stencilAttachment.loadAction = MTLLoadActionClear; descriptor.stencilAttachment.loadAction = MTLLoadActionClear;
descriptor.stencilAttachment.clearStencil = clearValues.stencil; descriptor.stencilAttachment.clearStencil = clearValues.stencil;
@ -149,7 +153,8 @@ namespace metal {
} }
CommandBuffer::CommandBuffer(CommandBufferBuilder* builder) CommandBuffer::CommandBuffer(CommandBufferBuilder* builder)
: CommandBufferBase(builder), mDevice(ToBackend(builder->GetDevice())), : CommandBufferBase(builder),
mDevice(ToBackend(builder->GetDevice())),
mCommands(builder->AcquireCommands()) { mCommands(builder->AcquireCommands()) {
} }
@ -172,8 +177,7 @@ namespace metal {
uint32_t currentSubpass = 0; uint32_t currentSubpass = 0;
while (mCommands.NextCommandId(&type)) { while (mCommands.NextCommandId(&type)) {
switch (type) { switch (type) {
case Command::BeginComputePass: case Command::BeginComputePass: {
{
mCommands.NextCommand<BeginComputePassCmd>(); mCommands.NextCommand<BeginComputePassCmd>();
encoders.BeginCompute(commandBuffer); encoders.BeginCompute(commandBuffer);
@ -181,21 +185,18 @@ namespace metal {
[encoders.compute setBytes:&pushConstants[nxt::ShaderStage::Compute] [encoders.compute setBytes:&pushConstants[nxt::ShaderStage::Compute]
length:sizeof(uint32_t) * kMaxPushConstants length:sizeof(uint32_t) * kMaxPushConstants
atIndex:0]; atIndex:0];
} } break;
break;
case Command::BeginRenderPass: case Command::BeginRenderPass: {
{ BeginRenderPassCmd* beginRenderPassCmd =
BeginRenderPassCmd* beginRenderPassCmd = mCommands.NextCommand<BeginRenderPassCmd>(); mCommands.NextCommand<BeginRenderPassCmd>();
encoders.currentRenderPass = ToBackend(beginRenderPassCmd->renderPass.Get()); encoders.currentRenderPass = ToBackend(beginRenderPassCmd->renderPass.Get());
encoders.currentFramebuffer = ToBackend(beginRenderPassCmd->framebuffer.Get()); encoders.currentFramebuffer = ToBackend(beginRenderPassCmd->framebuffer.Get());
encoders.EnsureNoBlitEncoder(); encoders.EnsureNoBlitEncoder();
currentSubpass = 0; currentSubpass = 0;
} } break;
break;
case Command::BeginRenderSubpass: case Command::BeginRenderSubpass: {
{
mCommands.NextCommand<BeginRenderSubpassCmd>(); mCommands.NextCommand<BeginRenderSubpassCmd>();
encoders.BeginSubpass(commandBuffer, currentSubpass); encoders.BeginSubpass(commandBuffer, currentSubpass);
@ -208,27 +209,22 @@ namespace metal {
[encoders.render setFragmentBytes:&pushConstants[nxt::ShaderStage::Fragment] [encoders.render setFragmentBytes:&pushConstants[nxt::ShaderStage::Fragment]
length:sizeof(uint32_t) * kMaxPushConstants length:sizeof(uint32_t) * kMaxPushConstants
atIndex:0]; atIndex:0];
} } break;
break;
case Command::CopyBufferToBuffer: case Command::CopyBufferToBuffer: {
{
CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>(); CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>();
auto& src = copy->source; auto& src = copy->source;
auto& dst = copy->destination; auto& dst = copy->destination;
encoders.EnsureBlit(commandBuffer); encoders.EnsureBlit(commandBuffer);
[encoders.blit [encoders.blit copyFromBuffer:ToBackend(src.buffer)->GetMTLBuffer()
copyFromBuffer:ToBackend(src.buffer)->GetMTLBuffer()
sourceOffset:src.offset sourceOffset:src.offset
toBuffer:ToBackend(dst.buffer)->GetMTLBuffer() toBuffer:ToBackend(dst.buffer)->GetMTLBuffer()
destinationOffset:dst.offset destinationOffset:dst.offset
size:copy->size]; size:copy->size];
} } break;
break;
case Command::CopyBufferToTexture: case Command::CopyBufferToTexture: {
{
CopyBufferToTextureCmd* copy = mCommands.NextCommand<CopyBufferToTextureCmd>(); CopyBufferToTextureCmd* copy = mCommands.NextCommand<CopyBufferToTextureCmd>();
auto& src = copy->source; auto& src = copy->source;
auto& dst = copy->destination; auto& dst = copy->destination;
@ -246,8 +242,7 @@ namespace metal {
size.depth = dst.depth; size.depth = dst.depth;
encoders.EnsureBlit(commandBuffer); encoders.EnsureBlit(commandBuffer);
[encoders.blit [encoders.blit copyFromBuffer:buffer->GetMTLBuffer()
copyFromBuffer:buffer->GetMTLBuffer()
sourceOffset:src.offset sourceOffset:src.offset
sourceBytesPerRow:copy->rowPitch sourceBytesPerRow:copy->rowPitch
sourceBytesPerImage:(copy->rowPitch * dst.height) sourceBytesPerImage:(copy->rowPitch * dst.height)
@ -256,11 +251,9 @@ namespace metal {
destinationSlice:0 destinationSlice:0
destinationLevel:dst.level destinationLevel:dst.level
destinationOrigin:origin]; destinationOrigin:origin];
} } break;
break;
case Command::CopyTextureToBuffer: case Command::CopyTextureToBuffer: {
{
CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>(); CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>();
auto& src = copy->source; auto& src = copy->source;
auto& dst = copy->destination; auto& dst = copy->destination;
@ -278,8 +271,7 @@ namespace metal {
size.depth = src.depth; size.depth = src.depth;
encoders.EnsureBlit(commandBuffer); encoders.EnsureBlit(commandBuffer);
[encoders.blit [encoders.blit copyFromTexture:texture->GetMTLTexture()
copyFromTexture:texture->GetMTLTexture()
sourceSlice:0 sourceSlice:0
sourceLevel:src.level sourceLevel:src.level
sourceOrigin:origin sourceOrigin:origin
@ -288,35 +280,29 @@ namespace metal {
destinationOffset:dst.offset destinationOffset:dst.offset
destinationBytesPerRow:copy->rowPitch destinationBytesPerRow:copy->rowPitch
destinationBytesPerImage:copy->rowPitch * src.height]; destinationBytesPerImage:copy->rowPitch * src.height];
} } break;
break;
case Command::Dispatch: case Command::Dispatch: {
{
DispatchCmd* dispatch = mCommands.NextCommand<DispatchCmd>(); DispatchCmd* dispatch = mCommands.NextCommand<DispatchCmd>();
ASSERT(encoders.compute); ASSERT(encoders.compute);
[encoders.compute dispatchThreadgroups:MTLSizeMake(dispatch->x, dispatch->y, dispatch->z) [encoders.compute
dispatchThreadgroups:MTLSizeMake(dispatch->x, dispatch->y, dispatch->z)
threadsPerThreadgroup:lastComputePipeline->GetLocalWorkGroupSize()]; threadsPerThreadgroup:lastComputePipeline->GetLocalWorkGroupSize()];
} } break;
break;
case Command::DrawArrays: case Command::DrawArrays: {
{
DrawArraysCmd* draw = mCommands.NextCommand<DrawArraysCmd>(); DrawArraysCmd* draw = mCommands.NextCommand<DrawArraysCmd>();
ASSERT(encoders.render); ASSERT(encoders.render);
[encoders.render [encoders.render drawPrimitives:lastRenderPipeline->GetMTLPrimitiveTopology()
drawPrimitives:lastRenderPipeline->GetMTLPrimitiveTopology()
vertexStart:draw->firstVertex vertexStart:draw->firstVertex
vertexCount:draw->vertexCount vertexCount:draw->vertexCount
instanceCount:draw->instanceCount instanceCount:draw->instanceCount
baseInstance:draw->firstInstance]; baseInstance:draw->firstInstance];
} } break;
break;
case Command::DrawElements: case Command::DrawElements: {
{
DrawElementsCmd* draw = mCommands.NextCommand<DrawElementsCmd>(); DrawElementsCmd* draw = mCommands.NextCommand<DrawElementsCmd>();
ASSERT(encoders.render); ASSERT(encoders.render);
@ -329,59 +315,50 @@ namespace metal {
instanceCount:draw->instanceCount instanceCount:draw->instanceCount
baseVertex:0 baseVertex:0
baseInstance:draw->firstInstance]; baseInstance:draw->firstInstance];
} } break;
break;
case Command::EndComputePass: case Command::EndComputePass: {
{
mCommands.NextCommand<EndComputePassCmd>(); mCommands.NextCommand<EndComputePassCmd>();
encoders.EndCompute(); encoders.EndCompute();
} } break;
break;
case Command::EndRenderPass: case Command::EndRenderPass: {
{
mCommands.NextCommand<EndRenderPassCmd>(); mCommands.NextCommand<EndRenderPassCmd>();
} } break;
break;
case Command::EndRenderSubpass: case Command::EndRenderSubpass: {
{
mCommands.NextCommand<EndRenderSubpassCmd>(); mCommands.NextCommand<EndRenderSubpassCmd>();
encoders.EndSubpass(); encoders.EndSubpass();
currentSubpass += 1; currentSubpass += 1;
} } break;
break;
case Command::SetComputePipeline: case Command::SetComputePipeline: {
{
SetComputePipelineCmd* cmd = mCommands.NextCommand<SetComputePipelineCmd>(); SetComputePipelineCmd* cmd = mCommands.NextCommand<SetComputePipelineCmd>();
lastComputePipeline = ToBackend(cmd->pipeline).Get(); lastComputePipeline = ToBackend(cmd->pipeline).Get();
ASSERT(encoders.compute); ASSERT(encoders.compute);
lastComputePipeline->Encode(encoders.compute); lastComputePipeline->Encode(encoders.compute);
} } break;
break;
case Command::SetRenderPipeline: case Command::SetRenderPipeline: {
{
SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>(); SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
lastRenderPipeline = ToBackend(cmd->pipeline).Get(); lastRenderPipeline = ToBackend(cmd->pipeline).Get();
ASSERT(encoders.render); ASSERT(encoders.render);
DepthStencilState* depthStencilState = ToBackend(lastRenderPipeline->GetDepthStencilState()); DepthStencilState* depthStencilState =
[encoders.render setDepthStencilState:depthStencilState->GetMTLDepthStencilState()]; ToBackend(lastRenderPipeline->GetDepthStencilState());
[encoders.render
setDepthStencilState:depthStencilState->GetMTLDepthStencilState()];
lastRenderPipeline->Encode(encoders.render); lastRenderPipeline->Encode(encoders.render);
} } break;
break;
case Command::SetPushConstants: case Command::SetPushConstants: {
{
SetPushConstantsCmd* cmd = mCommands.NextCommand<SetPushConstantsCmd>(); SetPushConstantsCmd* cmd = mCommands.NextCommand<SetPushConstantsCmd>();
uint32_t* values = mCommands.NextData<uint32_t>(cmd->count); uint32_t* values = mCommands.NextData<uint32_t>(cmd->count);
for (auto stage : IterateStages(cmd->stages)) { for (auto stage : IterateStages(cmd->stages)) {
memcpy(&pushConstants[stage][cmd->offset], values, cmd->count * sizeof(uint32_t)); memcpy(&pushConstants[stage][cmd->offset], values,
cmd->count * sizeof(uint32_t));
switch (stage) { switch (stage) {
case nxt::ShaderStage::Compute: case nxt::ShaderStage::Compute:
@ -392,13 +369,15 @@ namespace metal {
break; break;
case nxt::ShaderStage::Fragment: case nxt::ShaderStage::Fragment:
ASSERT(encoders.render); ASSERT(encoders.render);
[encoders.render setFragmentBytes: &pushConstants[nxt::ShaderStage::Fragment] [encoders.render
setFragmentBytes:&pushConstants[nxt::ShaderStage::Fragment]
length:sizeof(uint32_t) * kMaxPushConstants length:sizeof(uint32_t) * kMaxPushConstants
atIndex:0]; atIndex:0];
break; break;
case nxt::ShaderStage::Vertex: case nxt::ShaderStage::Vertex:
ASSERT(encoders.render); ASSERT(encoders.render);
[encoders.render setVertexBytes: &pushConstants[nxt::ShaderStage::Vertex] [encoders.render
setVertexBytes:&pushConstants[nxt::ShaderStage::Vertex]
length:sizeof(uint32_t) * kMaxPushConstants length:sizeof(uint32_t) * kMaxPushConstants
atIndex:0]; atIndex:0];
break; break;
@ -407,103 +386,95 @@ namespace metal {
break; break;
} }
} }
} } break;
break;
case Command::SetStencilReference: case Command::SetStencilReference: {
{
SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>(); SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
ASSERT(encoders.render); ASSERT(encoders.render);
[encoders.render setStencilReferenceValue:cmd->reference]; [encoders.render setStencilReferenceValue:cmd->reference];
} } break;
break;
case Command::SetBlendColor: case Command::SetBlendColor: {
{
SetBlendColorCmd* cmd = mCommands.NextCommand<SetBlendColorCmd>(); SetBlendColorCmd* cmd = mCommands.NextCommand<SetBlendColorCmd>();
ASSERT(encoders.render); ASSERT(encoders.render);
[encoders.render [encoders.render setBlendColorRed:cmd->r green:cmd->g blue:cmd->b alpha:cmd->a];
setBlendColorRed:cmd->r } break;
green:cmd->g
blue:cmd->b
alpha:cmd->a ];
}
break;
case Command::SetBindGroup: case Command::SetBindGroup: {
{
SetBindGroupCmd* cmd = mCommands.NextCommand<SetBindGroupCmd>(); SetBindGroupCmd* cmd = mCommands.NextCommand<SetBindGroupCmd>();
BindGroup* group = ToBackend(cmd->group.Get()); BindGroup* group = ToBackend(cmd->group.Get());
uint32_t groupIndex = cmd->index; uint32_t groupIndex = cmd->index;
const auto& layout = group->GetLayout()->GetBindingInfo(); const auto& layout = group->GetLayout()->GetBindingInfo();
// TODO(kainino@chromium.org): Maintain buffers and offsets arrays in BindGroup so that we // TODO(kainino@chromium.org): Maintain buffers and offsets arrays in BindGroup
// only have to do one setVertexBuffers and one setFragmentBuffers call here. // so that we only have to do one setVertexBuffers and one setFragmentBuffers
// call here.
for (size_t binding = 0; binding < layout.mask.size(); ++binding) { for (size_t binding = 0; binding < layout.mask.size(); ++binding) {
if (!layout.mask[binding]) { if (!layout.mask[binding]) {
continue; continue;
} }
auto stage = layout.visibilities[binding]; auto stage = layout.visibilities[binding];
bool vertStage = stage & nxt::ShaderStageBit::Vertex && lastRenderPipeline != nullptr; bool vertStage =
bool fragStage = stage & nxt::ShaderStageBit::Fragment && lastRenderPipeline != nullptr; stage & nxt::ShaderStageBit::Vertex && lastRenderPipeline != nullptr;
bool computeStage = stage & nxt::ShaderStageBit::Compute && lastComputePipeline != nullptr; bool fragStage =
stage & nxt::ShaderStageBit::Fragment && lastRenderPipeline != nullptr;
bool computeStage =
stage & nxt::ShaderStageBit::Compute && lastComputePipeline != nullptr;
uint32_t vertIndex = 0; uint32_t vertIndex = 0;
uint32_t fragIndex = 0; uint32_t fragIndex = 0;
uint32_t computeIndex = 0; uint32_t computeIndex = 0;
if (vertStage) { if (vertStage) {
ASSERT(lastRenderPipeline != nullptr); ASSERT(lastRenderPipeline != nullptr);
vertIndex = ToBackend(lastRenderPipeline->GetLayout())-> vertIndex = ToBackend(lastRenderPipeline->GetLayout())
GetBindingIndexInfo(nxt::ShaderStage::Vertex)[groupIndex][binding]; ->GetBindingIndexInfo(
nxt::ShaderStage::Vertex)[groupIndex][binding];
} }
if (fragStage) { if (fragStage) {
ASSERT(lastRenderPipeline != nullptr); ASSERT(lastRenderPipeline != nullptr);
fragIndex = ToBackend(lastRenderPipeline->GetLayout())-> fragIndex = ToBackend(lastRenderPipeline->GetLayout())
GetBindingIndexInfo(nxt::ShaderStage::Fragment)[groupIndex][binding]; ->GetBindingIndexInfo(
nxt::ShaderStage::Fragment)[groupIndex][binding];
} }
if (computeStage) { if (computeStage) {
ASSERT(lastComputePipeline != nullptr); ASSERT(lastComputePipeline != nullptr);
computeIndex = ToBackend(lastComputePipeline->GetLayout())-> computeIndex = ToBackend(lastComputePipeline->GetLayout())
GetBindingIndexInfo(nxt::ShaderStage::Compute)[groupIndex][binding]; ->GetBindingIndexInfo(
nxt::ShaderStage::Compute)[groupIndex][binding];
} }
switch (layout.types[binding]) { switch (layout.types[binding]) {
case nxt::BindingType::UniformBuffer: case nxt::BindingType::UniformBuffer:
case nxt::BindingType::StorageBuffer: case nxt::BindingType::StorageBuffer: {
{ BufferView* view =
BufferView* view = ToBackend(group->GetBindingAsBufferView(binding)); ToBackend(group->GetBindingAsBufferView(binding));
auto b = ToBackend(view->GetBuffer()); auto b = ToBackend(view->GetBuffer());
const id<MTLBuffer> buffer = b->GetMTLBuffer(); const id<MTLBuffer> buffer = b->GetMTLBuffer();
const NSUInteger offset = view->GetOffset(); const NSUInteger offset = view->GetOffset();
if (vertStage) { if (vertStage) {
[encoders.render [encoders.render setVertexBuffers:&buffer
setVertexBuffers:&buffer
offsets:&offset offsets:&offset
withRange:NSMakeRange(vertIndex, 1)]; withRange:NSMakeRange(vertIndex, 1)];
} }
if (fragStage) { if (fragStage) {
[encoders.render [encoders.render setFragmentBuffers:&buffer
setFragmentBuffers:&buffer
offsets:&offset offsets:&offset
withRange:NSMakeRange(fragIndex, 1)]; withRange:NSMakeRange(fragIndex, 1)];
} }
if (computeStage) { if (computeStage) {
[encoders.compute [encoders.compute setBuffers:&buffer
setBuffers:&buffer
offsets:&offset offsets:&offset
withRange:NSMakeRange(computeIndex, 1)]; withRange:NSMakeRange(computeIndex, 1)];
} }
} } break;
break;
case nxt::BindingType::Sampler: case nxt::BindingType::Sampler: {
{
auto sampler = ToBackend(group->GetBindingAsSampler(binding)); auto sampler = ToBackend(group->GetBindingAsSampler(binding));
if (vertStage) { if (vertStage) {
[encoders.render [encoders.render
@ -516,49 +487,39 @@ namespace metal {
atIndex:fragIndex]; atIndex:fragIndex];
} }
if (computeStage) { if (computeStage) {
[encoders.compute [encoders.compute setSamplerState:sampler->GetMTLSamplerState()
setSamplerState:sampler->GetMTLSamplerState()
atIndex:computeIndex]; atIndex:computeIndex];
} }
} } break;
break;
case nxt::BindingType::SampledTexture: case nxt::BindingType::SampledTexture: {
{ auto texture = ToBackend(
auto texture = ToBackend(group->GetBindingAsTextureView(binding)->GetTexture()); group->GetBindingAsTextureView(binding)->GetTexture());
if (vertStage) { if (vertStage) {
[encoders.render [encoders.render setVertexTexture:texture->GetMTLTexture()
setVertexTexture:texture->GetMTLTexture()
atIndex:vertIndex]; atIndex:vertIndex];
} }
if (fragStage) { if (fragStage) {
[encoders.render [encoders.render setFragmentTexture:texture->GetMTLTexture()
setFragmentTexture:texture->GetMTLTexture()
atIndex:fragIndex]; atIndex:fragIndex];
} }
if (computeStage) { if (computeStage) {
[encoders.compute [encoders.compute setTexture:texture->GetMTLTexture()
setTexture:texture->GetMTLTexture()
atIndex:computeIndex]; atIndex:computeIndex];
} }
} } break;
break;
} }
} }
} } break;
break;
case Command::SetIndexBuffer: case Command::SetIndexBuffer: {
{
SetIndexBufferCmd* cmd = mCommands.NextCommand<SetIndexBufferCmd>(); SetIndexBufferCmd* cmd = mCommands.NextCommand<SetIndexBufferCmd>();
auto b = ToBackend(cmd->buffer.Get()); auto b = ToBackend(cmd->buffer.Get());
indexBuffer = b->GetMTLBuffer(); indexBuffer = b->GetMTLBuffer();
indexBufferOffset = cmd->offset; indexBufferOffset = cmd->offset;
} } break;
break;
case Command::SetVertexBuffers: case Command::SetVertexBuffers: {
{
SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>(); SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>();
auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count); auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count);
auto offsets = mCommands.NextData<uint32_t>(cmd->count); auto offsets = mCommands.NextData<uint32_t>(cmd->count);
@ -578,25 +539,23 @@ namespace metal {
[encoders.render [encoders.render
setVertexBuffers:mtlBuffers.data() setVertexBuffers:mtlBuffers.data()
offsets:mtlOffsets.data() offsets:mtlOffsets.data()
withRange:NSMakeRange(kMaxBindingsPerGroup + cmd->startSlot, cmd->count)]; withRange:NSMakeRange(kMaxBindingsPerGroup + cmd->startSlot,
} cmd->count)];
break; } break;
case Command::TransitionBufferUsage: case Command::TransitionBufferUsage: {
{ TransitionBufferUsageCmd* cmd =
TransitionBufferUsageCmd* cmd = mCommands.NextCommand<TransitionBufferUsageCmd>(); mCommands.NextCommand<TransitionBufferUsageCmd>();
cmd->buffer->UpdateUsageInternal(cmd->usage); cmd->buffer->UpdateUsageInternal(cmd->usage);
} } break;
break;
case Command::TransitionTextureUsage: case Command::TransitionTextureUsage: {
{ TransitionTextureUsageCmd* cmd =
TransitionTextureUsageCmd* cmd = mCommands.NextCommand<TransitionTextureUsageCmd>(); mCommands.NextCommand<TransitionTextureUsageCmd>();
cmd->texture->UpdateUsageInternal(cmd->usage); cmd->texture->UpdateUsageInternal(cmd->usage);
} } break;
break;
} }
} }
@ -605,5 +564,4 @@ namespace metal {
ASSERT(encoders.compute == nil); ASSERT(encoders.compute == nil);
} }
} }} // namespace backend::metal
}

View File

@ -19,8 +19,7 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
namespace backend { namespace backend { namespace metal {
namespace metal {
class ComputePipeline : public ComputePipelineBase { class ComputePipeline : public ComputePipelineBase {
public: public:
@ -35,7 +34,6 @@ namespace metal {
MTLSize mLocalWorkgroupSize; MTLSize mLocalWorkgroupSize;
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_COMPUTEPIPELINEMTL_H_ #endif // BACKEND_METAL_COMPUTEPIPELINEMTL_H_

View File

@ -17,12 +17,10 @@
#include "backend/metal/MetalBackend.h" #include "backend/metal/MetalBackend.h"
#include "backend/metal/ShaderModuleMTL.h" #include "backend/metal/ShaderModuleMTL.h"
namespace backend { namespace backend { namespace metal {
namespace metal {
ComputePipeline::ComputePipeline(ComputePipelineBuilder* builder) ComputePipeline::ComputePipeline(ComputePipelineBuilder* builder)
: ComputePipelineBase(builder) { : ComputePipelineBase(builder) {
auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice(); auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice();
const auto& module = ToBackend(builder->GetStageInfo(nxt::ShaderStage::Compute).module); const auto& module = ToBackend(builder->GetStageInfo(nxt::ShaderStage::Compute).module);
@ -31,8 +29,8 @@ namespace metal {
auto compilationData = module->GetFunction(entryPoint.c_str(), ToBackend(GetLayout())); auto compilationData = module->GetFunction(entryPoint.c_str(), ToBackend(GetLayout()));
NSError* error = nil; NSError* error = nil;
mMtlComputePipelineState = [mtlDevice mMtlComputePipelineState =
newComputePipelineStateWithFunction:compilationData.function error:&error]; [mtlDevice newComputePipelineStateWithFunction:compilationData.function error:&error];
if (error != nil) { if (error != nil) {
NSLog(@" error => %@", error); NSLog(@" error => %@", error);
builder->HandleError("Error creating pipeline state"); builder->HandleError("Error creating pipeline state");
@ -55,5 +53,4 @@ namespace metal {
return mLocalWorkgroupSize; return mLocalWorkgroupSize;
} }
} }} // namespace backend::metal
}

View File

@ -19,8 +19,7 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
namespace backend { namespace backend { namespace metal {
namespace metal {
class Device; class Device;
@ -35,7 +34,6 @@ namespace metal {
id<MTLDepthStencilState> mMtlDepthStencilState = nil; id<MTLDepthStencilState> mMtlDepthStencilState = nil;
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_DEPTHSTENCILSTATEMTL_H_ #endif // BACKEND_METAL_DEPTHSTENCILSTATEMTL_H_

View File

@ -16,8 +16,7 @@
#include "backend/metal/MetalBackend.h" #include "backend/metal/MetalBackend.h"
namespace backend { namespace backend { namespace metal {
namespace metal {
namespace { namespace {
MTLCompareFunction MetalDepthStencilCompareFunction(nxt::CompareFunction compareFunction) { MTLCompareFunction MetalDepthStencilCompareFunction(nxt::CompareFunction compareFunction) {
@ -68,7 +67,8 @@ namespace metal {
MTLDepthStencilDescriptor* mtlDepthStencilDescriptor = [MTLDepthStencilDescriptor new]; MTLDepthStencilDescriptor* mtlDepthStencilDescriptor = [MTLDepthStencilDescriptor new];
auto& depth = GetDepth(); auto& depth = GetDepth();
mtlDepthStencilDescriptor.depthCompareFunction = MetalDepthStencilCompareFunction(depth.compareFunction); mtlDepthStencilDescriptor.depthCompareFunction =
MetalDepthStencilCompareFunction(depth.compareFunction);
mtlDepthStencilDescriptor.depthWriteEnabled = depth.depthWriteEnabled; mtlDepthStencilDescriptor.depthWriteEnabled = depth.depthWriteEnabled;
auto& stencil = GetStencil(); auto& stencil = GetStencil();
@ -76,17 +76,23 @@ namespace metal {
MTLStencilDescriptor* backFaceStencil = [MTLStencilDescriptor new]; MTLStencilDescriptor* backFaceStencil = [MTLStencilDescriptor new];
MTLStencilDescriptor* frontFaceStencil = [MTLStencilDescriptor new]; MTLStencilDescriptor* frontFaceStencil = [MTLStencilDescriptor new];
backFaceStencil.stencilCompareFunction = MetalDepthStencilCompareFunction(stencil.back.compareFunction); backFaceStencil.stencilCompareFunction =
backFaceStencil.stencilFailureOperation = MetalStencilOperation(stencil.back.stencilFail); MetalDepthStencilCompareFunction(stencil.back.compareFunction);
backFaceStencil.stencilFailureOperation =
MetalStencilOperation(stencil.back.stencilFail);
backFaceStencil.depthFailureOperation = MetalStencilOperation(stencil.back.depthFail); backFaceStencil.depthFailureOperation = MetalStencilOperation(stencil.back.depthFail);
backFaceStencil.depthStencilPassOperation = MetalStencilOperation(stencil.back.depthStencilPass); backFaceStencil.depthStencilPassOperation =
MetalStencilOperation(stencil.back.depthStencilPass);
backFaceStencil.readMask = stencil.readMask; backFaceStencil.readMask = stencil.readMask;
backFaceStencil.writeMask = stencil.writeMask; backFaceStencil.writeMask = stencil.writeMask;
frontFaceStencil.stencilCompareFunction = MetalDepthStencilCompareFunction(stencil.front.compareFunction); frontFaceStencil.stencilCompareFunction =
frontFaceStencil.stencilFailureOperation = MetalStencilOperation(stencil.front.stencilFail); MetalDepthStencilCompareFunction(stencil.front.compareFunction);
frontFaceStencil.stencilFailureOperation =
MetalStencilOperation(stencil.front.stencilFail);
frontFaceStencil.depthFailureOperation = MetalStencilOperation(stencil.front.depthFail); frontFaceStencil.depthFailureOperation = MetalStencilOperation(stencil.front.depthFail);
frontFaceStencil.depthStencilPassOperation = MetalStencilOperation(stencil.front.depthStencilPass); frontFaceStencil.depthStencilPassOperation =
MetalStencilOperation(stencil.front.depthStencilPass);
frontFaceStencil.readMask = stencil.readMask; frontFaceStencil.readMask = stencil.readMask;
frontFaceStencil.writeMask = stencil.writeMask; frontFaceStencil.writeMask = stencil.writeMask;
@ -97,7 +103,8 @@ namespace metal {
} }
auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice(); auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice();
mMtlDepthStencilState = [mtlDevice newDepthStencilStateWithDescriptor:mtlDepthStencilDescriptor]; mMtlDepthStencilState =
[mtlDevice newDepthStencilStateWithDescriptor:mtlDepthStencilDescriptor];
[mtlDepthStencilDescriptor release]; [mtlDepthStencilDescriptor release];
} }
@ -110,5 +117,4 @@ namespace metal {
return mMtlDepthStencilState; return mMtlDepthStencilState;
} }
} }} // namespace backend::metal
}

View File

@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "backend/metal/MetalBackend.h"
#include "backend/metal/BlendStateMTL.h" #include "backend/metal/BlendStateMTL.h"
#include "backend/metal/BufferMTL.h" #include "backend/metal/BufferMTL.h"
#include "backend/metal/CommandBufferMTL.h" #include "backend/metal/CommandBufferMTL.h"
#include "backend/metal/ComputePipelineMTL.h" #include "backend/metal/ComputePipelineMTL.h"
#include "backend/metal/DepthStencilStateMTL.h" #include "backend/metal/DepthStencilStateMTL.h"
#include "backend/metal/InputStateMTL.h" #include "backend/metal/InputStateMTL.h"
#include "backend/metal/MetalBackend.h"
#include "backend/metal/PipelineLayoutMTL.h" #include "backend/metal/PipelineLayoutMTL.h"
#include "backend/metal/RenderPipelineMTL.h" #include "backend/metal/RenderPipelineMTL.h"
#include "backend/metal/SamplerMTL.h" #include "backend/metal/SamplerMTL.h"

View File

@ -19,8 +19,7 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
namespace backend { namespace backend { namespace metal {
namespace metal {
class InputState : public InputStateBase { class InputState : public InputStateBase {
public: public:
@ -33,7 +32,6 @@ namespace metal {
MTLVertexDescriptor* mMtlVertexDescriptor = nil; MTLVertexDescriptor* mMtlVertexDescriptor = nil;
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_COMMANDINPUTSTATEMTL_H_ #endif // BACKEND_METAL_COMMANDINPUTSTATEMTL_H_

View File

@ -17,8 +17,7 @@
#include "backend/metal/MetalBackend.h" #include "backend/metal/MetalBackend.h"
#include "common/BitSetIterator.h" #include "common/BitSetIterator.h"
namespace backend { namespace backend { namespace metal {
namespace metal {
namespace { namespace {
MTLVertexFormat VertexFormatType(nxt::VertexFormat format) { MTLVertexFormat VertexFormatType(nxt::VertexFormat format) {
@ -44,8 +43,7 @@ namespace metal {
} }
} }
InputState::InputState(InputStateBuilder* builder) InputState::InputState(InputStateBuilder* builder) : InputStateBase(builder) {
: InputStateBase(builder) {
mMtlVertexDescriptor = [MTLVertexDescriptor new]; mMtlVertexDescriptor = [MTLVertexDescriptor new];
const auto& attributesSetMask = GetAttributesSetMask(); const auto& attributesSetMask = GetAttributesSetMask();
@ -95,5 +93,4 @@ namespace metal {
return mMtlVertexDescriptor; return mMtlVertexDescriptor;
} }
} }} // namespace backend::metal
}

View File

@ -26,12 +26,11 @@
#include "backend/ToBackend.h" #include "backend/ToBackend.h"
#include "common/Serial.h" #include "common/Serial.h"
#include <type_traits>
#import <Metal/Metal.h> #import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h> #import <QuartzCore/CAMetalLayer.h>
#include <type_traits>
namespace backend { namespace backend { namespace metal {
namespace metal {
class BindGroup; class BindGroup;
class BindGroupLayout; class BindGroupLayout;
@ -170,7 +169,6 @@ namespace metal {
~RenderPass(); ~RenderPass();
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_METALBACKEND_H_ #endif // BACKEND_METAL_METALBACKEND_H_

View File

@ -20,8 +20,8 @@
#include "backend/metal/ComputePipelineMTL.h" #include "backend/metal/ComputePipelineMTL.h"
#include "backend/metal/DepthStencilStateMTL.h" #include "backend/metal/DepthStencilStateMTL.h"
#include "backend/metal/InputStateMTL.h" #include "backend/metal/InputStateMTL.h"
#include "backend/metal/RenderPipelineMTL.h"
#include "backend/metal/PipelineLayoutMTL.h" #include "backend/metal/PipelineLayoutMTL.h"
#include "backend/metal/RenderPipelineMTL.h"
#include "backend/metal/ResourceUploader.h" #include "backend/metal/ResourceUploader.h"
#include "backend/metal/SamplerMTL.h" #include "backend/metal/SamplerMTL.h"
#include "backend/metal/ShaderModuleMTL.h" #include "backend/metal/ShaderModuleMTL.h"
@ -30,8 +30,7 @@
#include <unistd.h> #include <unistd.h>
namespace backend { namespace backend { namespace metal {
namespace metal {
nxtProcTable GetNonValidatingProcs(); nxtProcTable GetNonValidatingProcs();
nxtProcTable GetValidatingProcs(); nxtProcTable GetValidatingProcs();
@ -45,18 +44,18 @@ namespace metal {
// Device // Device
Device::Device(id<MTLDevice> mtlDevice) Device::Device(id<MTLDevice> mtlDevice)
: mMtlDevice(mtlDevice), mMapReadTracker(new MapReadRequestTracker(this)), : mMtlDevice(mtlDevice),
mMapReadTracker(new MapReadRequestTracker(this)),
mResourceUploader(new ResourceUploader(this)) { mResourceUploader(new ResourceUploader(this)) {
[mMtlDevice retain]; [mMtlDevice retain];
mCommandQueue = [mMtlDevice newCommandQueue]; mCommandQueue = [mMtlDevice newCommandQueue];
} }
Device::~Device() { Device::~Device() {
// Wait for all commands to be finished so we can free resources // Wait for all commands to be finished so we can free resources SubmitPendingCommandBuffer
// SubmitPendingCommandBuffer may not increment the pendingCommandSerial if there // may not increment the pendingCommandSerial if there are no pending commands, so we can't
// are no pending commands, so we can't store the pendingSerial before // store the pendingSerial before SubmitPendingCommandBuffer then wait for it to be passed.
// SubmitPendingCommandBuffer then wait for it to be passed. Instead we submit and // Instead we submit and wait for the serial before the next pendingCommandSerial.
// wait for the serial before the next pendingCommandSerial.
SubmitPendingCommandBuffer(); SubmitPendingCommandBuffer();
while (mFinishedCommandSerial != mPendingCommandSerial - 1) { while (mFinishedCommandSerial != mPendingCommandSerial - 1) {
usleep(100); usleep(100);
@ -165,7 +164,8 @@ namespace metal {
// Ok, ObjC blocks are weird. My understanding is that local variables are captured by value // Ok, ObjC blocks are weird. My understanding is that local variables are captured by value
// so this-> works as expected. However it is unclear how members are captured, (are they // so this-> works as expected. However it is unclear how members are captured, (are they
// captured using this-> or by value?) so we make a copy of the pendingCommandSerial on the stack. // captured using this-> or by value?) so we make a copy of the pendingCommandSerial on the
// stack.
Serial pendingSerial = mPendingCommandSerial; Serial pendingSerial = mPendingCommandSerial;
[mPendingCommands addCompletedHandler:^(id<MTLCommandBuffer>) { [mPendingCommands addCompletedHandler:^(id<MTLCommandBuffer>) {
this->mFinishedCommandSerial = pendingSerial; this->mFinishedCommandSerial = pendingSerial;
@ -178,10 +178,10 @@ namespace metal {
} }
uint64_t Device::GetPendingCommandSerial() { uint64_t Device::GetPendingCommandSerial() {
// If this is called, then it means some piece of code somewhere will wait for this serial to // If this is called, then it means some piece of code somewhere will wait for this serial
// complete. Make sure the pending command buffer is created so that it is on the worst case // to complete. Make sure the pending command buffer is created so that it is on the worst
// enqueued on the next Tick() and eventually increments the serial. Otherwise if no GPU work // case enqueued on the next Tick() and eventually increments the serial. Otherwise if no
// happens we could be waiting for this serial forever. // GPU work happens we could be waiting for this serial forever.
GetPendingCommandBuffer(); GetPendingCommandBuffer();
return mPendingCommandSerial; return mPendingCommandSerial;
} }
@ -196,8 +196,7 @@ namespace metal {
// Bind Group // Bind Group
BindGroup::BindGroup(BindGroupBuilder* builder) BindGroup::BindGroup(BindGroupBuilder* builder) : BindGroupBase(builder) {
: BindGroupBase(builder) {
} }
// Bind Group Layout // Bind Group Layout
@ -208,8 +207,7 @@ namespace metal {
// Framebuffer // Framebuffer
Framebuffer::Framebuffer(FramebufferBuilder* builder) Framebuffer::Framebuffer(FramebufferBuilder* builder) : FramebufferBase(builder) {
: FramebufferBase(builder) {
} }
Framebuffer::~Framebuffer() { Framebuffer::~Framebuffer() {
@ -217,8 +215,7 @@ namespace metal {
// Queue // Queue
Queue::Queue(QueueBuilder* builder) Queue::Queue(QueueBuilder* builder) : QueueBase(builder) {
: QueueBase(builder) {
Device* device = ToBackend(builder->GetDevice()); Device* device = ToBackend(builder->GetDevice());
mCommandQueue = [device->GetMTLDevice() newCommandQueue]; mCommandQueue = [device->GetMTLDevice() newCommandQueue];
} }
@ -245,12 +242,10 @@ namespace metal {
// RenderPass // RenderPass
RenderPass::RenderPass(RenderPassBuilder* builder) RenderPass::RenderPass(RenderPassBuilder* builder) : RenderPassBase(builder) {
: RenderPassBase(builder) {
} }
RenderPass::~RenderPass() { RenderPass::~RenderPass() {
} }
} }} // namespace backend::metal
}

View File

@ -25,21 +25,20 @@ namespace spirv_cross {
class CompilerMSL; class CompilerMSL;
} }
namespace backend { namespace backend { namespace metal {
namespace metal {
class PipelineLayout : public PipelineLayoutBase { class PipelineLayout : public PipelineLayoutBase {
public: public:
PipelineLayout(PipelineLayoutBuilder* builder); PipelineLayout(PipelineLayoutBuilder* builder);
using BindingIndexInfo = std::array<std::array<uint32_t, kMaxBindingsPerGroup>, kMaxBindGroups>; using BindingIndexInfo =
std::array<std::array<uint32_t, kMaxBindingsPerGroup>, kMaxBindGroups>;
const BindingIndexInfo& GetBindingIndexInfo(nxt::ShaderStage stage) const; const BindingIndexInfo& GetBindingIndexInfo(nxt::ShaderStage stage) const;
private: private:
PerStage<BindingIndexInfo> mIndexInfo; PerStage<BindingIndexInfo> mIndexInfo;
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_PIPELINELAYOUTMTL_H_ #endif // BACKEND_METAL_PIPELINELAYOUTMTL_H_

View File

@ -16,11 +16,9 @@
#include "backend/metal/MetalBackend.h" #include "backend/metal/MetalBackend.h"
namespace backend { namespace backend { namespace metal {
namespace metal {
PipelineLayout::PipelineLayout(PipelineLayoutBuilder* builder) PipelineLayout::PipelineLayout(PipelineLayoutBuilder* builder) : PipelineLayoutBase(builder) {
: PipelineLayoutBase(builder) {
// Each stage has its own numbering namespace in CompilerMSL. // Each stage has its own numbering namespace in CompilerMSL.
for (auto stage : IterateStages(kAllStages)) { for (auto stage : IterateStages(kAllStages)) {
// Buffer number 0 is reserved for push constants // Buffer number 0 is reserved for push constants
@ -58,9 +56,9 @@ namespace metal {
} }
} }
const PipelineLayout::BindingIndexInfo& PipelineLayout::GetBindingIndexInfo(nxt::ShaderStage stage) const { const PipelineLayout::BindingIndexInfo& PipelineLayout::GetBindingIndexInfo(
nxt::ShaderStage stage) const {
return mIndexInfo[stage]; return mIndexInfo[stage];
} }
} }} // namespace backend::metal
}

View File

@ -19,8 +19,7 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
namespace backend { namespace backend { namespace metal {
namespace metal {
class RenderPipeline : public RenderPipelineBase { class RenderPipeline : public RenderPipelineBase {
public: public:
@ -38,7 +37,6 @@ namespace metal {
id<MTLRenderPipelineState> mMtlRenderPipelineState = nil; id<MTLRenderPipelineState> mMtlRenderPipelineState = nil;
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_RENDERPIPELINEMTL_H_ #endif // BACKEND_METAL_RENDERPIPELINEMTL_H_

View File

@ -22,8 +22,7 @@
#include "backend/metal/ShaderModuleMTL.h" #include "backend/metal/ShaderModuleMTL.h"
#include "backend/metal/TextureMTL.h" #include "backend/metal/TextureMTL.h"
namespace backend { namespace backend { namespace metal {
namespace metal {
namespace { namespace {
MTLPrimitiveType MTLPrimitiveTopology(nxt::PrimitiveTopology primitiveTopology) { MTLPrimitiveType MTLPrimitiveTopology(nxt::PrimitiveTopology primitiveTopology) {
@ -41,7 +40,8 @@ namespace metal {
} }
} }
MTLPrimitiveTopologyClass MTLInputPrimitiveTopology(nxt::PrimitiveTopology primitiveTopology) { MTLPrimitiveTopologyClass MTLInputPrimitiveTopology(
nxt::PrimitiveTopology primitiveTopology) {
switch (primitiveTopology) { switch (primitiveTopology) {
case nxt::PrimitiveTopology::PointList: case nxt::PrimitiveTopology::PointList:
return MTLPrimitiveTopologyClassPoint; return MTLPrimitiveTopologyClassPoint;
@ -68,7 +68,6 @@ namespace metal {
: RenderPipelineBase(builder), : RenderPipelineBase(builder),
mMtlIndexType(MTLIndexFormat(GetIndexFormat())), mMtlIndexType(MTLIndexFormat(GetIndexFormat())),
mMtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) { mMtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) {
auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice(); auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice();
MTLRenderPipelineDescriptor* descriptor = [MTLRenderPipelineDescriptor new]; MTLRenderPipelineDescriptor* descriptor = [MTLRenderPipelineDescriptor new];
@ -77,7 +76,8 @@ namespace metal {
const auto& module = ToBackend(builder->GetStageInfo(stage).module); const auto& module = ToBackend(builder->GetStageInfo(stage).module);
const auto& entryPoint = builder->GetStageInfo(stage).entryPoint; const auto& entryPoint = builder->GetStageInfo(stage).entryPoint;
id<MTLFunction> function = module->GetFunction(entryPoint.c_str(), ToBackend(GetLayout())).function; id<MTLFunction> function =
module->GetFunction(entryPoint.c_str(), ToBackend(GetLayout())).function;
switch (stage) { switch (stage) {
case nxt::ShaderStage::Vertex: case nxt::ShaderStage::Vertex:
@ -95,7 +95,8 @@ namespace metal {
auto& subpassInfo = renderPass->GetSubpassInfo(GetSubPass()); auto& subpassInfo = renderPass->GetSubpassInfo(GetSubPass());
if (subpassInfo.depthStencilAttachmentSet) { if (subpassInfo.depthStencilAttachmentSet) {
const auto& attachmentInfo = renderPass->GetAttachmentInfo(subpassInfo.depthStencilAttachment); const auto& attachmentInfo =
renderPass->GetAttachmentInfo(subpassInfo.depthStencilAttachment);
descriptor.depthAttachmentPixelFormat = MetalPixelFormat(attachmentInfo.format); descriptor.depthAttachmentPixelFormat = MetalPixelFormat(attachmentInfo.format);
descriptor.stencilAttachmentPixelFormat = MetalPixelFormat(attachmentInfo.format); descriptor.stencilAttachmentPixelFormat = MetalPixelFormat(attachmentInfo.format);
} }
@ -104,8 +105,10 @@ namespace metal {
uint32_t attachment = subpassInfo.colorAttachments[attachmentSlot]; uint32_t attachment = subpassInfo.colorAttachments[attachmentSlot];
const auto& attachmentInfo = renderPass->GetAttachmentInfo(attachment); const auto& attachmentInfo = renderPass->GetAttachmentInfo(attachment);
descriptor.colorAttachments[attachmentSlot].pixelFormat = MetalPixelFormat(attachmentInfo.format); descriptor.colorAttachments[attachmentSlot].pixelFormat =
ToBackend(GetBlendState(attachmentSlot))->ApplyBlendState(descriptor.colorAttachments[attachmentSlot]); MetalPixelFormat(attachmentInfo.format);
ToBackend(GetBlendState(attachmentSlot))
->ApplyBlendState(descriptor.colorAttachments[attachmentSlot]);
} }
descriptor.inputPrimitiveTopology = MTLInputPrimitiveTopology(GetPrimitiveTopology()); descriptor.inputPrimitiveTopology = MTLInputPrimitiveTopology(GetPrimitiveTopology());
@ -116,8 +119,8 @@ namespace metal {
// TODO(kainino@chromium.org): push constants, textures, samplers // TODO(kainino@chromium.org): push constants, textures, samplers
NSError* error = nil; NSError* error = nil;
mMtlRenderPipelineState = [mtlDevice mMtlRenderPipelineState =
newRenderPipelineStateWithDescriptor:descriptor error:&error]; [mtlDevice newRenderPipelineStateWithDescriptor:descriptor error:&error];
if (error != nil) { if (error != nil) {
NSLog(@" error => %@", error); NSLog(@" error => %@", error);
builder->HandleError("Error creating pipeline state"); builder->HandleError("Error creating pipeline state");
@ -144,5 +147,4 @@ namespace metal {
[encoder setRenderPipelineState:mMtlRenderPipelineState]; [encoder setRenderPipelineState:mMtlRenderPipelineState];
} }
} }} // namespace backend::metal
}

View File

@ -20,8 +20,7 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
namespace backend { namespace backend { namespace metal {
namespace metal {
class Device; class Device;
@ -38,8 +37,6 @@ namespace metal {
SerialQueue<id<MTLBuffer>> mInflightUploadBuffers; SerialQueue<id<MTLBuffer>> mInflightUploadBuffers;
}; };
}} // namespace backend::metal
}
}
#endif // BACKEND_METAL_RESOURCEUPLOADER_H_ #endif // BACKEND_METAL_RESOURCEUPLOADER_H_

View File

@ -16,21 +16,23 @@
#include "backend/metal/MetalBackend.h" #include "backend/metal/MetalBackend.h"
namespace backend { namespace backend { namespace metal {
namespace metal {
ResourceUploader::ResourceUploader(Device* device) ResourceUploader::ResourceUploader(Device* device) : mDevice(device) {
: mDevice(device) {
} }
ResourceUploader::~ResourceUploader() { ResourceUploader::~ResourceUploader() {
ASSERT(mInflightUploadBuffers.Empty()); ASSERT(mInflightUploadBuffers.Empty());
} }
void ResourceUploader::BufferSubData(id<MTLBuffer> buffer, uint32_t start, uint32_t size, const void* data) { void ResourceUploader::BufferSubData(id<MTLBuffer> buffer,
// TODO(cwallez@chromium.org) use a ringbuffer instead of creating a small buffer for each update uint32_t start,
id<MTLBuffer> uploadBuffer = [mDevice->GetMTLDevice() newBufferWithLength:size uint32_t size,
options:MTLResourceStorageModeShared]; const void* data) {
// TODO(cwallez@chromium.org) use a ringbuffer instead of creating a small buffer for each
// update
id<MTLBuffer> uploadBuffer =
[mDevice->GetMTLDevice() newBufferWithLength:size options:MTLResourceStorageModeShared];
memcpy([uploadBuffer contents], data, size); memcpy([uploadBuffer contents], data, size);
id<MTLCommandBuffer> commandBuffer = mDevice->GetPendingCommandBuffer(); id<MTLCommandBuffer> commandBuffer = mDevice->GetPendingCommandBuffer();
@ -52,5 +54,4 @@ namespace metal {
mInflightUploadBuffers.ClearUpTo(finishedSerial); mInflightUploadBuffers.ClearUpTo(finishedSerial);
} }
} }} // namespace backend::metal
}

View File

@ -19,8 +19,7 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
namespace backend { namespace backend { namespace metal {
namespace metal {
class Sampler : public SamplerBase { class Sampler : public SamplerBase {
public: public:
@ -33,7 +32,6 @@ namespace metal {
id<MTLSamplerState> mMtlSamplerState = nil; id<MTLSamplerState> mMtlSamplerState = nil;
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_SAMPLERMTL_H_ #endif // BACKEND_METAL_SAMPLERMTL_H_

View File

@ -16,8 +16,7 @@
#include "backend/metal/MetalBackend.h" #include "backend/metal/MetalBackend.h"
namespace backend { namespace backend { namespace metal {
namespace metal {
namespace { namespace {
MTLSamplerMinMagFilter FilterModeToMinMagFilter(nxt::FilterMode mode) { MTLSamplerMinMagFilter FilterModeToMinMagFilter(nxt::FilterMode mode) {
@ -39,8 +38,7 @@ namespace metal {
} }
} }
Sampler::Sampler(SamplerBuilder* builder) Sampler::Sampler(SamplerBuilder* builder) : SamplerBase(builder) {
: SamplerBase(builder) {
auto desc = [MTLSamplerDescriptor new]; auto desc = [MTLSamplerDescriptor new];
[desc autorelease]; [desc autorelease];
desc.minFilter = FilterModeToMinMagFilter(builder->GetMinFilter()); desc.minFilter = FilterModeToMinMagFilter(builder->GetMinFilter());
@ -60,5 +58,4 @@ namespace metal {
return mMtlSamplerState; return mMtlSamplerState;
} }
} }} // namespace backend::metal
}

View File

@ -23,8 +23,7 @@ namespace spirv_cross {
class CompilerMSL; class CompilerMSL;
} }
namespace backend { namespace backend { namespace metal {
namespace metal {
class PipelineLayout; class PipelineLayout;
@ -45,7 +44,6 @@ namespace metal {
std::vector<uint32_t> mSpirv; std::vector<uint32_t> mSpirv;
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_SHADERMODULEMTL_H_ #endif // BACKEND_METAL_SHADERMODULEMTL_H_

View File

@ -21,8 +21,7 @@
#include <sstream> #include <sstream>
namespace backend { namespace backend { namespace metal {
namespace metal {
namespace { namespace {
@ -38,7 +37,6 @@ namespace metal {
UNREACHABLE(); UNREACHABLE();
} }
} }
} }
ShaderModule::ShaderModule(ShaderModuleBuilder* builder) ShaderModule::ShaderModule(ShaderModuleBuilder* builder)
@ -69,10 +67,8 @@ namespace metal {
// Create one resource binding entry per stage per binding. // Create one resource binding entry per stage per binding.
for (uint32_t group : IterateBitSet(layout->GetBindGroupsLayoutMask())) { for (uint32_t group : IterateBitSet(layout->GetBindGroupsLayoutMask())) {
const auto& bgInfo = layout->GetBindGroupLayout(group)->GetBindingInfo(); const auto& bgInfo = layout->GetBindGroupLayout(group)->GetBindingInfo();
for (uint32_t binding : IterateBitSet(bgInfo.mask)) { for (uint32_t binding : IterateBitSet(bgInfo.mask)) {
for (auto stage : IterateStages(bgInfo.visibilities[binding])) { for (auto stage : IterateStages(bgInfo.visibilities[binding])) {
uint32_t index = layout->GetBindingIndexInfo(stage)[group][binding]; uint32_t index = layout->GetBindingIndexInfo(stage)[group][binding];
@ -102,12 +98,14 @@ namespace metal {
auto mtlDevice = ToBackend(GetDevice())->GetMTLDevice(); auto mtlDevice = ToBackend(GetDevice())->GetMTLDevice();
NSError* error = nil; NSError* error = nil;
id<MTLLibrary> library = [mtlDevice newLibraryWithSource:mslSource options:nil error:&error]; id<MTLLibrary> library =
[mtlDevice newLibraryWithSource:mslSource options:nil error:&error];
if (error != nil) { if (error != nil) {
// TODO(cwallez@chromium.org): forward errors to caller // TODO(cwallez@chromium.org): forward errors to caller
NSLog(@"MTLDevice newLibraryWithSource => %@", error); NSLog(@"MTLDevice newLibraryWithSource => %@", error);
} }
// TODO(kainino@chromium.org): make this somehow more robust; it needs to behave like clean_func_name: // TODO(kainino@chromium.org): make this somehow more robust; it needs to behave like
// clean_func_name:
// https://github.com/KhronosGroup/SPIRV-Cross/blob/4e915e8c483e319d0dd7a1fa22318bef28f8cca3/spirv_msl.cpp#L1213 // https://github.com/KhronosGroup/SPIRV-Cross/blob/4e915e8c483e319d0dd7a1fa22318bef28f8cca3/spirv_msl.cpp#L1213
if (strcmp(functionName, "main") == 0) { if (strcmp(functionName, "main") == 0) {
functionName = "main0"; functionName = "main0";
@ -121,5 +119,4 @@ namespace metal {
return result; return result;
} }
} }} // namespace backend::metal
}

View File

@ -17,8 +17,7 @@
#include "backend/SwapChain.h" #include "backend/SwapChain.h"
namespace backend { namespace backend { namespace metal {
namespace metal {
class Device; class Device;
@ -31,7 +30,6 @@ namespace metal {
TextureBase* GetNextTextureImpl(TextureBuilder* builder) override; TextureBase* GetNextTextureImpl(TextureBuilder* builder) override;
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_SWAPCHAINGL_H_ #endif // BACKEND_METAL_SWAPCHAINGL_H_

View File

@ -19,11 +19,9 @@
#include <nxt/nxt_wsi.h> #include <nxt/nxt_wsi.h>
namespace backend { namespace backend { namespace metal {
namespace metal {
SwapChain::SwapChain(SwapChainBuilder* builder) SwapChain::SwapChain(SwapChainBuilder* builder) : SwapChainBase(builder) {
: SwapChainBase(builder) {
const auto& im = GetImplementation(); const auto& im = GetImplementation();
nxtWSIContextMetal wsiContext = {}; nxtWSIContextMetal wsiContext = {};
wsiContext.device = ToBackend(GetDevice())->GetMTLDevice(); wsiContext.device = ToBackend(GetDevice())->GetMTLDevice();
@ -46,5 +44,4 @@ namespace metal {
return new Texture(builder, nativeTexture); return new Texture(builder, nativeTexture);
} }
} }} // namespace backend::metal
}

View File

@ -19,8 +19,7 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
namespace backend { namespace backend { namespace metal {
namespace metal {
MTLPixelFormat MetalPixelFormat(nxt::TextureFormat format); MTLPixelFormat MetalPixelFormat(nxt::TextureFormat format);
@ -32,7 +31,8 @@ namespace metal {
id<MTLTexture> GetMTLTexture(); id<MTLTexture> GetMTLTexture();
void TransitionUsageImpl(nxt::TextureUsageBit currentUsage, nxt::TextureUsageBit targetUsage) override; void TransitionUsageImpl(nxt::TextureUsageBit currentUsage,
nxt::TextureUsageBit targetUsage) override;
private: private:
id<MTLTexture> mMtlTexture = nil; id<MTLTexture> mMtlTexture = nil;
@ -43,7 +43,6 @@ namespace metal {
TextureView(TextureViewBuilder* builder); TextureView(TextureViewBuilder* builder);
}; };
} }} // namespace backend::metal
}
#endif // BACKEND_METAL_TEXTUREMTL_H_ #endif // BACKEND_METAL_TEXTUREMTL_H_

View File

@ -16,8 +16,7 @@
#include "backend/metal/MetalBackend.h" #include "backend/metal/MetalBackend.h"
namespace backend { namespace backend { namespace metal {
namespace metal {
MTLPixelFormat MetalPixelFormat(nxt::TextureFormat format) { MTLPixelFormat MetalPixelFormat(nxt::TextureFormat format) {
switch (format) { switch (format) {
@ -59,8 +58,7 @@ namespace metal {
} }
} }
Texture::Texture(TextureBuilder* builder) Texture::Texture(TextureBuilder* builder) : TextureBase(builder) {
: TextureBase(builder) {
auto desc = [MTLTextureDescriptor new]; auto desc = [MTLTextureDescriptor new];
[desc autorelease]; [desc autorelease];
desc.textureType = MetalTextureType(GetDimension()); desc.textureType = MetalTextureType(GetDimension());
@ -93,8 +91,7 @@ namespace metal {
void Texture::TransitionUsageImpl(nxt::TextureUsageBit, nxt::TextureUsageBit) { void Texture::TransitionUsageImpl(nxt::TextureUsageBit, nxt::TextureUsageBit) {
} }
TextureView::TextureView(TextureViewBuilder* builder) TextureView::TextureView(TextureViewBuilder* builder) : TextureViewBase(builder) {
: TextureViewBase(builder) {
}
}
} }
}} // namespace backend::metal