summaryrefslogtreecommitdiff
path: root/drivers/vulkan/rendering_device_vulkan.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vulkan/rendering_device_vulkan.h')
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h143
1 files changed, 129 insertions, 14 deletions
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index f4fe9cf956..dc1b78c1d5 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -44,7 +44,11 @@
#endif
#include "vk_mem_alloc.h"
+#ifdef USE_VOLK
+#include <volk.h>
+#else
#include <vulkan/vulkan.h>
+#endif
class VulkanContext;
@@ -156,6 +160,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t texture_upload_region_size_px = 0;
Vector<uint8_t> _texture_get_data_from_image(Texture *tex, VkImage p_image, VmaAllocation p_allocation, uint32_t p_layer, bool p_2d = false);
+ Error _texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier, bool p_use_setup_queue);
/*****************/
/**** SAMPLER ****/
@@ -234,12 +239,87 @@ class RenderingDeviceVulkan : public RenderingDevice {
struct FramebufferFormatKey {
Vector<AttachmentFormat> attachments;
+ Vector<FramebufferPass> passes;
uint32_t view_count = 1;
bool operator<(const FramebufferFormatKey &p_key) const {
if (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 bs = p_key.attachments.size();
if (as != bs) {
@@ -266,16 +346,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
// IDs for a given format are always unique.
Map<FramebufferFormatKey, FramebufferFormatID> framebuffer_format_cache;
struct FramebufferFormat {
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)
- int color_attachments = 0; //used for pipeline validation
- TextureSamples samples;
+ Vector<TextureSamples> pass_samples;
uint32_t view_count = 1; // number of views
};
@@ -289,6 +367,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
InitialAction initial_depth_action;
FinalAction final_depth_action;
uint32_t view_count;
+
bool operator<(const VersionKey &p_key) const {
if (initial_color_action == p_key.initial_color_action) {
if (final_color_action == p_key.final_color_action) {
@@ -316,6 +395,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
struct Version {
VkFramebuffer framebuffer = VK_NULL_HANDLE;
VkRenderPass render_pass = VK_NULL_HANDLE; //this one is owned
+ uint32_t subpass_count = 1;
};
Map<VersionKey, Version> framebuffers;
@@ -536,7 +616,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
};
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 {
uint32_t push_constant_size = 0;
@@ -547,12 +627,19 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t compute_local_size[3] = { 0, 0, 0 };
+ struct SpecializationConstant {
+ PipelineSpecializationConstant constant;
+ uint32_t stage_flags = 0;
+ };
+
bool is_compute = false;
int max_output = 0;
Vector<Set> sets;
Vector<uint32_t> set_formats;
Vector<VkPipelineShaderStageCreateInfo> pipeline_stages;
+ Vector<SpecializationConstant> specialization_constants;
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
+ String name; //used for debug
};
String _shader_uniform_debug(RID p_shader, int p_set = -1);
@@ -570,8 +657,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
// Basically, you can mix and match pools as you
// like, but you'll run into fragmentation issues.
// Because of this, the recommended approach is to
- // create a a pool for every descriptor set type,
- // as this prevents fragmentation.
+ // create a pool for every descriptor set type, as
+ // this prevents fragmentation.
//
// This is implemented here as a having a list of
// pools (each can contain up to 64 sets) for each
@@ -656,6 +743,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
LocalVector<AttachableTexture> attachable_textures; //used for validation
Vector<Texture *> mutable_sampled_textures; //used for layout change
Vector<Texture *> mutable_storage_textures; //used for layout change
+ UniformSetInvalidatedCallback invalidated_callback = nullptr;
+ void *invalidated_callback_userdata = nullptr;
};
RID_Owner<UniformSet, true> uniform_set_owner;
@@ -680,6 +769,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
#ifdef DEBUG_ENABLED
struct Validation {
FramebufferFormatID framebuffer_format = 0;
+ uint32_t render_pass = 0;
uint32_t dynamic_state = 0;
VertexFormatID vertex_format = 0;
bool uses_restart_indices = false;
@@ -735,6 +825,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
struct DrawList {
VkCommandBuffer command_buffer = VK_NULL_HANDLE; // If persistent, this is owned, otherwise it's shared with the ringbuffer.
Rect2i viewport;
+ bool viewport_set = false;
struct SetState {
uint32_t pipeline_expected_format = 0;
@@ -758,7 +849,6 @@ class RenderingDeviceVulkan : public RenderingDevice {
#ifdef DEBUG_ENABLED
struct Validation {
bool active = true; // Means command buffer was not closed, so you can keep adding things.
- FramebufferFormatID framebuffer_format = INVALID_ID;
// Actual render pass values.
uint32_t dynamic_state = 0;
VertexFormatID vertex_format = INVALID_ID;
@@ -794,7 +884,15 @@ class RenderingDeviceVulkan : public RenderingDevice {
};
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;
+ 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;
Vector<RID> draw_list_bound_textures;
Vector<RID> draw_list_storage_textures;
@@ -802,10 +900,12 @@ class RenderingDeviceVulkan : public RenderingDevice {
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);
- 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);
_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);
+ 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 ****/
@@ -919,6 +1019,9 @@ class RenderingDeviceVulkan : public RenderingDevice {
VulkanContext *context = nullptr;
+ uint64_t image_memory = 0;
+ uint64_t buffer_memory = 0;
+
void _free_internal(RID p_id);
void _flush(bool p_current_frame);
@@ -941,6 +1044,7 @@ public:
virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const;
virtual bool texture_is_shared(RID p_texture);
virtual bool texture_is_valid(RID p_texture);
+ virtual Size2i texture_size(RID p_texture);
virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier = BARRIER_MASK_ALL);
virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier = BARRIER_MASK_ALL);
@@ -951,10 +1055,12 @@ public:
/*********************/
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 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_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 FramebufferFormatID framebuffer_get_format(RID p_framebuffer);
@@ -983,7 +1089,11 @@ public:
/**** SHADER ****/
/****************/
- virtual RID shader_create(const Vector<ShaderStageData> &p_stages);
+ virtual String shader_get_binary_cache_key() const;
+ virtual Vector<uint8_t> shader_compile_binary_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv, const String &p_shader_name = "");
+
+ virtual RID shader_create_from_bytecode(const Vector<uint8_t> &p_shader_binary);
+
virtual uint32_t shader_get_vertex_input_attribute_mask(RID p_shader);
/*****************/
@@ -996,6 +1106,7 @@ public:
virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set);
virtual bool uniform_set_is_valid(RID p_uniform_set);
+ virtual void uniform_set_set_invalidation_callback(RID p_uniform_set, UniformSetInvalidatedCallback p_callback, void *p_userdata);
virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL); //works for any buffer
virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL);
@@ -1005,14 +1116,14 @@ public:
/**** 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, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>());
virtual bool render_pipeline_is_valid(RID p_pipeline);
/**************************/
/**** COMPUTE PIPELINE ****/
/**************************/
- virtual RID compute_pipeline_create(RID p_shader);
+ virtual RID compute_pipeline_create(RID p_shader, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>());
virtual bool compute_pipeline_is_valid(RID p_pipeline);
/****************/
@@ -1044,6 +1155,10 @@ public:
virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect);
virtual void draw_list_disable_scissor(DrawListID p_list);
+ virtual uint32_t draw_list_get_current_pass();
+ 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);
/***********************/
@@ -1100,7 +1215,7 @@ public:
virtual RenderingDevice *create_local_device();
- virtual uint64_t get_memory_usage() const;
+ virtual uint64_t get_memory_usage(MemoryType p_type) const;
virtual void set_resource_name(RID p_id, const String p_name);