Implement Framebuffer Subpass support
* Required for better optimizing mobile platforms * Will be used by the Vulkan mobile renderer.
This commit is contained in:
parent
8ccadfabf2
commit
bde6f5eed1
35
doc/classes/RDFramebufferPass.xml
Normal file
35
doc/classes/RDFramebufferPass.xml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<class name="RDFramebufferPass" inherits="RefCounted" version="4.0">
|
||||||
|
<brief_description>
|
||||||
|
Framebuffer pass attachment description.
|
||||||
|
</brief_description>
|
||||||
|
<description>
|
||||||
|
This class contains the list of attachment descriptions for a framebuffer pass. Each points with an index to a previously supplied list of texture attachments.
|
||||||
|
Multipass framebuffers can optimize some configurations in mobile, on desktop they provide little to no advantage.
|
||||||
|
</description>
|
||||||
|
<tutorials>
|
||||||
|
</tutorials>
|
||||||
|
<methods>
|
||||||
|
</methods>
|
||||||
|
<members>
|
||||||
|
<member name="color_attachments" type="PackedInt32Array" setter="set_color_attachments" getter="get_color_attachments" default="PackedInt32Array()">
|
||||||
|
Color attachments in order starting from 0. If this attachment is not used by the shader, pass ATTACHMENT_UNUSED to skip.
|
||||||
|
</member>
|
||||||
|
<member name="depth_attachment" type="int" setter="set_depth_attachment" getter="get_depth_attachment" default="-1">
|
||||||
|
Depth attachment. ATTACHMENT_UNUSED should be used if no depth buffer is required for this pass.
|
||||||
|
</member>
|
||||||
|
<member name="input_attachments" type="PackedInt32Array" setter="set_input_attachments" getter="get_input_attachments" default="PackedInt32Array()">
|
||||||
|
Used for multipass framebuffers (more than one render pass). Converts an attachment to an input. Make sure to also supply it properly in the [RDUniform] for the uniform set.
|
||||||
|
</member>
|
||||||
|
<member name="preserve_attachments" type="PackedInt32Array" setter="set_preserve_attachments" getter="get_preserve_attachments" default="PackedInt32Array()">
|
||||||
|
Attachments to preserve in this pass (otherwise they are erased).
|
||||||
|
</member>
|
||||||
|
<member name="resolve_attachments" type="PackedInt32Array" setter="set_resolve_attachments" getter="get_resolve_attachments" default="PackedInt32Array()">
|
||||||
|
If the color attachments are multisampled, non-multisampled resolve attachments can be provided.
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
<constants>
|
||||||
|
<constant name="ATTACHMENT_UNUSED" value="-1">
|
||||||
|
</constant>
|
||||||
|
</constants>
|
||||||
|
</class>
|
@ -341,13 +341,29 @@
|
|||||||
<description>
|
<description>
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="draw_list_switch_to_next_pass">
|
||||||
|
<return type="int">
|
||||||
|
</return>
|
||||||
|
<description>
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="draw_list_switch_to_next_pass_split">
|
||||||
|
<return type="PackedInt64Array">
|
||||||
|
</return>
|
||||||
|
<argument index="0" name="splits" type="int">
|
||||||
|
</argument>
|
||||||
|
<description>
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="framebuffer_create">
|
<method name="framebuffer_create">
|
||||||
<return type="RID">
|
<return type="RID">
|
||||||
</return>
|
</return>
|
||||||
<argument index="0" name="textures" type="Array">
|
<argument index="0" name="textures" type="RID[]">
|
||||||
</argument>
|
</argument>
|
||||||
<argument index="1" name="validate_with_format" type="int" default="-1">
|
<argument index="1" name="validate_with_format" type="int" default="-1">
|
||||||
</argument>
|
</argument>
|
||||||
|
<argument index="2" name="view_count" type="int" default="1">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
@ -363,11 +379,27 @@
|
|||||||
<description>
|
<description>
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="framebuffer_create_multipass">
|
||||||
|
<return type="RID">
|
||||||
|
</return>
|
||||||
|
<argument index="0" name="textures" type="RID[]">
|
||||||
|
</argument>
|
||||||
|
<argument index="1" name="passes" type="RDFramebufferPass[]">
|
||||||
|
</argument>
|
||||||
|
<argument index="2" name="validate_with_format" type="int" default="-1">
|
||||||
|
</argument>
|
||||||
|
<argument index="3" name="view_count" type="int" default="1">
|
||||||
|
</argument>
|
||||||
|
<description>
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="framebuffer_format_create">
|
<method name="framebuffer_format_create">
|
||||||
<return type="int">
|
<return type="int">
|
||||||
</return>
|
</return>
|
||||||
<argument index="0" name="attachments" type="RDAttachmentFormat[]">
|
<argument index="0" name="attachments" type="RDAttachmentFormat[]">
|
||||||
</argument>
|
</argument>
|
||||||
|
<argument index="1" name="view_count" type="int" default="1">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
@ -379,11 +411,25 @@
|
|||||||
<description>
|
<description>
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="framebuffer_format_create_multipass">
|
||||||
|
<return type="int">
|
||||||
|
</return>
|
||||||
|
<argument index="0" name="attachments" type="RDAttachmentFormat[]">
|
||||||
|
</argument>
|
||||||
|
<argument index="1" name="passes" type="RDFramebufferPass[]">
|
||||||
|
</argument>
|
||||||
|
<argument index="2" name="view_count" type="int" default="1">
|
||||||
|
</argument>
|
||||||
|
<description>
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="framebuffer_format_get_texture_samples">
|
<method name="framebuffer_format_get_texture_samples">
|
||||||
<return type="int" enum="RenderingDevice.TextureSamples">
|
<return type="int" enum="RenderingDevice.TextureSamples">
|
||||||
</return>
|
</return>
|
||||||
<argument index="0" name="format" type="int">
|
<argument index="0" name="format" type="int">
|
||||||
</argument>
|
</argument>
|
||||||
|
<argument index="1" name="render_pass" type="int" default="0">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
@ -524,6 +570,8 @@
|
|||||||
</argument>
|
</argument>
|
||||||
<argument index="8" name="dynamic_state_flags" type="int" default="0">
|
<argument index="8" name="dynamic_state_flags" type="int" default="0">
|
||||||
</argument>
|
</argument>
|
||||||
|
<argument index="9" name="for_render_pass" type="int" default="0">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -234,12 +234,87 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||||||
|
|
||||||
struct FramebufferFormatKey {
|
struct FramebufferFormatKey {
|
||||||
Vector<AttachmentFormat> attachments;
|
Vector<AttachmentFormat> attachments;
|
||||||
|
Vector<FramebufferPass> passes;
|
||||||
uint32_t view_count = 1;
|
uint32_t view_count = 1;
|
||||||
bool operator<(const FramebufferFormatKey &p_key) const {
|
bool operator<(const FramebufferFormatKey &p_key) const {
|
||||||
if (view_count != p_key.view_count) {
|
if (view_count != p_key.view_count) {
|
||||||
return view_count < p_key.view_count;
|
return view_count < p_key.view_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t pass_size = passes.size();
|
||||||
|
uint32_t key_pass_size = p_key.passes.size();
|
||||||
|
if (pass_size != key_pass_size) {
|
||||||
|
return pass_size < key_pass_size;
|
||||||
|
}
|
||||||
|
const FramebufferPass *pass_ptr = passes.ptr();
|
||||||
|
const FramebufferPass *key_pass_ptr = p_key.passes.ptr();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < pass_size; i++) {
|
||||||
|
{ //compare color attachments
|
||||||
|
uint32_t attachment_size = pass_ptr[i].color_attachments.size();
|
||||||
|
uint32_t key_attachment_size = key_pass_ptr[i].color_attachments.size();
|
||||||
|
if (attachment_size != key_attachment_size) {
|
||||||
|
return attachment_size < key_attachment_size;
|
||||||
|
}
|
||||||
|
const int32_t *pass_attachment_ptr = pass_ptr[i].color_attachments.ptr();
|
||||||
|
const int32_t *key_pass_attachment_ptr = key_pass_ptr[i].color_attachments.ptr();
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < attachment_size; j++) {
|
||||||
|
if (pass_attachment_ptr[j] != key_pass_attachment_ptr[j]) {
|
||||||
|
return pass_attachment_ptr[j] < key_pass_attachment_ptr[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ //compare input attachments
|
||||||
|
uint32_t attachment_size = pass_ptr[i].input_attachments.size();
|
||||||
|
uint32_t key_attachment_size = key_pass_ptr[i].input_attachments.size();
|
||||||
|
if (attachment_size != key_attachment_size) {
|
||||||
|
return attachment_size < key_attachment_size;
|
||||||
|
}
|
||||||
|
const int32_t *pass_attachment_ptr = pass_ptr[i].input_attachments.ptr();
|
||||||
|
const int32_t *key_pass_attachment_ptr = key_pass_ptr[i].input_attachments.ptr();
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < attachment_size; j++) {
|
||||||
|
if (pass_attachment_ptr[j] != key_pass_attachment_ptr[j]) {
|
||||||
|
return pass_attachment_ptr[j] < key_pass_attachment_ptr[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ //compare resolve attachments
|
||||||
|
uint32_t attachment_size = pass_ptr[i].resolve_attachments.size();
|
||||||
|
uint32_t key_attachment_size = key_pass_ptr[i].resolve_attachments.size();
|
||||||
|
if (attachment_size != key_attachment_size) {
|
||||||
|
return attachment_size < key_attachment_size;
|
||||||
|
}
|
||||||
|
const int32_t *pass_attachment_ptr = pass_ptr[i].resolve_attachments.ptr();
|
||||||
|
const int32_t *key_pass_attachment_ptr = key_pass_ptr[i].resolve_attachments.ptr();
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < attachment_size; j++) {
|
||||||
|
if (pass_attachment_ptr[j] != key_pass_attachment_ptr[j]) {
|
||||||
|
return pass_attachment_ptr[j] < key_pass_attachment_ptr[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ //compare preserve attachments
|
||||||
|
uint32_t attachment_size = pass_ptr[i].preserve_attachments.size();
|
||||||
|
uint32_t key_attachment_size = key_pass_ptr[i].preserve_attachments.size();
|
||||||
|
if (attachment_size != key_attachment_size) {
|
||||||
|
return attachment_size < key_attachment_size;
|
||||||
|
}
|
||||||
|
const int32_t *pass_attachment_ptr = pass_ptr[i].preserve_attachments.ptr();
|
||||||
|
const int32_t *key_pass_attachment_ptr = key_pass_ptr[i].preserve_attachments.ptr();
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < attachment_size; j++) {
|
||||||
|
if (pass_attachment_ptr[j] != key_pass_attachment_ptr[j]) {
|
||||||
|
return pass_attachment_ptr[j] < key_pass_attachment_ptr[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pass_ptr[i].depth_attachment != key_pass_ptr[i].depth_attachment) {
|
||||||
|
return pass_ptr[i].depth_attachment < key_pass_ptr[i].depth_attachment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int as = attachments.size();
|
int as = attachments.size();
|
||||||
int bs = p_key.attachments.size();
|
int bs = p_key.attachments.size();
|
||||||
if (as != bs) {
|
if (as != bs) {
|
||||||
@ -266,16 +341,14 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
VkRenderPass _render_pass_create(const Vector<AttachmentFormat> &p_format, InitialAction p_initial_action, FinalAction p_final_action, InitialAction p_initial_depth_action, FinalAction p_final_depthcolor_action, int *r_color_attachment_count = nullptr, uint32_t p_view_count = 1);
|
VkRenderPass _render_pass_create(const Vector<AttachmentFormat> &p_attachments, const Vector<FramebufferPass> &p_passes, InitialAction p_initial_action, FinalAction p_final_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, uint32_t p_view_count = 1, Vector<TextureSamples> *r_samples = nullptr);
|
||||||
|
|
||||||
// This is a cache and it's never freed, it ensures
|
// This is a cache and it's never freed, it ensures
|
||||||
// IDs for a given format are always unique.
|
// IDs for a given format are always unique.
|
||||||
Map<FramebufferFormatKey, FramebufferFormatID> framebuffer_format_cache;
|
Map<FramebufferFormatKey, FramebufferFormatID> framebuffer_format_cache;
|
||||||
struct FramebufferFormat {
|
struct FramebufferFormat {
|
||||||
const Map<FramebufferFormatKey, FramebufferFormatID>::Element *E;
|
const Map<FramebufferFormatKey, FramebufferFormatID>::Element *E;
|
||||||
VkRenderPass render_pass = VK_NULL_HANDLE; //here for constructing shaders, never used, see section (7.2. Render Pass Compatibility from Vulkan spec)
|
VkRenderPass render_pass = VK_NULL_HANDLE; //here for constructing shaders, never used, see section (7.2. Render Pass Compatibility from Vulkan spec)
|
||||||
int color_attachments = 0; //used for pipeline validation
|
Vector<TextureSamples> pass_samples;
|
||||||
TextureSamples samples;
|
|
||||||
uint32_t view_count = 1; // number of views
|
uint32_t view_count = 1; // number of views
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -289,6 +362,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||||||
InitialAction initial_depth_action;
|
InitialAction initial_depth_action;
|
||||||
FinalAction final_depth_action;
|
FinalAction final_depth_action;
|
||||||
uint32_t view_count;
|
uint32_t view_count;
|
||||||
|
|
||||||
bool operator<(const VersionKey &p_key) const {
|
bool operator<(const VersionKey &p_key) const {
|
||||||
if (initial_color_action == p_key.initial_color_action) {
|
if (initial_color_action == p_key.initial_color_action) {
|
||||||
if (final_color_action == p_key.final_color_action) {
|
if (final_color_action == p_key.final_color_action) {
|
||||||
@ -316,6 +390,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||||||
struct Version {
|
struct Version {
|
||||||
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
||||||
VkRenderPass render_pass = VK_NULL_HANDLE; //this one is owned
|
VkRenderPass render_pass = VK_NULL_HANDLE; //this one is owned
|
||||||
|
uint32_t subpass_count = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
Map<VersionKey, Version> framebuffers;
|
Map<VersionKey, Version> framebuffers;
|
||||||
@ -536,7 +611,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||||||
};
|
};
|
||||||
|
|
||||||
uint32_t vertex_input_mask = 0; //inputs used, this is mostly for validation
|
uint32_t vertex_input_mask = 0; //inputs used, this is mostly for validation
|
||||||
int fragment_outputs = 0;
|
uint32_t fragment_output_mask = 0;
|
||||||
|
|
||||||
struct PushConstant {
|
struct PushConstant {
|
||||||
uint32_t push_constant_size = 0;
|
uint32_t push_constant_size = 0;
|
||||||
@ -680,6 +755,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
struct Validation {
|
struct Validation {
|
||||||
FramebufferFormatID framebuffer_format = 0;
|
FramebufferFormatID framebuffer_format = 0;
|
||||||
|
uint32_t render_pass = 0;
|
||||||
uint32_t dynamic_state = 0;
|
uint32_t dynamic_state = 0;
|
||||||
VertexFormatID vertex_format = 0;
|
VertexFormatID vertex_format = 0;
|
||||||
bool uses_restart_indices = false;
|
bool uses_restart_indices = false;
|
||||||
@ -735,6 +811,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||||||
struct DrawList {
|
struct DrawList {
|
||||||
VkCommandBuffer command_buffer = VK_NULL_HANDLE; // If persistent, this is owned, otherwise it's shared with the ringbuffer.
|
VkCommandBuffer command_buffer = VK_NULL_HANDLE; // If persistent, this is owned, otherwise it's shared with the ringbuffer.
|
||||||
Rect2i viewport;
|
Rect2i viewport;
|
||||||
|
bool viewport_set = false;
|
||||||
|
|
||||||
struct SetState {
|
struct SetState {
|
||||||
uint32_t pipeline_expected_format = 0;
|
uint32_t pipeline_expected_format = 0;
|
||||||
@ -758,7 +835,6 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
struct Validation {
|
struct Validation {
|
||||||
bool active = true; // Means command buffer was not closed, so you can keep adding things.
|
bool active = true; // Means command buffer was not closed, so you can keep adding things.
|
||||||
FramebufferFormatID framebuffer_format = INVALID_ID;
|
|
||||||
// Actual render pass values.
|
// Actual render pass values.
|
||||||
uint32_t dynamic_state = 0;
|
uint32_t dynamic_state = 0;
|
||||||
VertexFormatID vertex_format = INVALID_ID;
|
VertexFormatID vertex_format = INVALID_ID;
|
||||||
@ -794,7 +870,15 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DrawList *draw_list = nullptr; // One for regular draw lists, multiple for split.
|
DrawList *draw_list = nullptr; // One for regular draw lists, multiple for split.
|
||||||
|
uint32_t draw_list_subpass_count = 0;
|
||||||
uint32_t draw_list_count = 0;
|
uint32_t draw_list_count = 0;
|
||||||
|
VkRenderPass draw_list_render_pass;
|
||||||
|
VkFramebuffer draw_list_vkframebuffer;
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
FramebufferFormatID draw_list_framebuffer_format = INVALID_ID;
|
||||||
|
#endif
|
||||||
|
uint32_t draw_list_current_subpass = 0;
|
||||||
|
|
||||||
bool draw_list_split = false;
|
bool draw_list_split = false;
|
||||||
Vector<RID> draw_list_bound_textures;
|
Vector<RID> draw_list_bound_textures;
|
||||||
Vector<RID> draw_list_storage_textures;
|
Vector<RID> draw_list_storage_textures;
|
||||||
@ -802,10 +886,12 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||||||
bool draw_list_unbind_depth_textures = false;
|
bool draw_list_unbind_depth_textures = false;
|
||||||
|
|
||||||
void _draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil);
|
void _draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil);
|
||||||
Error _draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass);
|
Error _draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass, uint32_t *r_subpass_count);
|
||||||
Error _draw_list_render_pass_begin(Framebuffer *framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents, const Vector<RID> &p_storage_textures);
|
Error _draw_list_render_pass_begin(Framebuffer *framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents, const Vector<RID> &p_storage_textures);
|
||||||
_FORCE_INLINE_ DrawList *_get_draw_list_ptr(DrawListID p_id);
|
_FORCE_INLINE_ DrawList *_get_draw_list_ptr(DrawListID p_id);
|
||||||
Buffer *_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &dst_stage_mask, VkAccessFlags &dst_access, uint32_t p_post_barrier);
|
Buffer *_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &dst_stage_mask, VkAccessFlags &dst_access, uint32_t p_post_barrier);
|
||||||
|
Error _draw_list_allocate(const Rect2i &p_viewport, uint32_t p_splits, uint32_t p_subpass);
|
||||||
|
void _draw_list_free(Rect2i *r_last_viewport = nullptr);
|
||||||
|
|
||||||
/**********************/
|
/**********************/
|
||||||
/**** COMPUTE LIST ****/
|
/**** COMPUTE LIST ****/
|
||||||
@ -951,10 +1037,12 @@ public:
|
|||||||
/*********************/
|
/*********************/
|
||||||
|
|
||||||
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format, uint32_t p_view_count = 1);
|
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format, uint32_t p_view_count = 1);
|
||||||
|
virtual FramebufferFormatID framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, Vector<FramebufferPass> &p_passes, uint32_t p_view_count = 1);
|
||||||
virtual FramebufferFormatID framebuffer_format_create_empty(TextureSamples p_samples = TEXTURE_SAMPLES_1);
|
virtual FramebufferFormatID framebuffer_format_create_empty(TextureSamples p_samples = TEXTURE_SAMPLES_1);
|
||||||
virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format);
|
virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format, uint32_t p_pass = 0);
|
||||||
|
|
||||||
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1);
|
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1);
|
||||||
|
virtual RID framebuffer_create_multipass(const Vector<RID> &p_texture_attachments, Vector<FramebufferPass> &p_passes, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1);
|
||||||
virtual RID framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples = TEXTURE_SAMPLES_1, FramebufferFormatID p_format_check = INVALID_ID);
|
virtual RID framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples = TEXTURE_SAMPLES_1, FramebufferFormatID p_format_check = INVALID_ID);
|
||||||
|
|
||||||
virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer);
|
virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer);
|
||||||
@ -1005,7 +1093,7 @@ public:
|
|||||||
/**** RENDER PIPELINE ****/
|
/**** RENDER PIPELINE ****/
|
||||||
/*************************/
|
/*************************/
|
||||||
|
|
||||||
virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0);
|
virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0);
|
||||||
virtual bool render_pipeline_is_valid(RID p_pipeline);
|
virtual bool render_pipeline_is_valid(RID p_pipeline);
|
||||||
|
|
||||||
/**************************/
|
/**************************/
|
||||||
@ -1044,6 +1132,9 @@ public:
|
|||||||
virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect);
|
virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect);
|
||||||
virtual void draw_list_disable_scissor(DrawListID p_list);
|
virtual void draw_list_disable_scissor(DrawListID p_list);
|
||||||
|
|
||||||
|
virtual DrawListID draw_list_switch_to_next_pass();
|
||||||
|
virtual Error draw_list_switch_to_next_pass_split(uint32_t p_splits, DrawListID *r_split_ids);
|
||||||
|
|
||||||
virtual void draw_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL);
|
virtual void draw_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL);
|
||||||
|
|
||||||
/***********************/
|
/***********************/
|
||||||
|
@ -194,6 +194,7 @@ void register_server_types() {
|
|||||||
ClassDB::register_class<RDTextureFormat>();
|
ClassDB::register_class<RDTextureFormat>();
|
||||||
ClassDB::register_class<RDTextureView>();
|
ClassDB::register_class<RDTextureView>();
|
||||||
ClassDB::register_class<RDAttachmentFormat>();
|
ClassDB::register_class<RDAttachmentFormat>();
|
||||||
|
ClassDB::register_class<RDFramebufferPass>();
|
||||||
ClassDB::register_class<RDSamplerState>();
|
ClassDB::register_class<RDSamplerState>();
|
||||||
ClassDB::register_class<RDVertexAttribute>();
|
ClassDB::register_class<RDVertexAttribute>();
|
||||||
ClassDB::register_class<RDUniform>();
|
ClassDB::register_class<RDUniform>();
|
||||||
|
@ -31,20 +31,21 @@
|
|||||||
#include "pipeline_cache_rd.h"
|
#include "pipeline_cache_rd.h"
|
||||||
#include "core/os/memory.h"
|
#include "core/os/memory.h"
|
||||||
|
|
||||||
RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe) {
|
RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe, uint32_t p_render_pass) {
|
||||||
RD::PipelineMultisampleState multisample_state_version = multisample_state;
|
RD::PipelineMultisampleState multisample_state_version = multisample_state;
|
||||||
multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id);
|
multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id, p_render_pass);
|
||||||
|
|
||||||
RD::PipelineRasterizationState raster_state_version = rasterization_state;
|
RD::PipelineRasterizationState raster_state_version = rasterization_state;
|
||||||
raster_state_version.wireframe = p_wireframe;
|
raster_state_version.wireframe = p_wireframe;
|
||||||
|
|
||||||
RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, raster_state_version, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags);
|
RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, raster_state_version, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags, p_render_pass);
|
||||||
ERR_FAIL_COND_V(pipeline.is_null(), RID());
|
ERR_FAIL_COND_V(pipeline.is_null(), RID());
|
||||||
versions = (Version *)memrealloc(versions, sizeof(Version) * (version_count + 1));
|
versions = (Version *)memrealloc(versions, sizeof(Version) * (version_count + 1));
|
||||||
versions[version_count].framebuffer_id = p_framebuffer_format_id;
|
versions[version_count].framebuffer_id = p_framebuffer_format_id;
|
||||||
versions[version_count].vertex_id = p_vertex_format_id;
|
versions[version_count].vertex_id = p_vertex_format_id;
|
||||||
versions[version_count].wireframe = p_wireframe;
|
versions[version_count].wireframe = p_wireframe;
|
||||||
versions[version_count].pipeline = pipeline;
|
versions[version_count].pipeline = pipeline;
|
||||||
|
versions[version_count].render_pass = p_render_pass;
|
||||||
version_count++;
|
version_count++;
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ class PipelineCacheRD {
|
|||||||
struct Version {
|
struct Version {
|
||||||
RD::VertexFormatID vertex_id;
|
RD::VertexFormatID vertex_id;
|
||||||
RD::FramebufferFormatID framebuffer_id;
|
RD::FramebufferFormatID framebuffer_id;
|
||||||
|
uint32_t render_pass;
|
||||||
bool wireframe;
|
bool wireframe;
|
||||||
RID pipeline;
|
RID pipeline;
|
||||||
};
|
};
|
||||||
@ -57,7 +58,7 @@ class PipelineCacheRD {
|
|||||||
Version *versions;
|
Version *versions;
|
||||||
uint32_t version_count;
|
uint32_t version_count;
|
||||||
|
|
||||||
RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe);
|
RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe, uint32_t p_render_pass);
|
||||||
|
|
||||||
void _clear();
|
void _clear();
|
||||||
|
|
||||||
@ -65,7 +66,7 @@ public:
|
|||||||
void setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0);
|
void setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0);
|
||||||
void update_shader(RID p_shader);
|
void update_shader(RID p_shader);
|
||||||
|
|
||||||
_FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe = false) {
|
_FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe = false, uint32_t p_render_pass = 0) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
ERR_FAIL_COND_V_MSG(shader.is_null(), RID(),
|
ERR_FAIL_COND_V_MSG(shader.is_null(), RID(),
|
||||||
"Attempted to use an unused shader variant (shader is null),");
|
"Attempted to use an unused shader variant (shader is null),");
|
||||||
@ -74,13 +75,13 @@ public:
|
|||||||
spin_lock.lock();
|
spin_lock.lock();
|
||||||
RID result;
|
RID result;
|
||||||
for (uint32_t i = 0; i < version_count; i++) {
|
for (uint32_t i = 0; i < version_count; i++) {
|
||||||
if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id && versions[i].wireframe == p_wireframe) {
|
if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id && versions[i].wireframe == p_wireframe && versions[i].render_pass == p_render_pass) {
|
||||||
result = versions[i].pipeline;
|
result = versions[i].pipeline;
|
||||||
spin_lock.unlock();
|
spin_lock.unlock();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = _generate_version(p_vertex_format_id, p_framebuffer_format_id, p_wireframe);
|
result = _generate_version(p_vertex_format_id, p_framebuffer_format_id, p_wireframe, p_render_pass);
|
||||||
spin_lock.unlock();
|
spin_lock.unlock();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ RID RenderingDevice::_texture_create_shared_from_slice(const Ref<RDTextureView>
|
|||||||
return texture_create_shared_from_slice(p_view->base, p_with_texture, p_layer, p_mipmap, p_slice_type);
|
return texture_create_shared_from_slice(p_view->base, p_with_texture, p_layer, p_mipmap, p_slice_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments) {
|
RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments, uint32_t p_view_count) {
|
||||||
Vector<AttachmentFormat> attachments;
|
Vector<AttachmentFormat> attachments;
|
||||||
attachments.resize(p_attachments.size());
|
attachments.resize(p_attachments.size());
|
||||||
|
|
||||||
@ -107,12 +107,43 @@ RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create
|
|||||||
ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID);
|
ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID);
|
||||||
attachments.write[i] = af->base;
|
attachments.write[i] = af->base;
|
||||||
}
|
}
|
||||||
return framebuffer_format_create(attachments);
|
return framebuffer_format_create(attachments, p_view_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
RID RenderingDevice::_framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check) {
|
RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create_multipass(const TypedArray<RDAttachmentFormat> &p_attachments, const TypedArray<RDFramebufferPass> &p_passes, uint32_t p_view_count) {
|
||||||
|
Vector<AttachmentFormat> attachments;
|
||||||
|
attachments.resize(p_attachments.size());
|
||||||
|
|
||||||
|
for (int i = 0; i < p_attachments.size(); i++) {
|
||||||
|
Ref<RDAttachmentFormat> af = p_attachments[i];
|
||||||
|
ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID);
|
||||||
|
attachments.write[i] = af->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<FramebufferPass> passes;
|
||||||
|
for (int i = 0; i < p_passes.size(); i++) {
|
||||||
|
Ref<RDFramebufferPass> pass = p_passes[i];
|
||||||
|
ERR_CONTINUE(pass.is_null());
|
||||||
|
passes.push_back(pass->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
return framebuffer_format_create_multipass(attachments, passes, p_view_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
RID RenderingDevice::_framebuffer_create(const TypedArray<RID> &p_textures, FramebufferFormatID p_format_check, uint32_t p_view_count) {
|
||||||
Vector<RID> textures = Variant(p_textures);
|
Vector<RID> textures = Variant(p_textures);
|
||||||
return framebuffer_create(textures, p_format_check);
|
return framebuffer_create(textures, p_format_check, p_view_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
RID RenderingDevice::_framebuffer_create_multipass(const TypedArray<RID> &p_textures, const TypedArray<RDFramebufferPass> &p_passes, FramebufferFormatID p_format_check, uint32_t p_view_count) {
|
||||||
|
Vector<RID> textures = Variant(p_textures);
|
||||||
|
Vector<FramebufferPass> passes;
|
||||||
|
for (int i = 0; i < p_passes.size(); i++) {
|
||||||
|
Ref<RDFramebufferPass> pass = p_passes[i];
|
||||||
|
ERR_CONTINUE(pass.is_null());
|
||||||
|
passes.push_back(pass->base);
|
||||||
|
}
|
||||||
|
return framebuffer_create_multipass(textures, passes, p_format_check, p_view_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
RID RenderingDevice::_sampler_create(const Ref<RDSamplerState> &p_state) {
|
RID RenderingDevice::_sampler_create(const Ref<RDSamplerState> &p_state) {
|
||||||
@ -190,7 +221,7 @@ Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t
|
|||||||
return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_post_barrier);
|
return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_post_barrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags) {
|
RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass) {
|
||||||
PipelineRasterizationState rasterization_state;
|
PipelineRasterizationState rasterization_state;
|
||||||
if (p_rasterization_state.is_valid()) {
|
if (p_rasterization_state.is_valid()) {
|
||||||
rasterization_state = p_rasterization_state->base;
|
rasterization_state = p_rasterization_state->base;
|
||||||
@ -221,7 +252,7 @@ RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags);
|
return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags, p_for_render_pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<int64_t> RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const TypedArray<RID> &p_storage_textures) {
|
Vector<int64_t> RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const TypedArray<RID> &p_storage_textures) {
|
||||||
@ -242,6 +273,22 @@ Vector<int64_t> RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint3
|
|||||||
return split_ids;
|
return split_ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector<int64_t> RenderingDevice::_draw_list_switch_to_next_pass_split(uint32_t p_splits) {
|
||||||
|
Vector<DrawListID> splits;
|
||||||
|
splits.resize(p_splits);
|
||||||
|
|
||||||
|
Error err = draw_list_switch_to_next_pass_split(p_splits, splits.ptrw());
|
||||||
|
ERR_FAIL_COND_V(err != OK, Vector<int64_t>());
|
||||||
|
|
||||||
|
Vector<int64_t> split_ids;
|
||||||
|
split_ids.resize(splits.size());
|
||||||
|
for (int i = 0; i < splits.size(); i++) {
|
||||||
|
split_ids.write[i] = splits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return split_ids;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingDevice::_draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) {
|
void RenderingDevice::_draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) {
|
||||||
ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size);
|
ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size);
|
||||||
draw_list_set_push_constant(p_list, p_data.ptr(), p_data_size);
|
draw_list_set_push_constant(p_list, p_data.ptr(), p_data_size);
|
||||||
@ -269,10 +316,12 @@ void RenderingDevice::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "post_barrier"), &RenderingDevice::texture_clear, DEFVAL(BARRIER_MASK_ALL));
|
ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "post_barrier"), &RenderingDevice::texture_clear, DEFVAL(BARRIER_MASK_ALL));
|
||||||
ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "post_barrier"), &RenderingDevice::texture_resolve_multisample, DEFVAL(BARRIER_MASK_ALL));
|
ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "post_barrier"), &RenderingDevice::texture_resolve_multisample, DEFVAL(BARRIER_MASK_ALL));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("framebuffer_format_create", "attachments"), &RenderingDevice::_framebuffer_format_create);
|
ClassDB::bind_method(D_METHOD("framebuffer_format_create", "attachments", "view_count"), &RenderingDevice::_framebuffer_format_create, DEFVAL(1));
|
||||||
|
ClassDB::bind_method(D_METHOD("framebuffer_format_create_multipass", "attachments", "passes", "view_count"), &RenderingDevice::_framebuffer_format_create_multipass, DEFVAL(1));
|
||||||
ClassDB::bind_method(D_METHOD("framebuffer_format_create_empty", "samples"), &RenderingDevice::framebuffer_format_create_empty, DEFVAL(TEXTURE_SAMPLES_1));
|
ClassDB::bind_method(D_METHOD("framebuffer_format_create_empty", "samples"), &RenderingDevice::framebuffer_format_create_empty, DEFVAL(TEXTURE_SAMPLES_1));
|
||||||
ClassDB::bind_method(D_METHOD("framebuffer_format_get_texture_samples", "format"), &RenderingDevice::framebuffer_format_get_texture_samples);
|
ClassDB::bind_method(D_METHOD("framebuffer_format_get_texture_samples", "format", "render_pass"), &RenderingDevice::framebuffer_format_get_texture_samples, DEFVAL(0));
|
||||||
ClassDB::bind_method(D_METHOD("framebuffer_create", "textures", "validate_with_format"), &RenderingDevice::_framebuffer_create, DEFVAL(INVALID_FORMAT_ID));
|
ClassDB::bind_method(D_METHOD("framebuffer_create", "textures", "validate_with_format", "view_count"), &RenderingDevice::_framebuffer_create, DEFVAL(INVALID_FORMAT_ID), DEFVAL(1));
|
||||||
|
ClassDB::bind_method(D_METHOD("framebuffer_create_multipass", "textures", "passes", "validate_with_format", "view_count"), &RenderingDevice::_framebuffer_create_multipass, DEFVAL(INVALID_FORMAT_ID), DEFVAL(1));
|
||||||
ClassDB::bind_method(D_METHOD("framebuffer_create_empty", "size", "samples", "validate_with_format"), &RenderingDevice::framebuffer_create_empty, DEFVAL(TEXTURE_SAMPLES_1), DEFVAL(INVALID_FORMAT_ID));
|
ClassDB::bind_method(D_METHOD("framebuffer_create_empty", "size", "samples", "validate_with_format"), &RenderingDevice::framebuffer_create_empty, DEFVAL(TEXTURE_SAMPLES_1), DEFVAL(INVALID_FORMAT_ID));
|
||||||
ClassDB::bind_method(D_METHOD("framebuffer_get_format", "framebuffer"), &RenderingDevice::framebuffer_get_format);
|
ClassDB::bind_method(D_METHOD("framebuffer_get_format", "framebuffer"), &RenderingDevice::framebuffer_get_format);
|
||||||
|
|
||||||
@ -299,7 +348,7 @@ void RenderingDevice::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("buffer_clear", "buffer", "offset", "size_bytes", "post_barrier"), &RenderingDevice::buffer_clear, DEFVAL(BARRIER_MASK_ALL));
|
ClassDB::bind_method(D_METHOD("buffer_clear", "buffer", "offset", "size_bytes", "post_barrier"), &RenderingDevice::buffer_clear, DEFVAL(BARRIER_MASK_ALL));
|
||||||
ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data);
|
ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags"), &RenderingDevice::_render_pipeline_create, DEFVAL(0));
|
ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags", "for_render_pass"), &RenderingDevice::_render_pipeline_create, DEFVAL(0), DEFVAL(0));
|
||||||
ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid);
|
ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("compute_pipeline_create", "shader"), &RenderingDevice::compute_pipeline_create);
|
ClassDB::bind_method(D_METHOD("compute_pipeline_create", "shader"), &RenderingDevice::compute_pipeline_create);
|
||||||
@ -325,6 +374,9 @@ void RenderingDevice::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("draw_list_enable_scissor", "draw_list", "rect"), &RenderingDevice::draw_list_enable_scissor, DEFVAL(Rect2i()));
|
ClassDB::bind_method(D_METHOD("draw_list_enable_scissor", "draw_list", "rect"), &RenderingDevice::draw_list_enable_scissor, DEFVAL(Rect2i()));
|
||||||
ClassDB::bind_method(D_METHOD("draw_list_disable_scissor", "draw_list"), &RenderingDevice::draw_list_disable_scissor);
|
ClassDB::bind_method(D_METHOD("draw_list_disable_scissor", "draw_list"), &RenderingDevice::draw_list_disable_scissor);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("draw_list_switch_to_next_pass"), &RenderingDevice::draw_list_switch_to_next_pass);
|
||||||
|
ClassDB::bind_method(D_METHOD("draw_list_switch_to_next_pass_split", "splits"), &RenderingDevice::_draw_list_switch_to_next_pass_split);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("draw_list_end", "post_barrier"), &RenderingDevice::draw_list_end, DEFVAL(BARRIER_MASK_ALL));
|
ClassDB::bind_method(D_METHOD("draw_list_end", "post_barrier"), &RenderingDevice::draw_list_end, DEFVAL(BARRIER_MASK_ALL));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("compute_list_begin", "allow_draw_overlap"), &RenderingDevice::compute_list_begin, DEFVAL(false));
|
ClassDB::bind_method(D_METHOD("compute_list_begin", "allow_draw_overlap"), &RenderingDevice::compute_list_begin, DEFVAL(false));
|
||||||
|
@ -47,6 +47,7 @@ class RDPipelineRasterizationState;
|
|||||||
class RDPipelineMultisampleState;
|
class RDPipelineMultisampleState;
|
||||||
class RDPipelineDepthStencilState;
|
class RDPipelineDepthStencilState;
|
||||||
class RDPipelineColorBlendState;
|
class RDPipelineColorBlendState;
|
||||||
|
class RDFramebufferPass;
|
||||||
|
|
||||||
class RenderingDevice : public Object {
|
class RenderingDevice : public Object {
|
||||||
GDCLASS(RenderingDevice, Object)
|
GDCLASS(RenderingDevice, Object)
|
||||||
@ -517,10 +518,23 @@ public:
|
|||||||
|
|
||||||
// This ID is warranted to be unique for the same formats, does not need to be freed
|
// This ID is warranted to be unique for the same formats, does not need to be freed
|
||||||
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format, uint32_t p_view_count = 1) = 0;
|
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format, uint32_t p_view_count = 1) = 0;
|
||||||
|
struct FramebufferPass {
|
||||||
|
enum {
|
||||||
|
ATTACHMENT_UNUSED = -1
|
||||||
|
};
|
||||||
|
Vector<int32_t> color_attachments;
|
||||||
|
Vector<int32_t> input_attachments;
|
||||||
|
Vector<int32_t> resolve_attachments;
|
||||||
|
Vector<int32_t> preserve_attachments;
|
||||||
|
int32_t depth_attachment = ATTACHMENT_UNUSED;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual FramebufferFormatID framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, Vector<FramebufferPass> &p_passes, uint32_t p_view_count = 1) = 0;
|
||||||
virtual FramebufferFormatID framebuffer_format_create_empty(TextureSamples p_samples = TEXTURE_SAMPLES_1) = 0;
|
virtual FramebufferFormatID framebuffer_format_create_empty(TextureSamples p_samples = TEXTURE_SAMPLES_1) = 0;
|
||||||
virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format) = 0;
|
virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format, uint32_t p_pass = 0) = 0;
|
||||||
|
|
||||||
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1) = 0;
|
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1) = 0;
|
||||||
|
virtual RID framebuffer_create_multipass(const Vector<RID> &p_texture_attachments, Vector<FramebufferPass> &p_passes, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1) = 0;
|
||||||
virtual RID framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples = TEXTURE_SAMPLES_1, FramebufferFormatID p_format_check = INVALID_ID) = 0;
|
virtual RID framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples = TEXTURE_SAMPLES_1, FramebufferFormatID p_format_check = INVALID_ID) = 0;
|
||||||
|
|
||||||
virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer) = 0;
|
virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer) = 0;
|
||||||
@ -962,7 +976,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
virtual bool render_pipeline_is_valid(RID p_pipeline) = 0;
|
virtual bool render_pipeline_is_valid(RID p_pipeline) = 0;
|
||||||
virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0;
|
virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0) = 0;
|
||||||
|
|
||||||
/**************************/
|
/**************************/
|
||||||
/**** COMPUTE PIPELINE ****/
|
/**** COMPUTE PIPELINE ****/
|
||||||
@ -1018,6 +1032,9 @@ public:
|
|||||||
virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect) = 0;
|
virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect) = 0;
|
||||||
virtual void draw_list_disable_scissor(DrawListID p_list) = 0;
|
virtual void draw_list_disable_scissor(DrawListID p_list) = 0;
|
||||||
|
|
||||||
|
virtual DrawListID draw_list_switch_to_next_pass() = 0;
|
||||||
|
virtual Error draw_list_switch_to_next_pass_split(uint32_t p_splits, DrawListID *r_split_ids) = 0;
|
||||||
|
|
||||||
virtual void draw_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
|
virtual void draw_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
|
||||||
|
|
||||||
/***********************/
|
/***********************/
|
||||||
@ -1134,8 +1151,10 @@ protected:
|
|||||||
RID _texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture);
|
RID _texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture);
|
||||||
RID _texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D);
|
RID _texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D);
|
||||||
|
|
||||||
FramebufferFormatID _framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments);
|
FramebufferFormatID _framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments, uint32_t p_view_count);
|
||||||
RID _framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check = INVALID_ID);
|
FramebufferFormatID _framebuffer_format_create_multipass(const TypedArray<RDAttachmentFormat> &p_attachments, const TypedArray<RDFramebufferPass> &p_passes, uint32_t p_view_count);
|
||||||
|
RID _framebuffer_create(const TypedArray<RID> &p_textures, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1);
|
||||||
|
RID _framebuffer_create_multipass(const TypedArray<RID> &p_textures, const TypedArray<RDFramebufferPass> &p_passes, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1);
|
||||||
RID _sampler_create(const Ref<RDSamplerState> &p_state);
|
RID _sampler_create(const Ref<RDSamplerState> &p_state);
|
||||||
VertexFormatID _vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats);
|
VertexFormatID _vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats);
|
||||||
RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers);
|
RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers);
|
||||||
@ -1146,11 +1165,12 @@ protected:
|
|||||||
|
|
||||||
Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL);
|
Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL);
|
||||||
|
|
||||||
RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags = 0);
|
RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0);
|
||||||
|
|
||||||
Vector<int64_t> _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const TypedArray<RID> &p_storage_textures = TypedArray<RID>());
|
Vector<int64_t> _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const TypedArray<RID> &p_storage_textures = TypedArray<RID>());
|
||||||
void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
|
void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
|
||||||
void _compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
|
void _compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
|
||||||
|
Vector<int64_t> _draw_list_switch_to_next_pass_split(uint32_t p_splits);
|
||||||
};
|
};
|
||||||
|
|
||||||
VARIANT_ENUM_CAST(RenderingDevice::ShaderStage)
|
VARIANT_ENUM_CAST(RenderingDevice::ShaderStage)
|
||||||
|
@ -128,6 +128,34 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RDFramebufferPass : public RefCounted {
|
||||||
|
GDCLASS(RDFramebufferPass, RefCounted)
|
||||||
|
friend class RenderingDevice;
|
||||||
|
|
||||||
|
RD::FramebufferPass base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RD_SETGET(PackedInt32Array, color_attachments)
|
||||||
|
RD_SETGET(PackedInt32Array, input_attachments)
|
||||||
|
RD_SETGET(PackedInt32Array, resolve_attachments)
|
||||||
|
RD_SETGET(PackedInt32Array, preserve_attachments)
|
||||||
|
RD_SETGET(int32_t, depth_attachment)
|
||||||
|
protected:
|
||||||
|
enum {
|
||||||
|
ATTACHMENT_UNUSED = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
static void _bind_methods() {
|
||||||
|
RD_BIND(Variant::PACKED_INT32_ARRAY, RDFramebufferPass, color_attachments);
|
||||||
|
RD_BIND(Variant::PACKED_INT32_ARRAY, RDFramebufferPass, input_attachments);
|
||||||
|
RD_BIND(Variant::PACKED_INT32_ARRAY, RDFramebufferPass, resolve_attachments);
|
||||||
|
RD_BIND(Variant::PACKED_INT32_ARRAY, RDFramebufferPass, preserve_attachments);
|
||||||
|
RD_BIND(Variant::INT, RDFramebufferPass, depth_attachment);
|
||||||
|
|
||||||
|
BIND_CONSTANT(ATTACHMENT_UNUSED);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class RDSamplerState : public RefCounted {
|
class RDSamplerState : public RefCounted {
|
||||||
GDCLASS(RDSamplerState, RefCounted)
|
GDCLASS(RDSamplerState, RefCounted)
|
||||||
friend class RenderingDevice;
|
friend class RenderingDevice;
|
||||||
|
Loading…
Reference in New Issue
Block a user