Pipeline Creation Feedback impl

This commit is contained in:
CamilleLaVey
2026-07-30 18:57:15 -04:00
parent 200b81b087
commit 1188f285b7
5 changed files with 56 additions and 2 deletions
@@ -69,6 +69,9 @@ vk::Buffer CreateBuffer(const Device& device, const MemoryAllocator& memory_allo
if (device.IsExtConditionalRendering()) {
flags |= VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT;
}
if (device.IsBufferDeviceAddressSupported()) {
flags |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
}
const VkBufferCreateInfo buffer_ci = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
@@ -100,6 +103,9 @@ Buffer::Buffer(BufferCacheRuntime& runtime, DAddr cpu_addr_, u64 size_bytes_)
if (runtime.device.HasDebuggingToolAttached()) {
buffer.SetObjectNameEXT(fmt::format("Buffer 0x{:x}", CpuAddr()).c_str());
}
if (device->IsBufferDeviceAddressSupported()) {
device_address = device->GetLogical().GetBufferDeviceAddress(*buffer);
}
}
void Buffer::MarkUsage(u64 offset, u64 size) noexcept {
@@ -39,6 +39,10 @@ public:
return *buffer;
}
[[nodiscard]] VkDeviceAddress DeviceAddress() const noexcept {
return device_address;
}
[[nodiscard]] bool IsRegionUsed(u64 offset, u64 size) const noexcept {
return tracker.IsUsed(offset, size);
}
@@ -70,6 +74,7 @@ private:
vk::Buffer buffer;
std::vector<BufferView> views;
VideoCommon::UsageTracker tracker;
VkDeviceAddress device_address{};
u64 last_usage_tick{};
bool is_null{};
};
@@ -69,9 +69,17 @@ ComputePipeline::ComputePipeline(const Device& device_, Scheduler& scheduler, vk
if (device.IsKhrPipelineExecutablePropertiesEnabled() && Settings::values.renderer_debug.GetValue()) {
flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
}
VkPipelineCreationFeedback creation_feedback{};
const VkPipelineCreationFeedbackCreateInfo feedback_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO,
.pNext = nullptr,
.pPipelineCreationFeedback = &creation_feedback,
.pipelineStageCreationFeedbackCount = 0,
.pPipelineStageCreationFeedbacks = nullptr,
};
const VkComputePipelineCreateInfo compute_ci{
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.pNext = device.IsExtPipelineCreationFeedbackSupported() ? &feedback_ci : nullptr,
.flags = flags,
.stage{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
@@ -101,6 +109,14 @@ ComputePipeline::ComputePipeline(const Device& device_, Scheduler& scheduler, vk
return;
}
if ((creation_feedback.flags & VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT) != 0) {
const bool cache_hit =
(creation_feedback.flags &
VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT) != 0;
LOG_DEBUG(Render_Vulkan, "Compute pipeline {:016X} cache_hit={} duration={}us",
shader_hash, cache_hit, creation_feedback.duration / 1000);
}
// Log compute pipeline creation
if (GPU::Logging::IsActive()) {
GPU::Logging::GPULogger::GetInstance().LogPipelineStateChange(
@@ -1056,9 +1056,23 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.stencilAttachmentFormat = stencil_attachment_format,
};
VkPipelineCreationFeedback creation_feedback{};
const VkPipelineCreationFeedbackCreateInfo feedback_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO,
.pNext = device.IsKhrDynamicRenderingSupported() ? &rendering_ci : nullptr,
.pPipelineCreationFeedback = &creation_feedback,
.pipelineStageCreationFeedbackCount = 0,
.pPipelineStageCreationFeedbacks = nullptr,
};
const void* const create_next =
device.IsExtPipelineCreationFeedbackSupported()
? static_cast<const void*>(&feedback_ci)
: (device.IsKhrDynamicRenderingSupported() ? static_cast<const void*>(&rendering_ci)
: nullptr);
pipeline = device.GetLogical().CreateGraphicsPipeline({
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = device.IsKhrDynamicRenderingSupported() ? &rendering_ci : nullptr,
.pNext = create_next,
.flags = flags,
.stageCount = static_cast<u32>(shader_stages.size()),
.pStages = shader_stages.data(),
@@ -1078,6 +1092,14 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.basePipelineIndex = 0,
}, *pipeline_cache);
if ((creation_feedback.flags & VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT) != 0) {
const bool cache_hit =
(creation_feedback.flags &
VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT) != 0;
LOG_DEBUG(Render_Vulkan, "Graphics pipeline {:016X} cache_hit={} duration={}us",
key.Hash(), cache_hit, creation_feedback.duration / 1000);
}
// Log graphics pipeline creation
if (GPU::Logging::IsActive()) {
const std::string pipeline_info = fmt::format(
@@ -88,6 +88,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
EXTENSION(EXT, CONSERVATIVE_RASTERIZATION, conservative_rasterization) \
EXTENSION(EXT, DEPTH_RANGE_UNRESTRICTED, depth_range_unrestricted) \
EXTENSION(EXT, MEMORY_BUDGET, memory_budget) \
EXTENSION(EXT, PIPELINE_CREATION_FEEDBACK, pipeline_creation_feedback) \
EXTENSION(EXT, ROBUSTNESS_2, robustness_2) \
EXTENSION(EXT, SAMPLER_FILTER_MINMAX, sampler_filter_minmax) \
EXTENSION(EXT, SHADER_STENCIL_EXPORT, shader_stencil_export) \
@@ -484,6 +485,10 @@ FN_MAX_LIMIT_LIST
}
/// Returns true if the device supports descriptor buffers.
bool IsExtPipelineCreationFeedbackSupported() const {
return extensions.pipeline_creation_feedback;
}
bool IsExtDescriptorBufferSupported() const {
return extensions.descriptor_buffer;
}