summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dummy/rasterizer_dummy.h40
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp6
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp17
-rw-r--r--drivers/gles2/shader_compiler_gles2.h2
-rw-r--r--drivers/gles2/shaders/stdlib.glsl20
-rw-r--r--drivers/png/image_loader_png.cpp5
-rw-r--r--drivers/png/png_driver_common.cpp7
-rw-r--r--drivers/png/png_driver_common.h2
-rw-r--r--drivers/unix/ip_unix.h4
-rw-r--r--drivers/unix/net_socket_posix.cpp2
-rw-r--r--drivers/unix/os_unix.cpp16
-rw-r--r--drivers/unix/os_unix.h4
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp260
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h185
-rw-r--r--drivers/vulkan/vulkan_context.cpp29
-rw-r--r--drivers/vulkan/vulkan_context.h32
-rw-r--r--drivers/windows/dir_access_windows.cpp10
17 files changed, 417 insertions, 224 deletions
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index d619a20745..0d2d6b38a7 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -51,6 +51,14 @@ public:
int get_directional_light_shadow_size(RID p_light_intance) { return 0; }
void set_directional_shadow_count(int p_count) {}
+ /* SDFGI UPDATE */
+
+ virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) {}
+ virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const { return 0; }
+ virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const { return AABB(); }
+ virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const { return 0; }
+ virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) {}
+
/* SKY API */
RID sky_create() { return RID(); }
@@ -87,6 +95,11 @@ public:
virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {}
virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) {}
+ virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {}
+
+ virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) {}
+ virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) {}
+
void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {}
void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {}
@@ -114,6 +127,7 @@ public:
RID light_instance_create(RID p_light) { return RID(); }
void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {}
+ virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) {}
void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) {}
void light_instance_mark_visible(RID p_light_instance) {}
@@ -137,9 +151,13 @@ public:
virtual bool gi_probe_needs_update(RID p_probe) const { return false; }
virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) {}
+ virtual void gi_probe_set_quality(RS::GIProbeQuality) {}
+
virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {}
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {}
virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {}
+ virtual void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) {}
+ virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) {}
void set_scene_pass(uint64_t p_pass) {}
virtual void set_time(double p_time, double p_step) {}
@@ -148,7 +166,7 @@ public:
virtual RID render_buffers_create() { return RID(); }
virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa) {}
- virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve) {}
+ virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) {}
virtual bool screen_space_roughness_limiter_is_active() const { return false; }
virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) {}
@@ -158,6 +176,7 @@ public:
bool free(RID p_rid) { return true; }
virtual void update() {}
+ virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {}
RasterizerSceneDummy() {}
~RasterizerSceneDummy() {}
@@ -576,7 +595,8 @@ public:
void light_set_negative(RID p_light, bool p_enable) {}
void light_set_cull_mask(RID p_light, uint32_t p_mask) {}
void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {}
- void light_set_use_gi(RID p_light, bool p_enabled) {}
+ void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {}
+ void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {}
void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {}
@@ -595,7 +615,8 @@ public:
AABB light_get_aabb(RID p_light) const { return AABB(); }
float light_get_param(RID p_light, RS::LightParam p_param) { return 0.0; }
Color light_get_color(RID p_light) { return Color(); }
- bool light_get_use_gi(RID p_light) { return false; }
+ virtual RS::LightBakeMode light_get_bake_mode(RID p_light) { return RS::LIGHT_BAKE_DISABLED; }
+ virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) { return 0; }
uint64_t light_get_version(RID p_light) const { return 0; }
/* PROBE API */
@@ -604,9 +625,9 @@ public:
void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {}
void reflection_probe_set_intensity(RID p_probe, float p_intensity) {}
- void reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient) {}
- void reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy) {}
- void reflection_probe_set_interior_ambient_probe_contribution(RID p_probe, float p_contrib) {}
+ void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) {}
+ void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) {}
+ void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) {}
void reflection_probe_set_max_distance(RID p_probe, float p_distance) {}
void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {}
void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {}
@@ -861,6 +882,13 @@ public:
texture_owner.free(p_rid);
memdelete(texture);
}
+
+ if (mesh_owner.owns(p_rid)) {
+ // delete the mesh
+ DummyMesh *mesh = mesh_owner.getornull(p_rid);
+ mesh_owner.free(p_rid);
+ memdelete(mesh);
+ }
return true;
}
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 6eef04b87f..4dd66c06e6 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -2566,9 +2566,7 @@ Vector<uint8_t> RasterizerStorageGLES2::mesh_surface_get_array(RID p_mesh, int p
ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Vector<uint8_t>());
Surface *surface = mesh->surfaces[p_surface];
-#ifndef TOOLS_ENABLED
- ERR_PRINT("OpenGL ES 2.0 does not allow retrieving mesh array data");
-#endif
+
return surface->data;
}
@@ -2612,7 +2610,7 @@ Vector<Vector<uint8_t>> RasterizerStorageGLES2::mesh_surface_get_blend_shapes(RI
ERR_FAIL_COND_V(!mesh, Vector<Vector<uint8_t>>());
ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Vector<Vector<uint8_t>>());
#ifndef TOOLS_ENABLED
- ERR_PRINT("OpenGL ES 2.0 does not allow retrieving mesh array data");
+ ERR_PRINT("OpenGL ES 2.0 does not allow retrieving blend shape data");
#endif
return mesh->surfaces[p_surface]->blend_shape_data;
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 9b57f417cb..1e30f0dfa1 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -247,6 +247,9 @@ void ShaderCompilerGLES2::_dump_function_deps(SL::ShaderNode *p_node, const Stri
for (int i = 0; i < fnode->arguments.size(); i++) {
if (i > 0)
header += ", ";
+ if (fnode->arguments[i].is_const) {
+ header += "const ";
+ }
if (fnode->arguments[i].type == SL::TYPE_STRUCT) {
header += _qualstr(fnode->arguments[i].qualifier) + _mkid(fnode->arguments[i].type_str) + " " + _mkid(fnode->arguments[i].name);
} else {
@@ -262,7 +265,7 @@ void ShaderCompilerGLES2::_dump_function_deps(SL::ShaderNode *p_node, const Stri
}
}
-String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning) {
+String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) {
StringBuilder code;
switch (p_node->type) {
@@ -626,7 +629,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
if (arr_node->call_expression != nullptr) {
code += ".";
- code += _dump_node_code(arr_node->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += _dump_node_code(arr_node->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning, false);
}
if (arr_node->index_expression != nullptr) {
@@ -822,13 +825,17 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
} break;
default: {
- code += "(";
+ if (p_use_scope) {
+ code += "(";
+ }
code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += " ";
code += _opstr(op_node->op);
code += " ";
code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += ")";
+ if (p_use_scope) {
+ code += ")";
+ }
} break;
}
} break;
@@ -1009,6 +1016,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[RS::SHADER_CANVAS_ITEM].usage_defines["isinf"] = "#define IS_INF_USED\n";
actions[RS::SHADER_CANVAS_ITEM].usage_defines["isnan"] = "#define IS_NAN_USED\n";
actions[RS::SHADER_CANVAS_ITEM].usage_defines["trunc"] = "#define TRUNC_USED\n";
+ actions[RS::SHADER_CANVAS_ITEM].usage_defines["fma"] = "#define FMA_USED\n";
/** SPATIAL SHADER **/
@@ -1119,6 +1127,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[RS::SHADER_SPATIAL].usage_defines["isinf"] = "#define IS_INF_USED\n";
actions[RS::SHADER_SPATIAL].usage_defines["isnan"] = "#define IS_NAN_USED\n";
actions[RS::SHADER_SPATIAL].usage_defines["trunc"] = "#define TRUNC_USED\n";
+ actions[RS::SHADER_SPATIAL].usage_defines["fma"] = "#define FMA_USED\n";
actions[RS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
actions[RS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n";
diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h
index 369bf7877b..66a3af0739 100644
--- a/drivers/gles2/shader_compiler_gles2.h
+++ b/drivers/gles2/shader_compiler_gles2.h
@@ -75,7 +75,7 @@ private:
};
void _dump_function_deps(ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added);
- String _dump_node_code(ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning);
+ String _dump_node_code(ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope = true);
StringName current_func_name;
StringName vertex_name;
diff --git a/drivers/gles2/shaders/stdlib.glsl b/drivers/gles2/shaders/stdlib.glsl
index 9c74418743..807036dda6 100644
--- a/drivers/gles2/shaders/stdlib.glsl
+++ b/drivers/gles2/shaders/stdlib.glsl
@@ -417,4 +417,24 @@ highp mat4 outerProduct(highp vec4 c, highp vec4 r) {
#endif
+#if defined(FMA_USED)
+
+highp float fma(highp float a, highp float b, highp float c) {
+ return a * b + c;
+}
+
+highp vec2 fma(highp vec2 a, highp vec2 b, highp vec2 c) {
+ return a * b + c;
+}
+
+highp vec3 fma(highp vec3 a, highp vec3 b, highp vec3 c) {
+ return a * b + c;
+}
+
+highp vec4 fma(highp vec4 a, highp vec4 b, highp vec4 c) {
+ return a * b + c;
+}
+
+#endif
+
#endif
diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp
index 8af58a7ed7..79924b849c 100644
--- a/drivers/png/image_loader_png.cpp
+++ b/drivers/png/image_loader_png.cpp
@@ -50,7 +50,7 @@ Error ImageLoaderPNG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
f->close();
}
const uint8_t *reader = file_buffer.ptr();
- return PNGDriverCommon::png_to_image(reader, buffer_size, p_image);
+ return PNGDriverCommon::png_to_image(reader, buffer_size, p_force_linear, p_image);
}
void ImageLoaderPNG::get_recognized_extensions(List<String> *p_extensions) const {
@@ -61,7 +61,8 @@ Ref<Image> ImageLoaderPNG::load_mem_png(const uint8_t *p_png, int p_size) {
Ref<Image> img;
img.instance();
- Error err = PNGDriverCommon::png_to_image(p_png, p_size, img);
+ // the value of p_force_linear does not matter since it only applies to 16 bit
+ Error err = PNGDriverCommon::png_to_image(p_png, p_size, false, img);
ERR_FAIL_COND_V(err, Ref<Image>());
return img;
diff --git a/drivers/png/png_driver_common.cpp b/drivers/png/png_driver_common.cpp
index 77d5e68826..d3e187c501 100644
--- a/drivers/png/png_driver_common.cpp
+++ b/drivers/png/png_driver_common.cpp
@@ -58,7 +58,7 @@ static bool check_error(const png_image &image) {
return false;
}
-Error png_to_image(const uint8_t *p_source, size_t p_size, Ref<Image> p_image) {
+Error png_to_image(const uint8_t *p_source, size_t p_size, bool p_force_linear, Ref<Image> p_image) {
png_image png_img;
zeromem(&png_img, sizeof(png_img));
png_img.version = PNG_IMAGE_VERSION;
@@ -99,6 +99,11 @@ Error png_to_image(const uint8_t *p_source, size_t p_size, Ref<Image> p_image) {
return ERR_UNAVAILABLE;
}
+ if (!p_force_linear) {
+ // assume 16 bit pngs without sRGB or gAMA chunks are in sRGB format
+ png_img.flags |= PNG_IMAGE_FLAG_16BIT_sRGB;
+ }
+
const png_uint_32 stride = PNG_IMAGE_ROW_STRIDE(png_img);
Vector<uint8_t> buffer;
Error err = buffer.resize(PNG_IMAGE_BUFFER_SIZE(png_img, stride));
diff --git a/drivers/png/png_driver_common.h b/drivers/png/png_driver_common.h
index 12129f034e..2099ddc536 100644
--- a/drivers/png/png_driver_common.h
+++ b/drivers/png/png_driver_common.h
@@ -36,7 +36,7 @@
namespace PNGDriverCommon {
// Attempt to load png from buffer (p_source, p_size) into p_image
-Error png_to_image(const uint8_t *p_source, size_t p_size, Ref<Image> p_image);
+Error png_to_image(const uint8_t *p_source, size_t p_size, bool p_force_linear, Ref<Image> p_image);
// Append p_image, as a png, to p_buffer.
// Contents of p_buffer is unspecified if error returned.
diff --git a/drivers/unix/ip_unix.h b/drivers/unix/ip_unix.h
index 0580facac2..7497f64a53 100644
--- a/drivers/unix/ip_unix.h
+++ b/drivers/unix/ip_unix.h
@@ -38,12 +38,12 @@
class IP_Unix : public IP {
GDCLASS(IP_Unix, IP);
- virtual IP_Address _resolve_hostname(const String &p_hostname, IP::Type p_type);
+ virtual IP_Address _resolve_hostname(const String &p_hostname, IP::Type p_type) override;
static IP *_create_unix();
public:
- virtual void get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const;
+ virtual void get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const override;
static void make_default();
IP_Unix();
diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp
index 15ad187ab4..186804dbb1 100644
--- a/drivers/unix/net_socket_posix.cpp
+++ b/drivers/unix/net_socket_posix.cpp
@@ -245,7 +245,7 @@ _FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IP_Address p_ip, St
continue;
}
- if_v6id = (uint32_t)c.index.to_int64();
+ if_v6id = (uint32_t)c.index.to_int();
if (type == IP::TYPE_IPV6) {
break; // IPv6 uses index.
}
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 083cd64116..9a5fc6d1a4 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -163,21 +163,11 @@ String OS_Unix::get_name() const {
return "Unix";
}
-uint64_t OS_Unix::get_unix_time() const {
- return time(nullptr);
-};
-
-uint64_t OS_Unix::get_system_time_secs() const {
- struct timeval tv_now;
- gettimeofday(&tv_now, nullptr);
- return uint64_t(tv_now.tv_sec);
-}
-
-uint64_t OS_Unix::get_system_time_msecs() const {
+double OS_Unix::get_unix_time() const {
struct timeval tv_now;
gettimeofday(&tv_now, nullptr);
- return uint64_t(tv_now.tv_sec) * 1000 + uint64_t(tv_now.tv_usec) / 1000;
-}
+ return (double)tv_now.tv_sec + double(tv_now.tv_usec) / 1000000;
+};
OS::Date OS_Unix::get_date(bool utc) const {
time_t t = time(nullptr);
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 7d235803dc..2982e0c55c 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -77,9 +77,7 @@ public:
virtual Time get_time(bool utc) const;
virtual TimeZoneInfo get_time_zone_info() const;
- virtual uint64_t get_unix_time() const;
- virtual uint64_t get_system_time_secs() const;
- virtual uint64_t get_system_time_msecs() const;
+ virtual double get_unix_time() const;
virtual void delay_usec(uint32_t p_usec) const;
virtual uint64_t get_ticks_usec() const;
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 8c711837b4..cb26d3ce92 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -35,9 +35,10 @@
#include "core/os/os.h"
#include "core/project_settings.h"
#include "drivers/vulkan/vulkan_context.h"
+
#include "thirdparty/spirv-reflect/spirv_reflect.h"
-//#define FORCE_FULL_BARRIER
+#define FORCE_FULL_BARRIER
void RenderingDeviceVulkan::_add_dependency(RID p_id, RID p_depends_on) {
if (!dependency_map.has(p_depends_on)) {
@@ -64,7 +65,7 @@ void RenderingDeviceVulkan::_free_dependencies(RID p_id) {
dependency_map.erase(E);
}
- //reverse depenencies must be unreferenced
+ //reverse dependencies must be unreferenced
E = reverse_dependency_map.find(p_id);
if (E) {
@@ -2277,8 +2278,8 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
VkBufferImageCopy buffer_image_copy;
buffer_image_copy.bufferOffset = alloc_offset;
- buffer_image_copy.bufferRowLength = 0; //tigthly packed
- buffer_image_copy.bufferImageHeight = 0; //tigthly packed
+ buffer_image_copy.bufferRowLength = 0; //tightly packed
+ buffer_image_copy.bufferImageHeight = 0; //tightly packed
buffer_image_copy.imageSubresource.aspectMask = texture->read_aspect_mask;
buffer_image_copy.imageSubresource.mipLevel = mm_i;
@@ -2725,8 +2726,8 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
ERR_FAIL_COND_V_MSG(dst_tex->type != TEXTURE_TYPE_2D, ERR_INVALID_PARAMETER, "Destination texture must be 2D (or a slice of a 3D/Cube texture).");
ERR_FAIL_COND_V_MSG(dst_tex->samples != TEXTURE_SAMPLES_1, ERR_INVALID_PARAMETER, "Destination texture must not be multisampled.");
- ERR_FAIL_COND_V_MSG(src_tex->format != dst_tex->format, ERR_INVALID_PARAMETER, "Source and Destionation textures must be the same format.");
- ERR_FAIL_COND_V_MSG(src_tex->width != dst_tex->width && src_tex->height != dst_tex->height && src_tex->depth != dst_tex->depth, ERR_INVALID_PARAMETER, "Source and Destionation textures must have the same dimensions.");
+ ERR_FAIL_COND_V_MSG(src_tex->format != dst_tex->format, ERR_INVALID_PARAMETER, "Source and Destination textures must be the same format.");
+ ERR_FAIL_COND_V_MSG(src_tex->width != dst_tex->width && src_tex->height != dst_tex->height && src_tex->depth != dst_tex->depth, ERR_INVALID_PARAMETER, "Source and Destination textures must have the same dimensions.");
ERR_FAIL_COND_V_MSG(src_tex->read_aspect_mask != dst_tex->read_aspect_mask, ERR_INVALID_PARAMETER,
"Source and destination texture must be of the same type (color or depth).");
@@ -3216,6 +3217,63 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
return id;
}
+RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_create_empty(const Size2i &p_size) {
+ ERR_FAIL_COND_V(p_size.width <= 0 || p_size.height <= 0, INVALID_FORMAT_ID);
+
+ FramebufferFormatKey key;
+ key.empty_size = p_size;
+
+ const Map<FramebufferFormatKey, FramebufferFormatID>::Element *E = framebuffer_format_cache.find(key);
+ if (E) {
+ //exists, return
+ return E->get();
+ }
+
+ VkSubpassDescription subpass;
+ subpass.flags = 0;
+ subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+ subpass.inputAttachmentCount = 0; //unsupported for now
+ subpass.pInputAttachments = nullptr;
+ subpass.colorAttachmentCount = 0;
+ subpass.pColorAttachments = nullptr;
+ subpass.pDepthStencilAttachment = nullptr;
+ subpass.pResolveAttachments = nullptr;
+ subpass.preserveAttachmentCount = 0;
+ subpass.pPreserveAttachments = nullptr;
+
+ VkRenderPassCreateInfo render_pass_create_info;
+ render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+ render_pass_create_info.pNext = nullptr;
+ render_pass_create_info.flags = 0;
+ render_pass_create_info.attachmentCount = 0;
+ render_pass_create_info.pAttachments = nullptr;
+ render_pass_create_info.subpassCount = 1;
+ render_pass_create_info.pSubpasses = &subpass;
+ render_pass_create_info.dependencyCount = 0;
+ render_pass_create_info.pDependencies = nullptr;
+
+ VkRenderPass render_pass;
+ VkResult res = vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass);
+
+ ERR_FAIL_COND_V_MSG(res, VK_NULL_HANDLE, "vkCreateRenderPass for empty fb failed with error " + itos(res) + ".");
+
+ if (render_pass == VK_NULL_HANDLE) { //was likely invalid
+ return INVALID_ID;
+ }
+
+ FramebufferFormatID id = FramebufferFormatID(framebuffer_format_cache.size()) | (FramebufferFormatID(ID_TYPE_FRAMEBUFFER_FORMAT) << FramebufferFormatID(ID_BASE_SHIFT));
+
+ E = framebuffer_format_cache.insert(key, id);
+
+ FramebufferFormat fb_format;
+ fb_format.E = E;
+ fb_format.color_attachments = 0;
+ fb_format.render_pass = render_pass;
+ fb_format.samples = TEXTURE_SAMPLES_1;
+ framebuffer_formats[id] = fb_format;
+ return id;
+}
+
RenderingDevice::TextureSamples RenderingDeviceVulkan::framebuffer_format_get_texture_samples(FramebufferFormatID p_format) {
Map<FramebufferFormatID, FramebufferFormat>::Element *E = framebuffer_formats.find(p_format);
ERR_FAIL_COND_V(!E, TEXTURE_SAMPLES_1);
@@ -3227,6 +3285,16 @@ RenderingDevice::TextureSamples RenderingDeviceVulkan::framebuffer_format_get_te
/**** RENDER TARGET ****/
/***********************/
+RID RenderingDeviceVulkan::framebuffer_create_empty(const Size2i &p_size, FramebufferFormatID p_format_check) {
+ _THREAD_SAFE_METHOD_
+ Framebuffer framebuffer;
+ framebuffer.format_id = framebuffer_format_create_empty(p_size);
+ ERR_FAIL_COND_V(p_format_check != INVALID_FORMAT_ID && framebuffer.format_id != p_format_check, RID());
+ framebuffer.size = p_size;
+
+ return framebuffer_owner.make_rid(framebuffer);
+}
+
RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check) {
_THREAD_SAFE_METHOD_
@@ -3477,7 +3545,7 @@ RID RenderingDeviceVulkan::index_buffer_create(uint32_t p_index_count, IndexBuff
const uint16_t *index16 = (const uint16_t *)r;
for (uint32_t i = 0; i < p_index_count; i++) {
if (p_use_restart_indices && index16[i] == 0xFFFF) {
- continue; //restart index, ingnore
+ continue; //restart index, ignore
}
index_buffer.max_index = MAX(index16[i], index_buffer.max_index);
}
@@ -3485,7 +3553,7 @@ RID RenderingDeviceVulkan::index_buffer_create(uint32_t p_index_count, IndexBuff
const uint32_t *index32 = (const uint32_t *)r;
for (uint32_t i = 0; i < p_index_count; i++) {
if (p_use_restart_indices && index32[i] == 0xFFFFFFFF) {
- continue; //restart index, ingnore
+ continue; //restart index, ignore
}
index_buffer.max_index = MAX(index32[i], index_buffer.max_index);
}
@@ -4218,13 +4286,18 @@ RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Ve
return uniform_buffer_owner.make_rid(buffer);
}
-RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data) {
+RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data, uint32_t p_usage) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID());
Buffer buffer;
- Error err = _buffer_allocate(&buffer, p_size_bytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY);
+ buffer.usage = p_usage;
+ uint32_t flags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
+ if (p_usage & STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT) {
+ flags |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
+ }
+ Error err = _buffer_allocate(&buffer, p_size_bytes, flags, VMA_MEMORY_USAGE_GPU_ONLY);
ERR_FAIL_COND_V(err != OK, RID());
if (p_data.size()) {
@@ -4433,7 +4506,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
}
}
ERR_FAIL_COND_V_MSG(uniform_idx == -1, RID(),
- "All the shader bindings for the given set must be covered by the uniforms provided.");
+ "All the shader bindings for the given set must be covered by the uniforms provided. Binding (" + itos(set_uniform.binding) + ") was not provided.");
const Uniform &uniform = uniforms[uniform_idx];
@@ -5009,13 +5082,13 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
input_assembly_create_info.topology = topology_list[p_render_primitive];
input_assembly_create_info.primitiveRestartEnable = (p_render_primitive == RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX);
- //tesselation
- VkPipelineTessellationStateCreateInfo tesselation_create_info;
- tesselation_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
- tesselation_create_info.pNext = nullptr;
- tesselation_create_info.flags = 0;
+ //tessellation
+ VkPipelineTessellationStateCreateInfo tessellation_create_info;
+ tessellation_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
+ tessellation_create_info.pNext = nullptr;
+ tessellation_create_info.flags = 0;
ERR_FAIL_COND_V(p_rasterization_state.patch_control_points < 1 || p_rasterization_state.patch_control_points > limits.maxTessellationPatchSize, RID());
- tesselation_create_info.patchControlPoints = p_rasterization_state.patch_control_points;
+ tessellation_create_info.patchControlPoints = p_rasterization_state.patch_control_points;
VkPipelineViewportStateCreateInfo viewport_state_create_info;
viewport_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
@@ -5227,7 +5300,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
graphics_pipeline_create_info.pStages = shader->pipeline_stages.ptr();
graphics_pipeline_create_info.pVertexInputState = &pipeline_vertex_input_state_create_info;
graphics_pipeline_create_info.pInputAssemblyState = &input_assembly_create_info;
- graphics_pipeline_create_info.pTessellationState = &tesselation_create_info;
+ graphics_pipeline_create_info.pTessellationState = &tessellation_create_info;
graphics_pipeline_create_info.pViewportState = &viewport_state_create_info;
graphics_pipeline_create_info.pRasterizationState = &rasterization_state_create_info;
graphics_pipeline_create_info.pMultisampleState = &multisample_state_create_info;
@@ -5488,7 +5561,7 @@ Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebu
return OK;
}
-Error RenderingDeviceVulkan::_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) {
+Error RenderingDeviceVulkan::_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) {
VkRenderPassBeginInfo render_pass_begin;
render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
render_pass_begin.pNext = nullptr;
@@ -5533,6 +5606,37 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
render_pass_begin.clearValueCount = clear_values.size();
render_pass_begin.pClearValues = clear_values.ptr();
+ for (int i = 0; i < p_storage_textures.size(); i++) {
+ Texture *texture = texture_owner.getornull(p_storage_textures[i]);
+ ERR_CONTINUE_MSG(!(texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT), "Supplied storage texture " + itos(i) + " for draw list is not set to be used for storage.");
+
+ if (texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT) {
+ //must change layout to general
+ VkImageMemoryBarrier image_memory_barrier;
+ image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ image_memory_barrier.pNext = nullptr;
+ image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ image_memory_barrier.oldLayout = texture->layout;
+ image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
+
+ image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.image = texture->image;
+ image_memory_barrier.subresourceRange.aspectMask = texture->read_aspect_mask;
+ image_memory_barrier.subresourceRange.baseMipLevel = texture->base_mipmap;
+ image_memory_barrier.subresourceRange.levelCount = texture->mipmaps;
+ image_memory_barrier.subresourceRange.baseArrayLayer = texture->base_layer;
+ image_memory_barrier.subresourceRange.layerCount = texture->layers;
+
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+
+ texture->layout = VK_IMAGE_LAYOUT_GENERAL;
+
+ draw_list_storage_textures.push_back(p_storage_textures[i]);
+ }
+ }
+
vkCmdBeginRenderPass(command_buffer, &render_pass_begin, subpass_contents);
//mark textures as bound
@@ -5600,7 +5704,7 @@ void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list,
vkCmdClearAttachments(draw_list->command_buffer, clear_attachments.size(), clear_attachments.ptr(), 1, &cr);
}
-RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_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_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) {
+RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_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_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector<RID> &p_storage_textures) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time.");
@@ -5650,7 +5754,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
ERR_FAIL_COND_V(err != OK, INVALID_ID);
VkCommandBuffer command_buffer = frames[frame].draw_command_buffer;
- err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, vkframebuffer, render_pass, command_buffer, VK_SUBPASS_CONTENTS_INLINE);
+ err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, vkframebuffer, render_pass, command_buffer, VK_SUBPASS_CONTENTS_INLINE, p_storage_textures);
if (err != OK) {
return INVALID_ID;
@@ -5690,7 +5794,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
return ID_TYPE_DRAW_LIST;
}
-Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, 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) {
+Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, 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 Vector<RID> &p_storage_textures) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(p_splits < 1, ERR_INVALID_DECLARATION);
@@ -5772,7 +5876,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
VkCommandBuffer frame_command_buffer = frames[frame].draw_command_buffer;
- err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, vkframebuffer, render_pass, frame_command_buffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
+ err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, vkframebuffer, render_pass, frame_command_buffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, p_storage_textures);
if (err != OK) {
return ERR_CANT_CREATE;
@@ -5930,7 +6034,7 @@ void RenderingDeviceVulkan::draw_list_bind_render_pipeline(DrawListID p_list, RI
if (pipeline->push_constant_size) {
dl->state.pipeline_push_constant_stages = pipeline->push_constant_stages;
#ifdef DEBUG_ENABLED
- dl->validation.pipeline_push_constant_suppplied = false;
+ dl->validation.pipeline_push_constant_supplied = false;
#endif
}
@@ -6061,7 +6165,7 @@ void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, const
#endif
vkCmdPushConstants(dl->command_buffer, dl->state.pipeline_layout, dl->state.pipeline_push_constant_stages, 0, p_data_size, p_data);
#ifdef DEBUG_ENABLED
- dl->validation.pipeline_push_constant_suppplied = true;
+ dl->validation.pipeline_push_constant_supplied = true;
#endif
}
@@ -6082,14 +6186,14 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices
//make sure format is right
ERR_FAIL_COND_MSG(dl->validation.pipeline_vertex_format != dl->validation.vertex_format,
"The vertex format used to create the pipeline does not match the vertex format bound.");
- //make sure amount of instances is valid
+ //make sure number of instances is valid
ERR_FAIL_COND_MSG(p_instances > dl->validation.vertex_max_instances_allowed,
- "Amount of instances requested (" + itos(p_instances) + " is larger than the maximum amount suported by the bound vertex array (" + itos(dl->validation.vertex_max_instances_allowed) + ").");
+ "Number of instances requested (" + itos(p_instances) + " is larger than the maximum number supported by the bound vertex array (" + itos(dl->validation.vertex_max_instances_allowed) + ").");
}
if (dl->validation.pipeline_push_constant_size > 0) {
//using push constants, check that they were supplied
- ERR_FAIL_COND_MSG(!dl->validation.pipeline_push_constant_suppplied,
+ ERR_FAIL_COND_MSG(!dl->validation.pipeline_push_constant_supplied,
"The shader in this pipeline requires a push constant to be set before drawing, but it's not present.");
}
@@ -6253,6 +6357,33 @@ void RenderingDeviceVulkan::draw_list_end() {
draw_list_bound_textures.clear();
+ for (int i = 0; i < draw_list_storage_textures.size(); i++) {
+ Texture *texture = texture_owner.getornull(draw_list_storage_textures[i]);
+
+ VkImageMemoryBarrier image_memory_barrier;
+ image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ image_memory_barrier.pNext = nullptr;
+ image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ image_memory_barrier.oldLayout = texture->layout;
+ image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+ image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.image = texture->image;
+ image_memory_barrier.subresourceRange.aspectMask = texture->read_aspect_mask;
+ image_memory_barrier.subresourceRange.baseMipLevel = texture->base_mipmap;
+ image_memory_barrier.subresourceRange.levelCount = texture->mipmaps;
+ image_memory_barrier.subresourceRange.baseArrayLayer = texture->base_layer;
+ image_memory_barrier.subresourceRange.layerCount = texture->layers;
+
+ vkCmdPipelineBarrier(frames[frame].draw_command_buffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+
+ texture->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ }
+
+ draw_list_storage_textures.clear();
+
// To ensure proper synchronization, we must make sure rendering is done before:
// * Some buffer is copied
// * Another render pass happens (since we may be done
@@ -6325,7 +6456,7 @@ void RenderingDeviceVulkan::compute_list_bind_compute_pipeline(ComputeListID p_l
if (pipeline->push_constant_size) {
cl->state.pipeline_push_constant_stages = pipeline->push_constant_stages;
#ifdef DEBUG_ENABLED
- cl->validation.pipeline_push_constant_suppplied = false;
+ cl->validation.pipeline_push_constant_supplied = false;
#endif
}
@@ -6458,7 +6589,7 @@ void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list,
#endif
vkCmdPushConstants(cl->command_buffer, cl->state.pipeline_layout, cl->state.pipeline_push_constant_stages, 0, p_data_size, p_data);
#ifdef DEBUG_ENABLED
- cl->validation.pipeline_push_constant_suppplied = true;
+ cl->validation.pipeline_push_constant_supplied = true;
#endif
}
@@ -6485,7 +6616,7 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t
if (cl->validation.pipeline_push_constant_size > 0) {
//using push constants, check that they were supplied
- ERR_FAIL_COND_MSG(!cl->validation.pipeline_push_constant_suppplied,
+ ERR_FAIL_COND_MSG(!cl->validation.pipeline_push_constant_supplied,
"The shader in this pipeline requires a push constant to be set before drawing, but it's not present.");
}
@@ -6519,6 +6650,62 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t
vkCmdDispatch(cl->command_buffer, p_x_groups, p_y_groups, p_z_groups);
}
+void RenderingDeviceVulkan::compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset) {
+ ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST);
+ ERR_FAIL_COND(!compute_list);
+
+ ComputeList *cl = compute_list;
+ Buffer *buffer = storage_buffer_owner.getornull(p_buffer);
+ ERR_FAIL_COND(!buffer);
+
+ ERR_FAIL_COND_MSG(!(buffer->usage & STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT), "Buffer provided was not created to do indirect dispatch.");
+
+ ERR_FAIL_COND_MSG(p_offset + 12 > buffer->size, "Offset provided (+12) is past the end of buffer.");
+
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND_MSG(!cl->validation.active, "Submitted Compute Lists can no longer be modified.");
+#endif
+
+#ifdef DEBUG_ENABLED
+
+ ERR_FAIL_COND_MSG(!cl->validation.pipeline_active, "No compute pipeline was set before attempting to draw.");
+
+ if (cl->validation.pipeline_push_constant_size > 0) {
+ //using push constants, check that they were supplied
+ ERR_FAIL_COND_MSG(!cl->validation.pipeline_push_constant_supplied,
+ "The shader in this pipeline requires a push constant to be set before drawing, but it's not present.");
+ }
+
+#endif
+
+ //Bind descriptor sets
+
+ for (uint32_t i = 0; i < cl->state.set_count; i++) {
+ if (cl->state.sets[i].pipeline_expected_format == 0) {
+ continue; //nothing expected by this pipeline
+ }
+#ifdef DEBUG_ENABLED
+ if (cl->state.sets[i].pipeline_expected_format != cl->state.sets[i].uniform_set_format) {
+ if (cl->state.sets[i].uniform_set_format == 0) {
+ ERR_FAIL_MSG("Uniforms were never supplied for set (" + itos(i) + ") at the time of drawing, which are required by the pipeline");
+ } else if (uniform_set_owner.owns(cl->state.sets[i].uniform_set)) {
+ UniformSet *us = uniform_set_owner.getornull(cl->state.sets[i].uniform_set);
+ ERR_FAIL_MSG("Uniforms supplied for set (" + itos(i) + "):\n" + _shader_uniform_debug(us->shader_id, us->shader_set) + "\nare not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n" + _shader_uniform_debug(cl->state.pipeline_shader));
+ } else {
+ ERR_FAIL_MSG("Uniforms supplied for set (" + itos(i) + ", which was was just freed) are not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n" + _shader_uniform_debug(cl->state.pipeline_shader));
+ }
+ }
+#endif
+ if (!cl->state.sets[i].bound) {
+ //All good, see if this requires re-binding
+ vkCmdBindDescriptorSets(cl->command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, cl->state.pipeline_layout, i, 1, &cl->state.sets[i].descriptor_set, 0, nullptr);
+ cl->state.sets[i].bound = true;
+ }
+ }
+
+ vkCmdDispatchIndirect(cl->command_buffer, buffer->buffer, p_offset);
+}
+
void RenderingDeviceVulkan::compute_list_add_barrier(ComputeListID p_list) {
#ifdef FORCE_FULL_BARRIER
_full_barrier(true);
@@ -6558,10 +6745,17 @@ void RenderingDeviceVulkan::compute_list_end() {
#ifdef FORCE_FULL_BARRIER
_full_barrier(true);
#else
- _memory_barrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT, true);
+ _memory_barrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT, true);
#endif
}
+void RenderingDeviceVulkan::full_barrier() {
+#ifndef DEBUG_ENABLED
+ ERR_PRINT("Full barrier is debug-only, should not be used in production");
+#endif
+ _full_barrier(true);
+}
+
#if 0
void RenderingDeviceVulkan::draw_list_render_secondary_to_framebuffer(ID p_framebuffer, ID *p_draw_lists, uint32_t p_draw_list_count, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Variant> &p_clear_colors) {
@@ -7190,7 +7384,7 @@ uint64_t RenderingDeviceVulkan::get_captured_timestamp_gpu_time(uint32_t p_index
// this sucks because timestampPeriod multiplier is a float, while the timestamp is 64 bits nanosecs.
// so, in cases like nvidia which give you enormous numbers and 1 as multiplier, multiplying is next to impossible
- // need to do 128 bits fixed point multiplication to get the rigth value
+ // need to do 128 bits fixed point multiplication to get the right value
uint64_t shift_bits = 16;
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index 6b75154a8d..6f8bbc9c64 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -42,7 +42,9 @@
#endif
#endif
#include "vk_mem_alloc.h"
+
#include <vulkan/vulkan.h>
+
//todo:
//compute
//push constants
@@ -110,7 +112,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
/*****************/
// In Vulkan, the concept of textures does not exist,
- // intead there is the image (the memory prety much,
+ // instead there is the image (the memory pretty much,
// the view (how the memory is interpreted) and the
// sampler (how it's sampled from the shader).
//
@@ -203,11 +205,13 @@ class RenderingDeviceVulkan : public RenderingDevice {
struct Buffer {
uint32_t size;
+ uint32_t usage;
VkBuffer buffer;
VmaAllocation allocation;
VkDescriptorBufferInfo buffer_info; //used for binding
Buffer() {
size = 0;
+ usage = 0;
buffer = VK_NULL_HANDLE;
allocation = nullptr;
}
@@ -232,8 +236,13 @@ class RenderingDeviceVulkan : public RenderingDevice {
// used for the render pipelines.
struct FramebufferFormatKey {
+ Size2i empty_size;
Vector<AttachmentFormat> attachments;
bool operator<(const FramebufferFormatKey &p_key) const {
+ if (empty_size != p_key.empty_size) {
+ return empty_size < p_key.empty_size;
+ }
+
int as = attachments.size();
int bs = p_key.attachments.size();
if (as != bs) {
@@ -318,7 +327,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
// Vertex buffers in Vulkan are similar to how
// they work in OpenGL, except that instead of
- // an attribtue index, there is a buffer binding
+ // an attribute index, there is a buffer binding
// index (for binding the buffers in real-time)
// and a location index (what is used in the shader).
//
@@ -570,7 +579,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
struct DescriptorPoolKey {
union {
struct {
- uint16_t uniform_type[UNIFORM_TYPE_MAX]; //using 16 bits because, for sending arrays, each element is a pool set.
+ uint16_t uniform_type[UNIFORM_TYPE_MAX]; // Using 16 bits because, for sending arrays, each element is a pool set.
};
struct {
uint64_t key1;
@@ -712,115 +721,77 @@ class RenderingDeviceVulkan : public RenderingDevice {
Vector<SplitDrawListAllocator> split_draw_list_allocators;
struct DrawList {
- VkCommandBuffer command_buffer; //if persistent, this is owned, otherwise it's shared with the ringbuffer
+ VkCommandBuffer command_buffer; // If persistent, this is owned, otherwise it's shared with the ringbuffer.
Rect2i viewport;
struct SetState {
- uint32_t pipeline_expected_format;
- uint32_t uniform_set_format;
- VkDescriptorSet descriptor_set;
+ uint32_t pipeline_expected_format = 0;
+ uint32_t uniform_set_format = 0;
+ VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
RID uniform_set;
- bool bound;
- SetState() {
- bound = false;
- pipeline_expected_format = 0;
- uniform_set_format = 0;
- descriptor_set = VK_NULL_HANDLE;
- }
+ bool bound = false;
};
struct State {
SetState sets[MAX_UNIFORM_SETS];
- uint32_t set_count;
+ uint32_t set_count = 0;
RID pipeline;
RID pipeline_shader;
- VkPipelineLayout pipeline_layout;
+ VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
RID vertex_array;
RID index_array;
- uint32_t pipeline_push_constant_stages;
-
- State() {
- set_count = 0;
- pipeline_layout = VK_NULL_HANDLE;
- pipeline_push_constant_stages = 0;
- }
+ uint32_t pipeline_push_constant_stages = 0;
} state;
-#ifdef DEBUG_ENABLED
+#ifdef DEBUG_ENABLED
struct Validation {
- bool active; //means command buffer was not closes, so you can keep adding things
- FramebufferFormatID framebuffer_format;
- //actual render pass values
- uint32_t dynamic_state;
- VertexFormatID vertex_format; //INVALID_ID if not set
- uint32_t vertex_array_size; //0 if not set
- uint32_t vertex_max_instances_allowed;
- bool index_buffer_uses_restart_indices;
- uint32_t index_array_size; //0 if index buffer not set
- uint32_t index_array_max_index;
+ 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;
+ uint32_t vertex_array_size = 0;
+ uint32_t vertex_max_instances_allowed = 0xFFFFFFFF;
+ bool index_buffer_uses_restart_indices = false;
+ uint32_t index_array_size = 0;
+ uint32_t index_array_max_index = 0;
uint32_t index_array_offset;
Vector<uint32_t> set_formats;
Vector<bool> set_bound;
Vector<RID> set_rids;
- //last pipeline set values
- bool pipeline_active;
- uint32_t pipeline_dynamic_state;
- VertexFormatID pipeline_vertex_format;
+ // Last pipeline set values.
+ bool pipeline_active = false;
+ uint32_t pipeline_dynamic_state = 0;
+ VertexFormatID pipeline_vertex_format = INVALID_ID;
RID pipeline_shader;
- uint32_t invalid_set_from;
- bool pipeline_uses_restart_indices;
+ uint32_t invalid_set_from = 0;
+ bool pipeline_uses_restart_indices = false;
uint32_t pipeline_primitive_divisor;
uint32_t pipeline_primitive_minimum;
Vector<uint32_t> pipeline_set_formats;
- uint32_t pipeline_push_constant_size;
- bool pipeline_push_constant_suppplied;
-
- Validation() {
- active = true;
- dynamic_state = 0;
- vertex_format = INVALID_ID;
- vertex_array_size = 0;
- vertex_max_instances_allowed = 0xFFFFFFFF;
- framebuffer_format = INVALID_ID;
- index_array_size = 0; //not sent
- index_array_max_index = 0; //not set
- index_buffer_uses_restart_indices = false;
- invalid_set_from = 0;
-
- //pipeline state initalize
- pipeline_active = false;
- pipeline_dynamic_state = 0;
- pipeline_vertex_format = INVALID_ID;
- pipeline_uses_restart_indices = false;
- pipeline_push_constant_size = 0;
- pipeline_push_constant_suppplied = false;
- }
+ uint32_t pipeline_push_constant_size = 0;
+ bool pipeline_push_constant_supplied = false;
} validation;
#else
struct Validation {
- uint32_t vertex_array_size; //0 if not set
- uint32_t index_array_size; //0 if index buffer not set
+ uint32_t vertex_array_size = 0;
+ uint32_t index_array_size = 0;
uint32_t index_array_offset;
-
- Validation() {
- vertex_array_size = 0;
- index_array_size = 0; //not sent
- }
} validation;
-
#endif
};
- DrawList *draw_list; //one for regular draw lists, multiple for split.
+ DrawList *draw_list; // One for regular draw lists, multiple for split.
uint32_t draw_list_count;
bool draw_list_split;
Vector<RID> draw_list_bound_textures;
+ Vector<RID> draw_list_storage_textures;
bool draw_list_unbind_color_textures;
bool draw_list_unbind_depth_textures;
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_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);
+ 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);
/**********************/
@@ -828,62 +799,39 @@ class RenderingDeviceVulkan : public RenderingDevice {
/**********************/
struct ComputeList {
- VkCommandBuffer command_buffer; //if persistent, this is owned, otherwise it's shared with the ringbuffer
+ VkCommandBuffer command_buffer; // If persistent, this is owned, otherwise it's shared with the ringbuffer.
struct SetState {
- uint32_t pipeline_expected_format;
- uint32_t uniform_set_format;
- VkDescriptorSet descriptor_set;
+ uint32_t pipeline_expected_format = 0;
+ uint32_t uniform_set_format = 0;
+ VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
RID uniform_set;
- bool bound;
- SetState() {
- bound = false;
- pipeline_expected_format = 0;
- uniform_set_format = 0;
- descriptor_set = VK_NULL_HANDLE;
- }
+ bool bound = false;
};
struct State {
Set<Texture *> textures_to_sampled_layout;
-
SetState sets[MAX_UNIFORM_SETS];
- uint32_t set_count;
+ uint32_t set_count = 0;
RID pipeline;
RID pipeline_shader;
- VkPipelineLayout pipeline_layout;
- uint32_t pipeline_push_constant_stages;
-
- State() {
- set_count = 0;
- pipeline_layout = VK_NULL_HANDLE;
- pipeline_push_constant_stages = 0;
- }
+ VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
+ uint32_t pipeline_push_constant_stages = 0;
} state;
-#ifdef DEBUG_ENABLED
+#ifdef DEBUG_ENABLED
struct Validation {
- bool active; //means command buffer was not closes, so you can keep adding things
+ bool active = true; // Means command buffer was not closed, so you can keep adding things.
Vector<uint32_t> set_formats;
Vector<bool> set_bound;
Vector<RID> set_rids;
- //last pipeline set values
- bool pipeline_active;
+ // Last pipeline set values.
+ bool pipeline_active = false;
RID pipeline_shader;
- uint32_t invalid_set_from;
+ uint32_t invalid_set_from = 0;
Vector<uint32_t> pipeline_set_formats;
- uint32_t pipeline_push_constant_size;
- bool pipeline_push_constant_suppplied;
-
- Validation() {
- active = true;
- invalid_set_from = 0;
-
- //pipeline state initalize
- pipeline_active = false;
- pipeline_push_constant_size = 0;
- pipeline_push_constant_suppplied = false;
- }
+ uint32_t pipeline_push_constant_size = 0;
+ bool pipeline_push_constant_supplied = false;
} validation;
#endif
};
@@ -921,8 +869,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
List<ComputePipeline> compute_pipelines_to_dispose_of;
VkCommandPool command_pool;
- VkCommandBuffer setup_command_buffer; //used at the begining of every frame for set-up
- VkCommandBuffer draw_command_buffer; //used at the begining of every frame for set-up
+ VkCommandBuffer setup_command_buffer; //used at the beginning of every frame for set-up
+ VkCommandBuffer draw_command_buffer; //used at the beginning of every frame for set-up
struct Timestamp {
String description;
@@ -988,9 +936,11 @@ public:
/*********************/
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format);
+ virtual FramebufferFormatID framebuffer_format_create_empty(const Size2i &p_size);
virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format);
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID);
+ virtual RID framebuffer_create_empty(const Size2i &p_size, FramebufferFormatID p_format_check = INVALID_ID);
virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer);
@@ -1026,7 +976,7 @@ public:
/*****************/
virtual RID uniform_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>());
- virtual RID storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>());
+ virtual RID storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>(), uint32_t p_usage = 0);
virtual RID texture_buffer_create(uint32_t p_size_elements, DataFormat p_format, const Vector<uint8_t> &p_data = Vector<uint8_t>());
virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set);
@@ -1063,8 +1013,8 @@ public:
virtual DrawListID draw_list_begin_for_screen(DisplayServer::WindowID p_screen = 0, const Color &p_clear_color = Color());
- virtual DrawListID draw_list_begin(RID p_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_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2());
- virtual Error draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, 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());
+ virtual DrawListID draw_list_begin(RID p_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_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector<RID> &p_storage_textures = Vector<RID>());
+ virtual Error draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, 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 Vector<RID> &p_storage_textures = Vector<RID>());
virtual void draw_list_bind_render_pipeline(DrawListID p_list, RID p_render_pipeline);
virtual void draw_list_bind_uniform_set(DrawListID p_list, RID p_uniform_set, uint32_t p_index);
@@ -1091,8 +1041,11 @@ public:
virtual void compute_list_add_barrier(ComputeListID p_list);
virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups);
+ virtual void compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset);
virtual void compute_list_end();
+ virtual void full_barrier();
+
/**************/
/**** FREE ****/
/**************/
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index a8a29aaeea..997ed3935f 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -154,7 +154,7 @@ VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char **check_n
}
}
if (!found) {
- ERR_PRINT("Cant find layer: " + String(check_names[i]));
+ ERR_PRINT("Can't find layer: " + String(check_names[i]));
return 0;
}
}
@@ -344,6 +344,8 @@ Error VulkanContext::_create_physical_device() {
"Please look at the Getting Started guide for additional information.\n"
"vkCreateInstance Failure");
+ inst_initialized = true;
+
/* Make initial call to query gpu_count, then second call for gpu info*/
err = vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
@@ -1133,6 +1135,7 @@ Error VulkanContext::initialize() {
return err;
}
+ device_initialized = true;
return OK;
}
@@ -1584,15 +1587,21 @@ VulkanContext::~VulkanContext() {
if (queue_props) {
free(queue_props);
}
- for (uint32_t i = 0; i < FRAME_LAG; i++) {
- vkDestroyFence(device, fences[i], nullptr);
- vkDestroySemaphore(device, image_acquired_semaphores[i], nullptr);
- vkDestroySemaphore(device, draw_complete_semaphores[i], nullptr);
- if (separate_present_queue) {
- vkDestroySemaphore(device, image_ownership_semaphores[i], nullptr);
+ if (device_initialized) {
+ for (uint32_t i = 0; i < FRAME_LAG; i++) {
+ vkDestroyFence(device, fences[i], nullptr);
+ vkDestroySemaphore(device, image_acquired_semaphores[i], nullptr);
+ vkDestroySemaphore(device, draw_complete_semaphores[i], nullptr);
+ if (separate_present_queue) {
+ vkDestroySemaphore(device, image_ownership_semaphores[i], nullptr);
+ }
+ }
+ if (inst_initialized) {
+ DestroyDebugUtilsMessengerEXT(inst, dbg_messenger, nullptr);
}
+ vkDestroyDevice(device, nullptr);
+ }
+ if (inst_initialized) {
+ vkDestroyInstance(inst, nullptr);
}
- DestroyDebugUtilsMessengerEXT(inst, dbg_messenger, nullptr);
- vkDestroyDevice(device, nullptr);
- vkDestroyInstance(inst, nullptr);
}
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index ff1215ff5d..9ebea42ecb 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -53,6 +53,8 @@ class VulkanContext {
uint32_t queue_family_count;
VkQueueFamilyProperties *queue_props;
VkDevice device;
+ bool device_initialized = false;
+ bool inst_initialized = false;
//present
bool queues_initialized;
@@ -80,29 +82,15 @@ class VulkanContext {
} SwapchainImageResources;
struct Window {
- bool is_minimzed;
- VkSurfaceKHR surface;
- VkSwapchainKHR swapchain;
- SwapchainImageResources *swapchain_image_resources;
- VkPresentModeKHR presentMode;
- uint32_t current_buffer;
- int width;
- int height;
+ VkSurfaceKHR surface = VK_NULL_HANDLE;
+ VkSwapchainKHR swapchain = VK_NULL_HANDLE;
+ SwapchainImageResources *swapchain_image_resources = VK_NULL_HANDLE;
+ VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
+ uint32_t current_buffer = 0;
+ int width = 0;
+ int height = 0;
VkCommandPool present_cmd_pool; //for separate present queue
-
- VkRenderPass render_pass;
-
- Window() {
- width = 0;
- height = 0;
- render_pass = VK_NULL_HANDLE;
- current_buffer = 0;
- surface = VK_NULL_HANDLE;
- swapchain_image_resources = VK_NULL_HANDLE;
- swapchain = VK_NULL_HANDLE;
- is_minimzed = false;
- presentMode = VK_PRESENT_MODE_FIFO_KHR;
- }
+ VkRenderPass render_pass = VK_NULL_HANDLE;
};
struct LocalDevice {
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index d0f06ae4c4..b8153907a9 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -67,7 +67,11 @@ Error DirAccessWindows::list_dir_begin() {
list_dir_end();
p->h = FindFirstFileExW((current_dir + "\\*").c_str(), FindExInfoStandard, &p->fu, FindExSearchNameMatch, nullptr, 0);
- return (p->h == INVALID_HANDLE_VALUE) ? ERR_CANT_OPEN : OK;
+ if (p->h == INVALID_HANDLE_VALUE) {
+ return ERR_CANT_OPEN;
+ }
+
+ return OK;
}
String DirAccessWindows::get_next() {
@@ -286,10 +290,6 @@ Error DirAccessWindows::remove(String p_path) {
p_path = fix_path(p_path);
- printf("erasing %s\n", p_path.utf8().get_data());
- //WIN32_FILE_ATTRIBUTE_DATA fileInfo;
- //DWORD fileAttr = GetFileAttributesExW(p_path.c_str(), GetFileExInfoStandard, &fileInfo);
-
DWORD fileAttr;
fileAttr = GetFileAttributesW(p_path.c_str());