Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ExternalRevisions/SPIRV-Cross_repo_revision
Original file line number Diff line number Diff line change
@@ -1 +1 @@
aa217aeb6c9f0ace7a0ab233b28807edf45eb165
81739edf516c2bef043ac61f510b4bd78e126a22
3 changes: 3 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCmdDebug.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class MVKCmdDebugMarkerBegin : public MVKCmdDebugMarker {

public:
void encode(MVKCommandEncoder* cmdEncoder) override;
bool encodePerVertexPrepass(MVKCommandEncoder*) override { return true; }

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
Expand All @@ -62,6 +63,7 @@ class MVKCmdDebugMarkerEnd : public MVKCommand {
VkResult setContent(MVKCommandBuffer* cmdBuff);

void encode(MVKCommandEncoder* cmdEncoder) override;
bool encodePerVertexPrepass(MVKCommandEncoder*) override { return true; }

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
Expand All @@ -76,6 +78,7 @@ class MVKCmdDebugMarkerInsert : public MVKCmdDebugMarker {

public:
void encode(MVKCommandEncoder* cmdEncoder) override;
bool encodePerVertexPrepass(MVKCommandEncoder*) override { return true; }

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
Expand Down
4 changes: 2 additions & 2 deletions MoltenVK/MoltenVK/Commands/MVKCmdDebug.mm
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
if (mtlCmdEnc) {
[mtlCmdEnc pushDebugGroup: _markerName];
} else {
[cmdEncoder->_mtlCmdBuffer pushDebugGroup: _markerName];
cmdEncoder->pushCommandBufferDebugGroup(_markerName);
}
}

Expand All @@ -63,7 +63,7 @@
if (mtlCmdEnc) {
[mtlCmdEnc popDebugGroup];
} else {
[cmdEncoder->_mtlCmdBuffer popDebugGroup];
cmdEncoder->popCommandBufferDebugGroup();
}
}

Expand Down
74 changes: 74 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCmdDraw.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,31 @@
#include "MVKCommand.h"
#include "MVKMTLResourceBindings.h"
#include "MVKSmallVector.h"
#include "MVKPerVertexReplay.h"

#import <Metal/Metal.h>

class MVKGraphicsPipeline;

// Preserve the conservative power-of-two scratch ceiling used by recording validation.
static inline bool mvkCanEncodePerVertexDraw(uint32_t vertexCount, uint32_t instanceCount, uint32_t stride, VkPrimitiveTopology topology, uint64_t maxMTLBufferSize) {
if (!mvkPerVertexReplayVertexCount(topology)) { return false; }
if (!vertexCount || !instanceCount) { return true; }
if (!maxMTLBufferSize) { return false; }
uint64_t maxBufferSize = 1;
while (maxBufferSize <= maxMTLBufferSize / 2) { maxBufferSize *= 2; }
uint64_t recordCount = uint64_t(vertexCount) * instanceCount;
if (!stride || recordCount > UINT32_MAX || recordCount > maxBufferSize / stride) { return false; }
uint64_t primitiveCount = uint64_t(mvkPerVertexPrimitiveCount(vertexCount, topology)) * instanceCount;
uint64_t occurrenceCount = primitiveCount * mvkPerVertexReplayVertexCount(topology);
return primitiveCount <= UINT32_MAX / 3 && primitiveCount <= maxBufferSize / (3 * sizeof(uint32_t)) && occurrenceCount <= UINT32_MAX / 2 && occurrenceCount <= maxBufferSize / (2 * sizeof(uint32_t));
}

// PerVertex TES plan: status, replay arguments and constants, per-patch counts and offsets, then, 256-byte
// aligned for the fragment binding, the patch index of each generated triangle (at most 13 per patch).
static inline uint64_t mvkPerVertexTessPrimitiveIdOffset(uint64_t patches) { return mvkAlignByteCount(512 + patches * 2 * sizeof(uint32_t), 256); }
static inline uint64_t mvkPerVertexTessPlanSize(uint64_t patches) { return mvkPerVertexTessPrimitiveIdOffset(patches) + patches * 13 * sizeof(uint32_t); }


#pragma mark -
#pragma mark MVKCmdBindVertexBuffers
Expand All @@ -45,6 +67,7 @@ class MVKCmdBindVertexBuffers : public MVKCommand {
const VkDeviceSize* pStrides);

void encode(MVKCommandEncoder* cmdEncoder) override;
bool encodePerVertexPrepass(MVKCommandEncoder* cmdEncoder) override { encode(cmdEncoder); return true; }

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
Expand Down Expand Up @@ -77,6 +100,7 @@ class MVKCmdBindIndexBuffer : public MVKCommand {
VkIndexType indexType);

void encode(MVKCommandEncoder* cmdEncoder) override;
bool encodePerVertexPrepass(MVKCommandEncoder* cmdEncoder) override { encode(cmdEncoder); return true; }

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
Expand All @@ -99,6 +123,8 @@ class MVKCmdDraw : public MVKCommand {
uint32_t drawIndex = 0);

void encode(MVKCommandEncoder* cmdEncoder) override;
bool encodePerVertexPrepass(MVKCommandEncoder* cmdEncoder) override;
void encodePerVertexInput(MVKCommandEncoder* cmdEncoder, MVKGraphicsPipeline* pipeline);
void encodeIndexedIndirect(MVKCommandEncoder* cmdEncoder);

protected:
Expand Down Expand Up @@ -127,6 +153,8 @@ class MVKCmdDrawIndexed : public MVKCommand {
uint32_t drawIndex = 0);

void encode(MVKCommandEncoder* cmdEncoder) override;
bool encodePerVertexPrepass(MVKCommandEncoder* cmdEncoder) override;
void encodePerVertexInput(MVKCommandEncoder* cmdEncoder, MVKGraphicsPipeline* pipeline);

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
Expand Down Expand Up @@ -218,3 +246,49 @@ class MVKCmdDrawIndexedIndirect : public MVKCommand {
id<MTLBuffer> _mtlCountBuffer;
VkDeviceSize _mtlCountBufferOffset;
};


#pragma mark -
#pragma mark MVKCmdDrawMeshTasks

/** Vulkan command to draw mesh workgroups (vkCmdDrawMeshTasksEXT). */
class MVKCmdDrawMeshTasks : public MVKCommand {

public:
VkResult setContent(MVKCommandBuffer* cmdBuff, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);

void encode(MVKCommandEncoder* cmdEncoder) override;
bool encodePerVertexPrepass(MVKCommandEncoder* cmdEncoder) override;

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
bool encodeMesh(MVKCommandEncoder* cmdEncoder, bool prepass);

uint32_t _groupCountX;
uint32_t _groupCountY;
uint32_t _groupCountZ;
};


#pragma mark -
#pragma mark MVKCmdDrawMeshTasksIndirect

/**
* Vulkan command to draw one indirect grid of mesh workgroups (vkCmdDrawMeshTasksIndirectEXT, drawCount 1), with
* MVK_CONFIG_MESH_INDIRECT_GPU=1. The grid is read by Metal from the indirect buffer, with no CPU readback.
*/
class MVKCmdDrawMeshTasksIndirect : public MVKCommand {

public:
VkResult setContent(MVKCommandBuffer* cmdBuff, VkBuffer buffer, VkDeviceSize offset);

void encode(MVKCommandEncoder* cmdEncoder) override;
// A native mesh draw has nothing to capture: nothing to do in the PerVertex prepass, which continues.
bool encodePerVertexPrepass(MVKCommandEncoder*) override { return true; }

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;

id<MTLBuffer> _mtlIndirectBuffer;
VkDeviceSize _mtlIndirectBufferOffset;
};
Loading
Loading