Path: blob/master/servers/rendering/renderer_rd/pipeline_deferred_rd.h
12222 views
/**************************************************************************/1/* pipeline_deferred_rd.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 "servers/rendering/rendering_device.h"3334// Helper class for automatically deferring compilation of a pipeline to a background task.35// When attempting to retrieve the pipeline with the getter, the caller will automatically36// wait for it to be ready.3738class PipelineDeferredRD {39protected:40struct CreationParameters {41RID shader;42RD::FramebufferFormatID framebuffer_format;43RD::VertexFormatID vertex_format;44RD::RenderPrimitive render_primitive;45RD::PipelineRasterizationState rasterization_state;46RD::PipelineMultisampleState multisample_state;47RD::PipelineDepthStencilState depth_stencil_state;48RD::PipelineColorBlendState blend_state;49BitField<RD::PipelineDynamicStateFlags> dynamic_state_flags;50uint32_t for_render_pass;51Vector<RD::PipelineSpecializationConstant> specialization_constants;52bool is_compute;53};5455RID pipeline;56WorkerThreadPool::TaskID task = WorkerThreadPool::INVALID_TASK_ID;5758void _create(const CreationParameters &c) {59if (c.is_compute) {60pipeline = RD::get_singleton()->compute_pipeline_create(c.shader, c.specialization_constants);61} else {62pipeline = RD::get_singleton()->render_pipeline_create(c.shader, c.framebuffer_format, c.vertex_format, c.render_primitive, c.rasterization_state, c.multisample_state, c.depth_stencil_state, c.blend_state, c.dynamic_state_flags, c.for_render_pass, c.specialization_constants);63}64}6566void _start(const CreationParameters &c) {67free();68task = WorkerThreadPool::get_singleton()->add_template_task(this, &PipelineDeferredRD::_create, c, true, "PipelineCompilation");69}7071void _wait() {72if (task != WorkerThreadPool::INVALID_TASK_ID) {73WorkerThreadPool::get_singleton()->wait_for_task_completion(task);74task = WorkerThreadPool::INVALID_TASK_ID;75}76}7778public:79PipelineDeferredRD() {80// Default constructor.81}8283~PipelineDeferredRD() {84free();85}8687void create_render_pipeline(RID p_shader, RD::FramebufferFormatID p_framebuffer_format, RD::VertexFormatID p_vertex_format, RD::RenderPrimitive p_render_primitive, const RD::PipelineRasterizationState &p_rasterization_state, const RD::PipelineMultisampleState &p_multisample_state, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, BitField<RD::PipelineDynamicStateFlags> p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0, const Vector<RD::PipelineSpecializationConstant> &p_specialization_constants = Vector<RD::PipelineSpecializationConstant>()) {88CreationParameters c;89c.shader = p_shader;90c.framebuffer_format = p_framebuffer_format;91c.vertex_format = p_vertex_format;92c.render_primitive = p_render_primitive;93c.rasterization_state = p_rasterization_state;94c.multisample_state = p_multisample_state;95c.depth_stencil_state = p_depth_stencil_state;96c.blend_state = p_blend_state;97c.dynamic_state_flags = p_dynamic_state_flags;98c.for_render_pass = p_for_render_pass;99c.specialization_constants = p_specialization_constants;100c.is_compute = false;101_start(c);102}103104void create_compute_pipeline(RID p_shader, const Vector<RD::PipelineSpecializationConstant> &p_specialization_constants = Vector<RD::PipelineSpecializationConstant>()) {105CreationParameters c = {};106c.shader = p_shader;107c.specialization_constants = p_specialization_constants;108c.is_compute = true;109_start(c);110}111112RID get_rid() {113_wait();114return pipeline;115}116117void free() {118_wait();119120if (pipeline.is_valid()) {121RD::get_singleton()->free_rid(pipeline);122pipeline = RID();123}124}125};126127128