Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add VK_EXT_image_2d_view_of_3d support #2332

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

ncesario-lunarg
Copy link

Given a 3D texture that is backed by a placement heap in MoltenVK, the
approach taken here is to create a 2D texture that is backed by memory
pointing into a 3D texture's memory.

While ideal compared to alternative implementation solutions for this
extension, this approach is sensitive to how Apple lays out the memory
for 3D textures. The solution here uses
heapTextureSizeAndAlignWithDescriptor to determine the overall size of a
given 3D texture and index into the beginning of each "slice" of the 3D
texture. So far this is good enough for storage images in CTS.

FYI @kocdemir.

Copy link
Contributor

@billhollings billhollings left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for getting this started!

In addition to the inline change requests, I recognize this is just to solve one immediate extension issue, but if we can do what we can to simplify a future move to using MTLHeaps, we should try as best we can.

@@ -188,10 +188,6 @@
// Can't create MTLHeaps of zero size.
if (_allocationSize == 0) { return true; }

#if MVK_MACOS
// MTLHeaps on macOS must use private storage for now.
if (_mtlStorageMode != MTLStorageModePrivate) { return true; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of being removed, does this need to be modified to include a test for non-Apple-Silicon devices?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment below.

#if MVK_MACOS
// MTLHeaps on macOS must use private storage for now.
if (_mtlStorageMode != MTLStorageModePrivate) { return true; }
#endif
#if MVK_IOS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should both this section and the one above, be replaced with a single test for MVKMTLDeviceCapabilities.isAppleGPU?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH I'm not sure based on the docs, but I'll add that to be on the safe side. It looked like the usage of heaps in MoltenVK was mainly dependent on placement heaps, but my knowledge is still pretty sparse on the details here.

@@ -48,6 +48,16 @@ typedef struct {
class MVKImagePlane : public MVKBaseObject {

public:
struct HeapAllocation {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this declaration be moved to MVKDeviceMemory or MVKResource, since heaps can be used by buffers too?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I'll move it there.

@@ -1066,6 +1079,11 @@ static MTLRegion getMTLRegion(const ImgRgn& imgRgn) {
return _memoryBindings[0]->_deviceMemory ? _memoryBindings[0]->_deviceMemory->getMTLCPUCacheMode() : MTLCPUCacheModeDefaultCache;
}

MVKImagePlane::HeapAllocation* MVKImage::getHeapAllocation(uint32_t planeIndex) {
auto& heapAllocation = _planes[planeIndex]->_heapAllocation;
return (heapAllocation) ? &heapAllocation : nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It surprised me that this was compiling, until I noticed the operator bool() on the struct above.

While clever, we don't use this design pattern anywhere else, so I'm concerned others will balk the same way I did.

Maybe rename operator bool() to bool isValid(), for clarity.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to isValid().

@@ -1251,6 +1269,8 @@ static MTLRegion getMTLRegion(const ImgRgn& imgRgn) {
if (pExportInfo && pExportInfo->exportObjectType == VK_EXPORT_METAL_OBJECT_TYPE_METAL_IOSURFACE_BIT_EXT && !_ioSurface) {
setConfigurationResult(useIOSurface(nil));
}

_is2DViewCompatible = pCreateInfo->flags & VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use mvkIsAnyFlagEnabled() for consistency.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -395,6 +410,7 @@ class MVKImage : public MVKVulkanAPIDeviceObject {
bool _hasMutableFormat;
bool _shouldSupportAtomics;
bool _isLinearForAtomics;
bool _is2DViewCompatible = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this will apply only to 2D on 3D, and not for all 2D views?

Maybe rename to _is2DViewOn3DImageCompatible?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, makes sense. Done.

size_t size = 0; // Total size of this allocation
size_t align = 0; // Allocation alignment requirement

operator bool() const {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment below where this is used. Probably best to rename this to something like bool isValid().

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Done


// For now, this is only used for VK_EXT_image_2d_view_of_3d. Specifically, when the backing image of this view is 3D and the view is 2D,
// this texture will be allocated using a placement heap "on top of" the 3D textures backing memory.
id<MTLTexture> _mtlShadowTexture;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since _mtlTexture end up holding a reference to the same object, does this need to be a separate iVar than _mtlTexture?

If it is needed for some reason, move it up just below the _mtlTexture declaration. We try to organize iVars to minimize gaps in the underlying class structure (ie- keep all 8-byte iVars together).

It also feels dangerous that the MTLTexture is not retained in both _mtlTexture and _mtlShadowTexture, and released from both in the destructor. If in the future, we might possibly have different objects in the two iVars, then we'll end up with a hard to discover memory leak.

Finally, maybe it's me, but when I see _mtlShadowTexture, I keep thinking "shadow map texture". Maybe rename it to _mtlAliasTexture or something.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, there is no need for the extra MTLTexture in MVKImageViewPlane; I will remove it. I added this from a debug session and never reverted it (and also forgot to clean it up in the destructor when I was using it :/).

@ncesario-lunarg
Copy link
Author

Thanks for the review @billhollings! I've made the changes you've suggested locally, but I'm hitting a crash on dEQP-VK.api.get_memory_commitment.memory_commitment at https://github.com/ncesario-lunarg/MoltenVK/blob/d01e7ecf13ef9bd4d9af3dc61b13ce683299d5ba/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.mm#L205. I'm going to resolve that before updating this PR.

Given a 3D texture that is backed by a placement heap in MoltenVK, the
approach taken here is to create a 2D texture that is backed by memory
pointing into a 3D texture's memory.

While ideal compared to alternative implementation solutions for this
extension, this approach is sensitive to how Apple lays out the memory
for 3D textures. The solution here uses
heapTextureSizeAndAlignWithDescriptor to determine the overall size of a
given 3D texture and index into the beginning of each "slice" of the 3D
texture. So far this is good enough for storage images in CTS.
Sets VkPhysicalDeviceImage2DViewOf3DFeaturesEXT::sampler2DViewOf3D to
false, as CTS tests involving 2D views of sampled 3D textures are not
currently working.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants