diff --git a/qrenderdoc/Windows/PixelHistoryView.cpp b/qrenderdoc/Windows/PixelHistoryView.cpp index 15ce13a8a..0ae7f3f7c 100644 --- a/qrenderdoc/Windows/PixelHistoryView.cpp +++ b/qrenderdoc/Windows/PixelHistoryView.cpp @@ -278,6 +278,9 @@ public: { QString ret = tr("Primitive %1\n").arg(mod.primitiveID); + if(mod.primitiveID == ~0U) + ret = tr("Unknown primitive\n"); + if(mod.shaderDiscarded) ret += failureString(mod); diff --git a/renderdoc/driver/vulkan/vk_pixelhistory.cpp b/renderdoc/driver/vulkan/vk_pixelhistory.cpp index e03a1294a..b109a2c94 100644 --- a/renderdoc/driver/vulkan/vk_pixelhistory.cpp +++ b/renderdoc/driver/vulkan/vk_pixelhistory.cpp @@ -1991,6 +1991,12 @@ struct VulkanPixelHistoryPerFragmentCallback : VulkanPixelHistoryCallback { for(uint32_t i = 0; i < 2; i++) { + if(i == 0 && !m_pDriver->GetDeviceFeatures().geometryShader) + { + // without geometryShader, can't read primitive ID in pixel shader + continue; + } + VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, @@ -3141,24 +3147,35 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even } } - if(primitivesToCheck > 0) + // 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) { - VkMarkerRegion discardedRegion("VulkanPixelHistoryDiscardedFragmentsCallback"); - VkQueryPool occlPool; - CreateOcclusionPool(m_pDriver, primitivesToCheck, &occlPool); + if(primitivesToCheck > 0) + { + VkMarkerRegion discardedRegion("VulkanPixelHistoryDiscardedFragmentsCallback"); + VkQueryPool occlPool; + CreateOcclusionPool(m_pDriver, primitivesToCheck, &occlPool); - // Replay to see which primitives were discarded. - VulkanPixelHistoryDiscardedFragmentsCallback discardedCb(m_pDriver, shaderCache, callbackInfo, - discardedPrimsEvents, occlPool); - m_pDriver->ReplayLog(0, eventsWithFrags.rbegin()->first, eReplay_Full); - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); - discardedCb.FetchOcclusionResults(); - ObjDisp(dev)->DestroyQueryPool(Unwrap(dev), occlPool, NULL); + // Replay to see which primitives were discarded. + VulkanPixelHistoryDiscardedFragmentsCallback discardedCb( + m_pDriver, shaderCache, callbackInfo, discardedPrimsEvents, occlPool); + m_pDriver->ReplayLog(0, eventsWithFrags.rbegin()->first, eReplay_Full); + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + discardedCb.FetchOcclusionResults(); + ObjDisp(dev)->DestroyQueryPool(Unwrap(dev), occlPool, NULL); + for(size_t h = 0; h < history.size(); h++) + history[h].shaderDiscarded = + discardedCb.PrimitiveDiscarded(history[h].eventId, history[h].primitiveID); + } + } + else + { + // mark that we have no primitive IDs for(size_t h = 0; h < history.size(); h++) - history[h].shaderDiscarded = - discardedCb.PrimitiveDiscarded(history[h].eventId, history[h].primitiveID); + history[h].primitiveID = ~0U; } uint32_t discardOffset = 0; diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index e67e02141..e40122951 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -2510,8 +2510,8 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi enabledFeatures.geometryShader = true; else RDCWARN( - "geometryShader = false, lit mesh rendering will not be available if rendering on this " - "device."); + "geometryShader = false, pixel history primitive ID and triangle size overlay will not " + "be available, and local rendering on this device will not support lit mesh views."); // enable these features for simplicity, since we use them when available in the shader // debugging to simplify samples. If minlod isn't used then we omit it, and that's fine because