Path: blob/master/servers/rendering/rendering_device_graph.h
10277 views
/**************************************************************************/1/* rendering_device_graph.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "core/object/worker_thread_pool.h"33#include "rendering_device_commons.h"34#include "rendering_device_driver.h"3536// Buffer barriers have not shown any significant improvement or shown to be37// even detrimental to performance. However, there are currently some known38// cases where using them can solve problems that using singular memory39// barriers does not, probably due to driver issues (see comment on PR #8497640// https://github.com/godotengine/godot/pull/84976#issuecomment-1878566830).4142#define USE_BUFFER_BARRIERS 14344class RenderingDeviceGraph {45public:46struct ComputeListInstruction {47enum Type {48TYPE_NONE,49TYPE_BIND_PIPELINE,50TYPE_BIND_UNIFORM_SETS,51TYPE_DISPATCH,52TYPE_DISPATCH_INDIRECT,53TYPE_SET_PUSH_CONSTANT,54TYPE_UNIFORM_SET_PREPARE_FOR_USE55};5657Type type = TYPE_NONE;58};5960struct DrawListInstruction {61enum Type {62TYPE_NONE,63TYPE_BIND_INDEX_BUFFER,64TYPE_BIND_PIPELINE,65TYPE_BIND_UNIFORM_SETS,66TYPE_BIND_VERTEX_BUFFERS,67TYPE_CLEAR_ATTACHMENTS,68TYPE_DRAW,69TYPE_DRAW_INDEXED,70TYPE_DRAW_INDIRECT,71TYPE_DRAW_INDEXED_INDIRECT,72TYPE_EXECUTE_COMMANDS,73TYPE_NEXT_SUBPASS,74TYPE_SET_BLEND_CONSTANTS,75TYPE_SET_LINE_WIDTH,76TYPE_SET_PUSH_CONSTANT,77TYPE_SET_SCISSOR,78TYPE_SET_VIEWPORT,79TYPE_UNIFORM_SET_PREPARE_FOR_USE80};8182Type type = TYPE_NONE;83};8485struct RecordedCommand {86enum Type {87TYPE_NONE,88TYPE_BUFFER_CLEAR,89TYPE_BUFFER_COPY,90TYPE_BUFFER_GET_DATA,91TYPE_BUFFER_UPDATE,92TYPE_COMPUTE_LIST,93TYPE_DRAW_LIST,94TYPE_TEXTURE_CLEAR,95TYPE_TEXTURE_COPY,96TYPE_TEXTURE_GET_DATA,97TYPE_TEXTURE_RESOLVE,98TYPE_TEXTURE_UPDATE,99TYPE_CAPTURE_TIMESTAMP,100TYPE_DRIVER_CALLBACK,101TYPE_MAX102};103104Type type = TYPE_NONE;105int32_t adjacent_command_list_index = -1;106RDD::MemoryBarrier memory_barrier;107int32_t normalization_barrier_index = -1;108int normalization_barrier_count = 0;109int32_t transition_barrier_index = -1;110int32_t transition_barrier_count = 0;111#if USE_BUFFER_BARRIERS112int32_t buffer_barrier_index = -1;113int32_t buffer_barrier_count = 0;114#endif115int32_t label_index = -1;116BitField<RDD::PipelineStageBits> previous_stages = {};117BitField<RDD::PipelineStageBits> next_stages = {};118BitField<RDD::PipelineStageBits> self_stages = {};119};120121struct RecordedBufferCopy {122RDD::BufferID source;123RDD::BufferCopyRegion region;124};125126struct RecordedBufferToTextureCopy {127RDD::BufferID from_buffer;128RDD::BufferTextureCopyRegion region;129};130131enum ResourceUsage {132RESOURCE_USAGE_NONE,133RESOURCE_USAGE_COPY_FROM,134RESOURCE_USAGE_COPY_TO,135RESOURCE_USAGE_RESOLVE_FROM,136RESOURCE_USAGE_RESOLVE_TO,137RESOURCE_USAGE_UNIFORM_BUFFER_READ,138RESOURCE_USAGE_INDIRECT_BUFFER_READ,139RESOURCE_USAGE_TEXTURE_BUFFER_READ,140RESOURCE_USAGE_TEXTURE_BUFFER_READ_WRITE,141RESOURCE_USAGE_STORAGE_BUFFER_READ,142RESOURCE_USAGE_STORAGE_BUFFER_READ_WRITE,143RESOURCE_USAGE_VERTEX_BUFFER_READ,144RESOURCE_USAGE_INDEX_BUFFER_READ,145RESOURCE_USAGE_TEXTURE_SAMPLE,146RESOURCE_USAGE_STORAGE_IMAGE_READ,147RESOURCE_USAGE_STORAGE_IMAGE_READ_WRITE,148RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE,149RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE,150RESOURCE_USAGE_ATTACHMENT_FRAGMENT_SHADING_RATE_READ,151RESOURCE_USAGE_ATTACHMENT_FRAGMENT_DENSITY_MAP_READ,152RESOURCE_USAGE_GENERAL,153RESOURCE_USAGE_MAX154};155156struct ResourceTracker {157uint32_t reference_count = 0;158int64_t command_frame = -1;159BitField<RDD::PipelineStageBits> previous_frame_stages = {};160BitField<RDD::PipelineStageBits> current_frame_stages = {};161int32_t read_full_command_list_index = -1;162int32_t read_slice_command_list_index = -1;163int32_t write_command_or_list_index = -1;164int32_t draw_list_index = -1;165ResourceUsage draw_list_usage = RESOURCE_USAGE_NONE;166int32_t compute_list_index = -1;167ResourceUsage compute_list_usage = RESOURCE_USAGE_NONE;168ResourceUsage usage = RESOURCE_USAGE_NONE;169BitField<RDD::BarrierAccessBits> usage_access = {};170RDD::BufferID buffer_driver_id;171RDD::TextureID texture_driver_id;172RDD::TextureSubresourceRange texture_subresources;173Size2i texture_size;174uint32_t texture_usage = 0;175int32_t texture_slice_command_index = -1;176ResourceTracker *parent = nullptr;177ResourceTracker *dirty_shared_list = nullptr;178ResourceTracker *next_shared = nullptr;179Rect2i texture_slice_or_dirty_rect;180bool in_parent_dirty_list = false;181bool write_command_list_enabled = false;182bool is_discardable = false;183184_FORCE_INLINE_ void reset_if_outdated(int64_t new_command_frame) {185if (new_command_frame != command_frame) {186command_frame = new_command_frame;187previous_frame_stages = current_frame_stages;188current_frame_stages.clear();189read_full_command_list_index = -1;190read_slice_command_list_index = -1;191write_command_or_list_index = -1;192draw_list_index = -1;193compute_list_index = -1;194texture_slice_command_index = -1;195write_command_list_enabled = false;196}197}198};199200typedef RDD::RenderPassID (*RenderPassCreationFunction)(RenderingDeviceDriver *p_driver, VectorView<RDD::AttachmentLoadOp> p_load_ops, VectorView<RDD::AttachmentStoreOp> p_store_ops, void *p_user_data);201202struct FramebufferStorage {203RDD::FramebufferID framebuffer;204RDD::RenderPassID render_pass;205};206207struct FramebufferCache {208uint32_t width = 0;209uint32_t height = 0;210LocalVector<RDD::TextureID> textures;211LocalVector<ResourceTracker *> trackers;212HashMap<uint64_t, FramebufferStorage> storage_map;213void *render_pass_creation_user_data = nullptr;214};215216struct CommandBufferPool {217// Provided by RenderingDevice.218RDD::CommandPoolID pool;219220// Created internally by RenderingDeviceGraph.221LocalVector<RDD::CommandBufferID> buffers;222LocalVector<RDD::SemaphoreID> semaphores;223uint32_t buffers_used = 0;224};225226struct WorkaroundsState {227bool draw_list_found = false;228};229230enum AttachmentOperation {231// Loads or ignores if the attachment is discardable.232ATTACHMENT_OPERATION_DEFAULT,233// Clear the attachment to a value.234ATTACHMENT_OPERATION_CLEAR,235// Ignore any contents from the attachment.236ATTACHMENT_OPERATION_IGNORE,237};238239private:240struct InstructionList {241LocalVector<uint8_t> data;242LocalVector<ResourceTracker *> command_trackers;243LocalVector<ResourceUsage> command_tracker_usages;244BitField<RDD::PipelineStageBits> stages = {};245int32_t index = 0;246247void clear() {248data.clear();249command_trackers.clear();250command_tracker_usages.clear();251stages.clear();252}253};254255struct ComputeInstructionList : InstructionList {256#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)257uint32_t breadcrumb;258#endif259};260261struct DrawInstructionList : InstructionList {262FramebufferCache *framebuffer_cache = nullptr;263RDD::RenderPassID render_pass;264RDD::FramebufferID framebuffer;265Rect2i region;266LocalVector<AttachmentOperation> attachment_operations;267LocalVector<RDD::RenderPassClearValue> attachment_clear_values;268269#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)270uint32_t breadcrumb;271#endif272bool split_cmd_buffer = false;273};274275struct RecordedCommandSort {276uint32_t level = 0;277uint32_t priority = 0;278int32_t index = -1;279280RecordedCommandSort() = default;281282bool operator<(const RecordedCommandSort &p_other) const {283if (level < p_other.level) {284return true;285} else if (level > p_other.level) {286return false;287}288289if (priority < p_other.priority) {290return true;291} else if (priority > p_other.priority) {292return false;293}294295return index < p_other.index;296}297};298299struct RecordedCommandListNode {300int32_t command_index = -1;301int32_t next_list_index = -1;302};303304struct RecordedSliceListNode {305int32_t command_index = -1;306int32_t next_list_index = -1;307Rect2i subresources;308bool partial_coverage = false;309};310311struct RecordedBufferClearCommand : RecordedCommand {312RDD::BufferID buffer;313uint32_t offset = 0;314uint32_t size = 0;315};316317struct RecordedBufferCopyCommand : RecordedCommand {318RDD::BufferID source;319RDD::BufferID destination;320RDD::BufferCopyRegion region;321};322323struct RecordedBufferGetDataCommand : RecordedCommand {324RDD::BufferID source;325RDD::BufferID destination;326RDD::BufferCopyRegion region;327};328329struct RecordedBufferUpdateCommand : RecordedCommand {330RDD::BufferID destination;331uint32_t buffer_copies_count = 0;332333_FORCE_INLINE_ RecordedBufferCopy *buffer_copies() {334return reinterpret_cast<RecordedBufferCopy *>(&this[1]);335}336337_FORCE_INLINE_ const RecordedBufferCopy *buffer_copies() const {338return reinterpret_cast<const RecordedBufferCopy *>(&this[1]);339}340};341342struct RecordedDriverCallbackCommand : RecordedCommand {343RDD::DriverCallback callback;344void *userdata = nullptr;345};346347struct RecordedComputeListCommand : RecordedCommand {348uint32_t instruction_data_size = 0;349uint32_t breadcrumb = 0;350351_FORCE_INLINE_ uint8_t *instruction_data() {352return reinterpret_cast<uint8_t *>(&this[1]);353}354355_FORCE_INLINE_ const uint8_t *instruction_data() const {356return reinterpret_cast<const uint8_t *>(&this[1]);357}358};359360struct RecordedDrawListCommand : RecordedCommand {361FramebufferCache *framebuffer_cache = nullptr;362RDD::FramebufferID framebuffer;363RDD::RenderPassID render_pass;364uint32_t instruction_data_size = 0;365RDD::CommandBufferType command_buffer_type;366Rect2i region;367uint32_t clear_values_count = 0;368uint32_t trackers_count = 0;369370#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)371uint32_t breadcrumb = 0;372#endif373bool split_cmd_buffer = false;374375_FORCE_INLINE_ RDD::RenderPassClearValue *clear_values() {376return reinterpret_cast<RDD::RenderPassClearValue *>(&this[1]);377}378379_FORCE_INLINE_ const RDD::RenderPassClearValue *clear_values() const {380return reinterpret_cast<const RDD::RenderPassClearValue *>(&this[1]);381}382383_FORCE_INLINE_ ResourceTracker **trackers() {384return reinterpret_cast<ResourceTracker **>(&clear_values()[clear_values_count]);385}386387_FORCE_INLINE_ ResourceTracker *const *trackers() const {388return reinterpret_cast<ResourceTracker *const *>(&clear_values()[clear_values_count]);389}390391_FORCE_INLINE_ RDD::AttachmentLoadOp *load_ops() {392return reinterpret_cast<RDD::AttachmentLoadOp *>(&trackers()[trackers_count]);393}394395_FORCE_INLINE_ const RDD::AttachmentLoadOp *load_ops() const {396return reinterpret_cast<const RDD::AttachmentLoadOp *>(&trackers()[trackers_count]);397}398399_FORCE_INLINE_ RDD::AttachmentStoreOp *store_ops() {400return reinterpret_cast<RDD::AttachmentStoreOp *>(&load_ops()[trackers_count]);401}402403_FORCE_INLINE_ const RDD::AttachmentStoreOp *store_ops() const {404return reinterpret_cast<const RDD::AttachmentStoreOp *>(&load_ops()[trackers_count]);405}406407_FORCE_INLINE_ uint8_t *instruction_data() {408return reinterpret_cast<uint8_t *>(&store_ops()[trackers_count]);409}410411_FORCE_INLINE_ const uint8_t *instruction_data() const {412return reinterpret_cast<const uint8_t *>(&store_ops()[trackers_count]);413}414};415416struct RecordedTextureClearCommand : RecordedCommand {417RDD::TextureID texture;418RDD::TextureSubresourceRange range;419Color color;420};421422struct RecordedTextureCopyCommand : RecordedCommand {423RDD::TextureID from_texture;424RDD::TextureID to_texture;425uint32_t texture_copy_regions_count = 0;426427_FORCE_INLINE_ RDD::TextureCopyRegion *texture_copy_regions() {428return reinterpret_cast<RDD::TextureCopyRegion *>(&this[1]);429}430431_FORCE_INLINE_ const RDD::TextureCopyRegion *texture_copy_regions() const {432return reinterpret_cast<const RDD::TextureCopyRegion *>(&this[1]);433}434};435436struct RecordedTextureGetDataCommand : RecordedCommand {437RDD::TextureID from_texture;438RDD::BufferID to_buffer;439uint32_t buffer_texture_copy_regions_count = 0;440441_FORCE_INLINE_ RDD::BufferTextureCopyRegion *buffer_texture_copy_regions() {442return reinterpret_cast<RDD::BufferTextureCopyRegion *>(&this[1]);443}444445_FORCE_INLINE_ const RDD::BufferTextureCopyRegion *buffer_texture_copy_regions() const {446return reinterpret_cast<const RDD::BufferTextureCopyRegion *>(&this[1]);447}448};449450struct RecordedTextureResolveCommand : RecordedCommand {451RDD::TextureID from_texture;452RDD::TextureID to_texture;453uint32_t src_layer = 0;454uint32_t src_mipmap = 0;455uint32_t dst_layer = 0;456uint32_t dst_mipmap = 0;457};458459struct RecordedTextureUpdateCommand : RecordedCommand {460RDD::TextureID to_texture;461uint32_t buffer_to_texture_copies_count = 0;462463_FORCE_INLINE_ RecordedBufferToTextureCopy *buffer_to_texture_copies() {464return reinterpret_cast<RecordedBufferToTextureCopy *>(&this[1]);465}466467_FORCE_INLINE_ const RecordedBufferToTextureCopy *buffer_to_texture_copies() const {468return reinterpret_cast<const RecordedBufferToTextureCopy *>(&this[1]);469}470};471472struct RecordedCaptureTimestampCommand : RecordedCommand {473RDD::QueryPoolID pool;474uint32_t index = 0;475};476477struct DrawListBindIndexBufferInstruction : DrawListInstruction {478RDD::BufferID buffer;479RenderingDeviceCommons::IndexBufferFormat format;480uint32_t offset = 0;481};482483struct DrawListBindPipelineInstruction : DrawListInstruction {484RDD::PipelineID pipeline;485};486487struct DrawListBindUniformSetsInstruction : DrawListInstruction {488RDD::ShaderID shader;489uint32_t first_set_index = 0;490uint32_t set_count = 0;491492_FORCE_INLINE_ RDD::UniformSetID *uniform_set_ids() {493return reinterpret_cast<RDD::UniformSetID *>(&this[1]);494}495496_FORCE_INLINE_ const RDD::UniformSetID *uniform_set_ids() const {497return reinterpret_cast<const RDD::UniformSetID *>(&this[1]);498}499};500501struct DrawListBindVertexBuffersInstruction : DrawListInstruction {502uint32_t vertex_buffers_count = 0;503504_FORCE_INLINE_ RDD::BufferID *vertex_buffers() {505return reinterpret_cast<RDD::BufferID *>(&this[1]);506}507508_FORCE_INLINE_ const RDD::BufferID *vertex_buffers() const {509return reinterpret_cast<const RDD::BufferID *>(&this[1]);510}511512_FORCE_INLINE_ uint64_t *vertex_buffer_offsets() {513return reinterpret_cast<uint64_t *>(&vertex_buffers()[vertex_buffers_count]);514}515516_FORCE_INLINE_ const uint64_t *vertex_buffer_offsets() const {517return reinterpret_cast<const uint64_t *>(&vertex_buffers()[vertex_buffers_count]);518}519};520521struct DrawListClearAttachmentsInstruction : DrawListInstruction {522uint32_t attachments_clear_count = 0;523uint32_t attachments_clear_rect_count = 0;524525_FORCE_INLINE_ RDD::AttachmentClear *attachments_clear() {526return reinterpret_cast<RDD::AttachmentClear *>(&this[1]);527}528529_FORCE_INLINE_ const RDD::AttachmentClear *attachments_clear() const {530return reinterpret_cast<const RDD::AttachmentClear *>(&this[1]);531}532533_FORCE_INLINE_ Rect2i *attachments_clear_rect() {534return reinterpret_cast<Rect2i *>(&attachments_clear()[attachments_clear_count]);535}536537_FORCE_INLINE_ const Rect2i *attachments_clear_rect() const {538return reinterpret_cast<const Rect2i *>(&attachments_clear()[attachments_clear_count]);539}540};541542struct DrawListDrawInstruction : DrawListInstruction {543uint32_t vertex_count = 0;544uint32_t instance_count = 0;545};546547struct DrawListDrawIndexedInstruction : DrawListInstruction {548uint32_t index_count = 0;549uint32_t instance_count = 0;550uint32_t first_index = 0;551};552553struct DrawListDrawIndirectInstruction : DrawListInstruction {554RDD::BufferID buffer;555uint32_t offset = 0;556uint32_t draw_count = 0;557uint32_t stride = 0;558};559560struct DrawListDrawIndexedIndirectInstruction : DrawListInstruction {561RDD::BufferID buffer;562uint32_t offset = 0;563uint32_t draw_count = 0;564uint32_t stride = 0;565};566567struct DrawListEndRenderPassInstruction : DrawListInstruction {568// No contents.569};570571struct DrawListExecuteCommandsInstruction : DrawListInstruction {572RDD::CommandBufferID command_buffer;573};574575struct DrawListSetPushConstantInstruction : DrawListInstruction {576uint32_t size = 0;577RDD::ShaderID shader;578579_FORCE_INLINE_ uint8_t *data() {580return reinterpret_cast<uint8_t *>(&this[1]);581}582583_FORCE_INLINE_ const uint8_t *data() const {584return reinterpret_cast<const uint8_t *>(&this[1]);585}586};587588struct DrawListNextSubpassInstruction : DrawListInstruction {589RDD::CommandBufferType command_buffer_type;590};591592struct DrawListSetBlendConstantsInstruction : DrawListInstruction {593Color color;594};595596struct DrawListSetLineWidthInstruction : DrawListInstruction {597float width;598};599600struct DrawListSetScissorInstruction : DrawListInstruction {601Rect2i rect;602};603604struct DrawListSetViewportInstruction : DrawListInstruction {605Rect2i rect;606};607608struct DrawListUniformSetPrepareForUseInstruction : DrawListInstruction {609RDD::UniformSetID uniform_set;610RDD::ShaderID shader;611uint32_t set_index = 0;612};613614struct ComputeListBindPipelineInstruction : ComputeListInstruction {615RDD::PipelineID pipeline;616};617618struct ComputeListBindUniformSetsInstruction : ComputeListInstruction {619RDD::ShaderID shader;620uint32_t first_set_index = 0;621uint32_t set_count = 0;622623_FORCE_INLINE_ RDD::UniformSetID *uniform_set_ids() {624return reinterpret_cast<RDD::UniformSetID *>(&this[1]);625}626627_FORCE_INLINE_ const RDD::UniformSetID *uniform_set_ids() const {628return reinterpret_cast<const RDD::UniformSetID *>(&this[1]);629}630};631632struct ComputeListDispatchInstruction : ComputeListInstruction {633uint32_t x_groups = 0;634uint32_t y_groups = 0;635uint32_t z_groups = 0;636};637638struct ComputeListDispatchIndirectInstruction : ComputeListInstruction {639RDD::BufferID buffer;640uint32_t offset = 0;641};642643struct ComputeListSetPushConstantInstruction : ComputeListInstruction {644uint32_t size = 0;645RDD::ShaderID shader;646647_FORCE_INLINE_ uint8_t *data() {648return reinterpret_cast<uint8_t *>(&this[1]);649}650651_FORCE_INLINE_ const uint8_t *data() const {652return reinterpret_cast<const uint8_t *>(&this[1]);653}654};655656struct ComputeListUniformSetPrepareForUseInstruction : ComputeListInstruction {657RDD::UniformSetID uniform_set;658RDD::ShaderID shader;659uint32_t set_index = 0;660};661662struct BarrierGroup {663BitField<RDD::PipelineStageBits> src_stages = {};664BitField<RDD::PipelineStageBits> dst_stages = {};665RDD::MemoryBarrier memory_barrier;666LocalVector<RDD::TextureBarrier> normalization_barriers;667LocalVector<RDD::TextureBarrier> transition_barriers;668#if USE_BUFFER_BARRIERS669LocalVector<RDD::BufferBarrier> buffer_barriers;670#endif671672void clear() {673src_stages.clear();674dst_stages.clear();675memory_barrier.src_access.clear();676memory_barrier.dst_access.clear();677normalization_barriers.clear();678transition_barriers.clear();679#if USE_BUFFER_BARRIERS680buffer_barriers.clear();681#endif682}683};684685struct SecondaryCommandBuffer {686LocalVector<uint8_t> instruction_data;687RDD::CommandBufferID command_buffer;688RDD::CommandPoolID command_pool;689RDD::RenderPassID render_pass;690RDD::FramebufferID framebuffer;691WorkerThreadPool::TaskID task;692};693694struct Frame {695TightLocalVector<SecondaryCommandBuffer> secondary_command_buffers;696uint32_t secondary_command_buffers_used = 0;697};698699RDD *driver = nullptr;700RenderingContextDriver::Device device;701RenderPassCreationFunction render_pass_creation_function = nullptr;702int64_t tracking_frame = 0;703LocalVector<uint8_t> command_data;704LocalVector<uint32_t> command_data_offsets;705LocalVector<RDD::TextureBarrier> command_normalization_barriers;706LocalVector<RDD::TextureBarrier> command_transition_barriers;707LocalVector<RDD::BufferBarrier> command_buffer_barriers;708LocalVector<char> command_label_chars;709LocalVector<Color> command_label_colors;710LocalVector<uint32_t> command_label_offsets;711int32_t command_label_index = -1;712DrawInstructionList draw_instruction_list;713ComputeInstructionList compute_instruction_list;714uint32_t command_count = 0;715uint32_t command_label_count = 0;716LocalVector<RecordedCommandListNode> command_list_nodes;717LocalVector<RecordedSliceListNode> read_slice_list_nodes;718LocalVector<RecordedSliceListNode> write_slice_list_nodes;719int32_t command_timestamp_index = -1;720int32_t command_synchronization_index = -1;721bool command_synchronization_pending = false;722BarrierGroup barrier_group;723bool driver_honors_barriers : 1;724bool driver_clears_with_copy_engine : 1;725bool driver_buffers_require_transitions : 1;726WorkaroundsState workarounds_state;727TightLocalVector<Frame> frames;728uint32_t frame = 0;729730#ifdef DEV_ENABLED731RBMap<ResourceTracker *, uint32_t> write_dependency_counters;732#endif733734static String _usage_to_string(ResourceUsage p_usage);735static bool _is_write_usage(ResourceUsage p_usage);736static RDD::TextureLayout _usage_to_image_layout(ResourceUsage p_usage);737static RDD::BarrierAccessBits _usage_to_access_bits(ResourceUsage p_usage);738bool _check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) const;739bool _check_command_partial_coverage(ResourceTracker *p_resource_tracker, int32_t p_command_index) const;740int32_t _add_to_command_list(int32_t p_command_index, int32_t p_list_index);741void _add_adjacent_command(int32_t p_previous_command_index, int32_t p_command_index, RecordedCommand *r_command);742int32_t _add_to_slice_read_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index);743int32_t _add_to_write_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index, bool p_partial_coverage);744RecordedCommand *_allocate_command(uint32_t p_command_size, int32_t &r_command_index);745DrawListInstruction *_allocate_draw_list_instruction(uint32_t p_instruction_size);746ComputeListInstruction *_allocate_compute_list_instruction(uint32_t p_instruction_size);747void _check_discardable_attachment_dependency(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index);748void _add_command_to_graph(ResourceTracker **p_resource_trackers, ResourceUsage *p_resource_usages, uint32_t p_resource_count, int32_t p_command_index, RecordedCommand *r_command);749void _add_texture_barrier_to_command(RDD::TextureID p_texture_id, BitField<RDD::BarrierAccessBits> p_src_access, BitField<RDD::BarrierAccessBits> p_dst_access, ResourceUsage p_prev_usage, ResourceUsage p_next_usage, RDD::TextureSubresourceRange p_subresources, LocalVector<RDD::TextureBarrier> &r_barrier_vector, int32_t &r_barrier_index, int32_t &r_barrier_count);750#if USE_BUFFER_BARRIERS751void _add_buffer_barrier_to_command(RDD::BufferID p_buffer_id, BitField<RDD::BarrierAccessBits> p_src_access, BitField<RDD::BarrierAccessBits> p_dst_access, int32_t &r_barrier_index, int32_t &r_barrier_count);752#endif753void _run_compute_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);754void _get_draw_list_render_pass_and_framebuffer(const RecordedDrawListCommand *p_draw_list_command, RDD::RenderPassID &r_render_pass, RDD::FramebufferID &r_framebuffer);755void _run_draw_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);756void _add_draw_list_begin(FramebufferCache *p_framebuffer_cache, RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<AttachmentOperation> p_attachment_operations, VectorView<RDD::RenderPassClearValue> p_attachment_clear_values, BitField<RDD::PipelineStageBits> p_stages, uint32_t p_breadcrumb, bool p_split_cmd_buffer);757void _run_secondary_command_buffer_task(const SecondaryCommandBuffer *p_secondary);758void _wait_for_secondary_command_buffer_tasks();759void _run_render_commands(int32_t p_level, const RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count, RDD::CommandBufferID &r_command_buffer, CommandBufferPool &r_command_buffer_pool, int32_t &r_current_label_index, int32_t &r_current_label_level);760void _run_label_command_change(RDD::CommandBufferID p_command_buffer, int32_t p_new_label_index, int32_t p_new_level, bool p_ignore_previous_value, bool p_use_label_for_empty, const RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count, int32_t &r_current_label_index, int32_t &r_current_label_level);761void _boost_priority_for_render_commands(RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count, uint32_t &r_boosted_priority);762void _group_barriers_for_render_commands(RDD::CommandBufferID p_command_buffer, const RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count, bool p_full_memory_barrier);763void _print_render_commands(const RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count);764void _print_draw_list(const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);765void _print_compute_list(const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);766767public:768RenderingDeviceGraph();769~RenderingDeviceGraph();770void initialize(RDD *p_driver, RenderingContextDriver::Device p_device, RenderPassCreationFunction p_render_pass_creation_function, uint32_t p_frame_count, RDD::CommandQueueFamilyID p_secondary_command_queue_family, uint32_t p_secondary_command_buffers_per_frame);771void finalize();772void begin();773void add_buffer_clear(RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, uint32_t p_offset, uint32_t p_size);774void add_buffer_copy(RDD::BufferID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, RDD::BufferCopyRegion p_region);775void add_buffer_get_data(RDD::BufferID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, RDD::BufferCopyRegion p_region);776void add_buffer_update(RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, VectorView<RecordedBufferCopy> p_buffer_copies);777void add_driver_callback(RDD::DriverCallback p_callback, void *p_userdata, VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);778void add_compute_list_begin(RDD::BreadcrumbMarker p_phase = RDD::BreadcrumbMarker::NONE, uint32_t p_breadcrumb_data = 0);779void add_compute_list_bind_pipeline(RDD::PipelineID p_pipeline);780void add_compute_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);781void add_compute_list_bind_uniform_sets(RDD::ShaderID p_shader, VectorView<RDD::UniformSetID> p_uniform_set, uint32_t p_first_set_index, uint32_t p_set_count);782void add_compute_list_dispatch(uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups);783void add_compute_list_dispatch_indirect(RDD::BufferID p_buffer, uint32_t p_offset);784void add_compute_list_set_push_constant(RDD::ShaderID p_shader, const void *p_data, uint32_t p_data_size);785void add_compute_list_uniform_set_prepare_for_use(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);786void add_compute_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage);787void add_compute_list_usages(VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);788void add_compute_list_end();789void add_draw_list_begin(FramebufferCache *p_framebuffer_cache, Rect2i p_region, VectorView<AttachmentOperation> p_attachment_operations, VectorView<RDD::RenderPassClearValue> p_attachment_clear_values, BitField<RDD::PipelineStageBits> p_stages, uint32_t p_breadcrumb = 0, bool p_split_cmd_buffer = false);790void add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<AttachmentOperation> p_attachment_operations, VectorView<RDD::RenderPassClearValue> p_attachment_clear_values, BitField<RDD::PipelineStageBits> p_stages, uint32_t p_breadcrumb = 0, bool p_split_cmd_buffer = false);791void add_draw_list_bind_index_buffer(RDD::BufferID p_buffer, RDD::IndexBufferFormat p_format, uint32_t p_offset);792void add_draw_list_bind_pipeline(RDD::PipelineID p_pipeline, BitField<RDD::PipelineStageBits> p_pipeline_stage_bits);793void add_draw_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);794void add_draw_list_bind_uniform_sets(RDD::ShaderID p_shader, VectorView<RDD::UniformSetID> p_uniform_set, uint32_t p_first_index, uint32_t p_set_count);795void add_draw_list_bind_vertex_buffers(VectorView<RDD::BufferID> p_vertex_buffers, VectorView<uint64_t> p_vertex_buffer_offsets);796void add_draw_list_clear_attachments(VectorView<RDD::AttachmentClear> p_attachments_clear, VectorView<Rect2i> p_attachments_clear_rect);797void add_draw_list_draw(uint32_t p_vertex_count, uint32_t p_instance_count);798void add_draw_list_draw_indexed(uint32_t p_index_count, uint32_t p_instance_count, uint32_t p_first_index);799void add_draw_list_draw_indirect(RDD::BufferID p_buffer, uint32_t p_offset, uint32_t p_draw_count, uint32_t p_stride);800void add_draw_list_draw_indexed_indirect(RDD::BufferID p_buffer, uint32_t p_offset, uint32_t p_draw_count, uint32_t p_stride);801void add_draw_list_execute_commands(RDD::CommandBufferID p_command_buffer);802void add_draw_list_next_subpass(RDD::CommandBufferType p_command_buffer_type);803void add_draw_list_set_blend_constants(const Color &p_color);804void add_draw_list_set_line_width(float p_width);805void add_draw_list_set_push_constant(RDD::ShaderID p_shader, const void *p_data, uint32_t p_data_size);806void add_draw_list_set_scissor(Rect2i p_rect);807void add_draw_list_set_viewport(Rect2i p_rect);808void add_draw_list_uniform_set_prepare_for_use(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);809void add_draw_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage);810void add_draw_list_usages(VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);811void add_draw_list_end();812void add_texture_clear(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, const Color &p_color, const RDD::TextureSubresourceRange &p_range);813void add_texture_copy(RDD::TextureID p_src, ResourceTracker *p_src_tracker, RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, VectorView<RDD::TextureCopyRegion> p_texture_copy_regions);814void add_texture_get_data(RDD::TextureID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, VectorView<RDD::BufferTextureCopyRegion> p_buffer_texture_copy_regions, ResourceTracker *p_dst_tracker = nullptr);815void add_texture_resolve(RDD::TextureID p_src, ResourceTracker *p_src_tracker, RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, uint32_t p_src_layer, uint32_t p_src_mipmap, uint32_t p_dst_layer, uint32_t p_dst_mipmap);816void add_texture_update(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, VectorView<RecordedBufferToTextureCopy> p_buffer_copies, VectorView<ResourceTracker *> p_buffer_trackers = VectorView<ResourceTracker *>());817void add_capture_timestamp(RDD::QueryPoolID p_query_pool, uint32_t p_index);818void add_synchronization();819void begin_label(const Span<char> &p_label_name, const Color &p_color);820void end_label();821void end(bool p_reorder_commands, bool p_full_barriers, RDD::CommandBufferID &r_command_buffer, CommandBufferPool &r_command_buffer_pool);822static ResourceTracker *resource_tracker_create();823static void resource_tracker_free(ResourceTracker *p_tracker);824static FramebufferCache *framebuffer_cache_create();825static void framebuffer_cache_free(RDD *p_driver, FramebufferCache *p_cache);826};827828using RDG = RenderingDeviceGraph;829830831