mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 13:20:54 +00:00
Be more informative with 'capture incompatible' error messages on vulkan
This commit is contained in:
@@ -238,12 +238,18 @@ extern void *LoadVulkanLibrary();
|
||||
class VkDriverInfo
|
||||
{
|
||||
public:
|
||||
GPUVendor Vendor() { return m_Vendor; }
|
||||
uint32_t Major() { return m_Major; }
|
||||
uint32_t Minor() { return m_Minor; }
|
||||
uint32_t Patch() { return m_Patch; }
|
||||
GPUVendor Vendor() const { return m_Vendor; }
|
||||
uint32_t Major() const { return m_Major; }
|
||||
uint32_t Minor() const { return m_Minor; }
|
||||
uint32_t Patch() const { return m_Patch; }
|
||||
VkDriverInfo(const VkPhysicalDeviceProperties &physProps, bool active = false);
|
||||
|
||||
bool operator==(const VkDriverInfo &o) const
|
||||
{
|
||||
return m_Vendor == o.m_Vendor && m_Major == o.m_Major && m_Minor == o.m_Minor &&
|
||||
m_Patch == o.m_Patch;
|
||||
}
|
||||
|
||||
// checks for when we're running on metal and some non-queryable things aren't supported
|
||||
bool RunningOnMetal() const { return metalBackend; }
|
||||
// A workaround for a couple of bugs, removing texelFetch use from shaders.
|
||||
|
||||
@@ -4098,6 +4098,69 @@ void WrappedVulkan::AddDebugMessage(DebugMessage msg)
|
||||
}
|
||||
}
|
||||
|
||||
rdcstr WrappedVulkan::GetPhysDeviceCompatString(bool externalResource, bool origInvalid)
|
||||
{
|
||||
const VkDriverInfo &capture = m_OrigPhysicalDeviceData.driverInfo;
|
||||
const VkDriverInfo &replay = m_PhysicalDeviceData.driverInfo;
|
||||
|
||||
if(origInvalid)
|
||||
{
|
||||
return StringFormat::Fmt(
|
||||
"This was invalid at capture time.\n"
|
||||
"You must use API validation, as RenderDoc does not handle invalid API use like this.\n\n"
|
||||
"Captured on device: %s %s, %u.%u.%u",
|
||||
ToStr(capture.Vendor()).c_str(), m_OrigPhysicalDeviceData.props.deviceName, capture.Major(),
|
||||
capture.Minor(), capture.Patch());
|
||||
}
|
||||
|
||||
rdcstr ret;
|
||||
|
||||
if(externalResource)
|
||||
{
|
||||
ret =
|
||||
"This resource was externally imported, which cannot happen at replay time.\n"
|
||||
"Some drivers do not allow externally-imported resources to be bound to non-external "
|
||||
"memory, meaning that captures using resources like this can't be replayed.\n\n";
|
||||
}
|
||||
|
||||
if(capture == replay)
|
||||
{
|
||||
ret += StringFormat::Fmt("Captured and replayed on the same device: %s %s, %u.%u.%u",
|
||||
ToStr(capture.Vendor()).c_str(),
|
||||
m_OrigPhysicalDeviceData.props.deviceName, capture.Major(),
|
||||
capture.Minor(), capture.Patch());
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += StringFormat::Fmt(
|
||||
"Capture was made on: %s %s, %u.%u.%u\n"
|
||||
"Replayed on: %s %s, %u.%u.%u\n",
|
||||
|
||||
// capture device
|
||||
ToStr(capture.Vendor()).c_str(), m_OrigPhysicalDeviceData.props.deviceName, capture.Major(),
|
||||
capture.Minor(), capture.Patch(),
|
||||
|
||||
// replay device
|
||||
ToStr(replay.Vendor()).c_str(), m_PhysicalDeviceData.props.deviceName, replay.Major(),
|
||||
replay.Minor(), replay.Patch());
|
||||
|
||||
if(capture.Vendor() != replay.Vendor())
|
||||
{
|
||||
ret += "Captures are not commonly portable between GPUs from different vendors.";
|
||||
}
|
||||
else if(strcmp(m_OrigPhysicalDeviceData.props.deviceName, m_PhysicalDeviceData.props.deviceName))
|
||||
{
|
||||
ret += "Captures are sometimes not portable between different GPUs from a vendor.";
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += "Driver changes can sometimes cause captures to no longer work.";
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void WrappedVulkan::CheckErrorVkResult(VkResult vkr)
|
||||
{
|
||||
if(vkr == VK_SUCCESS || HasFatalError() || IsCaptureMode(m_State))
|
||||
|
||||
@@ -434,6 +434,8 @@ private:
|
||||
VkDevice m_Device;
|
||||
// the data about the physical device used for the above device
|
||||
PhysicalDeviceData m_PhysicalDeviceData;
|
||||
// the driver info for the original device
|
||||
PhysicalDeviceData m_OrigPhysicalDeviceData;
|
||||
// the family index that we've selected in CreateDevice for our queue. During replay, this is an
|
||||
// index in the replay-time queues, not the capture-time queues (i.e. after remapping)
|
||||
uint32_t m_QueueFamilyIdx;
|
||||
@@ -903,8 +905,10 @@ private:
|
||||
|
||||
void FirstFrame();
|
||||
|
||||
rdcstr GetPhysDeviceCompatString(bool external, bool origInvalid);
|
||||
bool CheckMemoryRequirements(const char *resourceName, ResourceId memId,
|
||||
VkDeviceSize memoryOffset, VkMemoryRequirements mrq, bool external);
|
||||
VkDeviceSize memoryOffset, const VkMemoryRequirements &mrq,
|
||||
bool external, const VkMemoryRequirements &origMrq);
|
||||
|
||||
void AddImplicitResolveResourceUsage(uint32_t subpass = 0);
|
||||
rdcarray<VkImageMemoryBarrier> GetImplicitRenderPassBarriers(uint32_t subpass = 0);
|
||||
|
||||
@@ -1497,12 +1497,15 @@ void VulkanCreationInfo::Memory::SimplifyBindings()
|
||||
}
|
||||
|
||||
void VulkanCreationInfo::Buffer::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
const VkBufferCreateInfo *pCreateInfo)
|
||||
const VkBufferCreateInfo *pCreateInfo,
|
||||
VkMemoryRequirements origMrq)
|
||||
{
|
||||
usage = pCreateInfo->usage;
|
||||
size = pCreateInfo->size;
|
||||
gpuAddress = 0;
|
||||
|
||||
mrq = origMrq;
|
||||
|
||||
external = false;
|
||||
|
||||
if(FindNextStruct(pCreateInfo, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO))
|
||||
@@ -1522,7 +1525,8 @@ void VulkanCreationInfo::BufferView::Init(VulkanResourceManager *resourceMan,
|
||||
}
|
||||
|
||||
void VulkanCreationInfo::Image::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
const VkImageCreateInfo *pCreateInfo)
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
VkMemoryRequirements origMrq)
|
||||
{
|
||||
type = pCreateInfo->imageType;
|
||||
format = pCreateInfo->format;
|
||||
@@ -1531,6 +1535,8 @@ void VulkanCreationInfo::Image::Init(VulkanResourceManager *resourceMan, VulkanC
|
||||
mipLevels = pCreateInfo->mipLevels;
|
||||
samples = RDCMAX(VK_SAMPLE_COUNT_1_BIT, pCreateInfo->samples);
|
||||
|
||||
mrq = origMrq;
|
||||
|
||||
linear = pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR;
|
||||
|
||||
external = false;
|
||||
|
||||
@@ -558,12 +558,14 @@ struct VulkanCreationInfo
|
||||
struct Buffer
|
||||
{
|
||||
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
const VkBufferCreateInfo *pCreateInfo);
|
||||
const VkBufferCreateInfo *pCreateInfo, VkMemoryRequirements origMrq);
|
||||
|
||||
VkBufferUsageFlags usage;
|
||||
uint64_t size;
|
||||
uint64_t gpuAddress;
|
||||
bool external;
|
||||
|
||||
VkMemoryRequirements mrq;
|
||||
};
|
||||
std::unordered_map<ResourceId, Buffer> m_Buffer;
|
||||
|
||||
@@ -582,7 +584,7 @@ struct VulkanCreationInfo
|
||||
struct Image
|
||||
{
|
||||
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
const VkImageCreateInfo *pCreateInfo);
|
||||
const VkImageCreateInfo *pCreateInfo, VkMemoryRequirements origMrq);
|
||||
|
||||
VkImageType type;
|
||||
VkFormat format;
|
||||
@@ -594,6 +596,8 @@ struct VulkanCreationInfo
|
||||
bool external;
|
||||
bool cube;
|
||||
TextureCategory creationFlags;
|
||||
|
||||
VkMemoryRequirements mrq;
|
||||
};
|
||||
std::unordered_map<ResourceId, Image> m_Image;
|
||||
|
||||
|
||||
@@ -332,7 +332,7 @@ RDResult WrappedVulkan::Initialise(VkInitParams ¶ms, uint64_t sectionVersion
|
||||
if(supportedExtensions.find(params.Extensions[i]) == supportedExtensions.end())
|
||||
{
|
||||
RETURN_ERROR_RESULT(ResultCode::APIHardwareUnsupported,
|
||||
"Capture requires extension '%s' which is not supported",
|
||||
"Capture requires instance extension '%s' which is not supported\n",
|
||||
params.Extensions[i].c_str());
|
||||
}
|
||||
}
|
||||
@@ -1609,6 +1609,17 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
|
||||
RDCLOG("Creating replay device from physical device %u", physicalDeviceIndex);
|
||||
|
||||
ObjDisp(physicalDevice)
|
||||
->GetPhysicalDeviceProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.props);
|
||||
|
||||
ObjDisp(physicalDevice)
|
||||
->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps);
|
||||
|
||||
ObjDisp(physicalDevice)
|
||||
->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.availFeatures);
|
||||
|
||||
m_PhysicalDeviceData.driverInfo = VkDriverInfo(m_PhysicalDeviceData.props, true);
|
||||
|
||||
rdcarray<VkDeviceQueueGlobalPriorityCreateInfoKHR *> queuePriorities;
|
||||
|
||||
for(uint32_t i = 0; i < CreateInfo.queueCreateInfoCount; i++)
|
||||
@@ -1622,6 +1633,11 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
queuePriorities.push_back(queuePrio);
|
||||
}
|
||||
|
||||
const PhysicalDeviceData &origData = m_OriginalPhysicalDevices[physicalDeviceIndex];
|
||||
|
||||
m_OrigPhysicalDeviceData = origData;
|
||||
m_OrigPhysicalDeviceData.driverInfo = VkDriverInfo(origData.props, false);
|
||||
|
||||
// we must make any modifications locally, so the free of pointers
|
||||
// in the serialised VkDeviceCreateInfo don't double-free
|
||||
VkDeviceCreateInfo createInfo = CreateInfo;
|
||||
@@ -1671,8 +1687,9 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
if(supportedExtensions.find(Extensions[i]) == supportedExtensions.end())
|
||||
{
|
||||
SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
|
||||
"Capture requires extension '%s' which is not supported",
|
||||
Extensions[i].c_str());
|
||||
"Capture requires extension '%s' which is not supported\n"
|
||||
"\n%s",
|
||||
Extensions[i].c_str(), GetPhysDeviceCompatString(false, false).c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1816,10 +1833,8 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
q.queueFlags |= VK_QUEUE_TRANSFER_BIT;
|
||||
}
|
||||
|
||||
PhysicalDeviceData &origData = m_OriginalPhysicalDevices[physicalDeviceIndex];
|
||||
|
||||
uint32_t origQCount = origData.queueCount;
|
||||
VkQueueFamilyProperties *origprops = origData.queueProps;
|
||||
const VkQueueFamilyProperties *origprops = origData.queueProps;
|
||||
|
||||
// create queue remapping
|
||||
for(uint32_t origQIndex = 0; origQIndex < origQCount; origQIndex++)
|
||||
@@ -2105,7 +2120,8 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
{ \
|
||||
SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, \
|
||||
"Capture requires physical device feature '" #feature \
|
||||
"' which is not supported"); \
|
||||
"' which is not supported\n\n%s", \
|
||||
GetPhysDeviceCompatString(false, false).c_str()); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
@@ -2176,14 +2192,14 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
|
||||
#define END_PHYS_EXT_CHECK() }
|
||||
|
||||
#define CHECK_PHYS_EXT_FEATURE(feature) \
|
||||
if(ext->feature && !avail.feature) \
|
||||
{ \
|
||||
SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, \
|
||||
"Capture requires physical device feature '" #feature \
|
||||
"' in struct '%s' which is not supported", \
|
||||
structName); \
|
||||
return false; \
|
||||
#define CHECK_PHYS_EXT_FEATURE(feature) \
|
||||
if(ext->feature && !avail.feature) \
|
||||
{ \
|
||||
SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, \
|
||||
"Capture requires physical device feature '" #feature \
|
||||
"' in struct '%s' which is not supported\n\n%s", \
|
||||
structName, GetPhysDeviceCompatString(false, false).c_str()); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
VkPhysicalDeviceDescriptorIndexingFeatures descIndexingFeatures = {};
|
||||
@@ -2272,7 +2288,9 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
|
||||
"Capture requires bufferDeviceAddress support, which is available, but "
|
||||
"bufferDeviceAddressCaptureReplay support is not available which is required to "
|
||||
"replay");
|
||||
"replay\n"
|
||||
"\n%s",
|
||||
GetPhysDeviceCompatString(false, false).c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2478,7 +2496,9 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
|
||||
"Capture requires bufferDeviceAddress support, which is available, but "
|
||||
"bufferDeviceAddressCaptureReplay support is not available which is required to "
|
||||
"replay");
|
||||
"replay\n"
|
||||
"\n%s",
|
||||
GetPhysDeviceCompatString(false, false).c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2497,7 +2517,9 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
|
||||
"Capture requires bufferDeviceAddress support, which is available, but "
|
||||
"bufferDeviceAddressCaptureReplay support is not available which is required to "
|
||||
"replay");
|
||||
"replay\n"
|
||||
"\n%s",
|
||||
GetPhysDeviceCompatString(false, false).c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -3573,20 +3595,10 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
}
|
||||
}
|
||||
|
||||
ObjDisp(physicalDevice)
|
||||
->GetPhysicalDeviceProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.props);
|
||||
|
||||
ObjDisp(physicalDevice)
|
||||
->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps);
|
||||
|
||||
ObjDisp(physicalDevice)
|
||||
->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.availFeatures);
|
||||
m_PhysicalDeviceData.enabledFeatures = enabledFeatures;
|
||||
|
||||
m_PhysicalDeviceData.driverInfo = VkDriverInfo(m_PhysicalDeviceData.props, true);
|
||||
|
||||
m_Replay->SetDriverInformation(m_PhysicalDeviceData.props);
|
||||
|
||||
m_PhysicalDeviceData.enabledFeatures = enabledFeatures;
|
||||
|
||||
// MoltenVK reports 0x3fffffff for this limit so just ignore that value if it comes up
|
||||
RDCASSERT(m_PhysicalDeviceData.props.limits.maxBoundDescriptorSets <
|
||||
ARRAY_COUNT(BakedCmdBufferInfo::pushDescriptorID[0]) ||
|
||||
|
||||
@@ -191,8 +191,9 @@ VkBindImageMemoryInfo *WrappedVulkan::UnwrapInfos(CaptureState state,
|
||||
}
|
||||
|
||||
bool WrappedVulkan::CheckMemoryRequirements(const char *resourceName, ResourceId memId,
|
||||
VkDeviceSize memoryOffset, VkMemoryRequirements mrq,
|
||||
bool external)
|
||||
VkDeviceSize memoryOffset,
|
||||
const VkMemoryRequirements &mrq, bool external,
|
||||
const VkMemoryRequirements &origMrq)
|
||||
{
|
||||
// verify that the memory meets basic requirements. If not, something changed and we should
|
||||
// bail loading this capture. This is a bit of an under-estimate since we just make sure
|
||||
@@ -203,65 +204,80 @@ bool WrappedVulkan::CheckMemoryRequirements(const char *resourceName, ResourceId
|
||||
VulkanCreationInfo::Memory &memInfo = m_CreationInfo.m_Memory[memId];
|
||||
uint32_t bit = 1U << memInfo.memoryTypeIndex;
|
||||
|
||||
bool origInvalid = false;
|
||||
|
||||
// verify type
|
||||
if((mrq.memoryTypeBits & bit) == 0)
|
||||
{
|
||||
rdcstr bitsString;
|
||||
|
||||
for(uint32_t i = 0; i < 32; i++)
|
||||
if((origMrq.memoryTypeBits & bit) == 0)
|
||||
{
|
||||
if(mrq.memoryTypeBits & (1U << i))
|
||||
bitsString += StringFormat::Fmt("%s%u", bitsString.empty() ? "" : ", ", i);
|
||||
}
|
||||
for(uint32_t i = 0; i < 32; i++)
|
||||
{
|
||||
if(origMrq.memoryTypeBits & (1U << i))
|
||||
bitsString += StringFormat::Fmt("%s%u", bitsString.empty() ? "" : ", ", i);
|
||||
}
|
||||
|
||||
if(external)
|
||||
origInvalid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SET_ERROR_RESULT(
|
||||
m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
|
||||
"Trying to bind %s to memory %s which is type %u, "
|
||||
"but only these types are allowed: %s\n"
|
||||
"This resource was created with external memory bindings, which is not represented in "
|
||||
"the capture.\n"
|
||||
"Some drivers do not allow externally-imported resources to be bound to non-external "
|
||||
"memory, meaning this cannot be replayed.",
|
||||
resourceName, ToStr(memOrigId).c_str(), memInfo.memoryTypeIndex, bitsString.c_str());
|
||||
return false;
|
||||
for(uint32_t i = 0; i < 32; i++)
|
||||
{
|
||||
if(mrq.memoryTypeBits & (1U << i))
|
||||
bitsString += StringFormat::Fmt("%s%u", bitsString.empty() ? "" : ", ", i);
|
||||
}
|
||||
}
|
||||
|
||||
SET_ERROR_RESULT(
|
||||
m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
|
||||
"Trying to bind %s to memory %s which is type %u, "
|
||||
"but only these types are allowed: %s\n"
|
||||
"This is most likely caused by incompatible hardware or drivers between capture and "
|
||||
"replay, causing a change in memory requirements.",
|
||||
resourceName, ToStr(memOrigId).c_str(), memInfo.memoryTypeIndex, bitsString.c_str());
|
||||
"Trying to bind %s to %s, but memory type is %u and only types %s are allowed.\n"
|
||||
"\n%s",
|
||||
resourceName, GetResourceDesc(memOrigId).name.c_str(), memInfo.memoryTypeIndex,
|
||||
bitsString.c_str(), GetPhysDeviceCompatString(external, origInvalid).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// verify offset alignment
|
||||
if((memoryOffset % mrq.alignment) != 0)
|
||||
{
|
||||
VkDeviceSize align = mrq.alignment;
|
||||
|
||||
if((memoryOffset % origMrq.alignment) != 0)
|
||||
{
|
||||
origInvalid = true;
|
||||
|
||||
align = origMrq.alignment;
|
||||
}
|
||||
|
||||
SET_ERROR_RESULT(
|
||||
m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
|
||||
"Trying to bind %s to memory %s which is type %u, "
|
||||
"but offset 0x%llx doesn't satisfy alignment 0x%llx.\n"
|
||||
"This is most likely caused by incompatible hardware or drivers between capture and "
|
||||
"replay, causing a change in memory requirements.",
|
||||
resourceName, ToStr(memOrigId).c_str(), memInfo.memoryTypeIndex, memoryOffset, mrq.alignment);
|
||||
"Trying to bind %s to %s, but memory offset 0x%llx doesn't satisfy alignment 0x%llx.\n"
|
||||
"\n%s",
|
||||
resourceName, GetResourceDesc(memOrigId).name.c_str(), memoryOffset, mrq.alignment,
|
||||
GetPhysDeviceCompatString(external, origInvalid).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// verify size
|
||||
if(mrq.size > memInfo.allocSize - memoryOffset)
|
||||
{
|
||||
SET_ERROR_RESULT(
|
||||
m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
|
||||
"Trying to bind %s to memory %s which is type %u, "
|
||||
"but at offset 0x%llx the reported size of 0x%llx won't fit the 0x%llx bytes of memory.\n"
|
||||
"This is most likely caused by incompatible hardware or drivers between capture and "
|
||||
"replay, causing a change in memory requirements.",
|
||||
resourceName, ToStr(memOrigId).c_str(), memInfo.memoryTypeIndex, memoryOffset, mrq.size,
|
||||
memInfo.allocSize);
|
||||
VkDeviceSize size = mrq.size;
|
||||
|
||||
if(origMrq.size > memInfo.allocSize - memoryOffset)
|
||||
{
|
||||
origInvalid = true;
|
||||
|
||||
size = origMrq.size;
|
||||
}
|
||||
|
||||
SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
|
||||
"Trying to bind %s to %s, but at memory offset 0x%llx the reported size of "
|
||||
"0x%llx won't fit the 0x%llx bytes of memory.\n"
|
||||
"\n%s",
|
||||
resourceName, GetResourceDesc(memOrigId).name.c_str(), memoryOffset, size,
|
||||
memInfo.allocSize, GetPhysDeviceCompatString(external, origInvalid).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -296,9 +312,11 @@ bool WrappedVulkan::Serialise_vkAllocateMemory(SerialiserType &ser, VkDevice dev
|
||||
SET_ERROR_RESULT(
|
||||
m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
|
||||
"Tried to allocate memory from index %u, but on replay we only have %u memory types.\n"
|
||||
"This is most likely caused by incompatible hardware or drivers between capture and "
|
||||
"replay, causing a change in memory requirements.",
|
||||
patched.memoryTypeIndex, m_PhysicalDeviceData.memProps.memoryTypeCount);
|
||||
"\n%s",
|
||||
patched.memoryTypeIndex, m_PhysicalDeviceData.memProps.memoryTypeCount,
|
||||
GetPhysDeviceCompatString(
|
||||
false, patched.memoryTypeIndex >= m_OrigPhysicalDeviceData.memProps.memoryTypeCount)
|
||||
.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1338,8 +1356,8 @@ bool WrappedVulkan::Serialise_vkBindBufferMemory(SerialiserType &ser, VkDevice d
|
||||
VkMemoryRequirements mrq = {};
|
||||
ObjDisp(device)->GetBufferMemoryRequirements(Unwrap(device), Unwrap(buffer), &mrq);
|
||||
|
||||
bool ok = CheckMemoryRequirements(("Buffer " + ToStr(resOrigId)).c_str(), GetResID(memory),
|
||||
memoryOffset, mrq, bufInfo.external);
|
||||
bool ok = CheckMemoryRequirements(GetResourceDesc(resOrigId).name.c_str(), GetResID(memory),
|
||||
memoryOffset, mrq, bufInfo.external, bufInfo.mrq);
|
||||
|
||||
if(!ok)
|
||||
return false;
|
||||
@@ -1461,8 +1479,8 @@ bool WrappedVulkan::Serialise_vkBindImageMemory(SerialiserType &ser, VkDevice de
|
||||
|
||||
VulkanCreationInfo::Image &imgInfo = m_CreationInfo.m_Image[GetResID(image)];
|
||||
|
||||
bool ok = CheckMemoryRequirements(("Image " + ToStr(resOrigId)).c_str(), GetResID(memory),
|
||||
memoryOffset, mrq, imgInfo.external);
|
||||
bool ok = CheckMemoryRequirements(GetResourceDesc(resOrigId).name.c_str(), GetResID(memory),
|
||||
memoryOffset, mrq, imgInfo.external, imgInfo.mrq);
|
||||
|
||||
if(!ok)
|
||||
return false;
|
||||
@@ -1631,7 +1649,8 @@ bool WrappedVulkan::Serialise_vkCreateBuffer(SerialiserType &ser, VkDevice devic
|
||||
ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), buf);
|
||||
GetResourceManager()->AddLiveResource(Buffer, buf);
|
||||
|
||||
m_CreationInfo.m_Buffer[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo);
|
||||
m_CreationInfo.m_Buffer[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo,
|
||||
memoryRequirements);
|
||||
}
|
||||
|
||||
AddResource(Buffer, ResourceType::Buffer, "Buffer");
|
||||
@@ -1841,7 +1860,7 @@ VkResult WrappedVulkan::vkCreateBuffer(VkDevice device, const VkBufferCreateInfo
|
||||
{
|
||||
GetResourceManager()->AddLiveResource(id, *pBuffer);
|
||||
|
||||
m_CreationInfo.m_Buffer[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo);
|
||||
m_CreationInfo.m_Buffer[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo, {});
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2132,7 +2151,8 @@ bool WrappedVulkan::Serialise_vkCreateImage(SerialiserType &ser, VkDevice device
|
||||
|
||||
NameVulkanObject(img, StringFormat::Fmt("Image %s", ToStr(Image).c_str()));
|
||||
|
||||
m_CreationInfo.m_Image[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo);
|
||||
m_CreationInfo.m_Image[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo,
|
||||
memoryRequirements);
|
||||
|
||||
bool inserted = false;
|
||||
auto state = InsertImageState(img, live, CreateInfo, eFrameRef_Unknown, &inserted);
|
||||
@@ -2525,7 +2545,7 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *
|
||||
{
|
||||
GetResourceManager()->AddLiveResource(id, *pImage);
|
||||
|
||||
m_CreationInfo.m_Image[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo);
|
||||
m_CreationInfo.m_Image[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo, {});
|
||||
}
|
||||
|
||||
LockedImageStateRef state =
|
||||
@@ -2732,9 +2752,9 @@ bool WrappedVulkan::Serialise_vkBindBufferMemory2(SerialiserType &ser, VkDevice
|
||||
|
||||
ObjDisp(device)->GetBufferMemoryRequirements(Unwrap(device), Unwrap(bindInfo.buffer), &mrqs[i]);
|
||||
|
||||
bool ok =
|
||||
CheckMemoryRequirements(("Buffer " + ToStr(resOrigId)).c_str(), GetResID(bindInfo.memory),
|
||||
bindInfo.memoryOffset, mrqs[i], bufInfo.external);
|
||||
bool ok = CheckMemoryRequirements(GetResourceDesc(resOrigId).name.c_str(),
|
||||
GetResID(bindInfo.memory), bindInfo.memoryOffset, mrqs[i],
|
||||
bufInfo.external, bufInfo.mrq);
|
||||
|
||||
if(!ok)
|
||||
return false;
|
||||
@@ -2877,9 +2897,9 @@ bool WrappedVulkan::Serialise_vkBindImageMemory2(SerialiserType &ser, VkDevice d
|
||||
VkMemoryRequirements mrq = {};
|
||||
ObjDisp(device)->GetImageMemoryRequirements(Unwrap(device), Unwrap(bindInfo.image), &mrq);
|
||||
|
||||
bool ok =
|
||||
CheckMemoryRequirements(("Image " + ToStr(resOrigId)).c_str(), GetResID(bindInfo.memory),
|
||||
bindInfo.memoryOffset, mrq, imgInfo.external);
|
||||
bool ok = CheckMemoryRequirements(GetResourceDesc(resOrigId).name.c_str(),
|
||||
GetResID(bindInfo.memory), bindInfo.memoryOffset, mrq,
|
||||
imgInfo.external, imgInfo.mrq);
|
||||
|
||||
if(!ok)
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user