Path: blob/master/servers/rendering/rendering_device_graph.h
20837 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 RaytracingListInstruction {47enum Type {48TYPE_NONE,49TYPE_BIND_PIPELINE,50TYPE_BIND_UNIFORM_SET,51TYPE_SET_PUSH_CONSTANT,52TYPE_TRACE_RAYS,53TYPE_UNIFORM_SET_PREPARE_FOR_USE,54};5556Type type = TYPE_NONE;57};5859struct ComputeListInstruction {60enum Type {61TYPE_NONE,62TYPE_BIND_PIPELINE,63TYPE_BIND_UNIFORM_SETS,64TYPE_DISPATCH,65TYPE_DISPATCH_INDIRECT,66TYPE_SET_PUSH_CONSTANT,67TYPE_UNIFORM_SET_PREPARE_FOR_USE68};6970Type type = TYPE_NONE;71};7273struct DrawListInstruction {74enum Type {75TYPE_NONE,76TYPE_BIND_INDEX_BUFFER,77TYPE_BIND_PIPELINE,78TYPE_BIND_UNIFORM_SETS,79TYPE_BIND_VERTEX_BUFFERS,80TYPE_CLEAR_ATTACHMENTS,81TYPE_DRAW,82TYPE_DRAW_INDEXED,83TYPE_DRAW_INDIRECT,84TYPE_DRAW_INDEXED_INDIRECT,85TYPE_EXECUTE_COMMANDS,86TYPE_NEXT_SUBPASS,87TYPE_SET_BLEND_CONSTANTS,88TYPE_SET_LINE_WIDTH,89TYPE_SET_PUSH_CONSTANT,90TYPE_SET_SCISSOR,91TYPE_SET_VIEWPORT,92TYPE_UNIFORM_SET_PREPARE_FOR_USE93};9495Type type = TYPE_NONE;96};9798struct RecordedCommand {99enum Type {100TYPE_NONE,101TYPE_ACCELERATION_STRUCTURE_BUILD,102TYPE_BUFFER_CLEAR,103TYPE_BUFFER_COPY,104TYPE_BUFFER_GET_DATA,105TYPE_BUFFER_UPDATE,106TYPE_COMPUTE_LIST,107TYPE_RAYTRACING_LIST,108TYPE_DRAW_LIST,109TYPE_TEXTURE_CLEAR_COLOR,110TYPE_TEXTURE_CLEAR_DEPTH_STENCIL,111TYPE_TEXTURE_COPY,112TYPE_TEXTURE_GET_DATA,113TYPE_TEXTURE_RESOLVE,114TYPE_TEXTURE_UPDATE,115TYPE_CAPTURE_TIMESTAMP,116TYPE_DRIVER_CALLBACK,117TYPE_MAX118};119120Type type = TYPE_NONE;121int32_t adjacent_command_list_index = -1;122RDD::MemoryAccessBarrier memory_barrier;123int32_t normalization_barrier_index = -1;124int normalization_barrier_count = 0;125int32_t transition_barrier_index = -1;126int32_t transition_barrier_count = 0;127#if USE_BUFFER_BARRIERS128int32_t buffer_barrier_index = -1;129int32_t buffer_barrier_count = 0;130#endif131int32_t acceleration_structure_barrier_index = -1;132int32_t acceleration_structure_barrier_count = 0;133int32_t label_index = -1;134BitField<RDD::PipelineStageBits> previous_stages = {};135BitField<RDD::PipelineStageBits> next_stages = {};136BitField<RDD::PipelineStageBits> self_stages = {};137};138139struct RecordedBufferCopy {140RDD::BufferID source;141RDD::BufferCopyRegion region;142};143144struct RecordedBufferToTextureCopy {145RDD::BufferID from_buffer;146RDD::BufferTextureCopyRegion region;147};148149enum ResourceUsage {150RESOURCE_USAGE_NONE,151RESOURCE_USAGE_COPY_FROM,152RESOURCE_USAGE_COPY_TO,153RESOURCE_USAGE_RESOLVE_FROM,154RESOURCE_USAGE_RESOLVE_TO,155RESOURCE_USAGE_UNIFORM_BUFFER_READ,156RESOURCE_USAGE_INDIRECT_BUFFER_READ,157RESOURCE_USAGE_TEXTURE_BUFFER_READ,158RESOURCE_USAGE_TEXTURE_BUFFER_READ_WRITE,159RESOURCE_USAGE_STORAGE_BUFFER_READ,160RESOURCE_USAGE_STORAGE_BUFFER_READ_WRITE,161RESOURCE_USAGE_VERTEX_BUFFER_READ,162RESOURCE_USAGE_INDEX_BUFFER_READ,163RESOURCE_USAGE_TEXTURE_SAMPLE,164RESOURCE_USAGE_STORAGE_IMAGE_READ,165RESOURCE_USAGE_STORAGE_IMAGE_READ_WRITE,166RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE,167RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE,168RESOURCE_USAGE_ATTACHMENT_FRAGMENT_SHADING_RATE_READ,169RESOURCE_USAGE_ATTACHMENT_FRAGMENT_DENSITY_MAP_READ,170RESOURCE_USAGE_GENERAL,171RESOURCE_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT,172RESOURCE_USAGE_ACCELERATION_STRUCTURE_READ,173RESOURCE_USAGE_ACCELERATION_STRUCTURE_READ_WRITE,174RESOURCE_USAGE_MAX175};176177struct ResourceTracker {178uint32_t reference_count = 0;179int64_t command_frame = -1;180BitField<RDD::PipelineStageBits> previous_frame_stages = {};181BitField<RDD::PipelineStageBits> current_frame_stages = {};182int32_t read_full_command_list_index = -1;183int32_t read_slice_command_list_index = -1;184int32_t write_command_or_list_index = -1;185int32_t draw_list_index = -1;186ResourceUsage draw_list_usage = RESOURCE_USAGE_NONE;187int32_t compute_list_index = -1;188int32_t raytracing_list_index = -1;189ResourceUsage compute_list_usage = RESOURCE_USAGE_NONE;190ResourceUsage raytracing_list_usage = RESOURCE_USAGE_NONE;191ResourceUsage usage = RESOURCE_USAGE_NONE;192BitField<RDD::BarrierAccessBits> usage_access = {};193RDD::BufferID buffer_driver_id;194RDD::TextureID texture_driver_id;195RDD::AccelerationStructureID acceleration_structure_driver_id;196RDD::TextureSubresourceRange texture_subresources;197Size2i texture_size;198uint32_t texture_usage = 0;199int32_t texture_slice_command_index = -1;200ResourceTracker *parent = nullptr;201ResourceTracker *dirty_shared_list = nullptr;202ResourceTracker *next_shared = nullptr;203Rect2i texture_slice_or_dirty_rect;204bool in_parent_dirty_list = false;205bool write_command_list_enabled = false;206bool is_discardable = false;207208_FORCE_INLINE_ void reset_if_outdated(int64_t new_command_frame) {209if (new_command_frame != command_frame) {210command_frame = new_command_frame;211previous_frame_stages = current_frame_stages;212current_frame_stages.clear();213read_full_command_list_index = -1;214read_slice_command_list_index = -1;215write_command_or_list_index = -1;216draw_list_index = -1;217compute_list_index = -1;218raytracing_list_index = -1;219texture_slice_command_index = -1;220write_command_list_enabled = false;221}222}223};224225typedef RDD::RenderPassID (*RenderPassCreationFunction)(RenderingDeviceDriver *p_driver, VectorView<RDD::AttachmentLoadOp> p_load_ops, VectorView<RDD::AttachmentStoreOp> p_store_ops, void *p_user_data);226227struct FramebufferStorage {228RDD::FramebufferID framebuffer;229RDD::RenderPassID render_pass;230};231232struct FramebufferCache {233uint32_t width = 0;234uint32_t height = 0;235LocalVector<RDD::TextureID> textures;236LocalVector<ResourceTracker *> trackers;237HashMap<uint64_t, FramebufferStorage> storage_map;238void *render_pass_creation_user_data = nullptr;239};240241struct CommandBufferPool {242// Provided by RenderingDevice.243RDD::CommandPoolID pool;244245// Created internally by RenderingDeviceGraph.246LocalVector<RDD::CommandBufferID> buffers;247LocalVector<RDD::SemaphoreID> semaphores;248uint32_t buffers_used = 0;249};250251struct WorkaroundsState {252bool draw_list_found = false;253};254255enum AttachmentOperation {256// Loads or ignores if the attachment is discardable.257ATTACHMENT_OPERATION_DEFAULT,258// Clear the attachment to a value.259ATTACHMENT_OPERATION_CLEAR,260// Ignore any contents from the attachment.261ATTACHMENT_OPERATION_IGNORE,262};263264private:265struct InstructionList {266LocalVector<uint8_t> data;267LocalVector<ResourceTracker *> command_trackers;268LocalVector<ResourceUsage> command_tracker_usages;269BitField<RDD::PipelineStageBits> stages = {};270int32_t index = 0;271272void clear() {273data.clear();274command_trackers.clear();275command_tracker_usages.clear();276stages.clear();277}278};279280struct ComputeInstructionList : InstructionList {281#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)282uint32_t breadcrumb;283#endif284};285286struct RaytracingInstructionList : InstructionList {287// No extra contents.288};289290struct DrawInstructionList : InstructionList {291FramebufferCache *framebuffer_cache = nullptr;292RDD::RenderPassID render_pass;293RDD::FramebufferID framebuffer;294Rect2i region;295LocalVector<AttachmentOperation> attachment_operations;296LocalVector<RDD::RenderPassClearValue> attachment_clear_values;297298#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)299uint32_t breadcrumb;300#endif301bool split_cmd_buffer = false;302};303304struct RecordedCommandSort {305uint32_t level = 0;306uint32_t priority = 0;307int32_t index = -1;308309RecordedCommandSort() = default;310311bool operator<(const RecordedCommandSort &p_other) const {312if (level < p_other.level) {313return true;314} else if (level > p_other.level) {315return false;316}317318if (priority < p_other.priority) {319return true;320} else if (priority > p_other.priority) {321return false;322}323324return index < p_other.index;325}326};327328struct RecordedCommandListNode {329int32_t command_index = -1;330int32_t next_list_index = -1;331};332333struct RecordedSliceListNode {334int32_t command_index = -1;335int32_t next_list_index = -1;336Rect2i subresources;337bool partial_coverage = false;338};339340struct RecordedAccelerationStructureBuildCommand : RecordedCommand {341RDD::AccelerationStructureID acceleration_structure;342RDD::BufferID scratch_buffer;343};344345struct RecordedBufferClearCommand : RecordedCommand {346RDD::BufferID buffer;347uint32_t offset = 0;348uint32_t size = 0;349};350351struct RecordedBufferCopyCommand : RecordedCommand {352RDD::BufferID source;353RDD::BufferID destination;354RDD::BufferCopyRegion region;355};356357struct RecordedBufferGetDataCommand : RecordedCommand {358RDD::BufferID source;359RDD::BufferID destination;360RDD::BufferCopyRegion region;361};362363struct RecordedBufferUpdateCommand : RecordedCommand {364RDD::BufferID destination;365uint32_t buffer_copies_count = 0;366367_FORCE_INLINE_ RecordedBufferCopy *buffer_copies() {368return reinterpret_cast<RecordedBufferCopy *>(&this[1]);369}370371_FORCE_INLINE_ const RecordedBufferCopy *buffer_copies() const {372return reinterpret_cast<const RecordedBufferCopy *>(&this[1]);373}374};375376struct RecordedDriverCallbackCommand : RecordedCommand {377RDD::DriverCallback callback;378void *userdata = nullptr;379};380381struct RecordedRaytracingListCommand : RecordedCommand {382uint32_t instruction_data_size = 0;383384_FORCE_INLINE_ uint8_t *instruction_data() {385return reinterpret_cast<uint8_t *>(&this[1]);386}387388_FORCE_INLINE_ const uint8_t *instruction_data() const {389return reinterpret_cast<const uint8_t *>(&this[1]);390}391};392393struct RecordedComputeListCommand : RecordedCommand {394uint32_t instruction_data_size = 0;395uint32_t breadcrumb = 0;396397_FORCE_INLINE_ uint8_t *instruction_data() {398return reinterpret_cast<uint8_t *>(&this[1]);399}400401_FORCE_INLINE_ const uint8_t *instruction_data() const {402return reinterpret_cast<const uint8_t *>(&this[1]);403}404};405406struct RecordedDrawListCommand : RecordedCommand {407FramebufferCache *framebuffer_cache = nullptr;408RDD::FramebufferID framebuffer;409RDD::RenderPassID render_pass;410uint32_t instruction_data_size = 0;411RDD::CommandBufferType command_buffer_type;412Rect2i region;413uint32_t clear_values_count = 0;414uint32_t trackers_count = 0;415416#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)417uint32_t breadcrumb = 0;418#endif419bool split_cmd_buffer = false;420421_FORCE_INLINE_ RDD::RenderPassClearValue *clear_values() {422return reinterpret_cast<RDD::RenderPassClearValue *>(&this[1]);423}424425_FORCE_INLINE_ const RDD::RenderPassClearValue *clear_values() const {426return reinterpret_cast<const RDD::RenderPassClearValue *>(&this[1]);427}428429_FORCE_INLINE_ ResourceTracker **trackers() {430return reinterpret_cast<ResourceTracker **>(&clear_values()[clear_values_count]);431}432433_FORCE_INLINE_ ResourceTracker *const *trackers() const {434return reinterpret_cast<ResourceTracker *const *>(&clear_values()[clear_values_count]);435}436437_FORCE_INLINE_ RDD::AttachmentLoadOp *load_ops() {438return reinterpret_cast<RDD::AttachmentLoadOp *>(&trackers()[trackers_count]);439}440441_FORCE_INLINE_ const RDD::AttachmentLoadOp *load_ops() const {442return reinterpret_cast<const RDD::AttachmentLoadOp *>(&trackers()[trackers_count]);443}444445_FORCE_INLINE_ RDD::AttachmentStoreOp *store_ops() {446return reinterpret_cast<RDD::AttachmentStoreOp *>(&load_ops()[trackers_count]);447}448449_FORCE_INLINE_ const RDD::AttachmentStoreOp *store_ops() const {450return reinterpret_cast<const RDD::AttachmentStoreOp *>(&load_ops()[trackers_count]);451}452453_FORCE_INLINE_ uint8_t *instruction_data() {454return reinterpret_cast<uint8_t *>(&store_ops()[trackers_count]);455}456457_FORCE_INLINE_ const uint8_t *instruction_data() const {458return reinterpret_cast<const uint8_t *>(&store_ops()[trackers_count]);459}460};461462struct RecordedTextureClearColorCommand : RecordedCommand {463RDD::TextureID texture;464RDD::TextureSubresourceRange range;465Color color;466};467468struct RecordedTextureClearDepthStencilCommand : RecordedCommand {469RDD::TextureID texture;470RDD::TextureSubresourceRange range;471float depth;472uint8_t stencil;473};474475struct RecordedTextureCopyCommand : RecordedCommand {476RDD::TextureID from_texture;477RDD::TextureID to_texture;478uint32_t texture_copy_regions_count = 0;479480_FORCE_INLINE_ RDD::TextureCopyRegion *texture_copy_regions() {481return reinterpret_cast<RDD::TextureCopyRegion *>(&this[1]);482}483484_FORCE_INLINE_ const RDD::TextureCopyRegion *texture_copy_regions() const {485return reinterpret_cast<const RDD::TextureCopyRegion *>(&this[1]);486}487};488489struct RecordedTextureGetDataCommand : RecordedCommand {490RDD::TextureID from_texture;491RDD::BufferID to_buffer;492uint32_t buffer_texture_copy_regions_count = 0;493494_FORCE_INLINE_ RDD::BufferTextureCopyRegion *buffer_texture_copy_regions() {495return reinterpret_cast<RDD::BufferTextureCopyRegion *>(&this[1]);496}497498_FORCE_INLINE_ const RDD::BufferTextureCopyRegion *buffer_texture_copy_regions() const {499return reinterpret_cast<const RDD::BufferTextureCopyRegion *>(&this[1]);500}501};502503struct RecordedTextureResolveCommand : RecordedCommand {504RDD::TextureID from_texture;505RDD::TextureID to_texture;506uint32_t src_layer = 0;507uint32_t src_mipmap = 0;508uint32_t dst_layer = 0;509uint32_t dst_mipmap = 0;510};511512struct RecordedTextureUpdateCommand : RecordedCommand {513RDD::TextureID to_texture;514uint32_t buffer_to_texture_copies_count = 0;515516_FORCE_INLINE_ RecordedBufferToTextureCopy *buffer_to_texture_copies() {517return reinterpret_cast<RecordedBufferToTextureCopy *>(&this[1]);518}519520_FORCE_INLINE_ const RecordedBufferToTextureCopy *buffer_to_texture_copies() const {521return reinterpret_cast<const RecordedBufferToTextureCopy *>(&this[1]);522}523};524525struct RecordedCaptureTimestampCommand : RecordedCommand {526RDD::QueryPoolID pool;527uint32_t index = 0;528};529530struct DrawListBindIndexBufferInstruction : DrawListInstruction {531RDD::BufferID buffer;532RenderingDeviceCommons::IndexBufferFormat format;533uint32_t offset = 0;534};535536struct DrawListBindPipelineInstruction : DrawListInstruction {537RDD::PipelineID pipeline;538};539540struct DrawListBindUniformSetsInstruction : DrawListInstruction {541RDD::ShaderID shader;542uint32_t first_set_index = 0;543uint32_t set_count = 0;544uint32_t dynamic_offsets_mask = 0u;545546_FORCE_INLINE_ RDD::UniformSetID *uniform_set_ids() {547return reinterpret_cast<RDD::UniformSetID *>(&this[1]);548}549550_FORCE_INLINE_ const RDD::UniformSetID *uniform_set_ids() const {551return reinterpret_cast<const RDD::UniformSetID *>(&this[1]);552}553};554555struct DrawListBindVertexBuffersInstruction : DrawListInstruction {556uint32_t vertex_buffers_count = 0;557uint64_t dynamic_offsets_mask = 0;558559_FORCE_INLINE_ RDD::BufferID *vertex_buffers() {560return reinterpret_cast<RDD::BufferID *>(&this[1]);561}562563_FORCE_INLINE_ const RDD::BufferID *vertex_buffers() const {564return reinterpret_cast<const RDD::BufferID *>(&this[1]);565}566567_FORCE_INLINE_ uint64_t *vertex_buffer_offsets() {568return reinterpret_cast<uint64_t *>(&vertex_buffers()[vertex_buffers_count]);569}570571_FORCE_INLINE_ const uint64_t *vertex_buffer_offsets() const {572return reinterpret_cast<const uint64_t *>(&vertex_buffers()[vertex_buffers_count]);573}574};575576struct DrawListClearAttachmentsInstruction : DrawListInstruction {577uint32_t attachments_clear_count = 0;578uint32_t attachments_clear_rect_count = 0;579580_FORCE_INLINE_ RDD::AttachmentClear *attachments_clear() {581return reinterpret_cast<RDD::AttachmentClear *>(&this[1]);582}583584_FORCE_INLINE_ const RDD::AttachmentClear *attachments_clear() const {585return reinterpret_cast<const RDD::AttachmentClear *>(&this[1]);586}587588_FORCE_INLINE_ Rect2i *attachments_clear_rect() {589return reinterpret_cast<Rect2i *>(&attachments_clear()[attachments_clear_count]);590}591592_FORCE_INLINE_ const Rect2i *attachments_clear_rect() const {593return reinterpret_cast<const Rect2i *>(&attachments_clear()[attachments_clear_count]);594}595};596597struct DrawListDrawInstruction : DrawListInstruction {598uint32_t vertex_count = 0;599uint32_t instance_count = 0;600};601602struct DrawListDrawIndexedInstruction : DrawListInstruction {603uint32_t index_count = 0;604uint32_t instance_count = 0;605uint32_t first_index = 0;606};607608struct DrawListDrawIndirectInstruction : DrawListInstruction {609RDD::BufferID buffer;610uint32_t offset = 0;611uint32_t draw_count = 0;612uint32_t stride = 0;613};614615struct DrawListDrawIndexedIndirectInstruction : DrawListInstruction {616RDD::BufferID buffer;617uint32_t offset = 0;618uint32_t draw_count = 0;619uint32_t stride = 0;620};621622struct DrawListEndRenderPassInstruction : DrawListInstruction {623// No contents.624};625626struct DrawListExecuteCommandsInstruction : DrawListInstruction {627RDD::CommandBufferID command_buffer;628};629630struct DrawListSetPushConstantInstruction : DrawListInstruction {631uint32_t size = 0;632RDD::ShaderID shader;633634_FORCE_INLINE_ uint8_t *data() {635return reinterpret_cast<uint8_t *>(&this[1]);636}637638_FORCE_INLINE_ const uint8_t *data() const {639return reinterpret_cast<const uint8_t *>(&this[1]);640}641};642643struct DrawListNextSubpassInstruction : DrawListInstruction {644RDD::CommandBufferType command_buffer_type;645};646647struct DrawListSetBlendConstantsInstruction : DrawListInstruction {648Color color;649};650651struct DrawListSetLineWidthInstruction : DrawListInstruction {652float width;653};654655struct DrawListSetScissorInstruction : DrawListInstruction {656Rect2i rect;657};658659struct DrawListSetViewportInstruction : DrawListInstruction {660Rect2i rect;661};662663struct DrawListUniformSetPrepareForUseInstruction : DrawListInstruction {664RDD::UniformSetID uniform_set;665RDD::ShaderID shader;666uint32_t set_index = 0;667};668669struct RaytracingListBuildAccelerationStructureInstruction : RaytracingListInstruction {670RDD::AccelerationStructureID acceleration_structure;671RDD::AccelerationStructureType acceleration_structure_type;672};673674struct RaytracingListBindPipelineInstruction : RaytracingListInstruction {675RDD::RaytracingPipelineID pipeline;676};677678struct RaytracingListBindUniformSetInstruction : RaytracingListInstruction {679RDD::UniformSetID uniform_set;680RDD::ShaderID shader;681uint32_t set_index = 0;682};683684struct RaytracingListSetPushConstantInstruction : RaytracingListInstruction {685uint32_t size = 0;686RDD::ShaderID shader;687688_FORCE_INLINE_ uint8_t *data() {689return reinterpret_cast<uint8_t *>(&this[1]);690}691692_FORCE_INLINE_ const uint8_t *data() const {693return reinterpret_cast<const uint8_t *>(&this[1]);694}695};696697struct RaytracingListTraceRaysInstruction : RaytracingListInstruction {698uint32_t width = 0;699uint32_t height = 0;700};701702struct RaytracingListUniformSetPrepareForUseInstruction : RaytracingListInstruction {703RDD::UniformSetID uniform_set;704RDD::ShaderID shader;705uint32_t set_index = 0;706};707708struct ComputeListBindPipelineInstruction : ComputeListInstruction {709RDD::PipelineID pipeline;710};711712struct ComputeListBindUniformSetsInstruction : ComputeListInstruction {713RDD::ShaderID shader;714uint32_t first_set_index = 0;715uint32_t set_count = 0;716uint32_t dynamic_offsets_mask = 0u;717718_FORCE_INLINE_ RDD::UniformSetID *uniform_set_ids() {719return reinterpret_cast<RDD::UniformSetID *>(&this[1]);720}721722_FORCE_INLINE_ const RDD::UniformSetID *uniform_set_ids() const {723return reinterpret_cast<const RDD::UniformSetID *>(&this[1]);724}725};726727struct ComputeListDispatchInstruction : ComputeListInstruction {728uint32_t x_groups = 0;729uint32_t y_groups = 0;730uint32_t z_groups = 0;731};732733struct ComputeListDispatchIndirectInstruction : ComputeListInstruction {734RDD::BufferID buffer;735uint32_t offset = 0;736};737738struct ComputeListSetPushConstantInstruction : ComputeListInstruction {739uint32_t size = 0;740RDD::ShaderID shader;741742_FORCE_INLINE_ uint8_t *data() {743return reinterpret_cast<uint8_t *>(&this[1]);744}745746_FORCE_INLINE_ const uint8_t *data() const {747return reinterpret_cast<const uint8_t *>(&this[1]);748}749};750751struct ComputeListUniformSetPrepareForUseInstruction : ComputeListInstruction {752RDD::UniformSetID uniform_set;753RDD::ShaderID shader;754uint32_t set_index = 0;755};756757struct BarrierGroup {758BitField<RDD::PipelineStageBits> src_stages = {};759BitField<RDD::PipelineStageBits> dst_stages = {};760RDD::MemoryAccessBarrier memory_barrier;761LocalVector<RDD::TextureBarrier> normalization_barriers;762LocalVector<RDD::TextureBarrier> transition_barriers;763#if USE_BUFFER_BARRIERS764LocalVector<RDD::BufferBarrier> buffer_barriers;765#endif766LocalVector<RDD::AccelerationStructureBarrier> acceleration_structure_barriers;767768void clear() {769src_stages.clear();770dst_stages.clear();771memory_barrier.src_access.clear();772memory_barrier.dst_access.clear();773normalization_barriers.clear();774transition_barriers.clear();775#if USE_BUFFER_BARRIERS776buffer_barriers.clear();777#endif778acceleration_structure_barriers.clear();779}780};781782struct SecondaryCommandBuffer {783LocalVector<uint8_t> instruction_data;784RDD::CommandBufferID command_buffer;785RDD::CommandPoolID command_pool;786RDD::RenderPassID render_pass;787RDD::FramebufferID framebuffer;788WorkerThreadPool::TaskID task;789};790791struct Frame {792TightLocalVector<SecondaryCommandBuffer> secondary_command_buffers;793uint32_t secondary_command_buffers_used = 0;794};795796RDD *driver = nullptr;797RenderingContextDriver::Device device;798RenderPassCreationFunction render_pass_creation_function = nullptr;799int64_t tracking_frame = 0;800LocalVector<uint8_t> command_data;801LocalVector<uint32_t> command_data_offsets;802LocalVector<RDD::TextureBarrier> command_normalization_barriers;803LocalVector<RDD::TextureBarrier> command_transition_barriers;804LocalVector<RDD::BufferBarrier> command_buffer_barriers;805LocalVector<RDD::AccelerationStructureBarrier> command_acceleration_structure_barriers;806LocalVector<char> command_label_chars;807LocalVector<Color> command_label_colors;808LocalVector<uint32_t> command_label_offsets;809int32_t command_label_index = -1;810DrawInstructionList draw_instruction_list;811ComputeInstructionList compute_instruction_list;812RaytracingInstructionList raytracing_instruction_list;813uint32_t command_count = 0;814uint32_t command_label_count = 0;815LocalVector<RecordedCommandListNode> command_list_nodes;816LocalVector<RecordedSliceListNode> read_slice_list_nodes;817LocalVector<RecordedSliceListNode> write_slice_list_nodes;818int32_t command_timestamp_index = -1;819int32_t command_synchronization_index = -1;820bool command_synchronization_pending = false;821BarrierGroup barrier_group;822bool driver_honors_barriers : 1;823bool driver_clears_with_copy_engine : 1;824bool driver_buffers_require_transitions : 1;825WorkaroundsState workarounds_state;826TightLocalVector<Frame> frames;827uint32_t frame = 0;828829#ifdef DEV_ENABLED830RBMap<ResourceTracker *, uint32_t> write_dependency_counters;831#endif832833static String _usage_to_string(ResourceUsage p_usage);834static bool _is_write_usage(ResourceUsage p_usage);835static RDD::TextureLayout _usage_to_image_layout(ResourceUsage p_usage);836static RDD::BarrierAccessBits _usage_to_access_bits(ResourceUsage p_usage);837bool _check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) const;838bool _check_command_partial_coverage(ResourceTracker *p_resource_tracker, int32_t p_command_index) const;839int32_t _add_to_command_list(int32_t p_command_index, int32_t p_list_index);840void _add_adjacent_command(int32_t p_previous_command_index, int32_t p_command_index, RecordedCommand *r_command);841int32_t _add_to_slice_read_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index);842int32_t _add_to_write_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index, bool p_partial_coverage);843RecordedCommand *_allocate_command(uint32_t p_command_size, int32_t &r_command_index);844DrawListInstruction *_allocate_draw_list_instruction(uint32_t p_instruction_size);845ComputeListInstruction *_allocate_compute_list_instruction(uint32_t p_instruction_size);846void _check_discardable_attachment_dependency(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index);847RaytracingListInstruction *_allocate_raytracing_list_instruction(uint32_t p_instruction_size);848void _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);849void _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);850#if USE_BUFFER_BARRIERS851void _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);852#endif853void _add_acceleration_structure_barrier_to_command(RDD::AccelerationStructureID p_acceleration_structure_id, BitField<RDD::BarrierAccessBits> p_src_access, BitField<RDD::BarrierAccessBits> p_dst_access, LocalVector<RDD::AccelerationStructureBarrier> &r_barrier_vector, int32_t &r_barrier_index, int32_t &r_barrier_count);854void _run_compute_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);855void _get_draw_list_render_pass_and_framebuffer(const RecordedDrawListCommand *p_draw_list_command, RDD::RenderPassID &r_render_pass, RDD::FramebufferID &r_framebuffer);856void _run_raytracing_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);857void _run_draw_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);858void _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);859void _run_secondary_command_buffer_task(const SecondaryCommandBuffer *p_secondary);860void _wait_for_secondary_command_buffer_tasks();861void _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);862void _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);863void _boost_priority_for_render_commands(RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count, uint32_t &r_boosted_priority);864void _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);865void _print_render_commands(const RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count);866void _print_draw_list(const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);867void _print_compute_list(const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);868void _print_raytracing_list(const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);869870public:871RenderingDeviceGraph();872~RenderingDeviceGraph();873void 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);874void finalize();875void begin();876void add_acceleration_structure_build(RDD::AccelerationStructureID p_acceleration_structure, RDD::BufferID p_scratch_buffer, ResourceTracker *p_dst_tracker, VectorView<ResourceTracker *> p_src_trackers);877void add_buffer_clear(RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, uint32_t p_offset, uint32_t p_size);878void add_buffer_copy(RDD::BufferID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, RDD::BufferCopyRegion p_region);879void add_buffer_get_data(RDD::BufferID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, RDD::BufferCopyRegion p_region);880void add_buffer_update(RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, VectorView<RecordedBufferCopy> p_buffer_copies);881void add_driver_callback(RDD::DriverCallback p_callback, void *p_userdata, VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);882void add_raytracing_list_begin();883void add_raytracing_list_bind_pipeline(RDD::RaytracingPipelineID p_pipeline);884void add_raytracing_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);885void add_raytracing_list_set_push_constant(RDD::ShaderID p_shader, const void *p_data, uint32_t p_data_size);886void add_raytracing_list_trace_rays(uint32_t p_width, uint32_t p_height);887void add_raytracing_list_uniform_set_prepare_for_use(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);888void add_raytracing_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage);889void add_raytracing_list_usages(VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);890void add_raytracing_list_end();891void add_compute_list_begin(RDD::BreadcrumbMarker p_phase = RDD::BreadcrumbMarker::NONE, uint32_t p_breadcrumb_data = 0);892void add_compute_list_bind_pipeline(RDD::PipelineID p_pipeline);893void add_compute_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);894void 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);895void add_compute_list_dispatch(uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups);896void add_compute_list_dispatch_indirect(RDD::BufferID p_buffer, uint32_t p_offset);897void add_compute_list_set_push_constant(RDD::ShaderID p_shader, const void *p_data, uint32_t p_data_size);898void add_compute_list_uniform_set_prepare_for_use(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);899void add_compute_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage);900void add_compute_list_usages(VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);901void add_compute_list_end();902void 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);903void 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);904void add_draw_list_bind_index_buffer(RDD::BufferID p_buffer, RDD::IndexBufferFormat p_format, uint32_t p_offset);905void add_draw_list_bind_pipeline(RDD::PipelineID p_pipeline, BitField<RDD::PipelineStageBits> p_pipeline_stage_bits);906void add_draw_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);907void 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);908void add_draw_list_bind_vertex_buffers(Span<RDD::BufferID> p_vertex_buffers, Span<uint64_t> p_vertex_buffer_offsets);909void add_draw_list_clear_attachments(VectorView<RDD::AttachmentClear> p_attachments_clear, VectorView<Rect2i> p_attachments_clear_rect);910void add_draw_list_draw(uint32_t p_vertex_count, uint32_t p_instance_count);911void add_draw_list_draw_indexed(uint32_t p_index_count, uint32_t p_instance_count, uint32_t p_first_index);912void add_draw_list_draw_indirect(RDD::BufferID p_buffer, uint32_t p_offset, uint32_t p_draw_count, uint32_t p_stride);913void add_draw_list_draw_indexed_indirect(RDD::BufferID p_buffer, uint32_t p_offset, uint32_t p_draw_count, uint32_t p_stride);914void add_draw_list_execute_commands(RDD::CommandBufferID p_command_buffer);915void add_draw_list_next_subpass(RDD::CommandBufferType p_command_buffer_type);916void add_draw_list_set_blend_constants(const Color &p_color);917void add_draw_list_set_line_width(float p_width);918void add_draw_list_set_push_constant(RDD::ShaderID p_shader, const void *p_data, uint32_t p_data_size);919void add_draw_list_set_scissor(Rect2i p_rect);920void add_draw_list_set_viewport(Rect2i p_rect);921void add_draw_list_uniform_set_prepare_for_use(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);922void add_draw_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage);923void add_draw_list_usages(VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);924void add_draw_list_end();925void add_texture_clear_color(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, const Color &p_color, const RDD::TextureSubresourceRange &p_range);926void add_texture_clear_depth_stencil(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, float p_depth, uint8_t p_stencil, const RDD::TextureSubresourceRange &p_range);927void 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);928void 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);929void 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);930void add_texture_update(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, VectorView<RecordedBufferToTextureCopy> p_buffer_copies, VectorView<ResourceTracker *> p_buffer_trackers = VectorView<ResourceTracker *>());931void add_capture_timestamp(RDD::QueryPoolID p_query_pool, uint32_t p_index);932void add_synchronization();933void begin_label(const Span<char> &p_label_name, const Color &p_color);934void end_label();935void end(bool p_reorder_commands, bool p_full_barriers, RDD::CommandBufferID &r_command_buffer, CommandBufferPool &r_command_buffer_pool);936static ResourceTracker *resource_tracker_create();937static void resource_tracker_free(ResourceTracker *p_tracker);938static FramebufferCache *framebuffer_cache_create();939static void framebuffer_cache_free(RDD *p_driver, FramebufferCache *p_cache);940};941942using RDG = RenderingDeviceGraph;943944945