update vulkan.h for multi-level command buffers (V121)
With minimal changes to keep everything building and functioning.
diff --git a/include/vkLayer.h b/include/vkLayer.h
index a1104db..6467354 100644
--- a/include/vkLayer.h
+++ b/include/vkLayer.h
@@ -122,6 +122,7 @@
PFN_vkCreateRenderPass CreateRenderPass;
PFN_vkCmdBeginRenderPass CmdBeginRenderPass;
PFN_vkCmdEndRenderPass CmdEndRenderPass;
+ PFN_vkCmdExecuteCommands CmdExecuteCommands;
PFN_vkCreateSwapChainWSI CreateSwapChainWSI;
PFN_vkDestroySwapChainWSI DestroySwapChainWSI;
PFN_vkGetSwapChainInfoWSI GetSwapChainInfoWSI;
diff --git a/include/vulkan.h b/include/vulkan.h
index 5444b1f..f4644f5 100644
--- a/include/vulkan.h
+++ b/include/vulkan.h
@@ -33,7 +33,7 @@
#include "vk_platform.h"
// Vulkan API version supported by this file
-#define VK_API_VERSION VK_MAKE_VERSION(0, 120, 0)
+#define VK_API_VERSION VK_MAKE_VERSION(0, 121, 0)
#ifdef __cplusplus
extern "C"
@@ -277,6 +277,14 @@
VK_ENUM_RANGE(TIMESTAMP_TYPE, TOP, BOTTOM)
} VkTimestampType;
+typedef enum VkRenderPassContents_
+{
+ VK_RENDER_PASS_CONTENTS_INLINE = 0x00000000,
+ VK_RENDER_PASS_CONTENTS_SECONDARY_CMD_BUFFERS = 0x00000001,
+
+ VK_ENUM_RANGE(RENDER_PASS_CONTENTS, INLINE, SECONDARY_CMD_BUFFERS)
+} VkRenderPassContents;
+
typedef enum VkBorderColor_
{
VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0x00000000,
@@ -324,6 +332,14 @@
VK_ENUM_RANGE(PRIMITIVE_TOPOLOGY, POINT_LIST, PATCH)
} VkPrimitiveTopology;
+typedef enum VkCmdBufferLevel_
+{
+ VK_CMD_BUFFER_LEVEL_PRIMARY = 0x00000000,
+ VK_CMD_BUFFER_LEVEL_SECONDARY = 0x00000001,
+
+ VK_ENUM_RANGE(CMD_BUFFER_LEVEL, PRIMARY, SECONDARY)
+} VkCmdBufferLevel;
+
typedef enum VkIndexType_
{
VK_INDEX_TYPE_UINT16 = 0x00000000,
@@ -760,7 +776,7 @@
VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 32,
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 33,
VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO = 34,
- VK_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO = 35,
+
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 36,
VK_STRUCTURE_TYPE_MEMORY_BARRIER = 37,
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 38,
@@ -1095,6 +1111,7 @@
VK_CMD_BUFFER_OPTIMIZE_PIPELINE_SWITCH_BIT = VK_BIT(1),
VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT = VK_BIT(2),
VK_CMD_BUFFER_OPTIMIZE_DESCRIPTOR_SET_SWITCH_BIT = VK_BIT(3),
+ VK_CMD_BUFFER_OPTIMIZE_NO_SIMULTANEOUS_USE_BIT = 0x00000010,
} VkCmdBufferOptimizeFlagBits;
// Pipeline statistics flags
@@ -1903,6 +1920,7 @@
VkStructureType sType; // Must be VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO
const void* pNext; // Pointer to next structure
uint32_t queueNodeIndex;
+ VkCmdBufferLevel level;
VkCmdBufferCreateFlags flags; // Command buffer creation flags
} VkCmdBufferCreateInfo;
@@ -1912,22 +1930,18 @@
const void* pNext; // Pointer to next structure
VkCmdBufferOptimizeFlags flags; // Command buffer optimization flags
+
+ VkRenderPass renderPass;
+ VkFramebuffer framebuffer;
} VkCmdBufferBeginInfo;
typedef struct VkRenderPassBegin_
{
VkRenderPass renderPass;
VkFramebuffer framebuffer;
+ VkRenderPassContents contents;
} VkRenderPassBegin;
-typedef struct VkCmdBufferGraphicsBeginInfo_
-{
- VkStructureType sType; // Must be VK_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO
- const void* pNext; // Pointer to next structure
-
- VkRenderPassBegin renderPassContinue; // Only needed when a render pass is split across two command buffers
-} VkCmdBufferGraphicsBeginInfo;
-
// Union allowing specification of floating point or raw color data. Actual value selected is based on image being cleared.
typedef union VkClearColorValue_
{
@@ -2147,7 +2161,8 @@
typedef VkResult (VKAPI *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, VkFramebuffer* pFramebuffer);
typedef VkResult (VKAPI *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass);
typedef void (VKAPI *PFN_vkCmdBeginRenderPass)(VkCmdBuffer cmdBuffer, const VkRenderPassBegin* pRenderPassBegin);
-typedef void (VKAPI *PFN_vkCmdEndRenderPass)(VkCmdBuffer cmdBuffer, VkRenderPass renderPass);
+typedef void (VKAPI *PFN_vkCmdEndRenderPass)(VkCmdBuffer cmdBuffer);
+typedef void (VKAPI *PFN_vkCmdExecuteCommands)(VkCmdBuffer cmdBuffer, uint32_t cmdBuffersCount, const VkCmdBuffer* pCmdBuffers);
#ifdef VK_PROTOTYPES
@@ -2809,8 +2824,12 @@
const VkRenderPassBegin* pRenderPassBegin);
void VKAPI vkCmdEndRenderPass(
+ VkCmdBuffer cmdBuffer);
+
+void VKAPI vkCmdExecuteCommands(
VkCmdBuffer cmdBuffer,
- VkRenderPass renderPass);
+ uint32_t cmdBuffersCount,
+ const VkCmdBuffer* pCmdBuffers);
#endif // VK_PROTOTYPES
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index 2d05e8d..b99a5b1 100644
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -2036,16 +2036,6 @@
if (CB_NEW != pCB->state)
resetCB(cmdBuffer);
pCB->state = CB_UPDATE_ACTIVE;
- if (pBeginInfo->pNext) {
- VkCmdBufferGraphicsBeginInfo* pCbGfxBI = (VkCmdBufferGraphicsBeginInfo*)pBeginInfo->pNext;
- if (VK_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO == pCbGfxBI->sType) {
- if (pCbGfxBI->renderPassContinue.renderPass)
- pCB->activeRenderPass = pCbGfxBI->renderPassContinue.renderPass;
- else
- log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_INVALID_RENDERPASS, "DS",
- "You cannot use a NULL RenderPass object in vkCmdBeginCommandBuffer()");
- }
- }
} else {
log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS",
"In vkBeginCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
@@ -2725,23 +2715,33 @@
}
}
-VK_LAYER_EXPORT void VKAPI vkCmdEndRenderPass(VkCmdBuffer cmdBuffer, VkRenderPass renderPass)
+VK_LAYER_EXPORT void VKAPI vkCmdEndRenderPass(VkCmdBuffer cmdBuffer)
{
GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
if (pCB) {
- if (renderPass) {
- if (!pCB->activeRenderPass) {
- log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
- "Incorrect call to vkCmdEndRenderPass() without an active RenderPass.");
- } else {
- updateCBTracking(cmdBuffer);
- addCmd(pCB, CMD_ENDRENDERPASS);
- pCB->activeRenderPass = 0;
- get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdEndRenderPass(cmdBuffer, renderPass);
- }
+ if (!pCB->activeRenderPass) {
+ log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
+ "Incorrect call to vkCmdEndRenderPass() without an active RenderPass.");
} else {
- log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_INVALID_RENDERPASS, "DS",
- "You cannot use a NULL RenderPass object in vkCmdEndRenderPass()");
+ updateCBTracking(cmdBuffer);
+ addCmd(pCB, CMD_ENDRENDERPASS);
+ pCB->activeRenderPass = 0;
+ get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdEndRenderPass(cmdBuffer);
+ }
+ }
+}
+
+VK_LAYER_EXPORT void VKAPI vkCmdExecuteCommands(VkCmdBuffer cmdBuffer, uint32_t cmdBuffersCount, const VkCmdBuffer* pCmdBuffers)
+{
+ GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
+ if (pCB) {
+ if (!pCB->activeRenderPass) {
+ log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
+ "Incorrect call to vkCmdExecuteCommands() without an active RenderPass.");
+ } else {
+ updateCBTracking(cmdBuffer);
+ addCmd(pCB, CMD_EXECUTECOMMANDS);
+ get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdExecuteCommands(cmdBuffer, cmdBuffersCount, pCmdBuffers);
}
}
}
@@ -2984,6 +2984,8 @@
return (void*) vkCmdBeginRenderPass;
if (!strcmp(funcName, "vkCmdEndRenderPass"))
return (void*) vkCmdEndRenderPass;
+ if (!strcmp(funcName, "vkCmdExecuteCommands"))
+ return (void*) vkCmdExecuteCommands;
if (!strcmp("drawStateDumpDotFile", funcName))
return (void*) drawStateDumpDotFile;
if (!strcmp("drawStateDumpCommandBufferDotFile", funcName))
diff --git a/layers/draw_state.h b/layers/draw_state.h
index 6f8f016..c46a28a 100644
--- a/layers/draw_state.h
+++ b/layers/draw_state.h
@@ -211,6 +211,7 @@
CMD_SAVEATOMICCOUNTERS,
CMD_BEGINRENDERPASS,
CMD_ENDRENDERPASS,
+ CMD_EXECUTECOMMANDS,
CMD_DBGMARKERBEGIN,
CMD_DBGMARKEREND,
} CMD_TYPE;
diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp
index 95710f6..9b92526 100644
--- a/layers/param_checker.cpp
+++ b/layers/param_checker.cpp
@@ -9476,8 +9476,7 @@
}
void PostCmdEndRenderPass(
- VkCmdBuffer cmdBuffer,
- VkRenderPass renderPass)
+ VkCmdBuffer cmdBuffer)
{
if(cmdBuffer == nullptr)
{
@@ -9485,23 +9484,48 @@
"vkCmdEndRenderPass parameter, VkCmdBuffer cmdBuffer, is null pointer");
return;
}
+}
- if(renderPass == nullptr)
+void PreCmdExecuteCommands(
+ VkCmdBuffer cmdBuffer)
+{
+ if(cmdBuffer == nullptr)
{
log_msg(mdd(cmdBuffer), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK",
- "vkCmdEndRenderPass parameter, VkRenderPass renderPass, is null pointer");
+ "vkCmdExecuteCommands parameter, VkCmdBuffer cmdBuffer, is null pointer");
+ return;
+ }
+}
+
+void PostCmdExecuteCommands(
+ VkCmdBuffer cmdBuffer)
+{
+ if(cmdBuffer == nullptr)
+ {
+ log_msg(mdd(cmdBuffer), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK",
+ "vkCmdExecuteCommands parameter, VkCmdBuffer cmdBuffer, is null pointer");
return;
}
}
VK_LAYER_EXPORT void VKAPI vkCmdEndRenderPass(
- VkCmdBuffer cmdBuffer,
- VkRenderPass renderPass)
+ VkCmdBuffer cmdBuffer)
{
PreCmdEndRenderPass(cmdBuffer);
- get_dispatch_table(pc_device_table_map, cmdBuffer)->CmdEndRenderPass(cmdBuffer, renderPass);
+ get_dispatch_table(pc_device_table_map, cmdBuffer)->CmdEndRenderPass(cmdBuffer);
- PostCmdEndRenderPass(cmdBuffer, renderPass);
+ PostCmdEndRenderPass(cmdBuffer);
+}
+
+VK_LAYER_EXPORT void VKAPI vkCmdExecuteCommands(
+ VkCmdBuffer cmdBuffer,
+ uint32_t cmdBuffersCount,
+ const VkCmdBuffer* pCmdBuffers)
+{
+ PreCmdExecuteCommands(cmdBuffer);
+ get_dispatch_table(pc_device_table_map, cmdBuffer)->CmdExecuteCommands(cmdBuffer, cmdBuffersCount, pCmdBuffers);
+
+ PostCmdExecuteCommands(cmdBuffer);
}
VK_LAYER_EXPORT void* VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
@@ -9694,6 +9718,8 @@
return (void*) vkCmdBeginRenderPass;
if (!strcmp(funcName, "vkCmdEndRenderPass"))
return (void*) vkCmdEndRenderPass;
+ if (!strcmp(funcName, "vkCmdExecuteCommands"))
+ return (void*) vkCmdExecuteCommands;
if (!strcmp(funcName, "vkGetGlobalExtensionCount"))
return (void*) vkGetGlobalExtensionCount;
if (!strcmp(funcName, "vkGetGlobalExtensionProperties"))
diff --git a/layers/screenshot.cpp b/layers/screenshot.cpp
index 313bb72..8a968e6 100644
--- a/layers/screenshot.cpp
+++ b/layers/screenshot.cpp
@@ -144,6 +144,7 @@
VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
NULL,
deviceMap[device]->queueNodeIndex,
+ VK_CMD_BUFFER_LEVEL_PRIMARY,
0
};
const VkCmdBufferBeginInfo cmdBufferBeginInfo = {
diff --git a/loader/table_ops.h b/loader/table_ops.h
index 9a523f3..52cb9c1 100644
--- a/loader/table_ops.h
+++ b/loader/table_ops.h
@@ -131,6 +131,7 @@
table->CreateRenderPass = (PFN_vkCreateRenderPass) gpa(dev, "vkCreateRenderPass");
table->CmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) gpa(dev, "vkCmdBeginRenderPass");
table->CmdEndRenderPass = (PFN_vkCmdEndRenderPass) gpa(dev, "vkCmdEndRenderPass");
+ table->CmdExecuteCommands = (PFN_vkCmdExecuteCommands) gpa(dev, "vkCmdExecuteCommands");
//TODO move into it's own table
//TODO also consider dropping trampoline code for these device level extensions entirely
// then don't need loader to know about these at all but then not queryable via GIPA
diff --git a/loader/trampoline.c b/loader/trampoline.c
index 5a47172..242f04e 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -1125,11 +1125,20 @@
disp->CmdBeginRenderPass(cmdBuffer, pRenderPassBegin);
}
-LOADER_EXPORT void VKAPI vkCmdEndRenderPass(VkCmdBuffer cmdBuffer, VkRenderPass renderPass)
+LOADER_EXPORT void VKAPI vkCmdEndRenderPass(VkCmdBuffer cmdBuffer)
{
const VkLayerDispatchTable *disp;
disp = loader_get_dispatch(cmdBuffer);
- disp->CmdEndRenderPass(cmdBuffer, renderPass);
+ disp->CmdEndRenderPass(cmdBuffer);
+}
+
+LOADER_EXPORT void VKAPI vkCmdExecuteCommands(VkCmdBuffer cmdBuffer, uint32_t cmdBuffersCount, const VkCmdBuffer* pCmdBuffers)
+{
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(cmdBuffer);
+
+ disp->CmdExecuteCommands(cmdBuffer, cmdBuffersCount, pCmdBuffers);
}
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index 59acc4f..4b8addb 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -211,7 +211,7 @@
VkResult result;
if (renderPass()) {
- cmdBuffer.EndRenderPass(renderPass());
+ cmdBuffer.EndRenderPass();
}
result = cmdBuffer.EndCommandBuffer();
diff --git a/tests/render_tests.cpp b/tests/render_tests.cpp
index 6aef6d0..b456ace 100644
--- a/tests/render_tests.cpp
+++ b/tests/render_tests.cpp
@@ -326,7 +326,7 @@
VkResult result;
if (renderPass()) {
- cmdBuffer.EndRenderPass(renderPass());
+ cmdBuffer.EndRenderPass();
}
result = cmdBuffer.EndCommandBuffer();
diff --git a/tests/vkrenderframework.cpp b/tests/vkrenderframework.cpp
index 126cd5e..545b904 100644
--- a/tests/vkrenderframework.cpp
+++ b/tests/vkrenderframework.cpp
@@ -1256,12 +1256,6 @@
return VK_SUCCESS;
}
-VkResult VkCommandBufferObj::BeginCommandBuffer(VkRenderPass renderpass_obj, VkFramebuffer framebuffer_obj)
-{
- begin(renderpass_obj, framebuffer_obj);
- return VK_SUCCESS;
-}
-
VkResult VkCommandBufferObj::BeginCommandBuffer()
{
begin();
@@ -1411,9 +1405,9 @@
vkCmdBeginRenderPass( obj(), &rp_begin);
}
-void VkCommandBufferObj::EndRenderPass(VkRenderPass renderpass)
+void VkCommandBufferObj::EndRenderPass()
{
- vkCmdEndRenderPass( obj(), renderpass);
+ vkCmdEndRenderPass(obj());
}
void VkCommandBufferObj::BindStateObject(VkStateBindPoint stateBindPoint, VkDynamicStateObject stateObject)
diff --git a/tests/vkrenderframework.h b/tests/vkrenderframework.h
index 0a57918..715648f 100644
--- a/tests/vkrenderframework.h
+++ b/tests/vkrenderframework.h
@@ -167,7 +167,6 @@
VkCmdBuffer GetBufferHandle();
VkResult BeginCommandBuffer();
VkResult BeginCommandBuffer(VkCmdBufferBeginInfo *pInfo);
- VkResult BeginCommandBuffer(VkRenderPass renderpass_obj, VkFramebuffer framebuffer_obj);
VkResult EndCommandBuffer();
void PipelineBarrier(VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages, bool32_t byRegion, uint32_t memBarrierCount, const void** ppMemBarriers);
void AddRenderTarget(VkImageObj *renderTarget);
@@ -183,7 +182,7 @@
void BindIndexBuffer(VkIndexBufferObj *indexBuffer, uint32_t offset);
void BindStateObject(VkStateBindPoint stateBindPoint, VkDynamicStateObject stateObject);
void BeginRenderPass(VkRenderPass renderpass, VkFramebuffer framebuffer);
- void EndRenderPass(VkRenderPass renderpass);
+ void EndRenderPass();
void Draw(uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount);
void DrawIndexed(uint32_t firstIndex, uint32_t indexCount, int32_t vertexOffset, uint32_t firstInstance, uint32_t instanceCount);
void QueueCommandBuffer();
diff --git a/tests/vktestbinding.cpp b/tests/vktestbinding.cpp
index d6b78fc..8eedac0 100644
--- a/tests/vktestbinding.cpp
+++ b/tests/vktestbinding.cpp
@@ -880,23 +880,6 @@
EXPECT(vkBeginCommandBuffer(obj(), info) == VK_SUCCESS);
}
-void CmdBuffer::begin(VkRenderPass renderpass_obj, VkFramebuffer framebuffer_obj)
-{
- VkCmdBufferBeginInfo info = {};
- VkCmdBufferGraphicsBeginInfo graphics_cmd_buf_info = {};
- graphics_cmd_buf_info.sType = VK_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO;
- graphics_cmd_buf_info.pNext = NULL;
- graphics_cmd_buf_info.renderPassContinue.renderPass = renderpass_obj;
- graphics_cmd_buf_info.renderPassContinue.framebuffer = framebuffer_obj;
-
- info.flags = VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT |
- VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT;
- info.sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO;
- info.pNext = &graphics_cmd_buf_info;
-
- begin(&info);
-}
-
void CmdBuffer::begin()
{
VkCmdBufferBeginInfo info = {};
diff --git a/tests/vktestbinding.h b/tests/vktestbinding.h
index efb640f..e56c79c 100644
--- a/tests/vktestbinding.h
+++ b/tests/vktestbinding.h
@@ -598,7 +598,6 @@
// vkBeginCommandBuffer()
void begin(const VkCmdBufferBeginInfo *info);
- void begin(VkRenderPass renderpass_obj, VkFramebuffer framebuffer_obj);
void begin();
// vkEndCommandBuffer()
diff --git a/vulkan.py b/vulkan.py
index 5f46856..95ad639 100755
--- a/vulkan.py
+++ b/vulkan.py
@@ -831,8 +831,12 @@
Param("const VkRenderPassBegin*", "pRenderPassBegin")]),
Proto("void", "CmdEndRenderPass",
+ [Param("VkCmdBuffer", "cmdBuffer")]),
+
+ Proto("void", "CmdExecuteCommands",
[Param("VkCmdBuffer", "cmdBuffer"),
- Param("VkRenderPass", "renderPass")]),
+ Param("uint32_t", "cmdBuffersCount"),
+ Param("const VkCmdBuffer*", "pCmdBuffers")]),
],
)