Clear attachments using layered rendering only if framebuffer is layered.
Consolidate testing of subpass layered rendering. Add MVKCommandEncoder _isUsingLayeredRendering member variable. Track layered rendering enabled in MVKRPSKeyClearAtt. Rename MVKRPSKeyClearAtt::enable() and ::isEnabled() functions. Add MVKRPSKeyClearAtt::reset() function. Consolidate viewport, scissor & attachment limits. MVKImage add validation for layered rendering when used as attachment.
This commit is contained in:
parent
e80b535526
commit
2da855a6bc
@ -30,7 +30,7 @@ Released TBD
|
|||||||
- Fix tessellated indirect draws using wrong kernels to map parameters.
|
- Fix tessellated indirect draws using wrong kernels to map parameters.
|
||||||
- Work around potential Metal bug with stage-in indirect buffers.
|
- Work around potential Metal bug with stage-in indirect buffers.
|
||||||
- Fix zero local threadgroup size in indirect tessellated rendering.
|
- Fix zero local threadgroup size in indirect tessellated rendering.
|
||||||
- Fix crash with multisample layered rendering on older macOS devices.
|
- Fix crash when clearing attachments using layered rendering on older macOS devices.
|
||||||
- Fixes to Metal renderpass layered rendering settings.
|
- Fixes to Metal renderpass layered rendering settings.
|
||||||
- `MoltenVKShaderConverter` tool: Add MSL version and platform command-line options.
|
- `MoltenVKShaderConverter` tool: Add MSL version and platform command-line options.
|
||||||
- Allow building external dependency libraries in `Debug` mode.
|
- Allow building external dependency libraries in `Debug` mode.
|
||||||
|
@ -115,7 +115,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t _firstViewport;
|
uint32_t _firstViewport;
|
||||||
MVKVectorInline<MTLViewport, kMVKCachedViewportCount> _mtlViewports;
|
MVKVectorInline<MTLViewport, kMVKCachedViewportScissorCount> _mtlViewports;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t _firstScissor;
|
uint32_t _firstScissor;
|
||||||
MVKVectorInline<MTLScissorRect, kMVKCachedScissorCount> _mtlScissors;
|
MVKVectorInline<MTLScissorRect, kMVKCachedViewportScissorCount> _mtlScissors;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -243,8 +243,8 @@ protected:
|
|||||||
|
|
||||||
std::vector<VkClearRect> _clearRects;
|
std::vector<VkClearRect> _clearRects;
|
||||||
std::vector<simd::float4> _vertices;
|
std::vector<simd::float4> _vertices;
|
||||||
simd::float4 _clearColors[kMVKAttachmentFormatCount];
|
simd::float4 _clearColors[kMVKClearAttachmentCount];
|
||||||
VkClearValue _vkClearValues[kMVKAttachmentFormatCount];
|
VkClearValue _vkClearValues[kMVKClearAttachmentCount];
|
||||||
MVKRPSKeyClearAtt _rpsKey;
|
MVKRPSKeyClearAtt _rpsKey;
|
||||||
uint32_t _mtlStencilValue;
|
uint32_t _mtlStencilValue;
|
||||||
bool _isClearingDepth;
|
bool _isClearingDepth;
|
||||||
|
@ -816,7 +816,7 @@ void MVKCmdClearAttachments::setContent(uint32_t attachmentCount,
|
|||||||
const VkClearAttachment* pAttachments,
|
const VkClearAttachment* pAttachments,
|
||||||
uint32_t rectCount,
|
uint32_t rectCount,
|
||||||
const VkClearRect* pRects) {
|
const VkClearRect* pRects) {
|
||||||
_rpsKey = kMVKRPSKeyClearAttDefault;
|
_rpsKey.reset();
|
||||||
_mtlStencilValue = 0;
|
_mtlStencilValue = 0;
|
||||||
_isClearingDepth = false;
|
_isClearingDepth = false;
|
||||||
_isClearingStencil = false;
|
_isClearingStencil = false;
|
||||||
@ -831,26 +831,26 @@ void MVKCmdClearAttachments::setContent(uint32_t attachmentCount,
|
|||||||
if (mvkIsAnyFlagEnabled(clrAtt.aspectMask, VK_IMAGE_ASPECT_COLOR_BIT)) {
|
if (mvkIsAnyFlagEnabled(clrAtt.aspectMask, VK_IMAGE_ASPECT_COLOR_BIT)) {
|
||||||
uint32_t caIdx = clrAtt.colorAttachment; // Might be VK_ATTACHMENT_UNUSED
|
uint32_t caIdx = clrAtt.colorAttachment; // Might be VK_ATTACHMENT_UNUSED
|
||||||
if (caIdx != VK_ATTACHMENT_UNUSED) {
|
if (caIdx != VK_ATTACHMENT_UNUSED) {
|
||||||
_rpsKey.enable(caIdx);
|
_rpsKey.enableAttachment(caIdx);
|
||||||
_vkClearValues[caIdx] = clrAtt.clearValue;
|
_vkClearValues[caIdx] = clrAtt.clearValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mvkIsAnyFlagEnabled(clrAtt.aspectMask, VK_IMAGE_ASPECT_DEPTH_BIT)) {
|
if (mvkIsAnyFlagEnabled(clrAtt.aspectMask, VK_IMAGE_ASPECT_DEPTH_BIT)) {
|
||||||
_isClearingDepth = true;
|
_isClearingDepth = true;
|
||||||
_rpsKey.enable(kMVKAttachmentFormatDepthStencilIndex);
|
_rpsKey.enableAttachment(kMVKClearAttachmentDepthStencilIndex);
|
||||||
mtlDepthVal = mvkMTLClearDepthFromVkClearValue(clrAtt.clearValue);
|
mtlDepthVal = mvkMTLClearDepthFromVkClearValue(clrAtt.clearValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mvkIsAnyFlagEnabled(clrAtt.aspectMask, VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
if (mvkIsAnyFlagEnabled(clrAtt.aspectMask, VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||||
_isClearingStencil = true;
|
_isClearingStencil = true;
|
||||||
_rpsKey.enable(kMVKAttachmentFormatDepthStencilIndex);
|
_rpsKey.enableAttachment(kMVKClearAttachmentDepthStencilIndex);
|
||||||
_mtlStencilValue = mvkMTLClearStencilFromVkClearValue(clrAtt.clearValue);
|
_mtlStencilValue = mvkMTLClearStencilFromVkClearValue(clrAtt.clearValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The depth value (including vertex position Z value) is held in the last index.
|
// The depth value (including vertex position Z value) is held in the last index.
|
||||||
_clearColors[kMVKAttachmentFormatDepthStencilIndex] = { mtlDepthVal, mtlDepthVal, mtlDepthVal, mtlDepthVal };
|
_clearColors[kMVKClearAttachmentDepthStencilIndex] = { mtlDepthVal, mtlDepthVal, mtlDepthVal, mtlDepthVal };
|
||||||
|
|
||||||
_clearRects.clear();
|
_clearRects.clear();
|
||||||
_clearRects.reserve(rectCount);
|
_clearRects.reserve(rectCount);
|
||||||
@ -932,8 +932,9 @@ void MVKCmdClearAttachments::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
uint32_t vtxCnt = (uint32_t)_vertices.size();
|
uint32_t vtxCnt = (uint32_t)_vertices.size();
|
||||||
uint32_t vtxBuffIdx = getDevice()->getMetalBufferIndexForVertexAttributeBinding(kMVKVertexContentBufferIndex);
|
uint32_t vtxBuffIdx = getDevice()->getMetalBufferIndexForVertexAttributeBinding(kMVKVertexContentBufferIndex);
|
||||||
|
|
||||||
// Populate the render pipeline state attachment key with attachment info from the subpass.
|
// Populate the render pipeline state attachment key with info from the subpass and framebuffer.
|
||||||
_rpsKey.mtlSampleCount = mvkSampleCountFromVkSampleCountFlagBits(subpass->getSampleCount());
|
_rpsKey.mtlSampleCount = mvkSampleCountFromVkSampleCountFlagBits(subpass->getSampleCount());
|
||||||
|
if (cmdEncoder->_isUsingLayeredRendering) { _rpsKey.enableLayeredRendering(); }
|
||||||
|
|
||||||
uint32_t caCnt = subpass->getColorAttachmentCount();
|
uint32_t caCnt = subpass->getColorAttachmentCount();
|
||||||
for (uint32_t caIdx = 0; caIdx < caCnt; caIdx++) {
|
for (uint32_t caIdx = 0; caIdx < caCnt; caIdx++) {
|
||||||
@ -945,7 +946,7 @@ void MVKCmdClearAttachments::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
|
|
||||||
VkFormat vkAttFmt = subpass->getDepthStencilFormat();
|
VkFormat vkAttFmt = subpass->getDepthStencilFormat();
|
||||||
MTLPixelFormat mtlAttFmt = cmdPool->getMTLPixelFormatFromVkFormat(vkAttFmt);
|
MTLPixelFormat mtlAttFmt = cmdPool->getMTLPixelFormatFromVkFormat(vkAttFmt);
|
||||||
_rpsKey.attachmentMTLPixelFormats[kMVKAttachmentFormatDepthStencilIndex] = mtlAttFmt;
|
_rpsKey.attachmentMTLPixelFormats[kMVKClearAttachmentDepthStencilIndex] = mtlAttFmt;
|
||||||
bool isClearingDepth = _isClearingDepth && mvkMTLPixelFormatIsDepthFormat(mtlAttFmt);
|
bool isClearingDepth = _isClearingDepth && mvkMTLPixelFormatIsDepthFormat(mtlAttFmt);
|
||||||
bool isClearingStencil = _isClearingStencil && mvkMTLPixelFormatIsStencilFormat(mtlAttFmt);
|
bool isClearingStencil = _isClearingStencil && mvkMTLPixelFormatIsStencilFormat(mtlAttFmt);
|
||||||
|
|
||||||
|
@ -420,6 +420,9 @@ public:
|
|||||||
/** The size of the threadgroup for the compute shader. */
|
/** The size of the threadgroup for the compute shader. */
|
||||||
MTLSize _mtlThreadgroupSize;
|
MTLSize _mtlThreadgroupSize;
|
||||||
|
|
||||||
|
/** Indicates whether the current render subpass is rendering to an array (layered) framebuffer. */
|
||||||
|
bool _isUsingLayeredRendering;
|
||||||
|
|
||||||
|
|
||||||
#pragma mark Construction
|
#pragma mark Construction
|
||||||
|
|
||||||
|
@ -234,6 +234,7 @@ void MVKCommandBuffer::recordDraw(MVKLoadStoreOverrideMixin* mvkDraw) {
|
|||||||
void MVKCommandEncoder::encode(id<MTLCommandBuffer> mtlCmdBuff) {
|
void MVKCommandEncoder::encode(id<MTLCommandBuffer> mtlCmdBuff) {
|
||||||
_subpassContents = VK_SUBPASS_CONTENTS_INLINE;
|
_subpassContents = VK_SUBPASS_CONTENTS_INLINE;
|
||||||
_renderSubpassIndex = 0;
|
_renderSubpassIndex = 0;
|
||||||
|
_isUsingLayeredRendering = false;
|
||||||
|
|
||||||
_mtlCmdBuffer = mtlCmdBuff; // not retained
|
_mtlCmdBuffer = mtlCmdBuff; // not retained
|
||||||
|
|
||||||
@ -280,7 +281,12 @@ void MVKCommandEncoder::setSubpass(VkSubpassContents subpassContents, uint32_t s
|
|||||||
_subpassContents = subpassContents;
|
_subpassContents = subpassContents;
|
||||||
_renderSubpassIndex = subpassIndex;
|
_renderSubpassIndex = subpassIndex;
|
||||||
|
|
||||||
beginMetalRenderPass(loadOverride, storeOverride);
|
_isUsingLayeredRendering = ((_framebuffer->getLayerCount() > 1) &&
|
||||||
|
_device->_pMetalFeatures->layeredRendering &&
|
||||||
|
(_device->_pMetalFeatures->multisampleLayeredRendering ||
|
||||||
|
(getSubpass()->getSampleCount() == VK_SAMPLE_COUNT_1_BIT)));
|
||||||
|
|
||||||
|
beginMetalRenderPass(loadOverride, storeOverride);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates _mtlRenderEncoder and marks cached render state as dirty so it will be set into the _mtlRenderEncoder.
|
// Creates _mtlRenderEncoder and marks cached render state as dirty so it will be set into the _mtlRenderEncoder.
|
||||||
@ -293,11 +299,7 @@ void MVKCommandEncoder::beginMetalRenderPass(bool loadOverride, bool storeOverri
|
|||||||
mtlRPDesc.visibilityResultBuffer = _occlusionQueryState.getVisibilityResultMTLBuffer();
|
mtlRPDesc.visibilityResultBuffer = _occlusionQueryState.getVisibilityResultMTLBuffer();
|
||||||
|
|
||||||
// Only set the layered rendering properties if layered rendering is supported and the framebuffer really has multiple layers
|
// Only set the layered rendering properties if layered rendering is supported and the framebuffer really has multiple layers
|
||||||
if ((_framebuffer->getLayerCount() > 1) &&
|
if (_isUsingLayeredRendering) {
|
||||||
_device->_pMetalFeatures->layeredRendering &&
|
|
||||||
(_device->_pMetalFeatures->multisampleLayeredRendering ||
|
|
||||||
(getSubpass()->getSampleCount() == VK_SAMPLE_COUNT_1_BIT))) {
|
|
||||||
|
|
||||||
VkExtent2D fbExtent = _framebuffer->getExtent2D();
|
VkExtent2D fbExtent = _framebuffer->getExtent2D();
|
||||||
mtlRPDesc.renderTargetWidthMVK = min(_renderArea.offset.x + _renderArea.extent.width, fbExtent.width);
|
mtlRPDesc.renderTargetWidthMVK = min(_renderArea.offset.x + _renderArea.extent.width, fbExtent.width);
|
||||||
mtlRPDesc.renderTargetHeightMVK = min(_renderArea.offset.y + _renderArea.extent.height, fbExtent.height);
|
mtlRPDesc.renderTargetHeightMVK = min(_renderArea.offset.y + _renderArea.extent.height, fbExtent.height);
|
||||||
|
@ -151,7 +151,7 @@ protected:
|
|||||||
void encodeImpl(uint32_t stage) override;
|
void encodeImpl(uint32_t stage) override;
|
||||||
void resetImpl() override;
|
void resetImpl() override;
|
||||||
|
|
||||||
MVKVectorInline<MTLViewport, kMVKCachedViewportCount> _mtlViewports, _mtlDynamicViewports;
|
MVKVectorInline<MTLViewport, kMVKCachedViewportScissorCount> _mtlViewports, _mtlDynamicViewports;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ protected:
|
|||||||
void encodeImpl(uint32_t stage) override;
|
void encodeImpl(uint32_t stage) override;
|
||||||
void resetImpl() override;
|
void resetImpl() override;
|
||||||
|
|
||||||
MVKVectorInline<MTLScissorRect, kMVKCachedScissorCount> _mtlScissors, _mtlDynamicScissors;
|
MVKVectorInline<MTLScissorRect, kMVKCachedViewportScissorCount> _mtlScissors, _mtlDynamicScissors;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include "MVKDevice.h"
|
#include "MVKDevice.h"
|
||||||
#include "MVKCommandBuffer.h"
|
#include "MVKCommandBuffer.h"
|
||||||
#include "MVKCommandResourceFactory.h"
|
|
||||||
#include "MVKCommandEncodingPool.h"
|
#include "MVKCommandEncodingPool.h"
|
||||||
#include "MVKCommand.h"
|
#include "MVKCommand.h"
|
||||||
#include "MVKCmdPipeline.h"
|
#include "MVKCmdPipeline.h"
|
||||||
|
@ -74,8 +74,9 @@ namespace std {
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKRPSKeyClearAtt
|
#pragma mark MVKRPSKeyClearAtt
|
||||||
|
|
||||||
#define kMVKAttachmentFormatCount 9
|
#define kMVKClearAttachmentCount (kMVKCachedColorAttachmentCount + 1)
|
||||||
#define kMVKAttachmentFormatDepthStencilIndex (kMVKAttachmentFormatCount - 1)
|
#define kMVKClearAttachmentDepthStencilIndex (kMVKClearAttachmentCount - 1)
|
||||||
|
#define kMVKClearAttachmentLayeredRenderingBitIndex kMVKClearAttachmentCount
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key to use for looking up cached MTLRenderPipelineState instances.
|
* Key to use for looking up cached MTLRenderPipelineState instances.
|
||||||
@ -85,37 +86,40 @@ namespace std {
|
|||||||
* This structure can be used as a key in a std::map and std::unordered_map.
|
* This structure can be used as a key in a std::map and std::unordered_map.
|
||||||
*/
|
*/
|
||||||
typedef struct MVKRPSKeyClearAtt_t {
|
typedef struct MVKRPSKeyClearAtt_t {
|
||||||
uint16_t attachmentMTLPixelFormats[kMVKAttachmentFormatCount];
|
uint16_t attachmentMTLPixelFormats[kMVKClearAttachmentCount];
|
||||||
uint16_t mtlSampleCount;
|
uint16_t mtlSampleCount;
|
||||||
uint32_t enabledFlags;
|
uint16_t flags; // bitcount > kMVKClearAttachmentLayeredRenderingBitIndex
|
||||||
|
|
||||||
const static uint32_t bitFlag = 1;
|
const static uint32_t bitFlag = 1;
|
||||||
|
|
||||||
void enable(uint32_t attIdx) { mvkEnableFlag(enabledFlags, bitFlag << attIdx); }
|
void enableAttachment(uint32_t attIdx) { mvkEnableFlag(flags, bitFlag << attIdx); }
|
||||||
|
|
||||||
bool isEnabled(uint32_t attIdx) { return mvkIsAnyFlagEnabled(enabledFlags, bitFlag << attIdx); }
|
bool isAttachmentEnabled(uint32_t attIdx) { return mvkIsAnyFlagEnabled(flags, bitFlag << attIdx); }
|
||||||
|
|
||||||
|
void enableLayeredRendering() { mvkEnableFlag(flags, bitFlag << kMVKClearAttachmentLayeredRenderingBitIndex); }
|
||||||
|
|
||||||
|
bool isLayeredRenderingEnabled() { return mvkIsAnyFlagEnabled(flags, bitFlag << kMVKClearAttachmentLayeredRenderingBitIndex); }
|
||||||
|
|
||||||
bool operator==(const MVKRPSKeyClearAtt_t& rhs) const {
|
bool operator==(const MVKRPSKeyClearAtt_t& rhs) const {
|
||||||
return ((enabledFlags == rhs.enabledFlags) &&
|
return ((flags == rhs.flags) &&
|
||||||
(mtlSampleCount == rhs.mtlSampleCount) &&
|
(mtlSampleCount == rhs.mtlSampleCount) &&
|
||||||
(memcmp(attachmentMTLPixelFormats, rhs.attachmentMTLPixelFormats, sizeof(attachmentMTLPixelFormats)) == 0));
|
(memcmp(attachmentMTLPixelFormats, rhs.attachmentMTLPixelFormats, sizeof(attachmentMTLPixelFormats)) == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t hash() const {
|
std::size_t hash() const {
|
||||||
std::size_t hash = mvkHash(&enabledFlags);
|
std::size_t hash = mvkHash(&flags);
|
||||||
hash = mvkHash(&mtlSampleCount, 1, hash);
|
hash = mvkHash(&mtlSampleCount, 1, hash);
|
||||||
return mvkHash(attachmentMTLPixelFormats, kMVKAttachmentFormatCount, hash);
|
return mvkHash(attachmentMTLPixelFormats, kMVKClearAttachmentCount, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
MVKRPSKeyClearAtt_t() {
|
void reset() {
|
||||||
memset(this, 0, sizeof(*this));
|
memset(this, 0, sizeof(*this));
|
||||||
mtlSampleCount = mvkSampleCountFromVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT);
|
mtlSampleCount = mvkSampleCountFromVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
} MVKRPSKeyClearAtt;
|
MVKRPSKeyClearAtt_t() { reset(); }
|
||||||
|
|
||||||
/** An instance populated with default values, for use in resetting other instances to default state. */
|
} MVKRPSKeyClearAtt;
|
||||||
const MVKRPSKeyClearAtt kMVKRPSKeyClearAttDefault;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash structure implementation for MVKRPSKeyClearAtt in std namespace,
|
* Hash structure implementation for MVKRPSKeyClearAtt in std namespace,
|
||||||
|
@ -95,12 +95,12 @@ id<MTLRenderPipelineState> MVKCommandResourceFactory::newCmdClearMTLRenderPipeli
|
|||||||
plDesc.sampleCount = attKey.mtlSampleCount;
|
plDesc.sampleCount = attKey.mtlSampleCount;
|
||||||
plDesc.inputPrimitiveTopologyMVK = MTLPrimitiveTopologyClassTriangle;
|
plDesc.inputPrimitiveTopologyMVK = MTLPrimitiveTopologyClassTriangle;
|
||||||
|
|
||||||
for (uint32_t caIdx = 0; caIdx < kMVKAttachmentFormatDepthStencilIndex; caIdx++) {
|
for (uint32_t caIdx = 0; caIdx < kMVKClearAttachmentDepthStencilIndex; caIdx++) {
|
||||||
MTLRenderPipelineColorAttachmentDescriptor* colorDesc = plDesc.colorAttachments[caIdx];
|
MTLRenderPipelineColorAttachmentDescriptor* colorDesc = plDesc.colorAttachments[caIdx];
|
||||||
colorDesc.pixelFormat = (MTLPixelFormat)attKey.attachmentMTLPixelFormats[caIdx];
|
colorDesc.pixelFormat = (MTLPixelFormat)attKey.attachmentMTLPixelFormats[caIdx];
|
||||||
colorDesc.writeMask = attKey.isEnabled(caIdx) ? MTLColorWriteMaskAll : MTLColorWriteMaskNone;
|
colorDesc.writeMask = attKey.isAttachmentEnabled(caIdx) ? MTLColorWriteMaskAll : MTLColorWriteMaskNone;
|
||||||
}
|
}
|
||||||
MTLPixelFormat mtlDSFormat = (MTLPixelFormat)attKey.attachmentMTLPixelFormats[kMVKAttachmentFormatDepthStencilIndex];
|
MTLPixelFormat mtlDSFormat = (MTLPixelFormat)attKey.attachmentMTLPixelFormats[kMVKClearAttachmentDepthStencilIndex];
|
||||||
if (mvkMTLPixelFormatIsDepthFormat(mtlDSFormat)) { plDesc.depthAttachmentPixelFormat = mtlDSFormat; }
|
if (mvkMTLPixelFormatIsDepthFormat(mtlDSFormat)) { plDesc.depthAttachmentPixelFormat = mtlDSFormat; }
|
||||||
if (mvkMTLPixelFormatIsStencilFormat(mtlDSFormat)) { plDesc.stencilAttachmentPixelFormat = mtlDSFormat; }
|
if (mvkMTLPixelFormatIsStencilFormat(mtlDSFormat)) { plDesc.stencilAttachmentPixelFormat = mtlDSFormat; }
|
||||||
|
|
||||||
@ -181,7 +181,6 @@ id<MTLFunction> MVKCommandResourceFactory::getBlitFragFunction(MVKRPSKeyBlitImg&
|
|||||||
|
|
||||||
id<MTLFunction> MVKCommandResourceFactory::getClearVertFunction(MVKRPSKeyClearAtt& attKey) {
|
id<MTLFunction> MVKCommandResourceFactory::getClearVertFunction(MVKRPSKeyClearAtt& attKey) {
|
||||||
id<MTLFunction> mtlFunc = nil;
|
id<MTLFunction> mtlFunc = nil;
|
||||||
bool allowLayers = _device->_pMetalFeatures->layeredRendering && (attKey.mtlSampleCount == 1 || _device->_pMetalFeatures->multisampleLayeredRendering);
|
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
NSMutableString* msl = [NSMutableString stringWithCapacity: (2 * KIBI) ];
|
NSMutableString* msl = [NSMutableString stringWithCapacity: (2 * KIBI) ];
|
||||||
[msl appendLineMVK: @"#include <metal_stdlib>"];
|
[msl appendLineMVK: @"#include <metal_stdlib>"];
|
||||||
@ -197,7 +196,7 @@ id<MTLFunction> MVKCommandResourceFactory::getClearVertFunction(MVKRPSKeyClearAt
|
|||||||
[msl appendLineMVK];
|
[msl appendLineMVK];
|
||||||
[msl appendLineMVK: @"typedef struct {"];
|
[msl appendLineMVK: @"typedef struct {"];
|
||||||
[msl appendLineMVK: @" float4 v_position [[position]];"];
|
[msl appendLineMVK: @" float4 v_position [[position]];"];
|
||||||
[msl appendFormat: @" uint layer%s;", allowLayers ? " [[render_target_array_index]]" : ""];
|
[msl appendFormat: @" uint layer%s;", attKey.isLayeredRenderingEnabled() ? " [[render_target_array_index]]" : ""];
|
||||||
[msl appendLineMVK: @"} VaryingsPos;"];
|
[msl appendLineMVK: @"} VaryingsPos;"];
|
||||||
[msl appendLineMVK];
|
[msl appendLineMVK];
|
||||||
|
|
||||||
@ -232,8 +231,8 @@ id<MTLFunction> MVKCommandResourceFactory::getClearFragFunction(MVKRPSKeyClearAt
|
|||||||
[msl appendLineMVK: @"} ClearColorsIn;"];
|
[msl appendLineMVK: @"} ClearColorsIn;"];
|
||||||
[msl appendLineMVK];
|
[msl appendLineMVK];
|
||||||
[msl appendLineMVK: @"typedef struct {"];
|
[msl appendLineMVK: @"typedef struct {"];
|
||||||
for (uint32_t caIdx = 0; caIdx < kMVKAttachmentFormatDepthStencilIndex; caIdx++) {
|
for (uint32_t caIdx = 0; caIdx < kMVKClearAttachmentDepthStencilIndex; caIdx++) {
|
||||||
if (attKey.isEnabled(caIdx)) {
|
if (attKey.isAttachmentEnabled(caIdx)) {
|
||||||
NSString* typeStr = getMTLFormatTypeString((MTLPixelFormat)attKey.attachmentMTLPixelFormats[caIdx]);
|
NSString* typeStr = getMTLFormatTypeString((MTLPixelFormat)attKey.attachmentMTLPixelFormats[caIdx]);
|
||||||
[msl appendFormat: @" %@4 color%u [[color(%u)]];", typeStr, caIdx, caIdx];
|
[msl appendFormat: @" %@4 color%u [[color(%u)]];", typeStr, caIdx, caIdx];
|
||||||
[msl appendLineMVK];
|
[msl appendLineMVK];
|
||||||
@ -246,8 +245,8 @@ id<MTLFunction> MVKCommandResourceFactory::getClearFragFunction(MVKRPSKeyClearAt
|
|||||||
[msl appendFormat: @"fragment ClearColorsOut %@(VaryingsPos varyings [[stage_in]], constant ClearColorsIn& ccIn [[buffer(0)]]) {", funcName];
|
[msl appendFormat: @"fragment ClearColorsOut %@(VaryingsPos varyings [[stage_in]], constant ClearColorsIn& ccIn [[buffer(0)]]) {", funcName];
|
||||||
[msl appendLineMVK];
|
[msl appendLineMVK];
|
||||||
[msl appendLineMVK: @" ClearColorsOut ccOut;"];
|
[msl appendLineMVK: @" ClearColorsOut ccOut;"];
|
||||||
for (uint32_t caIdx = 0; caIdx < kMVKAttachmentFormatDepthStencilIndex; caIdx++) {
|
for (uint32_t caIdx = 0; caIdx < kMVKClearAttachmentDepthStencilIndex; caIdx++) {
|
||||||
if (attKey.isEnabled(caIdx)) {
|
if (attKey.isAttachmentEnabled(caIdx)) {
|
||||||
NSString* typeStr = getMTLFormatTypeString((MTLPixelFormat)attKey.attachmentMTLPixelFormats[caIdx]);
|
NSString* typeStr = getMTLFormatTypeString((MTLPixelFormat)attKey.attachmentMTLPixelFormats[caIdx]);
|
||||||
[msl appendFormat: @" ccOut.color%u = %@4(ccIn.colors[%u]);", caIdx, typeStr, caIdx];
|
[msl appendFormat: @" ccOut.color%u = %@4(ccIn.colors[%u]);", caIdx, typeStr, caIdx];
|
||||||
[msl appendLineMVK];
|
[msl appendLineMVK];
|
||||||
|
@ -67,8 +67,8 @@ class MVKCommandResourceFactory;
|
|||||||
const static uint32_t kMVKVertexContentBufferIndex = 0;
|
const static uint32_t kMVKVertexContentBufferIndex = 0;
|
||||||
|
|
||||||
// Parameters to define the sizing of inline collections
|
// Parameters to define the sizing of inline collections
|
||||||
const static uint32_t kMVKCachedViewportCount = 16;
|
const static uint32_t kMVKCachedViewportScissorCount = 16;
|
||||||
const static uint32_t kMVKCachedScissorCount = 16;
|
const static uint32_t kMVKCachedColorAttachmentCount = 8;
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
@ -1002,13 +1002,13 @@ void MVKPhysicalDevice::initProperties() {
|
|||||||
// Limits
|
// Limits
|
||||||
#if MVK_IOS
|
#if MVK_IOS
|
||||||
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v1] ) {
|
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v1] ) {
|
||||||
_properties.limits.maxColorAttachments = 8;
|
_properties.limits.maxColorAttachments = kMVKCachedColorAttachmentCount;
|
||||||
} else {
|
} else {
|
||||||
_properties.limits.maxColorAttachments = 4;
|
_properties.limits.maxColorAttachments = 4; // < kMVKCachedColorAttachmentCount
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if MVK_MACOS
|
#if MVK_MACOS
|
||||||
_properties.limits.maxColorAttachments = 8;
|
_properties.limits.maxColorAttachments = kMVKCachedColorAttachmentCount;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_properties.limits.maxFragmentOutputAttachments = _properties.limits.maxColorAttachments;
|
_properties.limits.maxFragmentOutputAttachments = _properties.limits.maxColorAttachments;
|
||||||
@ -1038,7 +1038,7 @@ void MVKPhysicalDevice::initProperties() {
|
|||||||
float maxVPDim = max(_properties.limits.maxViewportDimensions[0], _properties.limits.maxViewportDimensions[1]);
|
float maxVPDim = max(_properties.limits.maxViewportDimensions[0], _properties.limits.maxViewportDimensions[1]);
|
||||||
_properties.limits.viewportBoundsRange[0] = (-2.0 * maxVPDim);
|
_properties.limits.viewportBoundsRange[0] = (-2.0 * maxVPDim);
|
||||||
_properties.limits.viewportBoundsRange[1] = (2.0 * maxVPDim) - 1;
|
_properties.limits.viewportBoundsRange[1] = (2.0 * maxVPDim) - 1;
|
||||||
_properties.limits.maxViewports = _features.multiViewport ? 16 : 1;
|
_properties.limits.maxViewports = _features.multiViewport ? kMVKCachedViewportScissorCount : 1;
|
||||||
|
|
||||||
_properties.limits.maxImageDimension3D = (2 * KIBI);
|
_properties.limits.maxImageDimension3D = (2 * KIBI);
|
||||||
_properties.limits.maxImageArrayLayers = (2 * KIBI);
|
_properties.limits.maxImageArrayLayers = (2 * KIBI);
|
||||||
|
@ -608,6 +608,11 @@ void MVKImage::validateConfig(const VkImageCreateInfo* pCreateInfo) {
|
|||||||
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, depth/stencil formats may only be used with 2D images."));
|
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, depth/stencil formats may only be used with 2D images."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isAttachment = mvkIsAnyFlagEnabled(pCreateInfo->usage, (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
|
||||||
|
if (isAttachment && (pCreateInfo->arrayLayers > 1) && !_device->_pMetalFeatures->layeredRendering) {
|
||||||
|
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : This device does not support rendering to array (layered) attachments."));
|
||||||
|
}
|
||||||
|
|
||||||
if (mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT)) {
|
if (mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT)) {
|
||||||
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Metal does not allow uncompressed views of compressed images."));
|
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Metal does not allow uncompressed views of compressed images."));
|
||||||
}
|
}
|
||||||
@ -635,8 +640,8 @@ VkSampleCountFlagBits MVKImage::validateSamples(const VkImageCreateInfo* pCreate
|
|||||||
validSamples = VK_SAMPLE_COUNT_1_BIT;
|
validSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !_device->_pMetalFeatures->multisampleLayeredRendering && mvkIsAnyFlagEnabled(pCreateInfo->usage, (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
|
bool isAttachment = mvkIsAnyFlagEnabled(pCreateInfo->usage, (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
|
||||||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT))) {
|
if (isAttachment && !_device->_pMetalFeatures->multisampleLayeredRendering) {
|
||||||
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : This device does not support rendering to multisampled array (layered) attachments. Setting sample count to 1."));
|
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : This device does not support rendering to multisampled array (layered) attachments. Setting sample count to 1."));
|
||||||
validSamples = VK_SAMPLE_COUNT_1_BIT;
|
validSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
}
|
}
|
||||||
|
@ -236,8 +236,8 @@ protected:
|
|||||||
VkPipelineRasterizationStateCreateInfo _rasterInfo;
|
VkPipelineRasterizationStateCreateInfo _rasterInfo;
|
||||||
VkPipelineDepthStencilStateCreateInfo _depthStencilInfo;
|
VkPipelineDepthStencilStateCreateInfo _depthStencilInfo;
|
||||||
|
|
||||||
MVKVectorInline<MTLViewport, kMVKCachedViewportCount> _mtlViewports;
|
MVKVectorInline<MTLViewport, kMVKCachedViewportScissorCount> _mtlViewports;
|
||||||
MVKVectorInline<MTLScissorRect, kMVKCachedScissorCount> _mtlScissors;
|
MVKVectorInline<MTLScissorRect, kMVKCachedViewportScissorCount> _mtlScissors;
|
||||||
|
|
||||||
MTLComputePipelineDescriptor* _mtlTessControlStageDesc = nil;
|
MTLComputePipelineDescriptor* _mtlTessControlStageDesc = nil;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user