Do host-coherent texel buffer caching just for buffer views
This commit is contained in:
parent
5eea556bf8
commit
d0059a2bdf
@ -72,10 +72,13 @@ public:
|
||||
#pragma mark Metal
|
||||
|
||||
/** Returns the Metal buffer underlying this memory allocation. */
|
||||
id<MTLBuffer> getMTLBuffer();
|
||||
id<MTLBuffer> getMTLBuffer();
|
||||
|
||||
/** Returns the offset at which the contents of this instance starts within the underlying Metal buffer. */
|
||||
inline NSUInteger getMTLBufferOffset() { return !_deviceMemory || _deviceMemory->getMTLHeap() || _isHostCoherentTexelBuffer ? 0 : _deviceMemoryOffset; }
|
||||
inline NSUInteger getMTLBufferOffset() { return !_deviceMemory || _deviceMemory->getMTLHeap() ? 0 : _deviceMemoryOffset; }
|
||||
|
||||
/** Returns the Metal buffer used as a cache for host-coherent texel buffers. */
|
||||
id<MTLBuffer> getMTLBufferCache();
|
||||
|
||||
|
||||
#pragma mark Construction
|
||||
@ -99,6 +102,7 @@ protected:
|
||||
|
||||
VkBufferUsageFlags _usage;
|
||||
bool _isHostCoherentTexelBuffer = false;
|
||||
id<MTLBuffer> _mtlBufferCache = nil;
|
||||
id<MTLBuffer> _mtlBuffer = nil;
|
||||
};
|
||||
|
||||
@ -132,9 +136,9 @@ protected:
|
||||
void propagateDebugName() override;
|
||||
|
||||
MVKBuffer* _buffer;
|
||||
NSUInteger _offset;
|
||||
id<MTLTexture> _mtlTexture;
|
||||
MTLPixelFormat _mtlPixelFormat;
|
||||
NSUInteger _mtlBufferOffset;
|
||||
NSUInteger _mtlBytesPerRow;
|
||||
VkExtent2D _textureSize;
|
||||
std::mutex _lock;
|
||||
|
@ -156,9 +156,9 @@ bool MVKBuffer::shouldFlushHostMemory() { return _isHostCoherentTexelBuffer; }
|
||||
VkResult MVKBuffer::flushToDevice(VkDeviceSize offset, VkDeviceSize size) {
|
||||
#if MVK_MACOS
|
||||
VkDeviceSize flushOffset, flushSize;
|
||||
if (shouldFlushHostMemory() && overlaps(offset, size, flushOffset, flushSize)) {
|
||||
memcpy(getMTLBuffer().contents, reinterpret_cast<const char *>(_deviceMemory->getHostMemoryAddress()) + flushOffset, flushSize);
|
||||
[getMTLBuffer() didModifyRange: NSMakeRange(flushOffset - _deviceMemoryOffset, flushSize)];
|
||||
if (shouldFlushHostMemory() && _mtlBufferCache && overlaps(offset, size, flushOffset, flushSize)) {
|
||||
memcpy(_mtlBufferCache.contents, reinterpret_cast<const char *>(_deviceMemory->getHostMemoryAddress()) + flushOffset, flushSize);
|
||||
[_mtlBufferCache didModifyRange: NSMakeRange(flushOffset - _deviceMemoryOffset, flushSize)];
|
||||
}
|
||||
#endif
|
||||
return VK_SUCCESS;
|
||||
@ -168,8 +168,8 @@ VkResult MVKBuffer::flushToDevice(VkDeviceSize offset, VkDeviceSize size) {
|
||||
VkResult MVKBuffer::pullFromDevice(VkDeviceSize offset, VkDeviceSize size) {
|
||||
#if MVK_MACOS
|
||||
VkDeviceSize pullOffset, pullSize;
|
||||
if (shouldFlushHostMemory() && overlaps(offset, size, pullOffset, pullSize)) {
|
||||
memcpy(reinterpret_cast<char *>(_deviceMemory->getHostMemoryAddress()) + pullOffset, reinterpret_cast<char *>(getMTLBuffer().contents) + pullOffset - _deviceMemoryOffset, pullSize);
|
||||
if (shouldFlushHostMemory() && _mtlBufferCache && overlaps(offset, size, pullOffset, pullSize)) {
|
||||
memcpy(reinterpret_cast<char *>(_deviceMemory->getHostMemoryAddress()) + pullOffset, reinterpret_cast<char *>(_mtlBufferCache.contents) + pullOffset - _deviceMemoryOffset, pullSize);
|
||||
}
|
||||
#endif
|
||||
return VK_SUCCESS;
|
||||
@ -187,15 +187,6 @@ id<MTLBuffer> MVKBuffer::getMTLBuffer() {
|
||||
offset: _deviceMemoryOffset]; // retained
|
||||
propagateDebugName();
|
||||
return _mtlBuffer;
|
||||
#if MVK_MACOS
|
||||
} else if (_isHostCoherentTexelBuffer) {
|
||||
// According to the Vulkan spec, buffers, like linear images, can always use host-coherent memory.
|
||||
// But texel buffers on Mac cannot use shared memory. So we need to use host-cached memory here.
|
||||
_mtlBuffer = [_device->getMTLDevice() newBufferWithLength: getByteCount()
|
||||
options: MTLResourceStorageModeManaged]; // retained
|
||||
propagateDebugName();
|
||||
return _mtlBuffer;
|
||||
#endif
|
||||
} else {
|
||||
return _deviceMemory->getMTLBuffer();
|
||||
}
|
||||
@ -203,6 +194,16 @@ id<MTLBuffer> MVKBuffer::getMTLBuffer() {
|
||||
return nil;
|
||||
}
|
||||
|
||||
id<MTLBuffer> MVKBuffer::getMTLBufferCache() {
|
||||
#if MVK_MACOS
|
||||
if (_isHostCoherentTexelBuffer && !_mtlBufferCache) {
|
||||
_mtlBufferCache = [_device->getMTLDevice() newBufferWithLength: getByteCount()
|
||||
options: MTLResourceStorageModeManaged]; // retained
|
||||
flushToDevice(_deviceMemoryOffset, _byteCount);
|
||||
}
|
||||
#endif
|
||||
return _mtlBufferCache;
|
||||
}
|
||||
|
||||
#pragma mark Construction
|
||||
|
||||
@ -236,6 +237,7 @@ void MVKBuffer::initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes)
|
||||
MVKBuffer::~MVKBuffer() {
|
||||
if (_deviceMemory) { _deviceMemory->removeBuffer(this); }
|
||||
if (_mtlBuffer) { [_mtlBuffer release]; }
|
||||
if (_mtlBufferCache) { [_mtlBufferCache release]; }
|
||||
}
|
||||
|
||||
|
||||
@ -259,7 +261,15 @@ id<MTLTexture> MVKBufferView::getMTLTexture() {
|
||||
if ( mvkIsAnyFlagEnabled(_buffer->getUsage(), VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) ) {
|
||||
usage |= MTLTextureUsageShaderWrite;
|
||||
}
|
||||
id<MTLBuffer> mtlBuff = _buffer->getMTLBuffer();
|
||||
id<MTLBuffer> mtlBuff;
|
||||
VkDeviceSize mtlBuffOffset;
|
||||
if (MVK_MACOS && _buffer->isMemoryHostCoherent()) {
|
||||
mtlBuff = _buffer->getMTLBufferCache();
|
||||
mtlBuffOffset = _offset;
|
||||
} else {
|
||||
mtlBuff = _buffer->getMTLBuffer();
|
||||
mtlBuffOffset = _buffer->getMTLBufferOffset() + _offset;
|
||||
}
|
||||
MTLTextureDescriptor* mtlTexDesc;
|
||||
if ( _device->_pMetalFeatures->textureBuffers ) {
|
||||
mtlTexDesc = [MTLTextureDescriptor textureBufferDescriptorWithPixelFormat: _mtlPixelFormat
|
||||
@ -276,7 +286,7 @@ id<MTLTexture> MVKBufferView::getMTLTexture() {
|
||||
mtlTexDesc.usage = usage;
|
||||
}
|
||||
_mtlTexture = [mtlBuff newTextureWithDescriptor: mtlTexDesc
|
||||
offset: _mtlBufferOffset
|
||||
offset: mtlBuffOffset
|
||||
bytesPerRow: _mtlBytesPerRow];
|
||||
propagateDebugName();
|
||||
}
|
||||
@ -289,7 +299,7 @@ id<MTLTexture> MVKBufferView::getMTLTexture() {
|
||||
MVKBufferView::MVKBufferView(MVKDevice* device, const VkBufferViewCreateInfo* pCreateInfo) : MVKVulkanAPIDeviceObject(device) {
|
||||
MVKPixelFormats* pixFmts = getPixelFormats();
|
||||
_buffer = (MVKBuffer*)pCreateInfo->buffer;
|
||||
_mtlBufferOffset = _buffer->getMTLBufferOffset() + pCreateInfo->offset;
|
||||
_offset = pCreateInfo->offset;
|
||||
_mtlPixelFormat = pixFmts->getMTLPixelFormat(pCreateInfo->format);
|
||||
VkExtent2D fmtBlockSize = pixFmts->getBlockTexelSize(pCreateInfo->format); // Pixel size of format
|
||||
size_t bytesPerBlock = pixFmts->getBytesPerBlock(pCreateInfo->format);
|
||||
|
Loading…
x
Reference in New Issue
Block a user