Merge pull request #140 from billhollings/master
Clearing multisampled textures + minor fix to depth clip mode handling.
This commit is contained in:
commit
4b5aca57af
@ -708,7 +708,7 @@ void MVKCmdClearAttachments::setContent(uint32_t attachmentCount,
|
||||
const VkClearAttachment* pAttachments,
|
||||
uint32_t rectCount,
|
||||
const VkClearRect* pRects) {
|
||||
_rpsKey.reset();
|
||||
_rpsKey = kMVKRPSKeyClearAttDefault;
|
||||
_mtlStencilValue = 0;
|
||||
_isClearingDepth = false;
|
||||
_isClearingStencil = false;
|
||||
@ -814,11 +814,11 @@ void MVKCmdClearAttachments::encode(MVKCommandEncoder* cmdEncoder) {
|
||||
VkExtent2D fbExtent = cmdEncoder->_framebuffer->getExtent2D();
|
||||
populateVertices(fbExtent.width, fbExtent.height);
|
||||
uint32_t vtxCnt = (uint32_t)_vertices.size();
|
||||
|
||||
uint32_t vtxBuffIdx = getDevice()->getMetalBufferIndexForVertexAttributeBinding(kMVKVertexContentBufferIndex);
|
||||
|
||||
// Populate the render pipeline state attachment key with
|
||||
// the format of each color attachment used by the subpass
|
||||
// Populate the render pipeline state attachment key with attachment info from the subpass.
|
||||
_rpsKey.mtlSampleCount = mvkSampleCountFromVkSampleCountFlagBits(subpass->getSampleCount());
|
||||
|
||||
uint32_t caCnt = subpass->getColorAttachmentCount();
|
||||
for (uint32_t caIdx = 0; caIdx < caCnt; caIdx++) {
|
||||
VkFormat vkAttFmt = subpass->getColorAttachmentFormat(caIdx);
|
||||
@ -868,9 +868,10 @@ void MVKCmdClearImage::setContent(VkImage image,
|
||||
_image = (MVKImage*)image;
|
||||
_imgLayout = imageLayout;
|
||||
_isDepthStencilClear = isDepthStencilClear;
|
||||
_mtlStencilValue = 0;
|
||||
|
||||
_rpsKey.reset();
|
||||
_mtlStencilValue = 0;
|
||||
_rpsKey = kMVKRPSKeyClearAttDefault;
|
||||
_rpsKey.mtlSampleCount = _image->getSampleCount();
|
||||
|
||||
if (_isDepthStencilClear) {
|
||||
_rpsKey.enable(kMVKAttachmentFormatDepthStencilIndex);
|
||||
|
@ -167,8 +167,6 @@ void MVKDepthStencilCommandEncoderState:: setDepthStencilState(VkPipelineDepthSt
|
||||
setStencilState(_depthStencilData.frontFaceStencilData, vkDepthStencilInfo.front, vkDepthStencilInfo.stencilTestEnable);
|
||||
setStencilState(_depthStencilData.backFaceStencilData, vkDepthStencilInfo.back, vkDepthStencilInfo.stencilTestEnable);
|
||||
|
||||
_depthStencilData.clearHash(); // Hash will change
|
||||
|
||||
markDirty();
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "MVKDevice.h"
|
||||
#include "MVKFoundation.h"
|
||||
#include "mvk_datatypes.h"
|
||||
#include <string>
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
@ -33,13 +34,16 @@
|
||||
|
||||
/**
|
||||
* Key to use for looking up cached MTLRenderPipelineState instances.
|
||||
* Holds the formats for each color attachment plus one depth/stencil attachment.
|
||||
* Indicates which attachments are used, and holds the Metal pixel formats for each
|
||||
* color attachment plus one depth/stencil attachment. Also holds the Metal sample count.
|
||||
*
|
||||
* This structure can be used as a key in a std::map and std::unordered_map.
|
||||
*/
|
||||
typedef struct MVKRPSKeyClearAtt_t {
|
||||
uint16_t attachmentMTLPixelFormats[kMVKAttachmentFormatCount];
|
||||
uint16_t mtlSampleCount;
|
||||
uint32_t enabledFlags;
|
||||
|
||||
const static uint32_t bitFlag = 1;
|
||||
|
||||
void enable(uint32_t attIdx) { mvkEnableFlag(enabledFlags, bitFlag << attIdx); }
|
||||
@ -55,14 +59,26 @@ typedef struct MVKRPSKeyClearAtt_t {
|
||||
|
||||
bool operator==(const MVKRPSKeyClearAtt_t& rhs) const {
|
||||
return ((enabledFlags == rhs.enabledFlags) &&
|
||||
(mtlSampleCount == rhs.mtlSampleCount) &&
|
||||
(memcmp(attachmentMTLPixelFormats, rhs.attachmentMTLPixelFormats, sizeof(attachmentMTLPixelFormats)) == 0));
|
||||
}
|
||||
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
std::size_t hash() const {
|
||||
std::size_t hash = mvkHash(&enabledFlags);
|
||||
hash = mvkHash(&mtlSampleCount, 1, hash);
|
||||
return mvkHash(attachmentMTLPixelFormats, kMVKAttachmentFormatCount, hash);
|
||||
}
|
||||
|
||||
MVKRPSKeyClearAtt_t() {
|
||||
memset(this, 0, sizeof(*this));
|
||||
mtlSampleCount = mvkSampleCountFromVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT);
|
||||
}
|
||||
|
||||
MVKRPSKeyClearAtt_t() { reset(); }
|
||||
} MVKRPSKeyClearAtt;
|
||||
|
||||
/** An instance populated with default values, for use in resetting other instances to default state. */
|
||||
const MVKRPSKeyClearAtt kMVKRPSKeyClearAttDefault;
|
||||
|
||||
/**
|
||||
* Hash structure implementation for MVKRPSKeyClearAtt in std namespace,
|
||||
* so MVKRPSKeyClearAtt can be used as a key in a std::map and std::unordered_map.
|
||||
@ -70,10 +86,7 @@ typedef struct MVKRPSKeyClearAtt_t {
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<MVKRPSKeyClearAtt> {
|
||||
std::size_t operator()(const MVKRPSKeyClearAtt& k) const {
|
||||
std::size_t hash = mvkHash(&k.enabledFlags, 1);
|
||||
return mvkHash(k.attachmentMTLPixelFormats, kMVKAttachmentFormatCount, hash);
|
||||
}
|
||||
std::size_t operator()(const MVKRPSKeyClearAtt& k) const { return k.hash(); }
|
||||
};
|
||||
}
|
||||
|
||||
@ -126,29 +139,18 @@ const MVKMTLStencilDescriptorData kMVKMTLStencilDescriptorDataDefault;
|
||||
* change as early as possible.
|
||||
*/
|
||||
typedef struct MVKMTLDepthStencilDescriptorData_t {
|
||||
std::size_t _hash;
|
||||
uint8_t depthCompareFunction; /**< The depth compare function (interpreted as MTLCompareFunction). */
|
||||
bool depthWriteEnabled; /**< Indicates whether depth writing is enabled. */
|
||||
MVKMTLStencilDescriptorData frontFaceStencilData;
|
||||
MVKMTLStencilDescriptorData backFaceStencilData;
|
||||
|
||||
std::size_t hash() {
|
||||
if ( !_hash ) { _hash = mvkHash((uint64_t*)this, sizeof(*this) / sizeof(uint64_t)); }
|
||||
return _hash;
|
||||
}
|
||||
void clearHash() { _hash = 0; }
|
||||
bool operator==(const MVKMTLDepthStencilDescriptorData_t& rhs) const {
|
||||
return (memcmp(this, &rhs, sizeof(*this)) == 0);
|
||||
}
|
||||
|
||||
bool operator==(const MVKMTLDepthStencilDescriptorData_t& rhs) const {
|
||||
MVKMTLDepthStencilDescriptorData_t* pLHS = (MVKMTLDepthStencilDescriptorData_t*)this;
|
||||
MVKMTLDepthStencilDescriptorData_t* pRHS = (MVKMTLDepthStencilDescriptorData_t*)&rhs;
|
||||
|
||||
if (pLHS == pRHS) { return true; }
|
||||
if (!pLHS) { return false; }
|
||||
if (!pRHS) { return false; }
|
||||
if (pLHS->hash() != pRHS->hash()) { return false; }
|
||||
|
||||
return (memcmp(pLHS, pRHS, sizeof(*this)) == 0);
|
||||
}
|
||||
std::size_t hash() const {
|
||||
return mvkHash((uint64_t*)this, sizeof(*this) / sizeof(uint64_t));
|
||||
}
|
||||
|
||||
MVKMTLDepthStencilDescriptorData_t() {
|
||||
|
||||
@ -156,7 +158,6 @@ typedef struct MVKMTLDepthStencilDescriptorData_t {
|
||||
// even if the structure contains alignment gaps.
|
||||
memset(this, 0, sizeof(*this));
|
||||
|
||||
_hash = 0;
|
||||
depthCompareFunction = MTLCompareFunctionAlways;
|
||||
depthWriteEnabled = false;
|
||||
|
||||
@ -171,11 +172,8 @@ const MVKMTLDepthStencilDescriptorData kMVKMTLDepthStencilDescriptorDataDefault;
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<MVKMTLDepthStencilDescriptorData_t> {
|
||||
std::size_t operator()(const MVKMTLDepthStencilDescriptorData_t& k) const {
|
||||
MVKMTLDepthStencilDescriptorData_t* pK = (MVKMTLDepthStencilDescriptorData_t*)&k;
|
||||
return pK->hash();
|
||||
}
|
||||
struct hash<MVKMTLDepthStencilDescriptorData> {
|
||||
std::size_t operator()(const MVKMTLDepthStencilDescriptorData& k) const { return k.hash(); }
|
||||
};
|
||||
}
|
||||
|
||||
@ -202,6 +200,10 @@ typedef struct MVKImageDescriptorData_t {
|
||||
return (memcmp(this, &rhs, sizeof(*this)) == 0);
|
||||
}
|
||||
|
||||
std::size_t hash() const {
|
||||
return mvkHash((uint64_t*)this, sizeof(*this) / sizeof(uint64_t));
|
||||
}
|
||||
|
||||
MVKImageDescriptorData_t() { memset(this, 0, sizeof(*this)); }
|
||||
|
||||
} __attribute__((aligned(sizeof(uint64_t)))) MVKImageDescriptorData;
|
||||
@ -213,9 +215,7 @@ typedef struct MVKImageDescriptorData_t {
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<MVKImageDescriptorData> {
|
||||
std::size_t operator()(const MVKImageDescriptorData& k) const {
|
||||
return mvkHash((uint64_t*)this, sizeof(*this) / sizeof(uint64_t));
|
||||
}
|
||||
std::size_t operator()(const MVKImageDescriptorData& k) const { return k.hash(); }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,7 @@ id<MTLRenderPipelineState> MVKCommandResourceFactory::newCmdClearMTLRenderPipeli
|
||||
plDesc.label = [NSString stringWithFormat: @"CmdClearAttachments%s", fragFuncSfx.data()];
|
||||
plDesc.vertexFunction = getFunctionNamed("vtxCmdClearAttachments");
|
||||
plDesc.fragmentFunction = getFunctionNamed((string("fragCmdClearAttachments") + fragFuncSfx).data());
|
||||
plDesc.sampleCount = attKey.mtlSampleCount;
|
||||
|
||||
for (uint32_t caIdx = 0; caIdx < kMVKAttachmentFormatDepthStencilIndex; caIdx++) {
|
||||
MTLRenderPipelineColorAttachmentDescriptor* colorDesc = plDesc.colorAttachments[caIdx];
|
||||
|
@ -330,8 +330,10 @@ void MVKPhysicalDevice::initMetalFeatures() {
|
||||
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v4] ) {
|
||||
_metalFeatures.mslVersion = SPIRVToMSLConverterOptions::makeMSLVersion(2);
|
||||
_metalFeatures.ioSurfaces = true;
|
||||
_metalFeatures.depthClipMode = true;
|
||||
}
|
||||
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v4] ) {
|
||||
_metalFeatures.depthClipMode = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MVK_MACOS
|
||||
@ -358,7 +360,7 @@ void MVKPhysicalDevice::initMetalFeatures() {
|
||||
#endif
|
||||
|
||||
for (uint32_t sc = VK_SAMPLE_COUNT_1_BIT; sc <= VK_SAMPLE_COUNT_64_BIT; sc <<= 1) {
|
||||
if ([_mtlDevice supportsTextureSampleCount: sc]) {
|
||||
if ([_mtlDevice supportsTextureSampleCount: mvkSampleCountFromVkSampleCountFlagBits((VkSampleCountFlagBits)sc)]) {
|
||||
_metalFeatures.supportedSampleCounts |= sc;
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
inline uint32_t getLayerCount() { return _arrayLayers; }
|
||||
|
||||
/** Returns the number of samples for each pixel of this image. */
|
||||
inline uint32_t getSampleCount() { return _samples; }
|
||||
inline VkSampleCountFlagBits getSampleCount() { return _samples; }
|
||||
|
||||
/**
|
||||
* Returns the number of bytes per image row at the specified zero-based mip level.
|
||||
|
@ -582,7 +582,7 @@ MVKImageView::MVKImageView(MVKDevice* device, const VkImageViewCreateInfo* pCrea
|
||||
|
||||
_mtlTexture = nil;
|
||||
_mtlPixelFormat = getSwizzledMTLPixelFormat(pCreateInfo->format, pCreateInfo->components);
|
||||
_mtlTextureType = mvkMTLTextureTypeFromVkImageViewType(pCreateInfo->viewType, (_image->getSampleCount() > 1));
|
||||
_mtlTextureType = mvkMTLTextureTypeFromVkImageViewType(pCreateInfo->viewType, (_image->getSampleCount() != VK_SAMPLE_COUNT_1_BIT));
|
||||
initMTLTextureViewSupport();
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,9 @@ public:
|
||||
/** Returns the format of the depth/stencil attachment. */
|
||||
VkFormat getDepthStencilFormat();
|
||||
|
||||
/** Returns the Vulkan sample count of the attachments used in this subpass. */
|
||||
VkSampleCountFlagBits getSampleCount();
|
||||
|
||||
/**
|
||||
* Populates the specified Metal MTLRenderPassDescriptor with content from this
|
||||
* instance, the specified framebuffer, and the specified array of clear values.
|
||||
@ -92,6 +95,9 @@ public:
|
||||
/** Returns the Vulkan format of this attachment. */
|
||||
VkFormat getFormat();
|
||||
|
||||
/** Returns the Vulkan sample count of this attachment. */
|
||||
VkSampleCountFlagBits getSampleCount();
|
||||
|
||||
/**
|
||||
* Populates the specified Metal color attachment description with the load and store actions for
|
||||
* the specified render subpass, and returns whether the load action will clear the attachment.
|
||||
|
@ -43,6 +43,21 @@ VkFormat MVKRenderSubpass::getDepthStencilFormat() {
|
||||
return _renderPass->_attachments[rpAttIdx].getFormat();
|
||||
}
|
||||
|
||||
VkSampleCountFlagBits MVKRenderSubpass::getSampleCount() {
|
||||
for (auto& ca : _colorAttachments) {
|
||||
uint32_t rpAttIdx = ca.attachment;
|
||||
if (rpAttIdx != VK_ATTACHMENT_UNUSED) {
|
||||
return _renderPass->_attachments[rpAttIdx].getSampleCount();
|
||||
}
|
||||
}
|
||||
uint32_t rpAttIdx = _depthStencilAttachment.attachment;
|
||||
if (rpAttIdx != VK_ATTACHMENT_UNUSED) {
|
||||
return _renderPass->_attachments[rpAttIdx].getSampleCount();
|
||||
}
|
||||
|
||||
return VK_SAMPLE_COUNT_1_BIT;
|
||||
}
|
||||
|
||||
void MVKRenderSubpass::populateMTLRenderPassDescriptor(MTLRenderPassDescriptor* mtlRPDesc,
|
||||
MVKFramebuffer* framebuffer,
|
||||
vector<VkClearValue>& clearValues,
|
||||
@ -192,6 +207,8 @@ MVKRenderSubpass::MVKRenderSubpass(MVKRenderPass* renderPass,
|
||||
|
||||
VkFormat MVKRenderPassAttachment::getFormat() { return _info.format; }
|
||||
|
||||
VkSampleCountFlagBits MVKRenderPassAttachment::getSampleCount() { return _info.samples; }
|
||||
|
||||
bool MVKRenderPassAttachment::populateMTLRenderPassAttachmentDescriptor(MTLRenderPassAttachmentDescriptor* mtlAttDesc,
|
||||
MVKRenderSubpass* subpass,
|
||||
bool isRenderingEntireAttachment,
|
||||
|
@ -131,9 +131,7 @@ typedef struct MVKShaderModuleKey_t {
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<MVKShaderModuleKey> {
|
||||
std::size_t operator()(const MVKShaderModuleKey& k) const {
|
||||
return k.codeHash;
|
||||
}
|
||||
std::size_t operator()(const MVKShaderModuleKey& k) const { return k.codeHash; }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -305,7 +305,7 @@ MVKShaderModule::MVKShaderModule(MVKDevice* device,
|
||||
size_t mslCodeLen = pCreateInfo->codeSize - hdrSize;
|
||||
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
codeHash = mvkHash(&magicNum, 1);
|
||||
codeHash = mvkHash(&magicNum);
|
||||
codeHash = mvkHash(pMSLCode, mslCodeLen, codeHash);
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.hashShaderCode, startTime);
|
||||
|
||||
@ -320,7 +320,7 @@ MVKShaderModule::MVKShaderModule(MVKDevice* device,
|
||||
size_t mslCodeLen = pCreateInfo->codeSize - hdrSize;
|
||||
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
codeHash = mvkHash(&magicNum, 1);
|
||||
codeHash = mvkHash(&magicNum);
|
||||
codeHash = mvkHash(pMSLCode, mslCodeLen, codeHash);
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.hashShaderCode, startTime);
|
||||
|
||||
|
@ -255,7 +255,7 @@ const T& mvkClamp(const T& val, const T& lower, const T& upper) {
|
||||
* value returned by previous calls as the seed in subsequent calls.
|
||||
*/
|
||||
template<class N>
|
||||
std::size_t mvkHash(const N* pVals, std::size_t count, std::size_t seed = 5381) {
|
||||
std::size_t mvkHash(const N* pVals, std::size_t count = 1, std::size_t seed = 5381) {
|
||||
std::size_t hash = seed;
|
||||
for (std::size_t i = 0; i < count; i++) { hash = ((hash << 5) + hash) ^ pVals[i]; }
|
||||
return hash;
|
||||
|
Loading…
x
Reference in New Issue
Block a user