Use enabled not available features to determine what shaders to create

* We still check available features to know which shaders we could create on
  replay, to determine whether we should add STORAGE_BIT to MSAA images we want
  to store into.
This commit is contained in:
baldurk
2020-05-19 12:57:28 +01:00
parent 5380b61b9d
commit a5fe4ebde5
16 changed files with 124 additions and 91 deletions
@@ -547,7 +547,7 @@ void VulkanReplay::FetchShaderFeedback(uint32_t eventId)
bool useBufferAddress = (m_pDriver->GetExtensions(NULL).ext_KHR_buffer_device_address ||
m_pDriver->GetExtensions(NULL).ext_EXT_buffer_device_address) &&
m_pDriver->GetDeviceFeatures().shaderInt64;
m_pDriver->GetDeviceEnabledFeatures().shaderInt64;
bool useBufferAddressKHR = m_pDriver->GetExtensions(NULL).ext_KHR_buffer_device_address;
+6 -6
View File
@@ -234,27 +234,27 @@ public:
VkDriverInfo(const VkPhysicalDeviceProperties &physProps);
// checks for when we're running on metal and some non-queryable things aren't supported
bool RunningOnMetal() { return metalBackend; }
bool RunningOnMetal() const { return metalBackend; }
// A workaround for a couple of bugs, removing texelFetch use from shaders.
// It means broken functionality but at least no instant crashes
bool TexelFetchBrokenDriver() { return texelFetchBrokenDriver; }
bool TexelFetchBrokenDriver() const { return texelFetchBrokenDriver; }
// Older AMD driver versions could sometimes cause image memory requirements to vary randomly
// between identical images. This means the memory required at capture could be less than at
// replay. To counteract this, on drivers with this issue we pad out the memory requirements
// enough to account for the change
bool UnreliableImageMemoryRequirements() { return unreliableImgMemReqs; }
bool UnreliableImageMemoryRequirements() const { return unreliableImgMemReqs; }
// another workaround, on some AMD driver versions creating an MSAA image with STORAGE_BIT
// causes graphical corruption trying to sample from it. We workaround it by preventing the
// MSAA <-> Array pipelines from creating, which removes the STORAGE_BIT and skips the copies.
// It means initial contents of MSAA images are missing but that's less important than being
// able to inspect MSAA images properly.
bool AMDStorageMSAABrokenDriver() { return amdStorageMSAABrokenDriver; }
bool AMDStorageMSAABrokenDriver() const { return amdStorageMSAABrokenDriver; }
// On Qualcomm it seems like binding a descriptor set with a dynamic offset will 'leak' and affect
// rendering on other descriptor sets that don't use offsets at all.
bool QualcommLeakingUBOOffsets() { return qualcommLeakingUBOOffsets; }
bool QualcommLeakingUBOOffsets() const { return qualcommLeakingUBOOffsets; }
// On Qualcomm emitting an image sample operation with DRef and explicit lod will crash on non-2D
// textures. Since 2D is the common/expected case, we avoid compiling that case entirely.
bool QualcommDrefNon2DCompileCrash() { return qualcommDrefNon2DCompileCrash; }
bool QualcommDrefNon2DCompileCrash() const { return qualcommDrefNon2DCompileCrash; }
private:
GPUVendor m_Vendor;
+10 -2
View File
@@ -385,7 +385,8 @@ private:
uint32_t uploadMemIndex = 0;
uint32_t GPULocalMemIndex = 0;
VkPhysicalDeviceFeatures features = {};
VkPhysicalDeviceFeatures availFeatures = {};
VkPhysicalDeviceFeatures enabledFeatures = {};
VkPhysicalDeviceProperties props = {};
VkPhysicalDeviceMemoryProperties memProps = {};
VkFormatProperties fmtprops[VK_FORMAT_RANGE_SIZE] = {};
@@ -1062,7 +1063,14 @@ public:
static VkResult GetProvidedInstanceExtensionProperties(uint32_t *pPropertyCount,
VkExtensionProperties *pProperties);
const VkPhysicalDeviceFeatures &GetDeviceFeatures() { return m_PhysicalDeviceData.features; }
const VkPhysicalDeviceFeatures &GetDeviceEnabledFeatures()
{
return m_PhysicalDeviceData.enabledFeatures;
}
const VkPhysicalDeviceFeatures &GetDeviceAvailableFeatures()
{
return m_PhysicalDeviceData.availFeatures;
}
const VkPhysicalDeviceProperties &GetDeviceProps() { return m_PhysicalDeviceData.props; }
const VkPhysicalDevicePerformanceQueryFeaturesKHR &GetPhysicalDevicePerformanceQueryFeatures()
{
+2 -2
View File
@@ -115,7 +115,7 @@ rdcarray<GPUCounter> VulkanReplay::EnumerateCounters()
{
rdcarray<GPUCounter> ret;
VkPhysicalDeviceFeatures availableFeatures = m_pDriver->GetDeviceFeatures();
VkPhysicalDeviceFeatures availableFeatures = m_pDriver->GetDeviceEnabledFeatures();
ret.push_back(GPUCounter::EventGPUDuration);
if(availableFeatures.pipelineStatisticsQuery)
@@ -831,7 +831,7 @@ rdcarray<CounterResult> VulkanReplay::FetchCounters(const rdcarray<GPUCounter> &
ret.append(FetchCountersKHR(vkKHRCounters));
}
VkPhysicalDeviceFeatures availableFeatures = m_pDriver->GetDeviceFeatures();
VkPhysicalDeviceFeatures availableFeatures = m_pDriver->GetDeviceEnabledFeatures();
VkDevice dev = m_pDriver->GetDev();
+3 -3
View File
@@ -703,7 +703,7 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver)
m_pDriver->vkDestroyRenderPass(dev, depthMS2ArrayRP, NULL);
if(!m_pDriver->GetDeviceFeatures().sampleRateShading)
if(!m_pDriver->GetDeviceEnabledFeatures().sampleRateShading)
{
RDCDEBUG("No depth Array -> MSAA copies can be supported without sample rate shading");
continue;
@@ -2476,8 +2476,8 @@ void VulkanReplay::TextureRendering::Init(WrappedVulkan *driver, VkDescriptorPoo
VkImageViewType viewtypes[] = {
VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_IMAGE_VIEW_TYPE_3D,
VK_IMAGE_VIEW_TYPE_2D_ARRAY,
driver->GetDeviceFeatures().imageCubeArray ? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
: VK_IMAGE_VIEW_TYPE_CUBE,
driver->GetDeviceEnabledFeatures().imageCubeArray ? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
: VK_IMAGE_VIEW_TYPE_CUBE,
};
VkSampleCountFlagBits sampleCounts[] = {VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_1_BIT,
VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT};
-2
View File
@@ -62,8 +62,6 @@ public:
void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, bytebuf &ret);
bool IsMS2ArraySupported() { return m_MS2ArrayPipe != VK_NULL_HANDLE; }
bool IsArray2MSSupported() { return m_Array2MSPipe != VK_NULL_HANDLE; }
void CopyTex2DMSToArray(VkImage destArray, VkImage srcMS, VkExtent3D extent, uint32_t layers,
uint32_t samples, VkFormat fmt);
void CopyArrayToTex2DMS(VkImage destMS, VkImage srcArray, VkExtent3D extent, uint32_t layers,
@@ -32,7 +32,7 @@
void VulkanDebugManager::CopyTex2DMSToArray(VkImage destArray, VkImage srcMS, VkExtent3D extent,
uint32_t layers, uint32_t samples, VkFormat fmt)
{
if(!m_pDriver->GetDeviceFeatures().shaderStorageImageWriteWithoutFormat)
if(!m_pDriver->GetDeviceEnabledFeatures().shaderStorageImageWriteWithoutFormat)
return;
if(m_MS2ArrayPipe == VK_NULL_HANDLE)
@@ -420,8 +420,8 @@ void VulkanDebugManager::CopyDepthTex2DMSToArray(VkImage destArray, VkImage srcM
void VulkanDebugManager::CopyArrayToTex2DMS(VkImage destMS, VkImage srcArray, VkExtent3D extent,
uint32_t layers, uint32_t samples, VkFormat fmt)
{
if(!m_pDriver->GetDeviceFeatures().shaderStorageImageMultisample ||
!m_pDriver->GetDeviceFeatures().shaderStorageImageWriteWithoutFormat)
if(!m_pDriver->GetDeviceEnabledFeatures().shaderStorageImageMultisample ||
!m_pDriver->GetDeviceEnabledFeatures().shaderStorageImageWriteWithoutFormat)
return;
if(m_Array2MSPipe == VK_NULL_HANDLE)
+4 -4
View File
@@ -784,7 +784,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
RemoveNextStruct(&pipeCreateInfo,
VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT);
if(m_pDriver->GetDeviceFeatures().depthClamp)
if(m_pDriver->GetDeviceEnabledFeatures().depthClamp)
{
rs->depthClampEnable = true;
}
@@ -810,7 +810,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
{
// do nothing
}
else if(m_pDriver->GetDeviceFeatures().fillModeNonSolid)
else if(m_pDriver->GetDeviceEnabledFeatures().fillModeNonSolid)
{
rs->polygonMode = VK_POLYGON_MODE_LINE;
}
@@ -1174,7 +1174,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
rs->cullMode = VK_CULL_MODE_NONE; // first render without any culling
rs->rasterizerDiscardEnable = false;
if(m_pDriver->GetDeviceFeatures().depthClamp)
if(m_pDriver->GetDeviceEnabledFeatures().depthClamp)
rs->depthClampEnable = true;
VkPipelineColorBlendStateCreateInfo *cb =
@@ -1536,7 +1536,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
rs->cullMode = VK_CULL_MODE_NONE;
rs->rasterizerDiscardEnable = false;
if(m_pDriver->GetDeviceFeatures().depthClamp)
if(m_pDriver->GetDeviceEnabledFeatures().depthClamp)
rs->depthClampEnable = true;
vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL,
+4 -4
View File
@@ -469,7 +469,7 @@ protected:
{
rs->cullMode = VK_CULL_MODE_NONE;
rs->rasterizerDiscardEnable = VK_FALSE;
if(m_pDriver->GetDeviceFeatures().depthClamp)
if(m_pDriver->GetDeviceEnabledFeatures().depthClamp)
rs->depthClampEnable = true;
}
@@ -1629,7 +1629,7 @@ private:
// Blending
{
if(m_pDriver->GetDeviceFeatures().independentBlend)
if(m_pDriver->GetDeviceEnabledFeatures().independentBlend)
{
for(size_t i = 0; i < p.attachments.size(); i++)
{
@@ -1993,7 +1993,7 @@ struct VulkanPixelHistoryPerFragmentCallback : VulkanPixelHistoryCallback
{
for(uint32_t i = 0; i < 2; i++)
{
if(i == 0 && !m_pDriver->GetDeviceFeatures().geometryShader)
if(i == 0 && !m_pDriver->GetDeviceEnabledFeatures().geometryShader)
{
// without geometryShader, can't read primitive ID in pixel shader
continue;
@@ -3168,7 +3168,7 @@ rdcarray<PixelModification> VulkanReplay::PixelHistory(rdcarray<EventUsage> even
// without the geometry shader feature we can't get the primitive ID, so we can't establish
// discard per-primitive so we assume all shaders don't discard.
if(m_pDriver->GetDeviceFeatures().geometryShader)
if(m_pDriver->GetDeviceEnabledFeatures().geometryShader)
{
if(primitivesToCheck > 0)
{
+1 -1
View File
@@ -359,7 +359,7 @@ VKMeshDisplayPipelines VulkanDebugManager::CacheMeshDisplayPipelines(VkPipelineL
// if the device doesn't support non-solid fill mode, fall back to fill. We don't try to patch
// index buffers for mesh render since it's not worth the trouble - mesh rendering happens locally
// and typically the local machine is capable enough to do line raster.
if(!m_pDriver->GetDeviceFeatures().fillModeNonSolid)
if(!m_pDriver->GetDeviceEnabledFeatures().fillModeNonSolid)
{
RDCWARN("Can't render mesh wireframes without non-solid fill mode support");
rs.polygonMode = VK_POLYGON_MODE_FILL;
+1 -1
View File
@@ -2806,7 +2806,7 @@ void VulkanReplay::CopyPixelForPixelHistory(VkCommandBuffer cmd, VkOffset2D offs
descSet = m_PixelHistory.MSDepthCopyDescSet;
else
descSet = m_PixelHistory.MSCopyDescSet;
if(!m_pDriver->GetDeviceFeatures().shaderStorageImageWriteWithoutFormat)
if(!m_pDriver->GetDeviceEnabledFeatures().shaderStorageImageWriteWithoutFormat)
return;
ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE,
+57 -40
View File
@@ -103,6 +103,54 @@ static const BuiltinShaderConfig builtinShaders[] = {
RDCCOMPILE_ASSERT(ARRAY_COUNT(builtinShaders) == arraydim<BuiltinShader>(),
"Missing built-in shader config");
static bool PassesChecks(const BuiltinShaderConfig &config, const VkDriverInfo &driverVersion,
const VkPhysicalDeviceFeatures &features)
{
if(config.checks & FeatureCheck::ShaderMSAAStorage)
{
if(driverVersion.TexelFetchBrokenDriver() || driverVersion.AMDStorageMSAABrokenDriver() ||
!features.shaderStorageImageMultisample)
{
return false;
}
}
if(config.checks & FeatureCheck::FormatlessWrite)
{
if(!features.shaderStorageImageWriteWithoutFormat)
{
return false;
}
}
if(config.checks & FeatureCheck::SampleShading)
{
if(!features.sampleRateShading)
{
return false;
}
}
if(config.checks & FeatureCheck::FragmentStores)
{
if(!features.fragmentStoresAndAtomics)
return false;
}
if(config.checks & FeatureCheck::NonMetalBackend)
{
// for now we don't allow it at all - in future we could check on whether it's been enabled
// via a more advanced query
if(driverVersion.RunningOnMetal())
return false;
}
if(config.stage == rdcspv::ShaderStage::Geometry && !features.geometryShader)
return false;
return true;
}
struct VulkanBlobShaderCallbacks
{
bool Create(uint32_t size, byte *data, SPIRVBlob *ret) const
@@ -149,7 +197,8 @@ VulkanShaderCache::VulkanShaderCache(WrappedVulkan *driver)
SetCaching(true);
VkDriverInfo driverVersion = driver->GetDriverInfo();
const VkPhysicalDeviceFeatures &features = driver->GetDeviceFeatures();
const VkPhysicalDeviceFeatures &enabledFeatures = driver->GetDeviceEnabledFeatures();
const VkPhysicalDeviceFeatures &availFeatures = driver->GetDeviceAvailableFeatures();
m_GlobalDefines = "#define HAS_BIT_CONVERSION 1\n";
if(driverVersion.TexelFetchBrokenDriver())
@@ -161,52 +210,20 @@ VulkanShaderCache::VulkanShaderCache(WrappedVulkan *driver)
rdcspv::CompilationSettings compileSettings;
compileSettings.lang = rdcspv::InputLanguage::VulkanGLSL;
m_MS2ArraySupported =
PassesChecks(builtinShaders[(size_t)BuiltinShader::MS2ArrayCS], driverVersion, availFeatures);
m_Array2MSSupported =
PassesChecks(builtinShaders[(size_t)BuiltinShader::Array2MSCS], driverVersion, availFeatures);
for(auto i : indices<BuiltinShader>())
{
const BuiltinShaderConfig &config = builtinShaders[i];
RDCASSERT(config.builtin == (BuiltinShader)i);
if(config.checks & FeatureCheck::ShaderMSAAStorage)
{
if(driverVersion.TexelFetchBrokenDriver() || driverVersion.AMDStorageMSAABrokenDriver() ||
!features.shaderStorageImageMultisample)
{
continue;
}
}
bool passesChecks = PassesChecks(config, driverVersion, enabledFeatures);
if(config.checks & FeatureCheck::FormatlessWrite)
{
if(!features.shaderStorageImageWriteWithoutFormat)
{
continue;
}
}
if(config.checks & FeatureCheck::SampleShading)
{
if(!features.sampleRateShading)
{
continue;
}
}
if(config.checks & FeatureCheck::FragmentStores)
{
if(!features.fragmentStoresAndAtomics)
continue;
}
if(config.checks & FeatureCheck::NonMetalBackend)
{
// for now we don't allow it at all - in future we could check on whether it's been enabled
// via a more advanced query
if(driverVersion.RunningOnMetal())
continue;
}
if(config.stage == rdcspv::ShaderStage::Geometry && !features.geometryShader)
if(!passesChecks)
continue;
rdcstr defines = m_GlobalDefines;
@@ -80,6 +80,8 @@ public:
void MakeGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo &pipeCreateInfo, ResourceId pipeline);
void MakeComputePipelineInfo(VkComputePipelineCreateInfo &pipeCreateInfo, ResourceId pipeline);
bool IsMS2ArraySupported() { return m_MS2ArraySupported; }
bool IsArray2MSSupported() { return m_Array2MSSupported; }
rdcstr GetGlobalDefines() { return m_GlobalDefines; }
void SetCaching(bool enabled) { m_CacheShaders = enabled; }
private:
@@ -97,6 +99,8 @@ private:
rdcstr m_GlobalDefines;
bool m_MS2ArraySupported = false, m_Array2MSSupported = false;
bool m_ShaderCacheDirty = false, m_CacheShaders = false;
std::map<uint32_t, SPIRVBlob> m_ShaderCache;
+21 -17
View File
@@ -678,7 +678,7 @@ public:
else if(viewInfo.viewType == VK_IMAGE_VIEW_TYPE_2D)
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
else if(viewInfo.viewType == VK_IMAGE_VIEW_TYPE_CUBE &&
m_pDriver->GetDeviceFeatures().imageCubeArray)
m_pDriver->GetDeviceEnabledFeatures().imageCubeArray)
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
viewInfo.components = viewProps.componentMapping;
@@ -1017,7 +1017,7 @@ public:
// needing to potentially compile lots of pipelines with different offsets. If we're actually
// using them and the device doesn't support the extended gather feature, the result will be
// wrong.
if(!m_pDriver->GetDeviceFeatures().shaderImageGatherExtended &&
if(!m_pDriver->GetDeviceEnabledFeatures().shaderImageGatherExtended &&
(uniformParams.offset.x != 0 || uniformParams.offset.y != 0 || uniformParams.offset.z != 0))
{
m_pDriver->AddDebugMessage(
@@ -1839,12 +1839,12 @@ private:
editor.AddCapability(rdcspv::Capability::Sampled1D);
editor.AddCapability(rdcspv::Capability::SampledBuffer);
if(m_pDriver->GetDeviceFeatures().shaderResourceMinLod)
if(m_pDriver->GetDeviceEnabledFeatures().shaderResourceMinLod)
editor.AddCapability(rdcspv::Capability::MinLod);
if(m_pDriver->GetDeviceFeatures().shaderImageGatherExtended)
if(m_pDriver->GetDeviceEnabledFeatures().shaderImageGatherExtended)
editor.AddCapability(rdcspv::Capability::ImageGatherExtended);
const bool cubeArray = (m_pDriver->GetDeviceFeatures().imageCubeArray != VK_FALSE);
const bool cubeArray = (m_pDriver->GetDeviceEnabledFeatures().imageCubeArray != VK_FALSE);
rdcspv::Id entryId = editor.MakeId();
@@ -2262,7 +2262,8 @@ private:
rdcspv::ImageOperandsAndParamDatas imageOperands;
if(m_pDriver->GetDeviceFeatures().shaderImageGatherExtended && offsets[i] != rdcspv::Id())
if(m_pDriver->GetDeviceEnabledFeatures().shaderImageGatherExtended &&
offsets[i] != rdcspv::Id())
imageOperands.setOffset(offsets[i]);
cases.add(rdcspv::OpLabel(label));
@@ -2296,7 +2297,7 @@ private:
cases.add(rdcspv::OpLabel(gradCase));
rdcspv::ImageOperandsAndParamDatas operands = imageOperands;
operands.setGrad(ddxs[i], ddys[i]);
if(m_pDriver->GetDeviceFeatures().shaderResourceMinLod)
if(m_pDriver->GetDeviceEnabledFeatures().shaderResourceMinLod)
operands.setMinLod(minlod);
rdcspv::Id combined = cases.add(rdcspv::OpSampledImage(
texSampCombinedTypes[i], editor.MakeId(), loadedImage, loadedSampler));
@@ -2331,7 +2332,8 @@ private:
rdcspv::ImageOperandsAndParamDatas imageOperands;
if(m_pDriver->GetDeviceFeatures().shaderImageGatherExtended && offsets[i] != rdcspv::Id())
if(m_pDriver->GetDeviceEnabledFeatures().shaderImageGatherExtended &&
offsets[i] != rdcspv::Id())
imageOperands.setOffset(offsets[i]);
cases.add(rdcspv::OpLabel(label));
@@ -2365,7 +2367,7 @@ private:
cases.add(rdcspv::OpLabel(gradCase));
rdcspv::ImageOperandsAndParamDatas operands = imageOperands;
operands.setGrad(ddxs[i], ddys[i]);
if(m_pDriver->GetDeviceFeatures().shaderResourceMinLod)
if(m_pDriver->GetDeviceEnabledFeatures().shaderResourceMinLod)
operands.setMinLod(minlod);
rdcspv::Id combined = cases.add(rdcspv::OpSampledImage(
texSampCombinedTypes[i], editor.MakeId(), loadedImage, loadedSampler));
@@ -2404,7 +2406,7 @@ private:
cases.add(rdcspv::OpLoad(texSampTypes[sampIdx], editor.MakeId(), bindVars[sampIdx]));
rdcspv::Id sampleResult;
if(m_pDriver->GetDeviceFeatures().shaderImageGatherExtended)
if(m_pDriver->GetDeviceEnabledFeatures().shaderImageGatherExtended)
{
rdcspv::Id mergeLabel = editor.MakeId();
rdcspv::Id constsCase = editor.MakeId();
@@ -2417,7 +2419,8 @@ private:
cases.add(rdcspv::OpLabel(baseCase));
rdcspv::ImageOperandsAndParamDatas operands = imageOperands;
if(m_pDriver->GetDeviceFeatures().shaderImageGatherExtended && offsets[i] != rdcspv::Id())
if(m_pDriver->GetDeviceEnabledFeatures().shaderImageGatherExtended &&
offsets[i] != rdcspv::Id())
imageOperands.setOffset(offsets[i]);
rdcspv::Id combined = cases.add(rdcspv::OpSampledImage(
@@ -2441,7 +2444,7 @@ private:
// if this feature isn't available, this path will never be exercised (since we only
// come in here when the actual shader used const offsets) so it's fine to drop it in
// that case to ensure the module is still legal.
if(m_pDriver->GetDeviceFeatures().shaderImageGatherExtended)
if(m_pDriver->GetDeviceEnabledFeatures().shaderImageGatherExtended)
operands.setConstOffsets(gatherOffsets);
rdcspv::Id combined = cases.add(rdcspv::OpSampledImage(
@@ -2463,7 +2466,8 @@ private:
}
else
{
if(m_pDriver->GetDeviceFeatures().shaderImageGatherExtended && offsets[i] != rdcspv::Id())
if(m_pDriver->GetDeviceEnabledFeatures().shaderImageGatherExtended &&
offsets[i] != rdcspv::Id())
imageOperands.setOffset(offsets[i]);
rdcspv::Id combined = cases.add(rdcspv::OpSampledImage(
@@ -3503,7 +3507,7 @@ ShaderDebugTrace *VulkanReplay::DebugPixel(uint32_t eventId, uint32_t x, uint32_
return new ShaderDebugTrace;
}
if(!m_pDriver->GetDeviceFeatures().fragmentStoresAndAtomics)
if(!m_pDriver->GetDeviceEnabledFeatures().fragmentStoresAndAtomics)
{
RDCWARN("Pixel debugging is not supported without fragment stores");
return new ShaderDebugTrace;
@@ -3583,7 +3587,7 @@ ShaderDebugTrace *VulkanReplay::DebugPixel(uint32_t eventId, uint32_t x, uint32_
else
{
// no geometry shader - safe to use as long as the geometry shader capability is available
usePrimitiveID = m_pDriver->GetDeviceFeatures().geometryShader != VK_FALSE;
usePrimitiveID = m_pDriver->GetDeviceEnabledFeatures().geometryShader != VK_FALSE;
if(Vulkan_Debug_ShaderDebugLogging())
{
@@ -3591,7 +3595,7 @@ ShaderDebugTrace *VulkanReplay::DebugPixel(uint32_t eventId, uint32_t x, uint32_
}
}
bool useSampleID = m_pDriver->GetDeviceFeatures().sampleRateShading != VK_FALSE;
bool useSampleID = m_pDriver->GetDeviceEnabledFeatures().sampleRateShading != VK_FALSE;
if(Vulkan_Debug_ShaderDebugLogging())
{
@@ -3611,7 +3615,7 @@ ShaderDebugTrace *VulkanReplay::DebugPixel(uint32_t eventId, uint32_t x, uint32_
}
else if(m_pDriver->GetExtensions(NULL).ext_EXT_buffer_device_address)
{
if(m_pDriver->GetDeviceFeatures().shaderInt64)
if(m_pDriver->GetDeviceEnabledFeatures().shaderInt64)
{
storageMode = EXT_bda;
@@ -1017,7 +1017,7 @@ bool WrappedVulkan::Serialise_vkEnumeratePhysicalDevices(SerialiserType &ser, Vk
m_OriginalPhysicalDevices[PhysicalDeviceIndex].props = physProps;
m_OriginalPhysicalDevices[PhysicalDeviceIndex].memProps = memProps;
m_OriginalPhysicalDevices[PhysicalDeviceIndex].features = physFeatures;
m_OriginalPhysicalDevices[PhysicalDeviceIndex].availFeatures = physFeatures;
m_OriginalPhysicalDevices[PhysicalDeviceIndex].queueCount = queueCount;
memcpy(m_OriginalPhysicalDevices[PhysicalDeviceIndex].queueProps, queueProps,
sizeof(queueProps));
@@ -3084,7 +3084,8 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps);
ObjDisp(physicalDevice)
->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.features);
->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.availFeatures);
m_PhysicalDeviceData.enabledFeatures = enabledFeatures;
m_PhysicalDeviceData.driverInfo = VkDriverInfo(m_PhysicalDeviceData.props);
@@ -3487,7 +3488,8 @@ VkResult WrappedVulkan::vkCreateDevice(VkPhysicalDevice physicalDevice,
->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps);
ObjDisp(physicalDevice)
->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.features);
->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.availFeatures);
m_PhysicalDeviceData.enabledFeatures = enabledFeatures;
m_PhysicalDeviceData.driverInfo = VkDriverInfo(m_PhysicalDeviceData.props);
@@ -1533,7 +1533,7 @@ bool WrappedVulkan::Serialise_vkCreateImage(SerialiserType &ser, VkDevice device
// of capability or because we disabled it as a workaround then we don't need this
// capability (and it might be the bug we're trying to work around by disabling the
// pipeline)
if(GetDebugManager()->IsArray2MSSupported())
if(GetShaderCache()->IsArray2MSSupported())
CreateInfo.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
}
else
@@ -1668,7 +1668,7 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *
{
// need to check the debug manager here since we might be creating this internal image from
// its constructor
if(GetDebugManager() && GetDebugManager()->IsArray2MSSupported())
if(GetDebugManager() && GetShaderCache()->IsArray2MSSupported())
createInfo_adjusted.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
}
else