diff --git a/gapis/api/vulkan/api/buffer.api b/gapis/api/vulkan/api/buffer.api index 0ffc9c160e..676a478acd 100644 --- a/gapis/api/vulkan/api/buffer.api +++ b/gapis/api/vulkan/api/buffer.api @@ -113,6 +113,7 @@ cmd VkResult vkCreateBuffer( DedicatedAllocation: ext.dedicatedAllocation ) } + case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO: {} } next.Ptr = as!VulkanStructHeader*(next.Ptr)[0:1][0].PNext } diff --git a/gapis/api/vulkan/api/enums.api b/gapis/api/vulkan/api/enums.api index fb703ba9e3..8adbe6cfe6 100644 --- a/gapis/api/vulkan/api/enums.api +++ b/gapis/api/vulkan/api/enums.api @@ -250,6 +250,11 @@ enum VkStructureType: u32 { VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR = 1000071003, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR = 1000071004, + //@extension("VK_KHR_external_memory_fd") + VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR = 1000074000, + VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR = 1000074001, + VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR = 1000074002, + //@extension("VK_KHR_external_semaphore_capabilities") VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = 1000076000, VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = 1000076001, diff --git a/gapis/api/vulkan/api/image.api b/gapis/api/vulkan/api/image.api index d2b1f958de..4274c7ba56 100644 --- a/gapis/api/vulkan/api/image.api +++ b/gapis/api/vulkan/api/image.api @@ -221,6 +221,7 @@ cmd VkResult vkCreateImage( } imageInfo.ViewFormatList = ifl } + case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO: {} } next.Ptr = as!VulkanStructHeader*(next.Ptr)[0:1][0].PNext } diff --git a/gapis/api/vulkan/api/memory.api b/gapis/api/vulkan/api/memory.api index 7e8c9e016a..bc132ef45b 100644 --- a/gapis/api/vulkan/api/memory.api +++ b/gapis/api/vulkan/api/memory.api @@ -71,6 +71,7 @@ @threadSafety("system") @indirect("VkDevice") @override +@custom cmd VkResult vkAllocateMemory( VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, @@ -119,6 +120,7 @@ cmd VkResult vkAllocateMemory( DeviceMask: ext.deviceMask, ) } + case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR: {} } next.Ptr = as!VulkanStructHeader*(next.Ptr)[0:1][0].PNext } diff --git a/gapis/api/vulkan/custom_replay.go b/gapis/api/vulkan/custom_replay.go index e66f3cbee0..7de118242b 100644 --- a/gapis/api/vulkan/custom_replay.go +++ b/gapis/api/vulkan/custom_replay.go @@ -991,6 +991,58 @@ func processExternalImageBarriers(barriers *[]VkImageMemoryBarrier) bool { return hasExternImageBarrier } +func (a *VkGetMemoryFdKHR) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder, w api.StateWatcher) error { + return a.mutate(ctx, id, s, nil, w) +} + +func (a *VkGetMemoryFdPropertiesKHR) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder, w api.StateWatcher) error { + return a.mutate(ctx, id, s, nil, w) +} + +func (a *VkAllocateMemory) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder, w api.StateWatcher) error { + if b == nil { + return a.mutate(ctx, id, s, b, w) + } + + a.Extras().Observations().ApplyReads(s.Memory.ApplicationPool()) + cb := CommandBuilder{Thread: a.Thread(), Arena: s.Arena} + hijack := cb.VkAllocateMemory(a.Device(), a.PAllocateInfo(), a.PAllocator(), a.PMemory(), a.Result()) + hijack.Extras().MustClone(a.Extras().All()...) + + // Remove VkImportMemoryFdInfoKHR structs from the pNext chain, + // because the fd will be invalid at replay time + pHeader := NewVulkanStructHeaderᵖ(hijack.PAllocateInfo()) + header := pHeader.MustRead(ctx, a, s, nil) + + var allocated []*api.AllocResult + defer func() { + for _, d := range allocated { + d.Free() + } + }() + + for !header.PNext().IsNullptr() { + pNext := NewVulkanStructHeaderᵖ(header.PNext()) + next := pNext.MustRead(ctx, a, s, nil) + if next.SType() == VkStructureType_VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR { + // update header.pNext + header.SetPNext(next.PNext()) + + // add a memory observation at pHeader, whose data is the new header value (with modified pNext) + newHeaderData := s.AllocDataOrPanic(ctx, header) // dummy allocation, just to get an ID for the header data + newHeaderRange, newHeaderID := newHeaderData.Data() + newHeaderRange.Base = pHeader.Address() // move the observation range to start at pHeader, to pretend we observed this modified header value + allocated = append(allocated, &newHeaderData) + hijack.AddRead(newHeaderRange, newHeaderID) // attach this observation to hijack, so that the new value is seen on the replay side + } else { + pHeader = pNext + header = next + } + } + + return hijack.mutate(ctx, id, s, b, w) +} + type vkQueueSubmitHijack struct { ctx context.Context id api.CmdID diff --git a/gapis/api/vulkan/extensions/khr_external_memory_fd.api b/gapis/api/vulkan/extensions/khr_external_memory_fd.api new file mode 100644 index 0000000000..3ca4e8f011 --- /dev/null +++ b/gapis/api/vulkan/extensions/khr_external_memory_fd.api @@ -0,0 +1,102 @@ +// Copyright (C) 2020 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Based off of the original vulkan.h header file which has the following +// license. + +// Copyright (c) 2015 The Khronos Group Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + +/////////// +// Enums // +/////////// + +// Updated in api/enums.api + +///////////// +// Structs // +///////////// + +@extension("VK_KHR_external_memory_fd") +class VkImportMemoryFdInfoKHR { + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlagBits handleType + int fd +} + +@extension("VK_KHR_external_memory_fd") +class VkMemoryFdPropertiesKHR { + VkStructureType sType + void* pNext + u32 memoryTypeBits +} + +@extension("VK_KHR_external_memory_fd") +class VkMemoryGetFdInfoKHR { + VkStructureType sType + const void* pNext + VkDeviceMemory memory + VkExternalMemoryHandleTypeFlagBits handleType +} + +////////////// +// Commands // +////////////// + +@extension("VK_KHR_external_memory_fd") +@threadSafety("system") +@indirect("VkDevice") +@custom +cmd VkResult vkGetMemoryFdKHR( + VkDevice device, + const VkMemoryGetFdInfoKHR* pGetFdInfo, + int* pFd) { + if !(device in Devices) { vkErrorInvalidDevice(device) } + if pGetFdInfo == null { vkErrorNullPointer("VkMemoryGetFdInfoKHR") } + if pFd == null { vkErrorNullPointer("int") } + return ? +} + +@extension("VK_KHR_external_memory_fd") +@threadSafety("system") +@indirect("VkDevice") +@custom +cmd VkResult vkGetMemoryFdPropertiesKHR( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + int fd, + VkMemoryFdPropertiesKHR* pMemoryFdProperties) { + if !(device in Devices) { vkErrorInvalidDevice(device) } + if pMemoryFdProperties == null { vkErrorNullPointer("VkMemoryFdPropertiesKHR") } + return ? +} \ No newline at end of file diff --git a/gapis/api/vulkan/external_memory.go b/gapis/api/vulkan/external_memory.go index 2cff8e6100..227275449f 100644 --- a/gapis/api/vulkan/external_memory.go +++ b/gapis/api/vulkan/external_memory.go @@ -264,7 +264,7 @@ func (e *externalMemoryStaging) allocMemory() error { pAllocInfo.Data(), ).AddWrite( pStagingMemory.Data(), - ).Mutate( + ).mutate( e.h.ctx, api.CmdNoID, e.h.s, e.h.b, nil, ) if err != nil { diff --git a/gapis/api/vulkan/vulkan.api b/gapis/api/vulkan/vulkan.api index 159b27ce98..caa2e02202 100644 --- a/gapis/api/vulkan/vulkan.api +++ b/gapis/api/vulkan/vulkan.api @@ -88,6 +88,7 @@ import "extensions/khr_bind_memory2.api" import "extensions/khr_16bit_storage.api" import "extensions/khr_external_fence_capabilities.api" import "extensions/khr_external_memory_capabilities.api" +import "extensions/khr_external_memory_fd.api" import "extensions/khr_external_semaphore_capabilities.api" import "extensions/khr_variable_pointers.api" import "extensions/khr_sampler_ycbcr_conversion.api"