mirror of
https://projects.blender.org/blender/blender.git
synced 2025-01-22 07:22:12 -05:00
Refactor: Vulkan: Store large data in separate vectors
VKRenderGraphNode is 892 bytes and most of the bytes are used for specific nodes. By storing large structs in separate vectors we can reduce the needed memory and improve cache pre-fetching. With this change the VKRenderGraphNode is reduced to 64 bytes. On a (50 frames shader_balls.blend) the end user performance is improved by 2%. | **Platform** | **Before** | **After** | | ---------------- | ---------- | --------- | | AMD W7700 | 1409 ms | 1383 ms | | NVIDIA RTX 6000 | 1443 ms | 1428 ms | Pull Request: https://projects.blender.org/blender/blender/pulls/133317
This commit is contained in:
parent
2114620c28
commit
ff804882bd
28 changed files with 160 additions and 75 deletions
|
@ -41,7 +41,8 @@ class VKBeginQueryNode : public VKNodeInfo<VKNodeType::BEGIN_QUERY,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
void set_node_data(Node &node, Storage & /* storage */, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.begin_query = create_info;
|
node.begin_query = create_info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,8 @@ class VKBeginRenderingNode : public VKNodeInfo<VKNodeType::BEGIN_RENDERING,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
void set_node_data(Node &node, Storage &storage, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
const bool use_render_pass = create_info.node_data.vk_render_pass_begin_info.renderPass !=
|
const bool use_render_pass = create_info.node_data.vk_render_pass_begin_info.renderPass !=
|
||||||
VK_NULL_HANDLE;
|
VK_NULL_HANDLE;
|
||||||
|
@ -73,7 +74,7 @@ class VKBeginRenderingNode : public VKNodeInfo<VKNodeType::BEGIN_RENDERING,
|
||||||
&create_info.node_data.stencil_attachment),
|
&create_info.node_data.stencil_attachment),
|
||||||
"When create_info.node_data.vk_rendering_info.pStencilAttachment points to "
|
"When create_info.node_data.vk_rendering_info.pStencilAttachment points to "
|
||||||
"something, it should point to create_info.node_data.stencil_attachment.");
|
"something, it should point to create_info.node_data.stencil_attachment.");
|
||||||
node.begin_rendering = create_info.node_data;
|
node.storage_index = storage.begin_rendering.append_and_get_index(create_info.node_data);
|
||||||
/* NOTE: pointers in vk_rendering_info will be set to the correct location just before sending
|
/* NOTE: pointers in vk_rendering_info will be set to the correct location just before sending
|
||||||
* to the command buffer. In the meantime these pointers are invalid.
|
* to the command buffer. In the meantime these pointers are invalid.
|
||||||
* VKRenderingAttachmentInfo's should be used instead. */
|
* VKRenderingAttachmentInfo's should be used instead. */
|
||||||
|
|
|
@ -42,9 +42,10 @@ class VKBlitImageNode : public VKNodeInfo<VKNodeType::BLIT_IMAGE,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
void set_node_data(Node &node, Storage &storage, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.blit_image = create_info;
|
node.storage_index = storage.blit_image.append_and_get_index(create_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -37,9 +37,10 @@ class VKClearAttachmentsNode : public VKNodeInfo<VKNodeType::CLEAR_ATTACHMENTS,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
void set_node_data(Node &node, Storage &storage, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.clear_attachments = create_info;
|
node.storage_index = storage.clear_attachments.append_and_get_index(create_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,7 +34,8 @@ class VKClearColorImageNode : public VKNodeInfo<VKNodeType::CLEAR_COLOR_IMAGE,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
void set_node_data(Node &node, Storage & /* storage */, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.clear_color_image = create_info;
|
node.clear_color_image = create_info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,8 @@ class VKClearDepthStencilImageNode : public VKNodeInfo<VKNodeType::CLEAR_DEPTH_S
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage & /* storage */, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.clear_depth_stencil_image = create_info.node_data;
|
node.clear_depth_stencil_image = create_info.node_data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,8 @@ class VKCopyBufferNode : public VKNodeInfo<VKNodeType::COPY_BUFFER,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage & /* storage */, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.copy_buffer = create_info;
|
node.copy_buffer = create_info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,9 +38,10 @@ class VKCopyBufferToImageNode : public VKNodeInfo<VKNodeType::COPY_BUFFER_TO_IMA
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage &storage, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.copy_buffer_to_image = create_info.node_data;
|
node.storage_index = storage.copy_buffer_to_image.append_and_get_index(create_info.node_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -42,9 +42,10 @@ class VKCopyImageNode : public VKNodeInfo<VKNodeType::COPY_IMAGE,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage &storage, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.copy_image = create_info.node_data;
|
node.storage_index = storage.copy_image.append_and_get_index(create_info.node_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -42,9 +42,10 @@ class VKCopyImageToBufferNode : public VKNodeInfo<VKNodeType::COPY_IMAGE_TO_BUFF
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage &storage, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.copy_image_to_buffer = create_info.node_data;
|
node.storage_index = storage.copy_image_to_buffer.append_and_get_index(create_info.node_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -49,7 +49,8 @@ class VKDispatchIndirectNode
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage & /* storage */, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.dispatch_indirect = create_info.dispatch_indirect_node;
|
node.dispatch_indirect = create_info.dispatch_indirect_node;
|
||||||
vk_pipeline_data_copy(node.dispatch_indirect.pipeline_data,
|
vk_pipeline_data_copy(node.dispatch_indirect.pipeline_data,
|
||||||
|
|
|
@ -45,7 +45,8 @@ class VKDispatchNode : public VKNodeInfo<VKNodeType::DISPATCH,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage & /* storage */, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.dispatch = create_info.dispatch_node;
|
node.dispatch = create_info.dispatch_node;
|
||||||
vk_pipeline_data_copy(node.dispatch.pipeline_data, create_info.dispatch_node.pipeline_data);
|
vk_pipeline_data_copy(node.dispatch.pipeline_data, create_info.dispatch_node.pipeline_data);
|
||||||
|
|
|
@ -46,10 +46,11 @@ class VKDrawIndexedIndirectNode
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage &storage, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.draw_indexed_indirect = create_info.node_data;
|
node.storage_index = storage.draw_indexed_indirect.append_and_get_index(create_info.node_data);
|
||||||
vk_pipeline_data_copy(node.draw_indexed_indirect.pipeline_data,
|
vk_pipeline_data_copy(storage.draw_indexed_indirect[node.storage_index].pipeline_data,
|
||||||
create_info.node_data.pipeline_data);
|
create_info.node_data.pipeline_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,10 +46,12 @@ class VKDrawIndexedNode : public VKNodeInfo<VKNodeType::DRAW_INDEXED,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage &storage, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.draw_indexed = create_info.node_data;
|
node.storage_index = storage.draw_indexed.append_and_get_index(create_info.node_data);
|
||||||
vk_pipeline_data_copy(node.draw_indexed.pipeline_data, create_info.node_data.pipeline_data);
|
vk_pipeline_data_copy(storage.draw_indexed[node.storage_index].pipeline_data,
|
||||||
|
create_info.node_data.pipeline_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -44,10 +44,12 @@ class VKDrawIndirectNode : public VKNodeInfo<VKNodeType::DRAW_INDIRECT,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage &storage, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.draw_indirect = create_info.node_data;
|
node.storage_index = storage.draw_indirect.append_and_get_index(create_info.node_data);
|
||||||
vk_pipeline_data_copy(node.draw_indirect.pipeline_data, create_info.node_data.pipeline_data);
|
vk_pipeline_data_copy(storage.draw_indirect[node.storage_index].pipeline_data,
|
||||||
|
create_info.node_data.pipeline_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -44,10 +44,12 @@ class VKDrawNode : public VKNodeInfo<VKNodeType::DRAW,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage &storage, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.draw = create_info.node_data;
|
node.storage_index = storage.draw.append_and_get_index(create_info.node_data);
|
||||||
vk_pipeline_data_copy(node.draw.pipeline_data, create_info.node_data.pipeline_data);
|
vk_pipeline_data_copy(storage.draw[node.storage_index].pipeline_data,
|
||||||
|
create_info.node_data.pipeline_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -40,7 +40,8 @@ class VKEndQueryNode : public VKNodeInfo<VKNodeType::END_QUERY,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
void set_node_data(Node &node, Storage & /*storage*/, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.end_query = create_info;
|
node.end_query = create_info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,8 @@ class VKEndRenderingNode : public VKNodeInfo<VKNodeType::END_RENDERING,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
void set_node_data(Node &node, Storage & /*storage*/, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.end_rendering = create_info;
|
node.end_rendering = create_info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,8 @@ class VKFillBufferNode : public VKNodeInfo<VKNodeType::FILL_BUFFER,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage & /* storage */, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.fill_buffer = create_info;
|
node.fill_buffer = create_info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,8 @@ class VKNodeInfo : public NonCopyable {
|
||||||
* This function must be implemented by all node classes. But due to cyclic inclusion of header
|
* This function must be implemented by all node classes. But due to cyclic inclusion of header
|
||||||
* files it is implemented as a template function.
|
* files it is implemented as a template function.
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info);
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage & /* storage */, const CreateInfo &create_info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract read/write resource dependencies from `create_info` and add them to `node_links`.
|
* Extract read/write resource dependencies from `create_info` and add them to `node_links`.
|
||||||
|
|
|
@ -41,7 +41,8 @@ class VKResetQueryPoolNode : public VKNodeInfo<VKNodeType::RESET_QUERY_POOL,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
void set_node_data(Node &node, Storage & /*storage*/, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.reset_query_pool = create_info;
|
node.reset_query_pool = create_info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ class VKSynchronizationNode : public VKNodeInfo<VKNodeType::SYNCHRONIZATION,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage & /* storage */, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
UNUSED_VARS(create_info);
|
UNUSED_VARS(create_info);
|
||||||
node.synchronization = {};
|
node.synchronization = {};
|
||||||
|
|
|
@ -34,7 +34,8 @@ class VKUpdateBufferNode : public VKNodeInfo<VKNodeType::UPDATE_BUFFER,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
static void set_node_data(Node &node, Storage & /* storage */, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.update_buffer = create_info;
|
node.update_buffer = create_info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,8 @@ class VKUpdateMipmapsNode : public VKNodeInfo<VKNodeType::UPDATE_MIPMAPS,
|
||||||
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
* (`VK*Data`/`VK*CreateInfo`) types can be included in the same header file as the logic. The
|
||||||
* actual node data (`VKRenderGraphNode` includes all header files.)
|
* actual node data (`VKRenderGraphNode` includes all header files.)
|
||||||
*/
|
*/
|
||||||
template<typename Node> void set_node_data(Node &node, const CreateInfo &create_info)
|
template<typename Node, typename Storage>
|
||||||
|
void set_node_data(Node &node, Storage & /*storage*/, const CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
node.update_mipmaps = create_info;
|
node.update_mipmaps = create_info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,7 +265,8 @@ void VKCommandBuilder::groups_build_commands(VKRenderGraph &render_graph,
|
||||||
const VKRenderGraphNode &last_node = render_graph.nodes_[group_node_handles.last()];
|
const VKRenderGraphNode &last_node = render_graph.nodes_[group_node_handles.last()];
|
||||||
bool will_be_suspended = last_node.type != VKNodeType::END_RENDERING;
|
bool will_be_suspended = last_node.type != VKNodeType::END_RENDERING;
|
||||||
if (will_be_suspended) {
|
if (will_be_suspended) {
|
||||||
node.begin_rendering.vk_rendering_info.flags = VK_RENDERING_SUSPENDING_BIT;
|
render_graph.storage_.begin_rendering[node.storage_index].vk_rendering_info.flags =
|
||||||
|
VK_RENDERING_SUSPENDING_BIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,8 +277,9 @@ void VKCommandBuilder::groups_build_commands(VKRenderGraph &render_graph,
|
||||||
if (!rendering_active) {
|
if (!rendering_active) {
|
||||||
/* Resume rendering scope. */
|
/* Resume rendering scope. */
|
||||||
VKRenderGraphNode &rendering_node = render_graph.nodes_[rendering_scope];
|
VKRenderGraphNode &rendering_node = render_graph.nodes_[rendering_scope];
|
||||||
rendering_node.begin_rendering.vk_rendering_info.flags = VK_RENDERING_RESUMING_BIT;
|
render_graph.storage_.begin_rendering[rendering_node.storage_index]
|
||||||
rendering_node.build_commands(command_buffer, active_pipelines);
|
.vk_rendering_info.flags = VK_RENDERING_RESUMING_BIT;
|
||||||
|
rendering_node.build_commands(command_buffer, render_graph.storage_, active_pipelines);
|
||||||
rendering_active = true;
|
rendering_active = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,7 +304,7 @@ void VKCommandBuilder::groups_build_commands(VKRenderGraph &render_graph,
|
||||||
<< ", node_type=" << node.type
|
<< ", node_type=" << node.type
|
||||||
<< ", debug group=" << render_graph.full_debug_group(node_handle) << "\n";
|
<< ", debug group=" << render_graph.full_debug_group(node_handle) << "\n";
|
||||||
#endif
|
#endif
|
||||||
node.build_commands(command_buffer, active_pipelines);
|
node.build_commands(command_buffer, render_graph.storage_, active_pipelines);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rendering_active) {
|
if (rendering_active) {
|
||||||
|
@ -317,7 +319,8 @@ void VKCommandBuilder::groups_build_commands(VKRenderGraph &render_graph,
|
||||||
}
|
}
|
||||||
|
|
||||||
VKRenderGraphNode &rendering_node = render_graph.nodes_[rendering_scope];
|
VKRenderGraphNode &rendering_node = render_graph.nodes_[rendering_scope];
|
||||||
rendering_node.begin_rendering.vk_rendering_info.flags = VK_RENDERING_RESUMING_BIT;
|
render_graph.storage_.begin_rendering[rendering_node.storage_index].vk_rendering_info.flags =
|
||||||
|
VK_RENDERING_RESUMING_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record group post barriers. */
|
/* Record group post barriers. */
|
||||||
|
|
|
@ -29,9 +29,10 @@ void VKRenderGraph::remove_nodes(Span<NodeHandle> node_handles)
|
||||||
"needs to be fixed when implementing a better scheduler.");
|
"needs to be fixed when implementing a better scheduler.");
|
||||||
links_.clear();
|
links_.clear();
|
||||||
for (VKRenderGraphNode &node : nodes_) {
|
for (VKRenderGraphNode &node : nodes_) {
|
||||||
node.free_data();
|
node.free_data(storage_);
|
||||||
}
|
}
|
||||||
nodes_.clear();
|
nodes_.clear();
|
||||||
|
storage_.reset();
|
||||||
|
|
||||||
debug_.node_group_map.clear();
|
debug_.node_group_map.clear();
|
||||||
debug_.used_groups.clear();
|
debug_.used_groups.clear();
|
||||||
|
|
|
@ -72,6 +72,9 @@ class VKRenderGraph : public NonCopyable {
|
||||||
Vector<VKRenderGraphNodeLinks> links_;
|
Vector<VKRenderGraphNodeLinks> links_;
|
||||||
/** All nodes inside the graph indexable via NodeHandle. */
|
/** All nodes inside the graph indexable via NodeHandle. */
|
||||||
Vector<VKRenderGraphNode> nodes_;
|
Vector<VKRenderGraphNode> nodes_;
|
||||||
|
/** Storage for large node datas to improve CPU cache pre-loading. */
|
||||||
|
VKRenderGraphStorage storage_;
|
||||||
|
|
||||||
/** Scheduler decides which nodes to select and in what order to execute them. */
|
/** Scheduler decides which nodes to select and in what order to execute them. */
|
||||||
VKScheduler scheduler_;
|
VKScheduler scheduler_;
|
||||||
/**
|
/**
|
||||||
|
@ -164,7 +167,7 @@ class VKRenderGraph : public NonCopyable {
|
||||||
links_.resize(nodes_.size());
|
links_.resize(nodes_.size());
|
||||||
}
|
}
|
||||||
VKRenderGraphNode &node = nodes_[node_handle];
|
VKRenderGraphNode &node = nodes_[node_handle];
|
||||||
node.set_node_data<NodeInfo>(create_info);
|
node.set_node_data<NodeInfo>(storage_, create_info);
|
||||||
|
|
||||||
VKRenderGraphNodeLinks &node_links = links_[node_handle];
|
VKRenderGraphNodeLinks &node_links = links_[node_handle];
|
||||||
BLI_assert(node_links.inputs.is_empty());
|
BLI_assert(node_links.inputs.is_empty());
|
||||||
|
|
|
@ -39,6 +39,41 @@ namespace blender::gpu::render_graph {
|
||||||
*/
|
*/
|
||||||
using NodeHandle = uint64_t;
|
using NodeHandle = uint64_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Node storage for nodes that uses large data structs.
|
||||||
|
*
|
||||||
|
* Some node structs are to large to store them as part of the node. The data are stored as a
|
||||||
|
* vector of structs. Typically structs that occupy more than one cache line (64 bytes) should be
|
||||||
|
* considered to be moved here.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct VKRenderGraphStorage {
|
||||||
|
Vector<VKBeginRenderingNode::Data> begin_rendering;
|
||||||
|
Vector<VKClearAttachmentsNode::Data> clear_attachments;
|
||||||
|
Vector<VKBlitImageNode::Data> blit_image;
|
||||||
|
Vector<VKCopyBufferToImageNode::Data> copy_buffer_to_image;
|
||||||
|
Vector<VKCopyImageNode::Data> copy_image;
|
||||||
|
Vector<VKCopyImageToBufferNode::Data> copy_image_to_buffer;
|
||||||
|
Vector<VKDrawNode::Data> draw;
|
||||||
|
Vector<VKDrawIndexedNode::Data> draw_indexed;
|
||||||
|
Vector<VKDrawIndexedIndirectNode::Data> draw_indexed_indirect;
|
||||||
|
Vector<VKDrawIndirectNode::Data> draw_indirect;
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
begin_rendering.clear();
|
||||||
|
clear_attachments.clear();
|
||||||
|
blit_image.clear();
|
||||||
|
copy_buffer_to_image.clear();
|
||||||
|
copy_image.clear();
|
||||||
|
copy_image_to_buffer.clear();
|
||||||
|
draw.clear();
|
||||||
|
draw_indexed.clear();
|
||||||
|
draw_indexed_indirect.clear();
|
||||||
|
draw_indirect.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node stored inside a render graph.
|
* Node stored inside a render graph.
|
||||||
*
|
*
|
||||||
|
@ -50,21 +85,11 @@ struct VKRenderGraphNode {
|
||||||
VKNodeType type;
|
VKNodeType type;
|
||||||
union {
|
union {
|
||||||
VKBeginQueryNode::Data begin_query;
|
VKBeginQueryNode::Data begin_query;
|
||||||
VKBeginRenderingNode::Data begin_rendering;
|
|
||||||
VKBlitImageNode::Data blit_image;
|
|
||||||
VKClearAttachmentsNode::Data clear_attachments;
|
|
||||||
VKClearColorImageNode::Data clear_color_image;
|
VKClearColorImageNode::Data clear_color_image;
|
||||||
VKClearDepthStencilImageNode::Data clear_depth_stencil_image;
|
VKClearDepthStencilImageNode::Data clear_depth_stencil_image;
|
||||||
VKCopyBufferNode::Data copy_buffer;
|
VKCopyBufferNode::Data copy_buffer;
|
||||||
VKCopyBufferToImageNode::Data copy_buffer_to_image;
|
|
||||||
VKCopyImageNode::Data copy_image;
|
|
||||||
VKCopyImageToBufferNode::Data copy_image_to_buffer;
|
|
||||||
VKDispatchNode::Data dispatch;
|
VKDispatchNode::Data dispatch;
|
||||||
VKDispatchIndirectNode::Data dispatch_indirect;
|
VKDispatchIndirectNode::Data dispatch_indirect;
|
||||||
VKDrawNode::Data draw;
|
|
||||||
VKDrawIndexedNode::Data draw_indexed;
|
|
||||||
VKDrawIndexedIndirectNode::Data draw_indexed_indirect;
|
|
||||||
VKDrawIndirectNode::Data draw_indirect;
|
|
||||||
VKEndQueryNode::Data end_query;
|
VKEndQueryNode::Data end_query;
|
||||||
VKEndRenderingNode::Data end_rendering;
|
VKEndRenderingNode::Data end_rendering;
|
||||||
VKFillBufferNode::Data fill_buffer;
|
VKFillBufferNode::Data fill_buffer;
|
||||||
|
@ -72,6 +97,7 @@ struct VKRenderGraphNode {
|
||||||
VKSynchronizationNode::Data synchronization;
|
VKSynchronizationNode::Data synchronization;
|
||||||
VKUpdateBufferNode::Data update_buffer;
|
VKUpdateBufferNode::Data update_buffer;
|
||||||
VKUpdateMipmapsNode::Data update_mipmaps;
|
VKUpdateMipmapsNode::Data update_mipmaps;
|
||||||
|
int64_t storage_index = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,14 +108,16 @@ struct VKRenderGraphNode {
|
||||||
* between consecutive use. Checking for unused node types will ensure that previous usage has
|
* between consecutive use. Checking for unused node types will ensure that previous usage has
|
||||||
* been reset. Resetting is done as part of `free_data`
|
* been reset. Resetting is done as part of `free_data`
|
||||||
*/
|
*/
|
||||||
template<typename NodeInfo> void set_node_data(const typename NodeInfo::CreateInfo &create_info)
|
template<typename NodeInfo>
|
||||||
|
void set_node_data(VKRenderGraphStorage &storage,
|
||||||
|
const typename NodeInfo::CreateInfo &create_info)
|
||||||
{
|
{
|
||||||
BLI_assert(type == VKNodeType::UNUSED);
|
BLI_assert(type == VKNodeType::UNUSED);
|
||||||
/* Instance of NodeInfo is needed to call virtual methods. CPP doesn't support overloading of
|
/* Instance of NodeInfo is needed to call virtual methods. CPP doesn't support overloading of
|
||||||
* static methods. */
|
* static methods. */
|
||||||
NodeInfo node_info;
|
NodeInfo node_info;
|
||||||
type = NodeInfo::node_type;
|
type = NodeInfo::node_type;
|
||||||
node_info.set_node_data(*this, create_info);
|
node_info.set_node_data(*this, storage, create_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,12 +204,21 @@ struct VKRenderGraphNode {
|
||||||
* `VKCommandBuilder::build_node` and `VKCommandBuilder::build_pipeline_barriers.
|
* `VKCommandBuilder::build_node` and `VKCommandBuilder::build_pipeline_barriers.
|
||||||
*/
|
*/
|
||||||
void build_commands(VKCommandBufferInterface &command_buffer,
|
void build_commands(VKCommandBufferInterface &command_buffer,
|
||||||
|
VKRenderGraphStorage &storage,
|
||||||
VKBoundPipelines &r_bound_pipelines)
|
VKBoundPipelines &r_bound_pipelines)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VKNodeType::UNUSED: {
|
case VKNodeType::UNUSED: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#define BUILD_COMMANDS_STORAGE(NODE_TYPE, NODE_CLASS, ATTRIBUTE_NAME) \
|
||||||
|
case NODE_TYPE: { \
|
||||||
|
NODE_CLASS node_info; \
|
||||||
|
node_info.build_commands( \
|
||||||
|
command_buffer, storage.ATTRIBUTE_NAME[storage_index], r_bound_pipelines); \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
#define BUILD_COMMANDS(NODE_TYPE, NODE_CLASS, ATTRIBUTE_NAME) \
|
#define BUILD_COMMANDS(NODE_TYPE, NODE_CLASS, ATTRIBUTE_NAME) \
|
||||||
case NODE_TYPE: { \
|
case NODE_TYPE: { \
|
||||||
NODE_CLASS node_info; \
|
NODE_CLASS node_info; \
|
||||||
|
@ -190,8 +227,9 @@ struct VKRenderGraphNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
BUILD_COMMANDS(VKNodeType::BEGIN_QUERY, VKBeginQueryNode, begin_query)
|
BUILD_COMMANDS(VKNodeType::BEGIN_QUERY, VKBeginQueryNode, begin_query)
|
||||||
BUILD_COMMANDS(VKNodeType::BEGIN_RENDERING, VKBeginRenderingNode, begin_rendering)
|
BUILD_COMMANDS_STORAGE(VKNodeType::BEGIN_RENDERING, VKBeginRenderingNode, begin_rendering)
|
||||||
BUILD_COMMANDS(VKNodeType::CLEAR_ATTACHMENTS, VKClearAttachmentsNode, clear_attachments)
|
BUILD_COMMANDS_STORAGE(
|
||||||
|
VKNodeType::CLEAR_ATTACHMENTS, VKClearAttachmentsNode, clear_attachments)
|
||||||
BUILD_COMMANDS(VKNodeType::CLEAR_COLOR_IMAGE, VKClearColorImageNode, clear_color_image)
|
BUILD_COMMANDS(VKNodeType::CLEAR_COLOR_IMAGE, VKClearColorImageNode, clear_color_image)
|
||||||
BUILD_COMMANDS(VKNodeType::CLEAR_DEPTH_STENCIL_IMAGE,
|
BUILD_COMMANDS(VKNodeType::CLEAR_DEPTH_STENCIL_IMAGE,
|
||||||
VKClearDepthStencilImageNode,
|
VKClearDepthStencilImageNode,
|
||||||
|
@ -201,33 +239,41 @@ struct VKRenderGraphNode {
|
||||||
BUILD_COMMANDS(VKNodeType::FILL_BUFFER, VKFillBufferNode, fill_buffer)
|
BUILD_COMMANDS(VKNodeType::FILL_BUFFER, VKFillBufferNode, fill_buffer)
|
||||||
BUILD_COMMANDS(VKNodeType::UPDATE_BUFFER, VKUpdateBufferNode, update_buffer)
|
BUILD_COMMANDS(VKNodeType::UPDATE_BUFFER, VKUpdateBufferNode, update_buffer)
|
||||||
BUILD_COMMANDS(VKNodeType::COPY_BUFFER, VKCopyBufferNode, copy_buffer)
|
BUILD_COMMANDS(VKNodeType::COPY_BUFFER, VKCopyBufferNode, copy_buffer)
|
||||||
BUILD_COMMANDS(
|
BUILD_COMMANDS_STORAGE(
|
||||||
VKNodeType::COPY_BUFFER_TO_IMAGE, VKCopyBufferToImageNode, copy_buffer_to_image)
|
VKNodeType::COPY_BUFFER_TO_IMAGE, VKCopyBufferToImageNode, copy_buffer_to_image)
|
||||||
BUILD_COMMANDS(VKNodeType::COPY_IMAGE, VKCopyImageNode, copy_image)
|
BUILD_COMMANDS_STORAGE(VKNodeType::COPY_IMAGE, VKCopyImageNode, copy_image)
|
||||||
BUILD_COMMANDS(
|
BUILD_COMMANDS_STORAGE(
|
||||||
VKNodeType::COPY_IMAGE_TO_BUFFER, VKCopyImageToBufferNode, copy_image_to_buffer)
|
VKNodeType::COPY_IMAGE_TO_BUFFER, VKCopyImageToBufferNode, copy_image_to_buffer)
|
||||||
BUILD_COMMANDS(VKNodeType::BLIT_IMAGE, VKBlitImageNode, blit_image)
|
BUILD_COMMANDS_STORAGE(VKNodeType::BLIT_IMAGE, VKBlitImageNode, blit_image)
|
||||||
BUILD_COMMANDS(VKNodeType::RESET_QUERY_POOL, VKResetQueryPoolNode, reset_query_pool)
|
BUILD_COMMANDS(VKNodeType::RESET_QUERY_POOL, VKResetQueryPoolNode, reset_query_pool)
|
||||||
BUILD_COMMANDS(VKNodeType::SYNCHRONIZATION, VKSynchronizationNode, synchronization)
|
BUILD_COMMANDS(VKNodeType::SYNCHRONIZATION, VKSynchronizationNode, synchronization)
|
||||||
BUILD_COMMANDS(VKNodeType::UPDATE_MIPMAPS, VKUpdateMipmapsNode, update_mipmaps)
|
BUILD_COMMANDS(VKNodeType::UPDATE_MIPMAPS, VKUpdateMipmapsNode, update_mipmaps)
|
||||||
BUILD_COMMANDS(VKNodeType::DISPATCH, VKDispatchNode, dispatch)
|
BUILD_COMMANDS(VKNodeType::DISPATCH, VKDispatchNode, dispatch)
|
||||||
BUILD_COMMANDS(VKNodeType::DISPATCH_INDIRECT, VKDispatchIndirectNode, dispatch_indirect)
|
BUILD_COMMANDS(VKNodeType::DISPATCH_INDIRECT, VKDispatchIndirectNode, dispatch_indirect)
|
||||||
BUILD_COMMANDS(VKNodeType::DRAW, VKDrawNode, draw)
|
BUILD_COMMANDS_STORAGE(VKNodeType::DRAW, VKDrawNode, draw)
|
||||||
BUILD_COMMANDS(VKNodeType::DRAW_INDEXED, VKDrawIndexedNode, draw_indexed)
|
BUILD_COMMANDS_STORAGE(VKNodeType::DRAW_INDEXED, VKDrawIndexedNode, draw_indexed)
|
||||||
BUILD_COMMANDS(
|
BUILD_COMMANDS_STORAGE(
|
||||||
VKNodeType::DRAW_INDEXED_INDIRECT, VKDrawIndexedIndirectNode, draw_indexed_indirect)
|
VKNodeType::DRAW_INDEXED_INDIRECT, VKDrawIndexedIndirectNode, draw_indexed_indirect)
|
||||||
BUILD_COMMANDS(VKNodeType::DRAW_INDIRECT, VKDrawIndirectNode, draw_indirect)
|
BUILD_COMMANDS_STORAGE(VKNodeType::DRAW_INDIRECT, VKDrawIndirectNode, draw_indirect)
|
||||||
#undef BUILD_COMMANDS
|
#undef BUILD_COMMANDS
|
||||||
|
#undef BUILD_COMMANDS_STORAGE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free data kept by the node
|
* Free data kept by the node
|
||||||
*/
|
*/
|
||||||
void free_data()
|
void free_data(VKRenderGraphStorage &storage)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
||||||
|
#define FREE_DATA_STORAGE(NODE_TYPE, NODE_CLASS, ATTRIBUTE_NAME) \
|
||||||
|
case NODE_TYPE: { \
|
||||||
|
NODE_CLASS node_info; \
|
||||||
|
node_info.free_data(storage.ATTRIBUTE_NAME[storage_index]); \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
#define FREE_DATA(NODE_TYPE, NODE_CLASS, ATTRIBUTE_NAME) \
|
#define FREE_DATA(NODE_TYPE, NODE_CLASS, ATTRIBUTE_NAME) \
|
||||||
case NODE_TYPE: { \
|
case NODE_TYPE: { \
|
||||||
NODE_CLASS node_info; \
|
NODE_CLASS node_info; \
|
||||||
|
@ -237,13 +283,14 @@ struct VKRenderGraphNode {
|
||||||
|
|
||||||
FREE_DATA(VKNodeType::DISPATCH, VKDispatchNode, dispatch)
|
FREE_DATA(VKNodeType::DISPATCH, VKDispatchNode, dispatch)
|
||||||
FREE_DATA(VKNodeType::DISPATCH_INDIRECT, VKDispatchIndirectNode, dispatch_indirect)
|
FREE_DATA(VKNodeType::DISPATCH_INDIRECT, VKDispatchIndirectNode, dispatch_indirect)
|
||||||
FREE_DATA(VKNodeType::DRAW, VKDrawNode, draw)
|
FREE_DATA_STORAGE(VKNodeType::DRAW, VKDrawNode, draw)
|
||||||
FREE_DATA(VKNodeType::DRAW_INDEXED, VKDrawIndexedNode, draw_indexed)
|
FREE_DATA_STORAGE(VKNodeType::DRAW_INDEXED, VKDrawIndexedNode, draw_indexed)
|
||||||
FREE_DATA(
|
FREE_DATA_STORAGE(
|
||||||
VKNodeType::DRAW_INDEXED_INDIRECT, VKDrawIndexedIndirectNode, draw_indexed_indirect)
|
VKNodeType::DRAW_INDEXED_INDIRECT, VKDrawIndexedIndirectNode, draw_indexed_indirect)
|
||||||
FREE_DATA(VKNodeType::DRAW_INDIRECT, VKDrawIndirectNode, draw_indirect)
|
FREE_DATA_STORAGE(VKNodeType::DRAW_INDIRECT, VKDrawIndirectNode, draw_indirect)
|
||||||
FREE_DATA(VKNodeType::UPDATE_BUFFER, VKUpdateBufferNode, update_buffer)
|
FREE_DATA(VKNodeType::UPDATE_BUFFER, VKUpdateBufferNode, update_buffer)
|
||||||
#undef FREE_DATA
|
#undef FREE_DATA
|
||||||
|
#undef FREE_DATA_STORAGE
|
||||||
|
|
||||||
case VKNodeType::UNUSED:
|
case VKNodeType::UNUSED:
|
||||||
case VKNodeType::BEGIN_QUERY:
|
case VKNodeType::BEGIN_QUERY:
|
||||||
|
@ -272,12 +319,16 @@ struct VKRenderGraphNode {
|
||||||
* Nodes are reset so they can be reused in consecutive calls. Data allocated by the node are
|
* Nodes are reset so they can be reused in consecutive calls. Data allocated by the node are
|
||||||
* freed. This function dispatches the free_data to the actual node implementation.
|
* freed. This function dispatches the free_data to the actual node implementation.
|
||||||
*/
|
*/
|
||||||
void reset()
|
void reset(VKRenderGraphStorage &storage)
|
||||||
{
|
{
|
||||||
free_data();
|
free_data(storage);
|
||||||
memset(this, 0, sizeof(VKRenderGraphNode));
|
|
||||||
type = VKNodeType::UNUSED;
|
type = VKNodeType::UNUSED;
|
||||||
|
storage_index = -1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BLI_STATIC_ASSERT(sizeof(VKRenderGraphNode) <= 64,
|
||||||
|
"VKRenderGraphNode should be kept small. Consider moving data to the "
|
||||||
|
"VKRenderGraphStorage class.");
|
||||||
|
|
||||||
} // namespace blender::gpu::render_graph
|
} // namespace blender::gpu::render_graph
|
||||||
|
|
Loading…
Reference in a new issue