|
@@ -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
|
|
|
|
- TextureSamples samples;
|
|
|
|
|
|
+ Vector<TextureSamples> pass_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);
|
|
|
|
|
|
/***********************/
|
|
/***********************/
|