Skip to content

Commit

Permalink
add VK_KHR_maintenance5 support
Browse files Browse the repository at this point in the history
  • Loading branch information
qbojj committed Feb 19, 2024
1 parent 0f6c619 commit 685bde6
Show file tree
Hide file tree
Showing 19 changed files with 220 additions and 21 deletions.
11 changes: 9 additions & 2 deletions qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ Q_DECLARE_METATYPE(CombinedSamplerData);

namespace
{

template <typename T>
T RDCMIN(const T &a, const T &b)
{
return a < b ? a : b;
}

QString getTextureRenderSamples(const TextureDescription *tex, const VKPipe::RenderPass &renderpass)
{
const uint32_t texSamples = tex ? tex->msSamp : 1;
Expand Down Expand Up @@ -2411,7 +2418,7 @@ void VulkanPipelineStateViewer::setState()
BufferDescription *buf = m_Ctx.GetBuffer(state.inputAssembly.indexBuffer.resourceId);

if(buf)
length = buf->length;
length = RDCMIN(buf->length, state.inputAssembly.indexBuffer.byteSize);

RDTreeWidgetItem *node = new RDTreeWidgetItem(
{tr("Index"), state.inputAssembly.indexBuffer.resourceId, tr("Index"), lit("-"),
Expand Down Expand Up @@ -3802,7 +3809,7 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe::
if(ib)
{
name = m_Ctx.GetResourceName(ia.indexBuffer.resourceId);
length = ib->length;
length = RDCMIN(ib->length, ia.indexBuffer.byteSize);
}

QString ifmt = lit("UNKNOWN");
Expand Down
2 changes: 1 addition & 1 deletion renderdoc/api/replay/pipestate.inl
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ BoundVBuffer PipeState::GetIBuffer() const
ret.resourceId = m_Vulkan->inputAssembly.indexBuffer.resourceId;
ret.byteOffset = m_Vulkan->inputAssembly.indexBuffer.byteOffset;
ret.byteStride = m_Vulkan->inputAssembly.indexBuffer.byteStride;
ret.byteSize = ~0ULL;
ret.byteSize = m_Vulkan->inputAssembly.indexBuffer.byteSize;
}
}

Expand Down
3 changes: 3 additions & 0 deletions renderdoc/api/replay/vk_pipestate.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,9 @@ struct IndexBuffer
DOCUMENT("The byte offset from the start of the buffer to the beginning of the index data.");
uint64_t byteOffset = 0;

DOCUMENT("The number of bytes in the index buffer.");
uint64_t byteSize = 0;

DOCUMENT(R"(The number of bytes for each index in the index buffer. Typically 2 or 4 bytes but
it can be 0 if no index buffer is bound.
)");
Expand Down
9 changes: 9 additions & 0 deletions renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,15 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *api, const ShaderStage s
outputIDs.push_back(v.id);
liveGlobals.push_back(v.id);
pointerIDs.push_back(THREAD_POINTER(v.id, outputs));

// VK_KHR_maintenance5 requires that if PointSize is not written during shader execution, it should be 1.0f
// so we will initialize it to 1.0f here (if it is not enabled then leaving it as 1.0f is harmless)
if(decorations[v.id].flags & Decorations::HasBuiltIn &&
decorations[v.id].builtIn == BuiltIn::PointSize)
{
ShaderVariable &pointSize = active.outputs.back();
pointSize.value.f32v[0] = 1.0f;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion renderdoc/driver/vulkan/extension_support.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ Maintainers can update this file by updating vk.xml in this folder and running `
* `VK_KHR_maintenance2`
* `VK_KHR_maintenance3`
* `VK_KHR_maintenance4`
* `VK_KHR_maintenance5`
* `VK_KHR_multiview`
* `VK_KHR_performance_query`
* `VK_KHR_pipeline_executable_properties`
Expand Down Expand Up @@ -235,7 +236,6 @@ KHR extensions will definitely be implemented at some point, though KHR extensio

* `VK_KHR_cooperative_matrix`
* `VK_KHR_dynamic_rendering_local_read`
* `VK_KHR_maintenance5`
* `VK_KHR_maintenance6`
* `VK_KHR_map_memory2`
* `VK_KHR_shader_expect_assume`
Expand Down
1 change: 1 addition & 0 deletions renderdoc/driver/vulkan/vk_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,7 @@ enum class VulkanChunk : uint32_t
vkCmdDrawMeshTasksEXT,
vkCmdDrawMeshTasksIndirectEXT,
vkCmdDrawMeshTasksIndirectCountEXT,
vkCmdBindIndexBuffer2KHR,
Max,
};

Expand Down
4 changes: 4 additions & 0 deletions renderdoc/driver/vulkan/vk_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3989,6 +3989,10 @@ bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
return Serialise_vkCmdSetTessellationDomainOriginEXT(ser, VK_NULL_HANDLE,
VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM);

case VulkanChunk::vkCmdBindIndexBuffer2KHR:
return Serialise_vkCmdBindIndexBuffer2KHR(ser, VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0,
VK_INDEX_TYPE_MAX_ENUM);

// chunks that are reserved but not yet serialised
case VulkanChunk::vkResetCommandPool:
case VulkanChunk::vkCreateDepthTargetView:
Expand Down
14 changes: 14 additions & 0 deletions renderdoc/driver/vulkan/vk_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -2812,4 +2812,18 @@ class WrappedVulkan : public IFrameCapturer
VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
VkBuffer countBuffer, VkDeviceSize countBufferOffset,
uint32_t maxDrawCount, uint32_t stride);

// VK_KHR_mainenance5
IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBindIndexBuffer2KHR, VkCommandBuffer commandBuffer,
VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size,
VkIndexType indexType);
IMPLEMENT_FUNCTION_SERIALISED(void, vkGetDeviceImageSubresourceLayoutKHR, VkDevice device,
const VkDeviceImageSubresourceInfoKHR *pInfo,
VkSubresourceLayout2KHR *pLayout);
IMPLEMENT_FUNCTION_SERIALISED(void, vkGetImageSubresourceLayout2KHR, VkDevice device,
VkImage image, const VkImageSubresource2KHR *pSubresource,
VkSubresourceLayout2KHR *pLayout);
IMPLEMENT_FUNCTION_SERIALISED(void, vkGetRenderingAreaGranularityKHR, VkDevice device,
const VkRenderingAreaInfoKHR *pRenderingAreaInfo,
VkExtent2D *pGranularity);
};
18 changes: 16 additions & 2 deletions renderdoc/driver/vulkan/vk_hookset_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,8 @@
DeclExt(EXT_scalar_block_layout); \
DeclExt(KHR_vertex_attribute_divisor); \
DeclExt(KHR_line_rasterization); \
DeclExt(KHR_calibrated_timestamps);
DeclExt(KHR_calibrated_timestamps); \
DeclExt(KHR_maintenance5);

// for simplicity and since the check itself is platform agnostic,
// these aren't protected in platform defines
Expand Down Expand Up @@ -679,7 +680,8 @@
CheckExt(EXT_scalar_block_layout, VK12); \
CheckExt(KHR_vertex_attribute_divisor, VKXX); \
CheckExt(KHR_line_rasterization, VKXX); \
CheckExt(KHR_calibrated_timestamps, VKXX);
CheckExt(KHR_calibrated_timestamps, VKXX); \
CheckExt(KHR_maintenance5, VKXX);

#define HookInitVulkanInstanceExts_PhysDev() \
HookInitExtension(KHR_surface, GetPhysicalDeviceSurfaceSupportKHR); \
Expand Down Expand Up @@ -982,6 +984,10 @@
HookInitExtension(KHR_calibrated_timestamps, GetCalibratedTimestampsKHR); \
HookInitExtension(KHR_line_rasterization, CmdSetLineStippleKHR); \
HookInitExtensionEXTtoKHR(CmdSetLineStipple); \
HookInitExtension(KHR_maintenance5, CmdBindIndexBuffer2KHR); \
HookInitExtension(KHR_maintenance5, GetDeviceImageSubresourceLayoutKHR); \
HookInitExtension(KHR_maintenance5, GetImageSubresourceLayout2KHR); \
HookInitExtension(KHR_maintenance5, GetRenderingAreaGranularityKHR); \
HookInitExtension_Device_Win32(); \
HookInitExtension_Device_Linux(); \
HookInitExtension_Device_GGP(); \
Expand Down Expand Up @@ -1790,6 +1796,14 @@
uint64_t *, pMaxDeviation); \
HookDefine3(void, vkCmdSetLineStippleKHR, VkCommandBuffer, commandBuffer, uint32_t, \
lineStippleFactor, uint16_t, lineStipplePattern); \
HookDefine5(void, vkCmdBindIndexBuffer2KHR, VkCommandBuffer, commandBuffer, VkBuffer, buffer, \
VkDeviceSize, offset, VkDeviceSize, size, VkIndexType, indexType); \
HookDefine3(void, vkGetDeviceImageSubresourceLayoutKHR, VkDevice, device, \
const VkDeviceImageSubresourceInfoKHR *, pInfo, VkSubresourceLayout2KHR *, pLayout); \
HookDefine4(void, vkGetImageSubresourceLayout2KHR, VkDevice, device, VkImage, image, \
const VkImageSubresource2KHR *, pSubresource, VkSubresourceLayout2KHR *, pLayout); \
HookDefine3(void, vkGetRenderingAreaGranularityKHR, VkDevice, device, \
const VkRenderingAreaInfoKHR *, pRenderingAreaInfo, VkExtent2D *, pGranularity); \
HookDefine_Win32(); \
HookDefine_Linux(); \
HookDefine_GGP(); \
Expand Down
13 changes: 10 additions & 3 deletions renderdoc/driver/vulkan/vk_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,16 @@ VK_LAYER_RENDERDOC_CaptureEnumerateInstanceExtensionProperties(
VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr(VkDevice device, const char *pName)
{
if(device == VK_NULL_HANDLE || pName == NULL)
return NULL;

PFN_vkGetDeviceProcAddr gpa = GetDeviceDispatchTable(Unwrap(device))->GetDeviceProcAddr;

// if GPA returns NULL, that means that the standard prohibits non-NULL values for this pName
// or that the return value is undefined
if(!gpa || !gpa(Unwrap(device), pName))
return NULL;

if(!strcmp("vkGetDeviceProcAddr", pName))
return (PFN_vkVoidFunction)&VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr;
if(!strcmp("vkCreateDevice", pName))
Expand All @@ -422,9 +432,6 @@ VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr(VkDevice device, const char *pName)

HookInitVulkanDevice();

if(device == VK_NULL_HANDLE)
return NULL;

InstanceDeviceInfo *instDevInfo = GetRecord(device)->instDevInfo;

DeclExts();
Expand Down
16 changes: 13 additions & 3 deletions renderdoc/driver/vulkan/vk_overlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,19 @@ void VulkanDebugManager::PatchLineStripIndexBuffer(const ActionDescription *acti

if(action->flags & ActionFlags::Indexed)
{
GetBufferData(rs.ibuffer.buf,
rs.ibuffer.offs + uint64_t(action->indexOffset) * rs.ibuffer.bytewidth,
uint64_t(action->numIndices) * rs.ibuffer.bytewidth, indices);
uint64_t offset = uint64_t(action->indexOffset) * rs.ibuffer.bytewidth;
uint64_t data_len = uint64_t(action->numIndices) * rs.ibuffer.bytewidth;

uint64_t len = RDCMIN(data_len, rs.ibuffer.size - offset);

GetBufferData(rs.ibuffer.buf, rs.ibuffer.offs + offset, len, indices);

if(len < data_len)
{
// fill the rest with 0s
indices.resize(static_cast<size_t>(data_len));
memset(indices.data() + len, 0, static_cast<size_t>(data_len - len));
}

if(rs.ibuffer.bytewidth == 4)
idx32 = (uint32_t *)indices.data();
Expand Down
9 changes: 7 additions & 2 deletions renderdoc/driver/vulkan/vk_postvs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4331,8 +4331,13 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state)

// fetch ibuffer
if(state.ibuffer.buf != ResourceId())
GetBufferData(state.ibuffer.buf, state.ibuffer.offs + action->indexOffset * idxsize,
uint64_t(action->numIndices) * idxsize, idxdata);
{
uint64_t offset = uint64_t(action->indexOffset) * idxsize;
uint64_t data_len = uint64_t(action->numIndices) * idxsize;

uint64_t len = RDCMIN(data_len, state.ibuffer.size - offset);
GetBufferData(state.ibuffer.buf, state.ibuffer.offs + offset, len, idxdata);
}

// figure out what the maximum index could be, so we can clamp our index buffer to something
// sane
Expand Down
1 change: 1 addition & 0 deletions renderdoc/driver/vulkan/vk_replay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,7 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
ret.inputAssembly.indexBuffer.resourceId = rm->GetOriginalID(state.ibuffer.buf);
ret.inputAssembly.indexBuffer.byteOffset = state.ibuffer.offs;
ret.inputAssembly.indexBuffer.byteStride = state.ibuffer.bytewidth;
ret.inputAssembly.indexBuffer.byteSize = state.ibuffer.size;
ret.inputAssembly.primitiveRestartEnable = state.primRestartEnable != VK_FALSE;
ret.inputAssembly.topology =
MakePrimitiveTopology(state.primitiveTopology, state.patchControlPoints);
Expand Down
15 changes: 11 additions & 4 deletions renderdoc/driver/vulkan/vk_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ void setupRenderingInfo(const VulkanRenderState::DynamicRendering &dynamicRender

VulkanRenderState::VulkanRenderState()
{
RDCEraseEl(ibuffer);
}

void VulkanRenderState::BeginRenderPassAndApplyState(WrappedVulkan *vk, VkCommandBuffer cmd,
Expand Down Expand Up @@ -606,9 +605,17 @@ void VulkanRenderState::BindPipeline(WrappedVulkan *vk, VkCommandBuffer cmd,
else if(ibuffer.bytewidth == 1)
type = VK_INDEX_TYPE_UINT8_KHR;

ObjDisp(cmd)->CmdBindIndexBuffer(
Unwrap(cmd), Unwrap(vk->GetResourceManager()->GetCurrentHandle<VkBuffer>(ibuffer.buf)),
ibuffer.offs, type);
VkBuffer idxBufferUnwrapped =
Unwrap(vk->GetResourceManager()->GetCurrentHandle<VkBuffer>(ibuffer.buf));
if(ibuffer.size == VK_WHOLE_SIZE)
{
ObjDisp(cmd)->CmdBindIndexBuffer(Unwrap(cmd), idxBufferUnwrapped, ibuffer.offs, type);
}
else
{
ObjDisp(cmd)->CmdBindIndexBuffer2KHR(Unwrap(cmd), idxBufferUnwrapped, ibuffer.offs,
ibuffer.size, type);
}
}

if(vk->DynamicVertexInput() && dynamicStates[VkDynamicVertexInputEXT])
Expand Down
1 change: 1 addition & 0 deletions renderdoc/driver/vulkan/vk_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ struct VulkanRenderState
{
ResourceId buf;
VkDeviceSize offs = 0;
VkDeviceSize size = VK_WHOLE_SIZE;
int bytewidth = 0;
} ibuffer;

Expand Down
3 changes: 2 additions & 1 deletion renderdoc/driver/vulkan/vk_stringise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
template <>
rdcstr DoStringise(const VulkanChunk &el)
{
RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1201, "Chunks changed without updating names");
RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1202, "Chunks changed without updating names");

BEGIN_ENUM_STRINGISE(VulkanChunk)
{
Expand Down Expand Up @@ -233,6 +233,7 @@ rdcstr DoStringise(const VulkanChunk &el)
STRINGISE_ENUM_CLASS(vkCmdDrawMeshTasksEXT)
STRINGISE_ENUM_CLASS(vkCmdDrawMeshTasksIndirectEXT)
STRINGISE_ENUM_CLASS(vkCmdDrawMeshTasksIndirectCountEXT)
STRINGISE_ENUM_CLASS(vkCmdBindIndexBuffer2KHR)
STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk");
}
END_ENUM_STRINGISE()
Expand Down
92 changes: 92 additions & 0 deletions renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3893,6 +3893,94 @@ void WrappedVulkan::vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer
}
}

template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer2KHR(SerialiserType &ser,
VkCommandBuffer commandBuffer,
VkBuffer buffer, VkDeviceSize offset,
VkDeviceSize size, VkIndexType indexType)
{
SERIALISE_ELEMENT(commandBuffer);
SERIALISE_ELEMENT(buffer).Important();
SERIALISE_ELEMENT(offset).OffsetOrSize();
SERIALISE_ELEMENT(size).OffsetOrSize();
SERIALISE_ELEMENT(indexType).Important();

Serialise_DebugMessages(ser);

SERIALISE_CHECK_READ_ERRORS();

if(IsReplayingAndReading())
{
m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer));

if(IsActiveReplaying(m_State))
{
if(InRerecordRange(m_LastCmdBufferID))
{
commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
ObjDisp(commandBuffer)
->CmdBindIndexBuffer2KHR(Unwrap(commandBuffer), Unwrap(buffer), offset, size, indexType);

{
VulkanRenderState &renderstate = GetCmdRenderState();
renderstate.ibuffer.buf = GetResID(buffer);
renderstate.ibuffer.offs = offset;
renderstate.ibuffer.size = size;

if(indexType == VK_INDEX_TYPE_UINT32)
renderstate.ibuffer.bytewidth = 4;
else if(indexType == VK_INDEX_TYPE_UINT8_KHR)
renderstate.ibuffer.bytewidth = 1;
else
renderstate.ibuffer.bytewidth = 2;
}
}
}
else
{
// track while reading, as we need to bind current topology & index byte width in AddAction
if(indexType == VK_INDEX_TYPE_UINT32)
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.ibuffer.bytewidth = 4;
else if(indexType == VK_INDEX_TYPE_UINT8_KHR)
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.ibuffer.bytewidth = 1;
else
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.ibuffer.bytewidth = 2;

// track while reading, as we need to track resource usage
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.ibuffer.buf = GetResID(buffer);

ObjDisp(commandBuffer)
->CmdBindIndexBuffer2KHR(Unwrap(commandBuffer), Unwrap(buffer), offset, size, indexType);
}
}

return true;
}

void WrappedVulkan::vkCmdBindIndexBuffer2KHR(VkCommandBuffer commandBuffer, VkBuffer buffer,
VkDeviceSize offset, VkDeviceSize size,
VkIndexType indexType)
{
SCOPED_DBG_SINK();

SERIALISE_TIME_CALL(
ObjDisp(commandBuffer)
->CmdBindIndexBuffer2KHR(Unwrap(commandBuffer), Unwrap(buffer), offset, size, indexType));

if(IsCaptureMode(m_State))
{
VkResourceRecord *record = GetRecord(commandBuffer);

CACHE_THREAD_SERIALISER();

SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBindIndexBuffer2KHR);
Serialise_vkCmdBindIndexBuffer2KHR(ser, commandBuffer, buffer, offset, size, indexType);

record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkBufferFrameReferenced(GetRecord(buffer), 0, VK_WHOLE_SIZE, eFrameRef_Read);
}
}

template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkCmdPushConstants(SerialiserType &ser, VkCommandBuffer commandBuffer,
VkPipelineLayout layout,
Expand Down Expand Up @@ -7733,3 +7821,7 @@ INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBeginRendering, VkCommandBuffer comma
const VkRenderingInfo *pRenderingInfo);

INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdEndRendering, VkCommandBuffer commandBuffer);

INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBindIndexBuffer2KHR, VkCommandBuffer commandBuffer,
VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size,
VkIndexType indexType);
Loading

0 comments on commit 685bde6

Please sign in to comment.