Vulkan: Occlusion Queries
Implements occlusion queries using VkQueryPools. Pull Request: https://projects.blender.org/blender/blender/pulls/123883
This commit is contained in:
@@ -267,6 +267,7 @@ set(VULKAN_SRC
|
||||
vulkan/vk_pixel_buffer.hh
|
||||
vulkan/vk_push_constants.hh
|
||||
vulkan/vk_query.hh
|
||||
vulkan/render_graph/nodes/vk_begin_query_node.hh
|
||||
vulkan/render_graph/nodes/vk_begin_rendering_node.hh
|
||||
vulkan/render_graph/nodes/vk_blit_image_node.hh
|
||||
vulkan/render_graph/nodes/vk_clear_attachments_node.hh
|
||||
@@ -282,10 +283,12 @@ set(VULKAN_SRC
|
||||
vulkan/render_graph/nodes/vk_draw_indexed_node.hh
|
||||
vulkan/render_graph/nodes/vk_draw_indirect_node.hh
|
||||
vulkan/render_graph/nodes/vk_draw_node.hh
|
||||
vulkan/render_graph/nodes/vk_end_query_node.hh
|
||||
vulkan/render_graph/nodes/vk_end_rendering_node.hh
|
||||
vulkan/render_graph/nodes/vk_fill_buffer_node.hh
|
||||
vulkan/render_graph/nodes/vk_node_info.hh
|
||||
vulkan/render_graph/nodes/vk_pipeline_data.hh
|
||||
vulkan/render_graph/nodes/vk_reset_query_pool_node.hh
|
||||
vulkan/render_graph/nodes/vk_synchronization_node.hh
|
||||
vulkan/render_graph/nodes/vk_update_mipmaps_node.hh
|
||||
vulkan/render_graph/vk_command_buffer_wrapper.hh
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vk_node_info.hh"
|
||||
|
||||
namespace blender::gpu::render_graph {
|
||||
|
||||
/**
|
||||
* Information stored inside the render graph node. See `VKRenderGraphNode`.
|
||||
*/
|
||||
struct VKBeginQueryData {
|
||||
VkQueryPool vk_query_pool;
|
||||
uint32_t query_index;
|
||||
VkQueryControlFlags vk_query_control_flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* Begin query
|
||||
*
|
||||
* - Contains logic to copy relevant data to the VKRenderGraphNode.
|
||||
* - Determine read/write resource dependencies.
|
||||
* - Add commands to a command builder.
|
||||
*/
|
||||
class VKBeginQueryNode : public VKNodeInfo<VKNodeType::BEGIN_QUERY,
|
||||
VKBeginQueryData,
|
||||
VKBeginQueryData,
|
||||
VK_PIPELINE_STAGE_NONE,
|
||||
VKResourceType::NONE> {
|
||||
public:
|
||||
/**
|
||||
* Update the node data with the data inside create_info.
|
||||
*
|
||||
* Has been implemented as a template to ensure all node specific data
|
||||
* (`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.)
|
||||
*/
|
||||
template<typename Node> void set_node_data(Node &node, const CreateInfo &create_info)
|
||||
{
|
||||
node.begin_query = create_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract read/write resource dependencies from `create_info` and add them to `node_links`.
|
||||
*/
|
||||
void build_links(VKResourceStateTracker & /*resources*/,
|
||||
VKRenderGraphNodeLinks & /*node_links*/,
|
||||
const CreateInfo & /*create_info*/) override
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the commands and add them to the command_buffer.
|
||||
*/
|
||||
void build_commands(VKCommandBufferInterface &command_buffer,
|
||||
Data &data,
|
||||
VKBoundPipelines & /*r_bound_pipelines*/) override
|
||||
{
|
||||
command_buffer.begin_query(data.vk_query_pool, data.query_index, data.vk_query_control_flags);
|
||||
}
|
||||
};
|
||||
} // namespace blender::gpu::render_graph
|
||||
@@ -0,0 +1,67 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vk_node_info.hh"
|
||||
|
||||
namespace blender::gpu::render_graph {
|
||||
|
||||
/**
|
||||
* Information stored inside the render graph node. See `VKRenderGraphNode`.
|
||||
*/
|
||||
struct VKEndQueryData {
|
||||
VkQueryPool vk_query_pool;
|
||||
uint32_t query_index;
|
||||
};
|
||||
|
||||
/**
|
||||
* End Query Node
|
||||
*
|
||||
* - Contains logic to copy relevant data to the VKRenderGraphNode.
|
||||
* - Determine read/write resource dependencies.
|
||||
* - Add commands to a command builder.
|
||||
*/
|
||||
class VKEndQueryNode : public VKNodeInfo<VKNodeType::END_QUERY,
|
||||
VKEndQueryData,
|
||||
VKEndQueryData,
|
||||
VK_PIPELINE_STAGE_NONE,
|
||||
VKResourceType::IMAGE> {
|
||||
public:
|
||||
/**
|
||||
* Update the node data with the data inside create_info.
|
||||
*
|
||||
* Has been implemented as a template to ensure all node specific data
|
||||
* (`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.)
|
||||
*/
|
||||
template<typename Node> void set_node_data(Node &node, const CreateInfo &create_info)
|
||||
{
|
||||
node.end_query = create_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract read/write resource dependencies from `create_info` and add them to `node_links`.
|
||||
*/
|
||||
void build_links(VKResourceStateTracker & /*resources*/,
|
||||
VKRenderGraphNodeLinks & /*node_links*/,
|
||||
const CreateInfo & /*create_info*/) override
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the commands and add them to the command_buffer.
|
||||
*/
|
||||
void build_commands(VKCommandBufferInterface &command_buffer,
|
||||
Data &data,
|
||||
VKBoundPipelines & /*r_bound_pipelines*/) override
|
||||
{
|
||||
command_buffer.end_query(data.vk_query_pool, data.query_index);
|
||||
}
|
||||
};
|
||||
} // namespace blender::gpu::render_graph
|
||||
@@ -21,6 +21,7 @@ namespace blender::gpu::render_graph {
|
||||
*/
|
||||
enum class VKNodeType {
|
||||
UNUSED,
|
||||
BEGIN_QUERY,
|
||||
BEGIN_RENDERING,
|
||||
BLIT_IMAGE,
|
||||
CLEAR_ATTACHMENTS,
|
||||
@@ -36,8 +37,10 @@ enum class VKNodeType {
|
||||
DRAW_INDEXED,
|
||||
DRAW_INDEXED_INDIRECT,
|
||||
DRAW_INDIRECT,
|
||||
END_QUERY,
|
||||
END_RENDERING,
|
||||
FILL_BUFFER,
|
||||
RESET_QUERY_POOL,
|
||||
SYNCHRONIZATION,
|
||||
UPDATE_MIPMAPS,
|
||||
};
|
||||
@@ -48,9 +51,15 @@ BLI_INLINE std::ostream &operator<<(std::ostream &os, const VKNodeType node_type
|
||||
case VKNodeType::UNUSED:
|
||||
os << "UNUSED";
|
||||
break;
|
||||
case VKNodeType::BEGIN_QUERY:
|
||||
os << "BEGIN_QUERY";
|
||||
break;
|
||||
case VKNodeType::BEGIN_RENDERING:
|
||||
os << "BEGIN_RENDERING";
|
||||
break;
|
||||
case VKNodeType::END_QUERY:
|
||||
os << "END_QUERY";
|
||||
break;
|
||||
case VKNodeType::END_RENDERING:
|
||||
os << "END_RENDERING";
|
||||
break;
|
||||
@@ -99,6 +108,9 @@ BLI_INLINE std::ostream &operator<<(std::ostream &os, const VKNodeType node_type
|
||||
case VKNodeType::DRAW_INDIRECT:
|
||||
os << "DRAW_INDIRECT";
|
||||
break;
|
||||
case VKNodeType::RESET_QUERY_POOL:
|
||||
os << "RESET_QUERY_POOL";
|
||||
break;
|
||||
case VKNodeType::SYNCHRONIZATION:
|
||||
os << "SYNCHRONIZATION";
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup gpu
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vk_node_info.hh"
|
||||
|
||||
namespace blender::gpu::render_graph {
|
||||
|
||||
/**
|
||||
* Information stored inside the render graph node. See `VKRenderGraphNode`.
|
||||
*/
|
||||
struct VKResetQueryPoolData {
|
||||
VkQueryPool vk_query_pool;
|
||||
uint32_t first_query;
|
||||
uint32_t query_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset query pool.
|
||||
*
|
||||
* - Contains logic to copy relevant data to the VKRenderGraphNode.
|
||||
* - Determine read/write resource dependencies.
|
||||
* - Add commands to a command builder.
|
||||
*/
|
||||
class VKResetQueryPoolNode : public VKNodeInfo<VKNodeType::RESET_QUERY_POOL,
|
||||
VKResetQueryPoolData,
|
||||
VKResetQueryPoolData,
|
||||
VK_PIPELINE_STAGE_NONE,
|
||||
VKResourceType::NONE> {
|
||||
public:
|
||||
/**
|
||||
* Update the node data with the data inside create_info.
|
||||
*
|
||||
* Has been implemented as a template to ensure all node specific data
|
||||
* (`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.)
|
||||
*/
|
||||
template<typename Node> void set_node_data(Node &node, const CreateInfo &create_info)
|
||||
{
|
||||
node.reset_query_pool = create_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract read/write resource dependencies from `create_info` and add them to `node_links`.
|
||||
*/
|
||||
void build_links(VKResourceStateTracker & /*resources*/,
|
||||
VKRenderGraphNodeLinks & /*node_links*/,
|
||||
const CreateInfo & /*create_info*/) override
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the commands and add them to the command_buffer.
|
||||
*/
|
||||
void build_commands(VKCommandBufferInterface &command_buffer,
|
||||
Data &data,
|
||||
VKBoundPipelines & /*r_bound_pipelines*/) override
|
||||
{
|
||||
command_buffer.reset_query_pool(data.vk_query_pool, data.first_query, data.query_count);
|
||||
}
|
||||
};
|
||||
} // namespace blender::gpu::render_graph
|
||||
@@ -421,6 +421,17 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
||||
log_.append(ss.str());
|
||||
}
|
||||
|
||||
void begin_query(VkQueryPool /*vk_query_pool*/,
|
||||
uint32_t /*query_index*/,
|
||||
VkQueryControlFlags /*vk_query_control_flags*/) override
|
||||
{
|
||||
}
|
||||
void end_query(VkQueryPool /*vk_query_pool*/, uint32_t /*query_index*/) override {}
|
||||
void reset_query_pool(VkQueryPool /*vk_query_pool*/,
|
||||
uint32_t /*first_query*/,
|
||||
uint32_t /*query_count*/) override
|
||||
{
|
||||
}
|
||||
void begin_debug_utils_label(const VkDebugUtilsLabelEXT * /*vk_debug_utils_label*/) override {}
|
||||
void end_debug_utils_label() override {}
|
||||
};
|
||||
|
||||
@@ -332,6 +332,25 @@ void VKCommandBufferWrapper::end_rendering()
|
||||
device.functions.vkCmdEndRendering(vk_command_buffer_);
|
||||
}
|
||||
|
||||
void VKCommandBufferWrapper::begin_query(VkQueryPool vk_query_pool,
|
||||
uint32_t query_index,
|
||||
VkQueryControlFlags vk_query_control_flags)
|
||||
{
|
||||
vkCmdBeginQuery(vk_command_buffer_, vk_query_pool, query_index, vk_query_control_flags);
|
||||
}
|
||||
|
||||
void VKCommandBufferWrapper::end_query(VkQueryPool vk_query_pool, uint32_t query_index)
|
||||
{
|
||||
vkCmdEndQuery(vk_command_buffer_, vk_query_pool, query_index);
|
||||
}
|
||||
|
||||
void VKCommandBufferWrapper::reset_query_pool(VkQueryPool vk_query_pool,
|
||||
uint32_t first_query,
|
||||
uint32_t query_count)
|
||||
{
|
||||
vkCmdResetQueryPool(vk_command_buffer_, vk_query_pool, first_query, query_count);
|
||||
}
|
||||
|
||||
void VKCommandBufferWrapper::begin_debug_utils_label(
|
||||
const VkDebugUtilsLabelEXT *vk_debug_utils_label)
|
||||
{
|
||||
|
||||
@@ -114,6 +114,14 @@ class VKCommandBufferInterface {
|
||||
uint32_t offset,
|
||||
uint32_t size,
|
||||
const void *p_values) = 0;
|
||||
virtual void begin_query(VkQueryPool vk_query_pool,
|
||||
uint32_t query_index,
|
||||
VkQueryControlFlags vk_query_control_flags) = 0;
|
||||
virtual void end_query(VkQueryPool vk_query_pool, uint32_t query_index) = 0;
|
||||
virtual void reset_query_pool(VkQueryPool vk_query_pool,
|
||||
uint32_t first_query,
|
||||
uint32_t query_count) = 0;
|
||||
|
||||
/* VK_KHR_dynamic_rendering */
|
||||
virtual void begin_rendering(const VkRenderingInfo *p_rendering_info) = 0;
|
||||
virtual void end_rendering() = 0;
|
||||
@@ -234,6 +242,11 @@ class VKCommandBufferWrapper : public VKCommandBufferInterface {
|
||||
uint32_t offset,
|
||||
uint32_t size,
|
||||
const void *p_values) override;
|
||||
void begin_query(VkQueryPool vk_query_pool,
|
||||
uint32_t query_index,
|
||||
VkQueryControlFlags vk_query_control_flags) override;
|
||||
void end_query(VkQueryPool vk_query_pool, uint32_t query_index) override;
|
||||
void reset_query_pool(VkQueryPool, uint32_t first_query, uint32_t query_count) override;
|
||||
void begin_rendering(const VkRenderingInfo *p_rendering_info) override;
|
||||
void end_rendering() override;
|
||||
void begin_debug_utils_label(const VkDebugUtilsLabelEXT *vk_debug_utils_label) override;
|
||||
|
||||
@@ -177,7 +177,9 @@ class VKRenderGraph : public NonCopyable {
|
||||
{ \
|
||||
add_node<NODE_CLASS>(create_info); \
|
||||
}
|
||||
ADD_NODE(VKBeginQueryNode)
|
||||
ADD_NODE(VKBeginRenderingNode)
|
||||
ADD_NODE(VKEndQueryNode)
|
||||
ADD_NODE(VKEndRenderingNode)
|
||||
ADD_NODE(VKClearAttachmentsNode)
|
||||
ADD_NODE(VKClearColorImageNode)
|
||||
@@ -194,6 +196,7 @@ class VKRenderGraph : public NonCopyable {
|
||||
ADD_NODE(VKDrawIndexedNode)
|
||||
ADD_NODE(VKDrawIndexedIndirectNode)
|
||||
ADD_NODE(VKDrawIndirectNode)
|
||||
ADD_NODE(VKResetQueryPoolNode)
|
||||
ADD_NODE(VKUpdateMipmapsNode)
|
||||
#undef ADD_NODE
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "nodes/vk_begin_query_node.hh"
|
||||
#include "nodes/vk_begin_rendering_node.hh"
|
||||
#include "nodes/vk_blit_image_node.hh"
|
||||
#include "nodes/vk_clear_attachments_node.hh"
|
||||
@@ -23,8 +24,10 @@
|
||||
#include "nodes/vk_draw_indexed_node.hh"
|
||||
#include "nodes/vk_draw_indirect_node.hh"
|
||||
#include "nodes/vk_draw_node.hh"
|
||||
#include "nodes/vk_end_query_node.hh"
|
||||
#include "nodes/vk_end_rendering_node.hh"
|
||||
#include "nodes/vk_fill_buffer_node.hh"
|
||||
#include "nodes/vk_reset_query_pool_node.hh"
|
||||
#include "nodes/vk_synchronization_node.hh"
|
||||
#include "nodes/vk_update_mipmaps_node.hh"
|
||||
|
||||
@@ -45,6 +48,7 @@ using NodeHandle = uint64_t;
|
||||
struct VKRenderGraphNode {
|
||||
VKNodeType type;
|
||||
union {
|
||||
VKBeginQueryNode::Data begin_query;
|
||||
VKBeginRenderingNode::Data begin_rendering;
|
||||
VKBlitImageNode::Data blit_image;
|
||||
VKClearAttachmentsNode::Data clear_attachments;
|
||||
@@ -60,8 +64,10 @@ struct VKRenderGraphNode {
|
||||
VKDrawIndexedNode::Data draw_indexed;
|
||||
VKDrawIndexedIndirectNode::Data draw_indexed_indirect;
|
||||
VKDrawIndirectNode::Data draw_indirect;
|
||||
VKEndQueryNode::Data end_query;
|
||||
VKEndRenderingNode::Data end_rendering;
|
||||
VKFillBufferNode::Data fill_buffer;
|
||||
VKResetQueryPoolNode::Data reset_query_pool;
|
||||
VKSynchronizationNode::Data synchronization;
|
||||
VKUpdateMipmapsNode::Data update_mipmaps;
|
||||
};
|
||||
@@ -110,6 +116,8 @@ struct VKRenderGraphNode {
|
||||
switch (type) {
|
||||
case VKNodeType::UNUSED:
|
||||
return VK_PIPELINE_STAGE_NONE;
|
||||
case VKNodeType::BEGIN_QUERY:
|
||||
return VKBeginQueryNode::pipeline_stage;
|
||||
case VKNodeType::BEGIN_RENDERING:
|
||||
return VKBeginRenderingNode::pipeline_stage;
|
||||
case VKNodeType::CLEAR_ATTACHMENTS:
|
||||
@@ -118,6 +126,8 @@ struct VKRenderGraphNode {
|
||||
return VKClearColorImageNode::pipeline_stage;
|
||||
case VKNodeType::CLEAR_DEPTH_STENCIL_IMAGE:
|
||||
return VKClearDepthStencilImageNode::pipeline_stage;
|
||||
case VKNodeType::END_QUERY:
|
||||
return VKEndQueryNode::pipeline_stage;
|
||||
case VKNodeType::END_RENDERING:
|
||||
return VKEndRenderingNode::pipeline_stage;
|
||||
case VKNodeType::FILL_BUFFER:
|
||||
@@ -144,6 +154,8 @@ struct VKRenderGraphNode {
|
||||
return VKDrawIndexedIndirectNode::pipeline_stage;
|
||||
case VKNodeType::DRAW_INDIRECT:
|
||||
return VKDrawIndirectNode::pipeline_stage;
|
||||
case VKNodeType::RESET_QUERY_POOL:
|
||||
return VKResetQueryPoolNode::pipeline_stage;
|
||||
case VKNodeType::SYNCHRONIZATION:
|
||||
return VKSynchronizationNode::pipeline_stage;
|
||||
case VKNodeType::UPDATE_MIPMAPS:
|
||||
@@ -173,12 +185,14 @@ struct VKRenderGraphNode {
|
||||
break; \
|
||||
}
|
||||
|
||||
BUILD_COMMANDS(VKNodeType::BEGIN_QUERY, VKBeginQueryNode, begin_query)
|
||||
BUILD_COMMANDS(VKNodeType::BEGIN_RENDERING, VKBeginRenderingNode, begin_rendering)
|
||||
BUILD_COMMANDS(VKNodeType::CLEAR_ATTACHMENTS, VKClearAttachmentsNode, clear_attachments)
|
||||
BUILD_COMMANDS(VKNodeType::CLEAR_COLOR_IMAGE, VKClearColorImageNode, clear_color_image)
|
||||
BUILD_COMMANDS(VKNodeType::CLEAR_DEPTH_STENCIL_IMAGE,
|
||||
VKClearDepthStencilImageNode,
|
||||
clear_depth_stencil_image)
|
||||
BUILD_COMMANDS(VKNodeType::END_QUERY, VKEndQueryNode, end_query)
|
||||
BUILD_COMMANDS(VKNodeType::END_RENDERING, VKEndRenderingNode, end_rendering)
|
||||
BUILD_COMMANDS(VKNodeType::FILL_BUFFER, VKFillBufferNode, fill_buffer)
|
||||
BUILD_COMMANDS(VKNodeType::COPY_BUFFER, VKCopyBufferNode, copy_buffer)
|
||||
@@ -188,6 +202,7 @@ struct VKRenderGraphNode {
|
||||
BUILD_COMMANDS(
|
||||
VKNodeType::COPY_IMAGE_TO_BUFFER, VKCopyImageToBufferNode, copy_image_to_buffer)
|
||||
BUILD_COMMANDS(VKNodeType::BLIT_IMAGE, VKBlitImageNode, blit_image)
|
||||
BUILD_COMMANDS(VKNodeType::RESET_QUERY_POOL, VKResetQueryPoolNode, reset_query_pool)
|
||||
BUILD_COMMANDS(VKNodeType::SYNCHRONIZATION, VKSynchronizationNode, synchronization)
|
||||
BUILD_COMMANDS(VKNodeType::UPDATE_MIPMAPS, VKUpdateMipmapsNode, update_mipmaps)
|
||||
BUILD_COMMANDS(VKNodeType::DISPATCH, VKDispatchNode, dispatch)
|
||||
@@ -225,10 +240,12 @@ struct VKRenderGraphNode {
|
||||
#undef FREE_DATA
|
||||
|
||||
case VKNodeType::UNUSED:
|
||||
case VKNodeType::BEGIN_QUERY:
|
||||
case VKNodeType::BEGIN_RENDERING:
|
||||
case VKNodeType::CLEAR_ATTACHMENTS:
|
||||
case VKNodeType::CLEAR_COLOR_IMAGE:
|
||||
case VKNodeType::CLEAR_DEPTH_STENCIL_IMAGE:
|
||||
case VKNodeType::END_QUERY:
|
||||
case VKNodeType::END_RENDERING:
|
||||
case VKNodeType::FILL_BUFFER:
|
||||
case VKNodeType::COPY_BUFFER:
|
||||
@@ -236,6 +253,7 @@ struct VKRenderGraphNode {
|
||||
case VKNodeType::COPY_IMAGE_TO_BUFFER:
|
||||
case VKNodeType::COPY_BUFFER_TO_IMAGE:
|
||||
case VKNodeType::BLIT_IMAGE:
|
||||
case VKNodeType::RESET_QUERY_POOL:
|
||||
case VKNodeType::SYNCHRONIZATION:
|
||||
case VKNodeType::UPDATE_MIPMAPS:
|
||||
break;
|
||||
|
||||
@@ -669,6 +669,16 @@ VkFormat to_vk_format(const shader::Type type)
|
||||
return VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
}
|
||||
|
||||
VkQueryType to_vk_query_type(const GPUQueryType query_type)
|
||||
{
|
||||
switch (query_type) {
|
||||
case GPU_QUERY_OCCLUSION:
|
||||
return VK_QUERY_TYPE_OCCLUSION;
|
||||
}
|
||||
BLI_assert_unreachable();
|
||||
return VK_QUERY_TYPE_OCCLUSION;
|
||||
}
|
||||
|
||||
VkImageType to_vk_image_type(const eGPUTextureType type)
|
||||
{
|
||||
/* See
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "vk_mem_alloc.h"
|
||||
|
||||
#include "GPU_index_buffer.hh"
|
||||
#include "gpu_query.hh"
|
||||
#include "gpu_shader_create_info.hh"
|
||||
#include "gpu_texture_private.hh"
|
||||
|
||||
@@ -52,6 +53,7 @@ VkFormat to_vk_format(const GPUVertCompType type,
|
||||
const uint32_t size,
|
||||
const GPUVertFetchMode fetch_mode);
|
||||
VkFormat to_vk_format(const shader::Type type);
|
||||
VkQueryType to_vk_query_type(const GPUQueryType query_type);
|
||||
|
||||
VkComponentSwizzle to_vk_component_swizzle(const char swizzle);
|
||||
VkImageViewType to_vk_image_view_type(const eGPUTextureType type,
|
||||
|
||||
@@ -7,28 +7,116 @@
|
||||
*/
|
||||
|
||||
#include "vk_query.hh"
|
||||
#include "vk_common.hh"
|
||||
#include "vk_backend.hh"
|
||||
#include "vk_context.hh"
|
||||
#include "vk_memory.hh"
|
||||
|
||||
#include "GPU_debug.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
void VKQueryPool::init(GPUQueryType /*type*/)
|
||||
VKQueryPool::~VKQueryPool()
|
||||
{
|
||||
NOT_YET_IMPLEMENTED
|
||||
VKBackend &backend = VKBackend::get();
|
||||
const VKDevice &device = backend.device;
|
||||
VK_ALLOCATION_CALLBACKS;
|
||||
|
||||
while (!vk_query_pools_.is_empty()) {
|
||||
VkQueryPool vk_query_pool = vk_query_pools_.pop_last();
|
||||
vkDestroyQueryPool(device.vk_handle(), vk_query_pool, vk_allocation_callbacks);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t VKQueryPool::query_index_in_pool() const
|
||||
{
|
||||
return queries_issued_ - (vk_query_pools_.size() - 1) * query_chunk_len_;
|
||||
}
|
||||
|
||||
void VKQueryPool::init(GPUQueryType type)
|
||||
{
|
||||
BLI_assert(vk_query_pools_.is_empty());
|
||||
queries_issued_ = 0;
|
||||
vk_query_type_ = to_vk_query_type(type);
|
||||
}
|
||||
|
||||
void VKQueryPool::begin_query()
|
||||
{
|
||||
NOT_YET_IMPLEMENTED
|
||||
VKBackend &backend = VKBackend::get();
|
||||
const VKDevice &device = backend.device;
|
||||
|
||||
uint32_t pool_index = queries_issued_ / query_chunk_len_;
|
||||
bool is_new_pool = (queries_issued_ % query_chunk_len_) == 0;
|
||||
|
||||
if (pool_index == vk_query_pools_.size()) {
|
||||
BLI_assert(is_new_pool);
|
||||
VK_ALLOCATION_CALLBACKS;
|
||||
|
||||
VkQueryPoolCreateInfo create_info = {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
|
||||
create_info.queryType = vk_query_type_;
|
||||
create_info.queryCount = query_chunk_len_;
|
||||
|
||||
VkQueryPool vk_query_pool = VK_NULL_HANDLE;
|
||||
vkCreateQueryPool(device.vk_handle(), &create_info, vk_allocation_callbacks, &vk_query_pool);
|
||||
vk_query_pools_.append(vk_query_pool);
|
||||
}
|
||||
BLI_assert(pool_index < vk_query_pools_.size());
|
||||
|
||||
/* When using a new query pool make sure to reset it before first usage. */
|
||||
VKContext &context = *VKContext::get();
|
||||
VkQueryPool vk_query_pool = vk_query_pools_[pool_index];
|
||||
if (is_new_pool) {
|
||||
render_graph::VKResetQueryPoolNode::Data reset_query_pool = {};
|
||||
reset_query_pool.vk_query_pool = vk_query_pool;
|
||||
reset_query_pool.first_query = 0;
|
||||
reset_query_pool.query_count = query_chunk_len_;
|
||||
context.render_graph.add_node(reset_query_pool);
|
||||
}
|
||||
|
||||
render_graph::VKBeginQueryNode::Data begin_query = {};
|
||||
begin_query.vk_query_pool = vk_query_pool;
|
||||
begin_query.query_index = query_index_in_pool();
|
||||
context.render_graph.add_node(begin_query);
|
||||
}
|
||||
|
||||
void VKQueryPool::end_query()
|
||||
{
|
||||
NOT_YET_IMPLEMENTED
|
||||
VKContext &context = *VKContext::get();
|
||||
render_graph::VKEndQueryNode::Data end_query = {};
|
||||
end_query.vk_query_pool = vk_query_pools_.last();
|
||||
end_query.query_index = query_index_in_pool();
|
||||
context.render_graph.add_node(end_query);
|
||||
queries_issued_ += 1;
|
||||
}
|
||||
|
||||
void VKQueryPool::get_occlusion_result(MutableSpan<uint32_t> /*r_values*/)
|
||||
void VKQueryPool::get_occlusion_result(MutableSpan<uint32_t> r_values)
|
||||
{
|
||||
NOT_YET_IMPLEMENTED
|
||||
VKContext &context = *VKContext::get();
|
||||
/* During selection the frame buffer is still rendering. It needs to finish the render scope to
|
||||
* ensure the END_RENDERING node */
|
||||
context.rendering_end();
|
||||
context.render_graph.submit();
|
||||
|
||||
int queries_left = queries_issued_;
|
||||
int pool_index = 0;
|
||||
VKBackend &backend = VKBackend::get();
|
||||
const VKDevice &device = backend.device;
|
||||
while (queries_left) {
|
||||
VkQueryPool vk_query_pool = vk_query_pools_[pool_index];
|
||||
uint32_t *r_values_chunk = &r_values[pool_index * query_chunk_len_];
|
||||
uint32_t values_chunk_size = min_ii(queries_left, query_chunk_len_);
|
||||
vkGetQueryPoolResults(device.vk_handle(),
|
||||
vk_query_pool,
|
||||
0,
|
||||
values_chunk_size,
|
||||
values_chunk_size * sizeof(uint32_t),
|
||||
r_values_chunk,
|
||||
sizeof(uint32_t),
|
||||
VK_QUERY_RESULT_WAIT_BIT);
|
||||
|
||||
queries_left = max_ii(queries_left - query_chunk_len_, 0);
|
||||
pool_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
||||
@@ -8,16 +8,31 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "gpu_query.hh"
|
||||
|
||||
#include "vk_common.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
class VKQueryPool : public QueryPool {
|
||||
const uint32_t query_chunk_len_ = 256;
|
||||
Vector<VkQueryPool> vk_query_pools_;
|
||||
VkQueryType vk_query_type_;
|
||||
uint32_t queries_issued_ = 0;
|
||||
|
||||
protected:
|
||||
~VKQueryPool();
|
||||
|
||||
public:
|
||||
void init(GPUQueryType type) override;
|
||||
void begin_query() override;
|
||||
void end_query() override;
|
||||
void get_occlusion_result(MutableSpan<uint32_t> r_values) override;
|
||||
|
||||
private:
|
||||
uint32_t query_index_in_pool() const;
|
||||
};
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
||||
Reference in New Issue
Block a user