summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp4
-rw-r--r--drivers/alsa/audio_driver_alsa.h10
-rw-r--r--drivers/alsamidi/midi_driver_alsamidi.cpp2
-rw-r--r--drivers/alsamidi/midi_driver_alsamidi.h2
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp2
-rw-r--r--drivers/coremidi/midi_driver_coremidi.cpp2
-rw-r--r--drivers/coremidi/midi_driver_coremidi.h2
-rw-r--r--drivers/dummy/rasterizer_dummy.h108
-rw-r--r--drivers/dummy/texture_loader_dummy.cpp2
-rw-r--r--drivers/png/SCsub19
-rw-r--r--drivers/png/image_loader_png.cpp2
-rw-r--r--drivers/png/png_driver_common.cpp1
-rw-r--r--drivers/png/png_driver_common.h3
-rw-r--r--drivers/png/resource_saver_png.cpp2
-rw-r--r--drivers/png/resource_saver_png.h2
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.cpp2
-rw-r--r--drivers/spirv-reflect/SCsub8
-rw-r--r--drivers/unix/dir_access_unix.cpp4
-rw-r--r--drivers/unix/file_access_unix.cpp2
-rw-r--r--drivers/unix/ip_unix.cpp2
-rw-r--r--drivers/unix/net_socket_posix.cpp4
-rw-r--r--drivers/unix/os_unix.cpp5
-rw-r--r--drivers/unix/os_unix.h50
-rw-r--r--drivers/unix/rw_lock_posix.cpp2
-rw-r--r--drivers/unix/syslog_logger.cpp2
-rw-r--r--drivers/unix/thread_posix.cpp4
-rw-r--r--drivers/vulkan/SCsub30
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp338
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h246
-rw-r--r--drivers/vulkan/vulkan_context.cpp49
-rw-r--r--drivers/vulkan/vulkan_context.h84
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp2
-rw-r--r--drivers/windows/dir_access_windows.cpp4
-rw-r--r--drivers/windows/dir_access_windows.h10
-rw-r--r--drivers/windows/file_access_windows.cpp2
-rw-r--r--drivers/windows/rw_lock_windows.cpp2
-rw-r--r--drivers/windows/thread_windows.h2
-rw-r--r--drivers/winmidi/midi_driver_winmidi.cpp2
-rw-r--r--drivers/winmidi/midi_driver_winmidi.h2
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.cpp2
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.h22
41 files changed, 597 insertions, 448 deletions
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp
index 90c3d3af83..7aa3787ced 100644
--- a/drivers/alsa/audio_driver_alsa.cpp
+++ b/drivers/alsa/audio_driver_alsa.cpp
@@ -32,8 +32,8 @@
#ifdef ALSA_ENABLED
+#include "core/config/project_settings.h"
#include "core/os/os.h"
-#include "core/project_settings.h"
#include <errno.h>
@@ -183,7 +183,7 @@ void AudioDriverALSA::thread_func(void *p_udata) {
int total = 0;
while (todo && !ad->exit_thread) {
- uint8_t *src = (uint8_t *)ad->samples_out.ptr();
+ int16_t *src = (int16_t *)ad->samples_out.ptr();
int wrote = snd_pcm_writei(ad->pcm_handle, (void *)(src + (total * ad->channels)), todo);
if (wrote > 0) {
diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h
index d1220d126e..bb4b1c5476 100644
--- a/drivers/alsa/audio_driver_alsa.h
+++ b/drivers/alsa/audio_driver_alsa.h
@@ -56,17 +56,17 @@ class AudioDriverALSA : public AudioDriver {
static void thread_func(void *p_udata);
- unsigned int mix_rate;
+ unsigned int mix_rate = 0;
SpeakerMode speaker_mode;
snd_pcm_uframes_t buffer_frames;
snd_pcm_uframes_t buffer_size;
snd_pcm_uframes_t period_size;
- int channels;
+ int channels = 0;
- bool active;
- bool thread_exited;
- mutable bool exit_thread;
+ bool active = false;
+ bool thread_exited = false;
+ mutable bool exit_thread = false;
public:
const char *get_name() const {
diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp
index 69a6956c2b..07a4360cd2 100644
--- a/drivers/alsamidi/midi_driver_alsamidi.cpp
+++ b/drivers/alsamidi/midi_driver_alsamidi.cpp
@@ -33,7 +33,7 @@
#include "midi_driver_alsamidi.h"
#include "core/os/os.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
#include <errno.h>
diff --git a/drivers/alsamidi/midi_driver_alsamidi.h b/drivers/alsamidi/midi_driver_alsamidi.h
index 6aabe8e3fd..fef87459c7 100644
--- a/drivers/alsamidi/midi_driver_alsamidi.h
+++ b/drivers/alsamidi/midi_driver_alsamidi.h
@@ -36,7 +36,7 @@
#include "core/os/midi_driver.h"
#include "core/os/mutex.h"
#include "core/os/thread.h"
-#include "core/vector.h"
+#include "core/templates/vector.h"
#include <alsa/asoundlib.h>
#include <stdio.h>
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index 48d0a29516..60c491f5f8 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -32,8 +32,8 @@
#include "audio_driver_coreaudio.h"
+#include "core/config/project_settings.h"
#include "core/os/os.h"
-#include "core/project_settings.h"
#define kOutputBus 0
#define kInputBus 1
diff --git a/drivers/coremidi/midi_driver_coremidi.cpp b/drivers/coremidi/midi_driver_coremidi.cpp
index 004c594e17..b9e7853735 100644
--- a/drivers/coremidi/midi_driver_coremidi.cpp
+++ b/drivers/coremidi/midi_driver_coremidi.cpp
@@ -32,7 +32,7 @@
#include "midi_driver_coremidi.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
#include <CoreAudio/HostTime.h>
#include <CoreServices/CoreServices.h>
diff --git a/drivers/coremidi/midi_driver_coremidi.h b/drivers/coremidi/midi_driver_coremidi.h
index 0459544f75..02167aa891 100644
--- a/drivers/coremidi/midi_driver_coremidi.h
+++ b/drivers/coremidi/midi_driver_coremidi.h
@@ -34,7 +34,7 @@
#define MIDI_DRIVER_COREMIDI_H
#include "core/os/midi_driver.h"
-#include "core/vector.h"
+#include "core/templates/vector.h"
#include <CoreMIDI/CoreMIDI.h>
#include <stdio.h>
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index bef4d999af..f674c36500 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -32,13 +32,13 @@
#define RASTERIZER_DUMMY_H
#include "core/math/camera_matrix.h"
-#include "core/rid_owner.h"
-#include "core/self_list.h"
+#include "core/templates/rid_owner.h"
+#include "core/templates/self_list.h"
#include "scene/resources/mesh.h"
-#include "servers/rendering/rasterizer.h"
+#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
-class RasterizerSceneDummy : public RasterizerScene {
+class RasterizerSceneDummy : public RendererSceneRender {
public:
/* SHADOW ATLAS API */
@@ -86,8 +86,8 @@ public:
void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) override {}
void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override {}
- 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) override {}
- void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) override {}
+ void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) override {}
+ void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {}
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) override {}
@@ -96,9 +96,9 @@ public:
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) override {}
- void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) override {}
+ void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) override {}
- void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density) override {}
+ void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override {}
void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) override {}
void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override {}
void environment_set_volumetric_fog_filter_active(bool p_enable) override {}
@@ -161,7 +161,7 @@ public:
void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) override {}
RID render_buffers_create() override { return RID(); }
- 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) override {}
+ 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, bool p_use_debanding) override {}
void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override {}
bool screen_space_roughness_limiter_is_active() const override { return false; }
@@ -175,29 +175,31 @@ public:
void update() override {}
void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) override {}
+ bool is_low_end() const override { return true; }
+
RasterizerSceneDummy() {}
~RasterizerSceneDummy() {}
};
-class RasterizerStorageDummy : public RasterizerStorage {
+class RasterizerStorageDummy : public RendererStorage {
public:
/* TEXTURE API */
struct DummyTexture {
- int width;
- int height;
- uint32_t flags;
- Image::Format format;
+ int width = 0;
+ int height = 0;
+ uint32_t flags = 0;
+ Image::Format format = Image::Format::FORMAT_MAX;
Ref<Image> image;
String path;
};
struct DummySurface {
- uint32_t format;
- RS::PrimitiveType primitive;
+ uint32_t format = 0;
+ RS::PrimitiveType primitive = RS::PrimitiveType::PRIMITIVE_MAX;
Vector<uint8_t> array;
- int vertex_count;
+ int vertex_count = 0;
Vector<uint8_t> index_array;
- int index_count;
+ int index_count = 0;
AABB aabb;
Vector<Vector<uint8_t>> blend_shapes;
Vector<AABB> bone_aabbs;
@@ -205,8 +207,8 @@ public:
struct DummyMesh {
Vector<DummySurface> surfaces;
- int blend_shape_count;
- RS::BlendShapeMode blend_shape_mode;
+ int blend_shape_count = 0;
+ RS::BlendShapeMode blend_shape_mode = RS::BlendShapeMode::BLEND_SHAPE_MODE_NORMALIZED;
};
mutable RID_PtrOwner<DummyTexture> texture_owner;
@@ -251,9 +253,17 @@ public:
void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
+ /* CANVAS TEXTURE API */
+
+ RID canvas_texture_create() override { return RID(); }
+ void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override {}
+ void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override {}
+
+ void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override {}
+ void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override {}
+
#if 0
RID texture_create() override {
-
DummyTexture *texture = memnew(DummyTexture);
ERR_FAIL_COND_V(!texture, RID());
return texture_owner.make_rid(texture);
@@ -375,7 +385,7 @@ public:
bool material_is_animated(RID p_material) override { return false; }
bool material_casts_shadows(RID p_material) override { return false; }
void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {}
- void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) override {}
+ void material_update_dependency(RID p_material, InstanceBaseDependency *p_instance) override {}
/* MESH API */
@@ -591,6 +601,8 @@ public:
void light_directional_set_blend_splits(RID p_light, bool p_enable) override {}
bool light_directional_get_blend_splits(RID p_light) const override { return false; }
void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) override {}
+ void light_directional_set_sky_only(RID p_light, bool p_sky_only) override {}
+ bool light_directional_is_sky_only(RID p_light) const override { return false; }
RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const override { return RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE; }
RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) override { return RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; }
@@ -632,8 +644,8 @@ public:
float reflection_probe_get_origin_max_distance(RID p_probe) const override { return 0.0; }
bool reflection_probe_renders_shadows(RID p_probe) const override { return false; }
- void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) override {}
- void skeleton_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) override {}
+ void base_update_dependency(RID p_base, InstanceBaseDependency *p_instance) override {}
+ void skeleton_update_dependency(RID p_base, InstanceBaseDependency *p_instance) override {}
/* DECAL API */
@@ -700,24 +712,20 @@ public:
/* LIGHTMAP CAPTURE */
#if 0
struct Instantiable {
-
- SelfList<RasterizerScene::InstanceBase>::List instance_list;
+ SelfList<RendererSceneRender::InstanceBase>::List instance_list;
_FORCE_INLINE_ void instance_change_notify(bool p_aabb = true, bool p_materials = true) override {
-
- SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first();
+ SelfList<RendererSceneRender::InstanceBase> *instances = instance_list.first();
while (instances) override {
-
//instances->self()->base_changed(p_aabb, p_materials);
instances = instances->next();
}
}
_FORCE_INLINE_ void instance_remove_deps() override {
- SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first();
+ SelfList<RendererSceneRender::InstanceBase> *instances = instance_list.first();
while (instances) override {
-
- SelfList<RasterizerScene::InstanceBase> *next = instances->next();
+ SelfList<RendererSceneRender::InstanceBase> *next = instances->next();
//instances->self()->base_removed();
instances = next;
}
@@ -729,7 +737,6 @@ public:
};
struct LightmapCapture : public Instantiable {
-
Vector<LightmapCaptureOctree> octree;
AABB bounds;
Transform cell_xform;
@@ -821,8 +828,8 @@ public:
int particles_get_draw_passes(RID p_particles) const override { return 0; }
RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const override { return RID(); }
- void particles_add_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance) override {}
- void particles_remove_collision(RID p_particles, RasterizerScene::InstanceBase *p_instance) override {}
+ void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) override {}
+ void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) override {}
void update_particles() override {}
@@ -880,6 +887,9 @@ public:
void render_target_disable_clear_request(RID p_render_target) override {}
void render_target_do_clear_request(RID p_render_target) override {}
+ void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override {}
+ Rect2i render_target_get_sdf_rect(RID p_render_target) const override { return Rect2i(); }
+
RS::InstanceType get_base_type(RID p_rid) const override {
if (mesh_owner.owns(p_rid)) {
return RS::INSTANCE_MESH;
@@ -919,7 +929,7 @@ public:
String get_video_adapter_name() const override { return String(); }
String get_video_adapter_vendor() const override { return String(); }
- static RasterizerStorage *base_singleton;
+ static RendererStorage *base_singleton;
void capture_timestamps_begin() override {}
void capture_timestamp(const String &p_name) override {}
@@ -933,25 +943,25 @@ public:
~RasterizerStorageDummy() {}
};
-class RasterizerCanvasDummy : public RasterizerCanvas {
+class RasterizerCanvasDummy : public RendererCanvasRender {
public:
- TextureBindingID request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat, RID p_multimesh) override { return 0; }
- void free_texture_binding(TextureBindingID p_binding) override {}
-
PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) override { return 0; }
void free_polygon(PolygonID p_polygon) override {}
- void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform) override {}
+ void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) override {}
void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override {}
RID light_create() override { return RID(); }
void light_set_texture(RID p_rid, RID p_texture) override {}
- void light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution) override {}
- void light_update_shadow(RID p_rid, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override {}
+ void light_set_use_shadow(RID p_rid, bool p_enable) override {}
+ void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override {}
+ void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) override {}
+ void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) override {}
RID occluder_polygon_create() override { return RID(); }
- void occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines) override {}
+ void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) override {}
void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) override {}
+ void set_shadow_texture_size(int p_size) override {}
void draw_window_margins(int *p_margins, RID *p_margin_textures) override {}
@@ -962,7 +972,7 @@ public:
~RasterizerCanvasDummy() {}
};
-class RasterizerDummy : public Rasterizer {
+class RasterizerDummy : public RendererCompositor {
private:
uint64_t frame = 1;
float delta = 0;
@@ -973,9 +983,9 @@ protected:
RasterizerSceneDummy scene;
public:
- RasterizerStorage *get_storage() override { return &storage; }
- RasterizerCanvas *get_canvas() override { return &canvas; }
- RasterizerScene *get_scene() override { return &scene; }
+ RendererStorage *get_storage() override { return &storage; }
+ RendererCanvasRender *get_canvas() override { return &canvas; }
+ RendererSceneRender *get_scene() override { return &scene; }
void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) override {}
@@ -996,7 +1006,7 @@ public:
void finalize() override {}
- static Rasterizer *_create_current() {
+ static RendererCompositor *_create_current() {
return memnew(RasterizerDummy);
}
diff --git a/drivers/dummy/texture_loader_dummy.cpp b/drivers/dummy/texture_loader_dummy.cpp
index ddd2943720..6158a2ac54 100644
--- a/drivers/dummy/texture_loader_dummy.cpp
+++ b/drivers/dummy/texture_loader_dummy.cpp
@@ -31,7 +31,7 @@
#include "texture_loader_dummy.h"
#include "core/os/file_access.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
#include <string.h>
diff --git a/drivers/png/SCsub b/drivers/png/SCsub
index db08be0c47..26508dc612 100644
--- a/drivers/png/SCsub
+++ b/drivers/png/SCsub
@@ -5,6 +5,9 @@ Import("env")
env_png = env.Clone()
# Thirdparty source files
+
+thirdparty_obj = []
+
if env["builtin_libpng"]:
thirdparty_dir = "#thirdparty/libpng/"
thirdparty_sources = [
@@ -41,7 +44,7 @@ if env["builtin_libpng"]:
env_thirdparty = env_png.Clone()
env_thirdparty.disable_warnings()
- env_thirdparty.add_source_files(env.drivers_sources, thirdparty_sources)
+ env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
if use_neon:
env_neon = env_thirdparty.Clone()
@@ -52,9 +55,17 @@ if env["builtin_libpng"]:
neon_sources.append(env_neon.Object(thirdparty_dir + "/arm/filter_neon_intrinsics.c"))
neon_sources.append(env_neon.Object(thirdparty_dir + "/arm/filter_neon.S"))
neon_sources.append(env_neon.Object(thirdparty_dir + "/arm/palette_neon_intrinsics.c"))
- env.drivers_sources += neon_sources
+ thirdparty_obj += neon_sources
+
+ env.drivers_sources += thirdparty_obj
+
# Godot source files
-env_png.add_source_files(env.drivers_sources, "*.cpp")
-Export("env")
+driver_obj = []
+
+env_png.add_source_files(driver_obj, "*.cpp")
+env.drivers_sources += driver_obj
+
+# Needed to force rebuilding the driver files when the thirdparty library is updated.
+env.Depends(driver_obj, thirdparty_obj)
diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp
index 79924b849c..cd0c68e947 100644
--- a/drivers/png/image_loader_png.cpp
+++ b/drivers/png/image_loader_png.cpp
@@ -31,7 +31,7 @@
#include "image_loader_png.h"
#include "core/os/os.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
#include "drivers/png/png_driver_common.h"
#include <string.h>
diff --git a/drivers/png/png_driver_common.cpp b/drivers/png/png_driver_common.cpp
index d3e187c501..aed3fc9414 100644
--- a/drivers/png/png_driver_common.cpp
+++ b/drivers/png/png_driver_common.cpp
@@ -203,5 +203,4 @@ Error image_to_png(const Ref<Image> &p_image, Vector<uint8_t> &p_buffer) {
return OK;
}
-
} // namespace PNGDriverCommon
diff --git a/drivers/png/png_driver_common.h b/drivers/png/png_driver_common.h
index 2099ddc536..e47996193f 100644
--- a/drivers/png/png_driver_common.h
+++ b/drivers/png/png_driver_common.h
@@ -31,7 +31,7 @@
#ifndef PNG_DRIVER_COMMON_H
#define PNG_DRIVER_COMMON_H
-#include "core/image.h"
+#include "core/io/image.h"
namespace PNGDriverCommon {
@@ -41,7 +41,6 @@ Error png_to_image(const uint8_t *p_source, size_t p_size, bool p_force_linear,
// Append p_image, as a png, to p_buffer.
// Contents of p_buffer is unspecified if error returned.
Error image_to_png(const Ref<Image> &p_image, Vector<uint8_t> &p_buffer);
-
} // namespace PNGDriverCommon
#endif
diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp
index 3a0b319a45..a2d0d5881a 100644
--- a/drivers/png/resource_saver_png.cpp
+++ b/drivers/png/resource_saver_png.cpp
@@ -30,7 +30,7 @@
#include "resource_saver_png.h"
-#include "core/image.h"
+#include "core/io/image.h"
#include "core/os/file_access.h"
#include "drivers/png/png_driver_common.h"
#include "scene/resources/texture.h"
diff --git a/drivers/png/resource_saver_png.h b/drivers/png/resource_saver_png.h
index c32b383521..1d4dcfb57f 100644
--- a/drivers/png/resource_saver_png.h
+++ b/drivers/png/resource_saver_png.h
@@ -31,7 +31,7 @@
#ifndef RESOURCE_SAVER_PNG_H
#define RESOURCE_SAVER_PNG_H
-#include "core/image.h"
+#include "core/io/image.h"
#include "core/io/resource_saver.h"
class ResourceSaverPNG : public ResourceFormatSaver {
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
index a6bc4f3b2c..5acaa3ac99 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
@@ -32,8 +32,8 @@
#ifdef PULSEAUDIO_ENABLED
+#include "core/config/project_settings.h"
#include "core/os/os.h"
-#include "core/project_settings.h"
void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) {
AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata;
diff --git a/drivers/spirv-reflect/SCsub b/drivers/spirv-reflect/SCsub
index d0ffaf068d..1e7b3de0e6 100644
--- a/drivers/spirv-reflect/SCsub
+++ b/drivers/spirv-reflect/SCsub
@@ -2,8 +2,7 @@
Import("env")
-env_spirv_reflect = env.Clone()
-env_spirv_reflect.disable_warnings()
+# Thirdparty source files
thirdparty_dir = "#thirdparty/spirv-reflect/"
thirdparty_sources = [
@@ -12,6 +11,7 @@ thirdparty_sources = [
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
-env_spirv_reflect.add_source_files(env.drivers_sources, thirdparty_sources)
+env_thirdparty = env.Clone()
+env_thirdparty.disable_warnings()
-Export("env")
+env_thirdparty.add_source_files(env.drivers_sources, thirdparty_sources)
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 5b99a2f53f..63fa143a03 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -32,9 +32,9 @@
#if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED)
-#include "core/list.h"
#include "core/os/memory.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
+#include "core/templates/list.h"
#include <errno.h>
#include <stdio.h>
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index 51c657007c..ce1e135fe0 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -33,7 +33,7 @@
#if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED)
#include "core/os/os.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
#include <sys/stat.h>
#include <sys/types.h>
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp
index 05eedccc1d..94ea567c3b 100644
--- a/drivers/unix/ip_unix.cpp
+++ b/drivers/unix/ip_unix.cpp
@@ -91,7 +91,7 @@ static IP_Address _sockaddr2ip(struct sockaddr *p_addr) {
IP_Address IP_Unix::_resolve_hostname(const String &p_hostname, Type p_type) {
struct addrinfo hints;
- struct addrinfo *result;
+ struct addrinfo *result = nullptr;
memset(&hints, 0, sizeof(struct addrinfo));
if (p_type == TYPE_IPV4) {
diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp
index 186804dbb1..0ee97256fc 100644
--- a/drivers/unix/net_socket_posix.cpp
+++ b/drivers/unix/net_socket_posix.cpp
@@ -348,11 +348,11 @@ Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) {
// recv/recvfrom and an ICMP reply was received from a previous send/sendto.
unsigned long disable = 0;
if (ioctlsocket(_sock, SIO_UDP_CONNRESET, &disable) == SOCKET_ERROR) {
- print_verbose("Unable to turn off UDP WSAECONNRESET behaviour on Windows");
+ print_verbose("Unable to turn off UDP WSAECONNRESET behavior on Windows");
}
if (ioctlsocket(_sock, SIO_UDP_NETRESET, &disable) == SOCKET_ERROR) {
// This feature seems not to be supported on wine.
- print_verbose("Unable to turn off UDP WSAENETRESET behaviour on Windows");
+ print_verbose("Unable to turn off UDP WSAENETRESET behavior on Windows");
}
}
#endif
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 96c338f86b..ca08d689b9 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -32,10 +32,10 @@
#ifdef UNIX_ENABLED
+#include "core/config/project_settings.h"
#include "core/debugger/engine_debugger.h"
#include "core/debugger/script_debugger.h"
#include "core/os/thread_dummy.h"
-#include "core/project_settings.h"
#include "drivers/unix/dir_access_unix.h"
#include "drivers/unix/file_access_unix.h"
#include "drivers/unix/net_socket_posix.h"
@@ -127,7 +127,6 @@ void OS_Unix::initialize_core() {
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA);
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_FILESYSTEM);
- //FileAccessBufferedFA<FileAccessUnix>::make_default();
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_RESOURCES);
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_USERDATA);
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_FILESYSTEM);
@@ -331,7 +330,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
int status;
waitpid(pid, &status, 0);
if (r_exitcode) {
- *r_exitcode = WEXITSTATUS(status);
+ *r_exitcode = WIFEXITED(status) ? WEXITSTATUS(status) : status;
}
} else {
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 2982e0c55c..51e5a00e36 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -45,7 +45,7 @@ protected:
virtual int unix_initialize_audio(int p_audio_driver);
//virtual Error initialize(int p_video_driver,int p_audio_driver);
- virtual void finalize_core();
+ virtual void finalize_core() override;
String stdin_buf;
@@ -53,7 +53,7 @@ public:
OS_Unix();
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
- virtual String get_stdin_string(bool p_block);
+ virtual String get_stdin_string(bool p_block) override;
//virtual void set_mouse_show(bool p_show);
//virtual void set_mouse_grab(bool p_grab);
@@ -65,39 +65,39 @@ public:
//virtual VideoMode get_video_mode() const;
//virtual void get_fullscreen_mode_list(List<VideoMode> *p_list) const;
- virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
- virtual Error close_dynamic_library(void *p_library_handle);
- virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
+ virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) override;
+ virtual Error close_dynamic_library(void *p_library_handle) override;
+ virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override;
- virtual Error set_cwd(const String &p_cwd);
+ virtual Error set_cwd(const String &p_cwd) override;
- virtual String get_name() const;
+ virtual String get_name() const override;
- virtual Date get_date(bool utc) const;
- virtual Time get_time(bool utc) const;
- virtual TimeZoneInfo get_time_zone_info() const;
+ virtual Date get_date(bool utc) const override;
+ virtual Time get_time(bool utc) const override;
+ virtual TimeZoneInfo get_time_zone_info() const override;
- virtual double get_unix_time() const;
+ virtual double get_unix_time() const override;
- virtual void delay_usec(uint32_t p_usec) const;
- virtual uint64_t get_ticks_usec() const;
+ virtual void delay_usec(uint32_t p_usec) const override;
+ virtual uint64_t get_ticks_usec() const override;
- virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr);
- virtual Error kill(const ProcessID &p_pid);
- virtual int get_process_id() const;
+ virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override;
+ virtual Error kill(const ProcessID &p_pid) override;
+ virtual int get_process_id() const override;
- virtual bool has_environment(const String &p_var) const;
- virtual String get_environment(const String &p_var) const;
- virtual bool set_environment(const String &p_var, const String &p_value) const;
- virtual String get_locale() const;
+ virtual bool has_environment(const String &p_var) const override;
+ virtual String get_environment(const String &p_var) const override;
+ virtual bool set_environment(const String &p_var, const String &p_value) const override;
+ virtual String get_locale() const override;
- virtual int get_processor_count() const;
+ virtual int get_processor_count() const override;
- virtual void debug_break();
- virtual void initialize_debugging();
+ virtual void debug_break() override;
+ virtual void initialize_debugging() override;
- virtual String get_executable_path() const;
- virtual String get_user_data_dir() const;
+ virtual String get_executable_path() const override;
+ virtual String get_user_data_dir() const override;
};
class UnixTerminalLogger : public StdLogger {
diff --git a/drivers/unix/rw_lock_posix.cpp b/drivers/unix/rw_lock_posix.cpp
index 50b74e84f7..cf24d54c50 100644
--- a/drivers/unix/rw_lock_posix.cpp
+++ b/drivers/unix/rw_lock_posix.cpp
@@ -32,7 +32,7 @@
#include "rw_lock_posix.h"
-#include "core/error_macros.h"
+#include "core/error/error_macros.h"
#include "core/os/memory.h"
#include <stdio.h>
diff --git a/drivers/unix/syslog_logger.cpp b/drivers/unix/syslog_logger.cpp
index a4c7070f0e..b29d1ec541 100644
--- a/drivers/unix/syslog_logger.cpp
+++ b/drivers/unix/syslog_logger.cpp
@@ -31,7 +31,7 @@
#ifdef UNIX_ENABLED
#include "syslog_logger.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
#include <syslog.h>
void SyslogLogger::logv(const char *p_format, va_list p_list, bool p_err) {
diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp
index 285088342b..f4e3de7646 100644
--- a/drivers/unix/thread_posix.cpp
+++ b/drivers/unix/thread_posix.cpp
@@ -32,9 +32,9 @@
#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS)
+#include "core/object/script_language.h"
#include "core/os/memory.h"
-#include "core/safe_refcount.h"
-#include "core/script_language.h"
+#include "core/templates/safe_refcount.h"
#ifdef PTHREAD_BSD_SET_NAME
#include <pthread_np.h>
diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub
index 61d91711da..14b9d63204 100644
--- a/drivers/vulkan/SCsub
+++ b/drivers/vulkan/SCsub
@@ -2,7 +2,7 @@
Import("env")
-env.add_source_files(env.drivers_sources, "*.cpp")
+thirdparty_obj = []
# FIXME: Refactor all this to reduce code duplication.
if env["platform"] == "android":
@@ -22,7 +22,8 @@ if env["platform"] == "android":
thirdparty_dir = "#thirdparty/vulkan"
vma_sources = [thirdparty_dir + "/android/vk_mem_alloc.cpp"]
- env_thirdparty.add_source_files(env.drivers_sources, vma_sources)
+ env_thirdparty.add_source_files(thirdparty_obj, vma_sources)
+
elif env["platform"] == "iphone":
# Use bundled Vulkan headers
thirdparty_dir = "#thirdparty/vulkan"
@@ -33,7 +34,8 @@ elif env["platform"] == "iphone":
env_thirdparty.disable_warnings()
vma_sources = [thirdparty_dir + "/vk_mem_alloc.cpp"]
- env_thirdparty.add_source_files(env.drivers_sources, vma_sources)
+ env_thirdparty.add_source_files(thirdparty_obj, vma_sources)
+
elif env["builtin_vulkan"]:
# Use bundled Vulkan headers
thirdparty_dir = "#thirdparty/vulkan"
@@ -59,7 +61,6 @@ elif env["builtin_vulkan"]:
if env["platform"] == "windows":
loader_sources.append("dirent_on_windows.c")
- loader_sources.append("dxgi_loader.c")
env_thirdparty.AppendUnique(
CPPDEFINES=[
"VK_USE_PLATFORM_WIN32_KHR",
@@ -99,8 +100,9 @@ elif env["builtin_vulkan"]:
env_thirdparty.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])
loader_sources = [thirdparty_dir + "/loader/" + file for file in loader_sources]
- env_thirdparty.add_source_files(env.drivers_sources, loader_sources)
- env_thirdparty.add_source_files(env.drivers_sources, vma_sources)
+ env_thirdparty.add_source_files(thirdparty_obj, loader_sources)
+ env_thirdparty.add_source_files(thirdparty_obj, vma_sources)
+
else: # Always build VMA.
thirdparty_dir = "#thirdparty/vulkan"
env.Prepend(CPPPATH=[thirdparty_dir])
@@ -110,4 +112,18 @@ else: # Always build VMA.
env_thirdparty.disable_warnings()
vma_sources = [thirdparty_dir + "/vk_mem_alloc.cpp"]
- env_thirdparty.add_source_files(env.drivers_sources, vma_sources)
+ env_thirdparty.add_source_files(thirdparty_obj, vma_sources)
+
+
+env.drivers_sources += thirdparty_obj
+
+
+# Godot source files
+
+driver_obj = []
+
+env.add_source_files(driver_obj, "*.cpp")
+env.drivers_sources += driver_obj
+
+# Needed to force rebuilding the driver files when the thirdparty code is updated.
+env.Depends(driver_obj, thirdparty_obj)
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 9fe3f7e6c0..2c92707270 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -30,15 +30,66 @@
#include "rendering_device_vulkan.h"
-#include "core/hashfuncs.h"
+#include "core/config/project_settings.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
-#include "core/project_settings.h"
+#include "core/templates/hashfuncs.h"
#include "drivers/vulkan/vulkan_context.h"
#include "thirdparty/spirv-reflect/spirv_reflect.h"
-#define FORCE_FULL_BARRIER
+//#define FORCE_FULL_BARRIER
+
+// Get the Vulkan object information and possible stage access types (bitwise OR'd with incoming values)
+RenderingDeviceVulkan::Buffer *RenderingDeviceVulkan::_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &stage_mask, VkAccessFlags &access_mask) {
+ Buffer *buffer = nullptr;
+ if (vertex_buffer_owner.owns(p_buffer)) {
+ stage_mask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
+ access_mask |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
+ buffer = vertex_buffer_owner.getornull(p_buffer);
+ } else if (index_buffer_owner.owns(p_buffer)) {
+ stage_mask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
+ access_mask |= VK_ACCESS_INDEX_READ_BIT;
+ buffer = index_buffer_owner.getornull(p_buffer);
+ } else if (uniform_buffer_owner.owns(p_buffer)) {
+ stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ access_mask |= VK_ACCESS_UNIFORM_READ_BIT;
+ buffer = uniform_buffer_owner.getornull(p_buffer);
+ } else if (texture_buffer_owner.owns(p_buffer)) {
+ stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ access_mask |= VK_ACCESS_SHADER_READ_BIT;
+ buffer = &texture_buffer_owner.getornull(p_buffer)->buffer;
+ } else if (storage_buffer_owner.owns(p_buffer)) {
+ stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ access_mask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ buffer = storage_buffer_owner.getornull(p_buffer);
+ }
+ return buffer;
+}
+
+static void update_external_dependency_for_store(VkSubpassDependency &dependency, bool is_sampled, bool is_storage, bool is_depth) {
+ // Transitioning from write to read, protect the shaders that may use this next
+ // Allow for copies/image layout transitions
+ dependency.dstStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ dependency.dstAccessMask |= VK_ACCESS_TRANSFER_READ_BIT;
+
+ if (is_sampled) {
+ dependency.dstStageMask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ dependency.dstAccessMask |= VK_ACCESS_SHADER_READ_BIT;
+ } else if (is_storage) {
+ dependency.dstStageMask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ dependency.dstAccessMask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ } else {
+ dependency.dstStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ dependency.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ }
+
+ if (is_depth) {
+ // Depth resources have addtional stages that may be interested in them
+ dependency.dstStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
+ dependency.dstAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+ }
+}
void RenderingDeviceVulkan::_add_dependency(RID p_id, RID p_depends_on) {
if (!dependency_map.has(p_depends_on)) {
@@ -564,6 +615,7 @@ int RenderingDeviceVulkan::get_format_vertex_size(DataFormat p_format) {
case DATA_FORMAT_B8G8R8A8_SNORM:
case DATA_FORMAT_B8G8R8A8_UINT:
case DATA_FORMAT_B8G8R8A8_SINT:
+ case DATA_FORMAT_A2B10G10R10_UNORM_PACK32:
return 4;
case DATA_FORMAT_R16_UNORM:
case DATA_FORMAT_R16_SNORM:
@@ -1310,6 +1362,7 @@ Error RenderingDeviceVulkan::_buffer_allocate(Buffer *p_buffer, uint32_t p_size,
p_buffer->buffer_info.buffer = p_buffer->buffer;
p_buffer->buffer_info.offset = 0;
p_buffer->buffer_info.range = p_size;
+ p_buffer->usage = p_usage;
return OK;
}
@@ -1640,16 +1693,16 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
#endif
}
- if (p_format.type == TEXTURE_TYPE_CUBE || p_format.type == TEXTURE_TYPE_CUBE_ARRAY) {
+ if (p_format.texture_type == TEXTURE_TYPE_CUBE || p_format.texture_type == TEXTURE_TYPE_CUBE_ARRAY) {
image_create_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
}
/*if (p_format.type == TEXTURE_TYPE_2D || p_format.type == TEXTURE_TYPE_2D_ARRAY) {
image_create_info.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
}*/
- ERR_FAIL_INDEX_V(p_format.type, TEXTURE_TYPE_MAX, RID());
+ ERR_FAIL_INDEX_V(p_format.texture_type, TEXTURE_TYPE_MAX, RID());
- image_create_info.imageType = vulkan_image_type[p_format.type];
+ image_create_info.imageType = vulkan_image_type[p_format.texture_type];
ERR_FAIL_COND_V_MSG(p_format.width < 1, RID(), "Width must be equal or greater than 1 for all textures");
@@ -1674,10 +1727,10 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_create_info.mipLevels = p_format.mipmaps;
- if (p_format.type == TEXTURE_TYPE_1D_ARRAY || p_format.type == TEXTURE_TYPE_2D_ARRAY || p_format.type == TEXTURE_TYPE_CUBE_ARRAY || p_format.type == TEXTURE_TYPE_CUBE) {
+ if (p_format.texture_type == TEXTURE_TYPE_1D_ARRAY || p_format.texture_type == TEXTURE_TYPE_2D_ARRAY || p_format.texture_type == TEXTURE_TYPE_CUBE_ARRAY || p_format.texture_type == TEXTURE_TYPE_CUBE) {
ERR_FAIL_COND_V_MSG(p_format.array_layers < 1, RID(),
"Amount of layers must be equal or greater than 1 for arrays and cubemaps.");
- ERR_FAIL_COND_V_MSG((p_format.type == TEXTURE_TYPE_CUBE_ARRAY || p_format.type == TEXTURE_TYPE_CUBE) && (p_format.array_layers % 6) != 0, RID(),
+ ERR_FAIL_COND_V_MSG((p_format.texture_type == TEXTURE_TYPE_CUBE_ARRAY || p_format.texture_type == TEXTURE_TYPE_CUBE) && (p_format.array_layers % 6) != 0, RID(),
"Cubemap and cubemap array textures must provide a layer number that is multiple of 6");
image_create_info.arrayLayers = p_format.array_layers;
} else {
@@ -1807,7 +1860,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
VkResult err = vmaCreateImage(allocator, &image_create_info, &allocInfo, &texture.image, &texture.allocation, &texture.allocation_info);
ERR_FAIL_COND_V_MSG(err, RID(), "vmaCreateImage failed with error " + itos(err) + ".");
- texture.type = p_format.type;
+ texture.type = p_format.texture_type;
texture.format = p_format.format;
texture.width = image_create_info.extent.width;
texture.height = image_create_info.extent.height;
@@ -1875,7 +1928,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,
};
- image_view_create_info.viewType = view_types[p_format.type];
+ image_view_create_info.viewType = view_types[p_format.texture_type];
if (p_view.format_override == DATA_FORMAT_MAX) {
image_view_create_info.format = image_create_info.format;
} else {
@@ -1932,7 +1985,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_memory_barrier.subresourceRange.baseArrayLayer = 0;
image_memory_barrier.subresourceRange.layerCount = image_create_info.arrayLayers;
- vkCmdPipelineBarrier(frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
RID id = texture_owner.make_rid(texture);
@@ -2042,15 +2095,26 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p
ERR_FAIL_COND_V_MSG(p_slice_type == TEXTURE_SLICE_3D && src_texture->type != TEXTURE_TYPE_3D, RID(),
"Can only create a 3D slice from a 3D texture");
+ ERR_FAIL_COND_V_MSG(p_slice_type == TEXTURE_SLICE_2D_ARRAY && (src_texture->type != TEXTURE_TYPE_2D_ARRAY), RID(),
+ "Can only create an array slice from a 2D array mipmap");
+
//create view
ERR_FAIL_UNSIGNED_INDEX_V(p_mipmap, src_texture->mipmaps, RID());
ERR_FAIL_UNSIGNED_INDEX_V(p_layer, src_texture->layers, RID());
+ int slice_layers = 1;
+ if (p_slice_type == TEXTURE_SLICE_2D_ARRAY) {
+ ERR_FAIL_COND_V_MSG(p_layer != 0, RID(), "layer must be 0 when obtaining a 2D array mipmap slice");
+ slice_layers = src_texture->layers;
+ } else if (p_slice_type == TEXTURE_SLICE_CUBEMAP) {
+ slice_layers = 6;
+ }
+
Texture texture = *src_texture;
get_image_format_required_size(texture.format, texture.width, texture.height, texture.depth, p_mipmap + 1, &texture.width, &texture.height);
texture.mipmaps = 1;
- texture.layers = p_slice_type == TEXTURE_SLICE_CUBEMAP ? 6 : 1;
+ texture.layers = slice_layers;
texture.base_mipmap = p_mipmap;
texture.base_layer = p_layer;
@@ -2104,7 +2168,7 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p
}
image_view_create_info.subresourceRange.baseMipLevel = p_mipmap;
image_view_create_info.subresourceRange.levelCount = 1;
- image_view_create_info.subresourceRange.layerCount = p_slice_type == TEXTURE_SLICE_CUBEMAP ? 6 : 1;
+ image_view_create_info.subresourceRange.layerCount = slice_layers;
image_view_create_info.subresourceRange.baseArrayLayer = p_layer;
if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
@@ -2189,7 +2253,7 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
image_memory_barrier.subresourceRange.baseArrayLayer = p_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
uint32_t mipmap_offset = 0;
@@ -2322,7 +2386,7 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
image_memory_barrier.subresourceRange.baseArrayLayer = p_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
return OK;
@@ -2485,6 +2549,9 @@ Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t
image_memory_barrier.pNext = nullptr;
image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ if (tex->usage_flags & TEXTURE_USAGE_STORAGE_BIT) {
+ image_memory_barrier.dstAccessMask |= VK_ACCESS_SHADER_WRITE_BIT;
+ }
image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
image_memory_barrier.newLayout = tex->layout;
image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
@@ -2496,7 +2563,7 @@ Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t
image_memory_barrier.subresourceRange.baseArrayLayer = p_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
_flush(true);
@@ -2672,7 +2739,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
image_memory_barrier.subresourceRange.baseArrayLayer = p_src_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
{ //make dst readable
@@ -2694,7 +2761,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
image_memory_barrier.subresourceRange.baseArrayLayer = p_src_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
}
@@ -2755,7 +2822,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
{ //Dest
VkImageMemoryBarrier image_memory_barrier;
@@ -2824,7 +2891,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
{ //make dst readable
@@ -2846,7 +2913,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
image_memory_barrier.subresourceRange.baseArrayLayer = dst_tex->base_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
}
@@ -2878,16 +2945,22 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
- VkImageLayout layout = src_tex->layout;
+ VkImageLayout clear_layout = (src_tex->layout == VK_IMAGE_LAYOUT_GENERAL) ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
- if (src_tex->layout != VK_IMAGE_LAYOUT_GENERAL) { //storage may be in general state
+ // NOTE: Perhaps the valid stages/accesses for a given onwner should be a property of the owner. (Here and places like _get_buffer_from_owner)
+ const VkPipelineStageFlags valid_texture_stages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ constexpr VkAccessFlags read_access = VK_ACCESS_SHADER_READ_BIT;
+ constexpr VkAccessFlags read_write_access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ const VkAccessFlags valid_texture_access = (src_tex->usage_flags & TEXTURE_USAGE_STORAGE_BIT) ? read_write_access : read_access;
+
+ { // Barrier from previous access with optional layout change (see clear_layout logic above)
VkImageMemoryBarrier image_memory_barrier;
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
- image_memory_barrier.srcAccessMask = 0;
+ image_memory_barrier.srcAccessMask = valid_texture_access;
image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
image_memory_barrier.oldLayout = src_tex->layout;
- image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ image_memory_barrier.newLayout = clear_layout;
image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
@@ -2898,8 +2971,7 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer + p_base_layer;
image_memory_barrier.subresourceRange.layerCount = p_layers;
- layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
- vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, valid_texture_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
VkClearColorValue clear_color;
@@ -2915,16 +2987,15 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
range.baseMipLevel = src_tex->base_mipmap + p_base_mipmap;
range.levelCount = p_mipmaps;
- vkCmdClearColorImage(command_buffer, src_tex->image, layout, &clear_color, 1, &range);
-
- if (src_tex->layout != VK_IMAGE_LAYOUT_GENERAL) { //storage may be in general state
+ vkCmdClearColorImage(command_buffer, src_tex->image, clear_layout, &clear_color, 1, &range);
+ { // Barrier to post clear accesses (changing back the layout if needed)
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_TRANSFER_WRITE_BIT;
- image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
- image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ image_memory_barrier.dstAccessMask = valid_texture_access;
+ image_memory_barrier.oldLayout = clear_layout;
image_memory_barrier.newLayout = src_tex->layout;
image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
@@ -2936,7 +3007,7 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer + p_base_layer;
image_memory_barrier.subresourceRange.layerCount = p_layers;
- vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, valid_texture_stages, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
return OK;
@@ -2991,6 +3062,19 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
Vector<VkAttachmentReference> depth_stencil_references;
Vector<VkAttachmentReference> resolve_references;
+ // Set up a dependencies from/to external equivalent to the default (implicit) one, and then amend them
+ const VkPipelineStageFlags default_access_mask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
+ VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; // From Section 7.1 of Vulkan API Spec v1.1.148
+
+ VkPipelineStageFlags reading_stages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
+ VkSubpassDependency dependencies[2] = { { VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, default_access_mask, 0 },
+ { 0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, default_access_mask, 0, 0 } };
+ VkSubpassDependency &dependency_from_external = dependencies[0];
+ VkSubpassDependency &dependency_to_external = dependencies[1];
+
for (int i = 0; i < p_format.size(); i++) {
ERR_FAIL_INDEX_V(p_format[i].format, DATA_FORMAT_MAX, VK_NULL_HANDLE);
ERR_FAIL_INDEX_V(p_format[i].samples, TEXTURE_SAMPLES_MAX, VK_NULL_HANDLE);
@@ -3006,11 +3090,16 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
bool is_sampled = p_format[i].usage_flags & TEXTURE_USAGE_SAMPLING_BIT;
bool is_storage = p_format[i].usage_flags & TEXTURE_USAGE_STORAGE_BIT;
+ // For each UNDEFINED, assume the prior use was a *read*, as we'd be discarding the output of a write
+ // Also, each UNDEFINED will do an immediate layout transition (write), s.t. we must ensure execution syncronization vs.
+ // the read. If this is a performance issue, one could track the actual last accessor of each resource, adding only that
+ // stage
switch (is_depth_stencil ? p_initial_depth_action : p_initial_color_action) {
case INITIAL_ACTION_CLEAR: {
description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ dependency_from_external.srcStageMask |= reading_stages;
} break;
case INITIAL_ACTION_KEEP: {
if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
@@ -3021,10 +3110,12 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ dependency_from_external.srcStageMask |= reading_stages;
} else {
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ dependency_from_external.srcStageMask |= reading_stages;
}
} break;
case INITIAL_ACTION_DROP: {
@@ -3036,10 +3127,12 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ dependency_from_external.srcStageMask |= reading_stages;
} else {
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ dependency_from_external.srcStageMask |= reading_stages;
}
} break;
case INITIAL_ACTION_CONTINUE: {
@@ -3055,6 +3148,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ dependency_from_external.srcStageMask |= reading_stages;
}
} break;
default: {
@@ -3068,14 +3162,17 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ update_external_dependency_for_store(dependency_to_external, is_sampled, is_storage, false);
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+ update_external_dependency_for_store(dependency_to_external, is_sampled, is_storage, true);
} else {
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ // TODO: What does this mean about the next usage (and thus appropriate dependency masks
}
} break;
case FINAL_ACTION_DISCARD: {
@@ -3128,9 +3225,24 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
} else if (p_format[i].usage_flags & TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT) {
reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
resolve_references.push_back(reference);
+ // if resolves are done, we need to ensure the copy is safe
+ dependency_to_external.dstStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ dependency_to_external.dstAccessMask |= VK_ACCESS_TRANSFER_READ_BIT;
} else {
ERR_FAIL_V_MSG(VK_NULL_HANDLE, "Texture index " + itos(i) + " is neither color, depth stencil or resolve so it can't be used as attachment.");
}
+
+ // NOTE: Big Mallet Approach -- any layout transition causes a full barrier
+ if (reference.layout != description.initialLayout) {
+ // NOTE: this should be smarter based on the textures knowledge of it's previous role
+ dependency_from_external.srcStageMask |= VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
+ dependency_from_external.srcAccessMask |= VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
+ }
+ if (reference.layout != description.finalLayout) {
+ // NOTE: this should be smarter based on the textures knowledge of it's subsequent role
+ dependency_to_external.dstStageMask |= VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
+ dependency_to_external.dstAccessMask |= VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
+ }
}
ERR_FAIL_COND_V_MSG(depth_stencil_references.size() > 1, VK_NULL_HANDLE,
@@ -3159,8 +3271,8 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
render_pass_create_info.pAttachments = attachments.ptr();
render_pass_create_info.subpassCount = 1;
render_pass_create_info.pSubpasses = &subpass;
- render_pass_create_info.dependencyCount = 0;
- render_pass_create_info.pDependencies = nullptr;
+ render_pass_create_info.dependencyCount = 2;
+ render_pass_create_info.pDependencies = dependencies;
VkRenderPass render_pass;
VkResult res = vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass);
@@ -3185,7 +3297,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
}
int color_references;
- VkRenderPass render_pass = _render_pass_create(p_format, INITIAL_ACTION_CLEAR, FINAL_ACTION_DISCARD, INITIAL_ACTION_CLEAR, FINAL_ACTION_DISCARD, &color_references); //actions don't matter for this use case
+ VkRenderPass render_pass = _render_pass_create(p_format, INITIAL_ACTION_CLEAR, FINAL_ACTION_READ, INITIAL_ACTION_CLEAR, FINAL_ACTION_READ, &color_references); //actions don't matter for this use case
if (render_pass == VK_NULL_HANDLE) { //was likely invalid
return INVALID_ID;
@@ -3385,13 +3497,21 @@ RID RenderingDeviceVulkan::sampler_create(const SamplerState &p_state) {
/**** VERTEX ARRAY ****/
/**********************/
-RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data) {
+RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data, bool p_use_as_storage) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID());
+ ERR_FAIL_COND_V_MSG(draw_list != nullptr && p_data.size(), RID(),
+ "Creating buffers with data is forbidden during creation of a draw list");
+ ERR_FAIL_COND_V_MSG(compute_list != nullptr && p_data.size(), RID(),
+ "Creating buffers with data is forbidden during creation of a draw list");
+ uint32_t usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ if (p_use_as_storage) {
+ usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
+ }
Buffer buffer;
- _buffer_allocate(&buffer, p_size_bytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY);
+ _buffer_allocate(&buffer, p_size_bytes, usage, VMA_MEMORY_USAGE_GPU_ONLY);
if (p_data.size()) {
uint64_t data_size = p_data.size();
const uint8_t *r = p_data.ptr();
@@ -3425,7 +3545,7 @@ RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(cons
ERR_FAIL_COND_V(used_locations.has(p_vertex_formats[i].location), INVALID_ID);
ERR_FAIL_COND_V_MSG(get_format_vertex_size(p_vertex_formats[i].format) == 0, INVALID_ID,
- "Data format for attachment (" + itos(i) + ") is not valid for a vertex array.");
+ "Data format for attachment (" + itos(i) + "), '" + named_formats[p_vertex_formats[i].format] + "', is not valid for a vertex array.");
vdcache.bindings[i].binding = i;
vdcache.bindings[i].stride = p_vertex_formats[i].stride;
@@ -3512,6 +3632,10 @@ RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFo
RID RenderingDeviceVulkan::index_buffer_create(uint32_t p_index_count, IndexBufferFormat p_format, const Vector<uint8_t> &p_data, bool p_use_restart_indices) {
_THREAD_SAFE_METHOD_
+ ERR_FAIL_COND_V_MSG(draw_list != nullptr && p_data.size(), RID(),
+ "Creating buffers with data is forbidden during creation of a draw list");
+ ERR_FAIL_COND_V_MSG(compute_list != nullptr && p_data.size(), RID(),
+ "Creating buffers with data is forbidden during creation of a draw list");
ERR_FAIL_COND_V(p_index_count == 0, RID());
@@ -3626,13 +3750,11 @@ String RenderingDeviceVulkan::_shader_uniform_debug(RID p_shader, int p_set) {
}
#if 0
bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLayoutBinding> > &bindings, Vector<Vector<UniformInfo> > &uniform_infos, const glslang::TObjectReflection &reflection, RenderingDevice::ShaderStage p_stage, Shader::PushConstant &push_constant, String *r_error) {
-
VkDescriptorSetLayoutBinding layout_binding;
UniformInfo info;
switch (reflection.getType()->getBasicType()) {
case glslang::EbtSampler: {
-
//print_line("DEBUG: IsSampler");
if (reflection.getType()->getSampler().dim == glslang::EsdBuffer) {
//texture buffers
@@ -3730,13 +3852,10 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
} break;
/*case glslang::EbtReference: {
-
} break;*/
/*case glslang::EbtAtomicUint: {
-
} break;*/
default: {
-
if (reflection.getType()->getQualifier().hasOffset() || reflection.name.find(".") != std::string::npos) {
//member of uniform block?
return true;
@@ -4205,8 +4324,10 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
}
pipeline_layout_create_info.pSetLayouts = layouts.ptr();
+ // Needs to be declared in this outer scope, otherwise it may not outlive its assignment
+ // to pipeline_layout_create_info.
+ VkPushConstantRange push_constant_range;
if (push_constant.push_constant_size) {
- VkPushConstantRange push_constant_range;
push_constant_range.stageFlags = push_constant.push_constants_vk_stage;
push_constant_range.offset = 0;
push_constant_range.size = push_constant.push_constant_size;
@@ -4258,6 +4379,10 @@ RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Ve
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID());
+ ERR_FAIL_COND_V_MSG(draw_list != nullptr && p_data.size(), RID(),
+ "Creating buffers with data is forbidden during creation of a draw list");
+ ERR_FAIL_COND_V_MSG(compute_list != nullptr && p_data.size(), RID(),
+ "Creating buffers with data is forbidden during creation of a draw list");
Buffer buffer;
Error err = _buffer_allocate(&buffer, p_size_bytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY);
@@ -4273,6 +4398,10 @@ RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Ve
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_MSG(draw_list != nullptr && p_data.size(), RID(),
+ "Creating buffers with data is forbidden during creation of a draw list");
+ ERR_FAIL_COND_V_MSG(compute_list != nullptr && p_data.size(), RID(),
+ "Creating buffers with data is forbidden during creation of a draw list");
ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID());
@@ -4296,6 +4425,10 @@ RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Ve
RID RenderingDeviceVulkan::texture_buffer_create(uint32_t p_size_elements, DataFormat p_format, const Vector<uint8_t> &p_data) {
_THREAD_SAFE_METHOD_
+ ERR_FAIL_COND_V_MSG(draw_list != nullptr && p_data.size(), RID(),
+ "Creating buffers with data is forbidden during creation of a draw list");
+ ERR_FAIL_COND_V_MSG(compute_list != nullptr && p_data.size(), RID(),
+ "Creating buffers with data is forbidden during creation of a draw list");
uint32_t element_size = get_format_vertex_size(p_format);
ERR_FAIL_COND_V_MSG(element_size == 0, RID(), "Format requested is not supported for texture buffers");
@@ -4444,7 +4577,7 @@ void RenderingDeviceVulkan::_descriptor_pool_free(const DescriptorPoolKey &p_key
vkDestroyDescriptorPool(device, p_pool->pool, nullptr);
descriptor_pools[p_key].erase(p_pool);
memdelete(p_pool);
- if (descriptor_pools[p_key].empty()) {
+ if (descriptor_pools[p_key].is_empty()) {
descriptor_pools.erase(p_key);
}
}
@@ -4478,7 +4611,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
List<Vector<VkBufferView>> buffer_views;
List<Vector<VkDescriptorImageInfo>> image_infos;
//used for verification to make sure a uniform set does not use a framebuffer bound texture
- Vector<RID> attachable_textures;
+ LocalVector<UniformSet::AttachableTexture> attachable_textures;
Vector<Texture *> mutable_sampled_textures;
Vector<Texture *> mutable_storage_textures;
@@ -4491,12 +4624,12 @@ 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. Binding (" + itos(set_uniform.binding) + ") was not provided.");
+ "All the shader bindings for the given set must be covered by the uniforms provided. Binding (" + itos(set_uniform.binding) + "), set (" + itos(p_shader_set) + ") was not provided.");
const Uniform &uniform = uniforms[uniform_idx];
- ERR_FAIL_COND_V_MSG(uniform.type != set_uniform.type, RID(),
- "Mismatch uniform type for binding (" + itos(set_uniform.binding) + "). Expected '" + shader_uniform_names[set_uniform.type] + "', supplied: '" + shader_uniform_names[uniform.type] + "'.");
+ ERR_FAIL_COND_V_MSG(uniform.uniform_type != set_uniform.type, RID(),
+ "Mismatch uniform type for binding (" + itos(set_uniform.binding) + "), set (" + itos(p_shader_set) + "). Expected '" + shader_uniform_names[set_uniform.type] + "', supplied: '" + shader_uniform_names[uniform.uniform_type] + "'.");
VkWriteDescriptorSet write; //common header
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
@@ -4511,7 +4644,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
write.pTexelBufferView = nullptr;
uint32_t type_size = 1;
- switch (uniform.type) {
+ switch (uniform.uniform_type) {
case UNIFORM_TYPE_SAMPLER: {
if (uniform.ids.size() != set_uniform.length) {
if (set_uniform.length > 1) {
@@ -4571,7 +4704,10 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
img_info.imageView = texture->view;
if (texture->usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT)) {
- attachable_textures.push_back(texture->owner.is_valid() ? texture->owner : uniform.ids[j + 1]);
+ UniformSet::AttachableTexture attachable_texture;
+ attachable_texture.bind = set_uniform.binding;
+ attachable_texture.texture = texture->owner.is_valid() ? texture->owner : uniform.ids[j + 1];
+ attachable_textures.push_back(attachable_texture);
}
if (texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT) {
@@ -4621,7 +4757,10 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
img_info.imageView = texture->view;
if (texture->usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT)) {
- attachable_textures.push_back(texture->owner.is_valid() ? texture->owner : uniform.ids[j]);
+ UniformSet::AttachableTexture attachable_texture;
+ attachable_texture.bind = set_uniform.binding;
+ attachable_texture.texture = texture->owner.is_valid() ? texture->owner : uniform.ids[j];
+ attachable_textures.push_back(attachable_texture);
}
if (texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT) {
@@ -4794,7 +4933,15 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
ERR_FAIL_COND_V_MSG(uniform.ids.size() != 1, RID(),
"Storage buffer supplied (binding: " + itos(uniform.binding) + ") must provide one ID (" + itos(uniform.ids.size()) + " provided).");
- Buffer *buffer = storage_buffer_owner.getornull(uniform.ids[0]);
+ Buffer *buffer = nullptr;
+
+ if (storage_buffer_owner.owns(uniform.ids[0])) {
+ buffer = storage_buffer_owner.getornull(uniform.ids[0]);
+ } else if (vertex_buffer_owner.owns(uniform.ids[0])) {
+ buffer = vertex_buffer_owner.getornull(uniform.ids[0]);
+
+ ERR_FAIL_COND_V_MSG(!(buffer->usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), RID(), "Vertex buffer supplied (binding: " + itos(uniform.binding) + ") was not created with storage flag.");
+ }
ERR_FAIL_COND_V_MSG(!buffer, RID(), "Storage buffer supplied (binding: " + itos(uniform.binding) + ") is invalid.");
//if 0, then its sized on link time
@@ -4885,44 +5032,27 @@ Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint
ERR_FAIL_COND_V_MSG(draw_list && p_sync_with_draw, ERR_INVALID_PARAMETER,
"Updating buffers in 'sync to draw' mode is forbidden during creation of a draw list");
+ ERR_FAIL_COND_V_MSG(compute_list && p_sync_with_draw, ERR_INVALID_PARAMETER,
+ "Updating buffers in 'sync to draw' mode is forbidden during creation of a compute list");
- VkPipelineStageFlags dst_stage_mask;
- VkAccessFlags dst_access;
+ // Protect subsequent updates...
+ VkPipelineStageFlags dst_stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT;
+ VkAccessFlags dst_access = VK_ACCESS_TRANSFER_WRITE_BIT;
- Buffer *buffer = nullptr;
- if (vertex_buffer_owner.owns(p_buffer)) {
- dst_stage_mask = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
- dst_access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
- buffer = vertex_buffer_owner.getornull(p_buffer);
- } else if (index_buffer_owner.owns(p_buffer)) {
- dst_stage_mask = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
- dst_access = VK_ACCESS_INDEX_READ_BIT;
- buffer = index_buffer_owner.getornull(p_buffer);
- } else if (uniform_buffer_owner.owns(p_buffer)) {
- dst_stage_mask = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- dst_access = VK_ACCESS_UNIFORM_READ_BIT;
- buffer = uniform_buffer_owner.getornull(p_buffer);
- } else if (texture_buffer_owner.owns(p_buffer)) {
- dst_stage_mask = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- dst_access = VK_ACCESS_SHADER_READ_BIT;
- buffer = &texture_buffer_owner.getornull(p_buffer)->buffer;
- } else if (storage_buffer_owner.owns(p_buffer)) {
- dst_stage_mask = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- dst_access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
- buffer = storage_buffer_owner.getornull(p_buffer);
- } else {
+ Buffer *buffer = _get_buffer_from_owner(p_buffer, dst_stage_mask, dst_access);
+ if (!buffer) {
ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Buffer argument is not a valid buffer of any type.");
}
ERR_FAIL_COND_V_MSG(p_offset + p_size > buffer->size, ERR_INVALID_PARAMETER,
"Attempted to write buffer (" + itos((p_offset + p_size) - buffer->size) + " bytes) past the end.");
+ _buffer_memory_barrier(buffer->buffer, p_offset, p_size, dst_stage_mask, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_access, VK_ACCESS_TRANSFER_WRITE_BIT, p_sync_with_draw);
Error err = _buffer_update(buffer, p_offset, (uint8_t *)p_data, p_size, p_sync_with_draw);
if (err) {
return err;
}
- _buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, p_sync_with_draw);
#ifdef FORCE_FULL_BARRIER
_full_barrier(p_sync_with_draw);
#else
@@ -4934,20 +5064,20 @@ Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint
Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
_THREAD_SAFE_METHOD_
- Buffer *buffer = nullptr;
- if (vertex_buffer_owner.owns(p_buffer)) {
- buffer = vertex_buffer_owner.getornull(p_buffer);
- } else if (index_buffer_owner.owns(p_buffer)) {
- buffer = index_buffer_owner.getornull(p_buffer);
- } else if (texture_buffer_owner.owns(p_buffer)) {
- buffer = &texture_buffer_owner.getornull(p_buffer)->buffer;
- } else if (storage_buffer_owner.owns(p_buffer)) {
- buffer = storage_buffer_owner.getornull(p_buffer);
- } else {
+ // It could be this buffer was just created
+ VkPipelineShaderStageCreateFlags src_stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT;
+ VkAccessFlags src_access_mask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ // Get the vulkan buffer and the potential stage/access possible
+ Buffer *buffer = _get_buffer_from_owner(p_buffer, src_stage_mask, src_access_mask);
+ if (!buffer) {
ERR_FAIL_V_MSG(Vector<uint8_t>(), "Buffer is either invalid or this type of buffer can't be retrieved. Only Index and Vertex buffers allow retrieving.");
}
+ // Make sure no one is using the buffer -- the "false" gets us to the same command buffer as below.
+ _buffer_memory_barrier(buffer->buffer, 0, buffer->size, src_stage_mask, src_access_mask, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT, false);
+
VkCommandBuffer command_buffer = frames[frame].setup_command_buffer;
+
Buffer tmp_buffer;
_buffer_allocate(&tmp_buffer, buffer->size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
VkBufferCopy region;
@@ -5614,7 +5744,7 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
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);
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
texture->layout = VK_IMAGE_LAYOUT_GENERAL;
@@ -6030,7 +6160,7 @@ void RenderingDeviceVulkan::draw_list_bind_render_pipeline(DrawListID p_list, RI
void RenderingDeviceVulkan::draw_list_bind_uniform_set(DrawListID p_list, RID p_uniform_set, uint32_t p_index) {
#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_MSG(p_index >= limits.maxBoundDescriptorSets || p_index > MAX_UNIFORM_SETS,
+ ERR_FAIL_COND_MSG(p_index >= limits.maxBoundDescriptorSets || p_index >= MAX_UNIFORM_SETS,
"Attempting to bind a descriptor set (" + itos(p_index) + ") greater than what the hardware supports (" + itos(limits.maxBoundDescriptorSets) + ").");
#endif
DrawList *dl = _get_draw_list_ptr(p_list);
@@ -6055,13 +6185,13 @@ void RenderingDeviceVulkan::draw_list_bind_uniform_set(DrawListID p_list, RID p_
#ifdef DEBUG_ENABLED
{ //validate that textures bound are not attached as framebuffer bindings
uint32_t attachable_count = uniform_set->attachable_textures.size();
- const RID *attachable_ptr = uniform_set->attachable_textures.ptr();
+ const UniformSet::AttachableTexture *attachable_ptr = uniform_set->attachable_textures.ptr();
uint32_t bound_count = draw_list_bound_textures.size();
const RID *bound_ptr = draw_list_bound_textures.ptr();
for (uint32_t i = 0; i < attachable_count; i++) {
for (uint32_t j = 0; j < bound_count; j++) {
- ERR_FAIL_COND_MSG(attachable_ptr[i] == bound_ptr[j],
- "Attempted to use the same texture in framebuffer attachment and a uniform set, this is not allowed.");
+ ERR_FAIL_COND_MSG(attachable_ptr[i].texture == bound_ptr[j],
+ "Attempted to use the same texture in framebuffer attachment and a uniform (set: " + itos(p_index) + ", binding: " + itos(attachable_ptr[i].bind) + "), this is not allowed.");
}
}
}
@@ -6265,7 +6395,7 @@ void RenderingDeviceVulkan::draw_list_enable_scissor(DrawListID p_list, const Re
Rect2i rect = p_rect;
rect.position += dl->viewport.position;
- rect = dl->viewport.clip(rect);
+ rect = dl->viewport.intersection(rect);
if (rect.get_area() == 0) {
return;
@@ -6352,7 +6482,7 @@ void RenderingDeviceVulkan::draw_list_end() {
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);
+ vkCmdPipelineBarrier(frames[frame].draw_command_buffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
texture->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
@@ -6452,7 +6582,7 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
ComputeList *cl = compute_list;
#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_MSG(p_index >= limits.maxBoundDescriptorSets || p_index > MAX_UNIFORM_SETS,
+ ERR_FAIL_COND_MSG(p_index >= limits.maxBoundDescriptorSets || p_index >= MAX_UNIFORM_SETS,
"Attempting to bind a descriptor set (" + itos(p_index) + ") greater than what the hardware supports (" + itos(limits.maxBoundDescriptorSets) + ").");
#endif
@@ -6494,7 +6624,7 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
image_memory_barrier.subresourceRange.baseArrayLayer = textures_to_sampled[i]->base_layer;
image_memory_barrier.subresourceRange.layerCount = textures_to_sampled[i]->layers;
- vkCmdPipelineBarrier(cl->command_buffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(cl->command_buffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
textures_to_sampled[i]->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
@@ -6691,13 +6821,12 @@ void RenderingDeviceVulkan::compute_list_add_barrier(ComputeListID p_list) {
void RenderingDeviceVulkan::compute_list_end() {
ERR_FAIL_COND(!compute_list);
-
for (Set<Texture *>::Element *E = compute_list->state.textures_to_sampled_layout.front(); E; E = E->next()) {
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.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT;
image_memory_barrier.oldLayout = E->get()->layout;
image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
@@ -6710,7 +6839,8 @@ void RenderingDeviceVulkan::compute_list_end() {
image_memory_barrier.subresourceRange.baseArrayLayer = E->get()->base_layer;
image_memory_barrier.subresourceRange.layerCount = E->get()->layers;
- vkCmdPipelineBarrier(compute_list->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ // TODO: Look at the usages in the compute list and determine tighter dst stage and access masks based on some "final" usage equivalent
+ vkCmdPipelineBarrier(compute_list->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
E->get()->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
@@ -6720,7 +6850,7 @@ void RenderingDeviceVulkan::compute_list_end() {
#ifdef FORCE_FULL_BARRIER
_full_barrier(true);
#else
- _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);
+ _memory_barrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_ACCESS_SHADER_WRITE_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
}
@@ -6733,7 +6863,6 @@ void RenderingDeviceVulkan::full_barrier() {
#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) {
-
VkCommandBuffer frame_cmdbuf = frames[frame].frame_buffer;
ERR_FAIL_COND(!frame_cmdbuf);
@@ -6762,7 +6891,6 @@ void RenderingDeviceVulkan::draw_list_render_secondary_to_framebuffer(ID p_frame
ID screen_format = screen_get_framebuffer_format();
{
-
VkCommandBuffer *command_buffers = (VkCommandBuffer *)alloca(sizeof(VkCommandBuffer) * p_draw_list_count);
uint32_t command_buffer_count = 0;
@@ -6786,7 +6914,6 @@ void RenderingDeviceVulkan::draw_list_render_secondary_to_framebuffer(ID p_frame
}
vkCmdEndRenderPass(frame_cmdbuf);
-
}
#endif
@@ -7549,7 +7676,6 @@ RenderingDevice *RenderingDeviceVulkan::create_local_device() {
}
RenderingDeviceVulkan::RenderingDeviceVulkan() {
- screen_prepared = false;
}
RenderingDeviceVulkan::~RenderingDeviceVulkan() {
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index 6f8bbc9c64..05c5b9c63e 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -31,9 +31,10 @@
#ifndef RENDERING_DEVICE_VULKAN_H
#define RENDERING_DEVICE_VULKAN_H
-#include "core/oa_hash_map.h"
#include "core/os/thread_safe.h"
-#include "core/rid_owner.h"
+#include "core/templates/local_vector.h"
+#include "core/templates/oa_hash_map.h"
+#include "core/templates/rid_owner.h"
#include "servers/rendering/rendering_device.h"
#ifdef DEBUG_ENABLED
@@ -45,11 +46,6 @@
#include <vulkan/vulkan.h>
-//todo:
-//compute
-//push constants
-//views of texture slices
-
class VulkanContext;
class RenderingDeviceVulkan : public RenderingDevice {
@@ -99,7 +95,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
ID_BASE_SHIFT = 58 //5 bits for ID types
};
- VkDevice device;
+ VkDevice device = VK_NULL_HANDLE;
Map<RID, Set<RID>> dependency_map; //IDs to IDs that depend on it
Map<RID, Set<RID>> reverse_dependency_map; //same as above, but in reverse
@@ -124,35 +120,35 @@ class RenderingDeviceVulkan : public RenderingDevice {
// for a framebuffer to render into it.
struct Texture {
- VkImage image;
- VmaAllocation allocation;
+ VkImage image = VK_NULL_HANDLE;
+ VmaAllocation allocation = nullptr;
VmaAllocationInfo allocation_info;
- VkImageView view;
+ VkImageView view = VK_NULL_HANDLE;
TextureType type;
DataFormat format;
TextureSamples samples;
- uint32_t width;
- uint32_t height;
- uint32_t depth;
- uint32_t layers;
- uint32_t mipmaps;
- uint32_t usage_flags;
- uint32_t base_mipmap;
- uint32_t base_layer;
+ uint32_t width = 0;
+ uint32_t height = 0;
+ uint32_t depth = 0;
+ uint32_t layers = 0;
+ uint32_t mipmaps = 0;
+ uint32_t usage_flags = 0;
+ uint32_t base_mipmap = 0;
+ uint32_t base_layer = 0;
Vector<DataFormat> allowed_shared_formats;
VkImageLayout layout;
- uint32_t read_aspect_mask;
- uint32_t barrier_aspect_mask;
- bool bound; //bound to framebffer
+ uint32_t read_aspect_mask = 0;
+ uint32_t barrier_aspect_mask = 0;
+ bool bound = false; //bound to framebffer
RID owner;
};
RID_Owner<Texture, true> texture_owner;
- uint32_t texture_upload_region_size_px;
+ 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);
@@ -188,32 +184,28 @@ class RenderingDeviceVulkan : public RenderingDevice {
// See the comments in the code to understand better how it works.
struct StagingBufferBlock {
- VkBuffer buffer;
- VmaAllocation allocation;
- uint64_t frame_used;
- uint32_t fill_amount;
+ VkBuffer buffer = VK_NULL_HANDLE;
+ VmaAllocation allocation = nullptr;
+ uint64_t frame_used = 0;
+ uint32_t fill_amount = 0;
};
Vector<StagingBufferBlock> staging_buffer_blocks;
- int staging_buffer_current;
- uint32_t staging_buffer_block_size;
- uint64_t staging_buffer_max_size;
- bool staging_buffer_used;
+ int staging_buffer_current = 0;
+ uint32_t staging_buffer_block_size = 0;
+ uint64_t staging_buffer_max_size = 0;
+ bool staging_buffer_used = false;
Error _staging_buffer_allocate(uint32_t p_amount, uint32_t p_required_align, uint32_t &r_alloc_offset, uint32_t &r_alloc_size, bool p_can_segment = true, bool p_on_draw_command_buffer = false);
Error _insert_staging_block();
struct Buffer {
- uint32_t size;
- uint32_t usage;
- VkBuffer buffer;
- VmaAllocation allocation;
+ uint32_t size = 0;
+ uint32_t usage = 0;
+ VkBuffer buffer = VK_NULL_HANDLE;
+ VmaAllocation allocation = nullptr;
VkDescriptorBufferInfo buffer_info; //used for binding
Buffer() {
- size = 0;
- usage = 0;
- buffer = VK_NULL_HANDLE;
- allocation = nullptr;
}
};
@@ -276,15 +268,15 @@ class RenderingDeviceVulkan : public RenderingDevice {
Map<FramebufferFormatKey, FramebufferFormatID> framebuffer_format_cache;
struct FramebufferFormat {
const Map<FramebufferFormatKey, FramebufferFormatID>::Element *E;
- VkRenderPass render_pass; //here for constructing shaders, never used, see section (7.2. Render Pass Compatibility from Vulkan spec)
- int color_attachments; //used for pipeline validation
+ 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;
};
Map<FramebufferFormatID, FramebufferFormat> framebuffer_formats;
struct Framebuffer {
- FramebufferFormatID format_id;
+ FramebufferFormatID format_id = 0;
struct VersionKey {
InitialAction initial_color_action;
FinalAction final_color_action;
@@ -307,12 +299,12 @@ class RenderingDeviceVulkan : public RenderingDevice {
}
};
- uint32_t storage_mask;
+ uint32_t storage_mask = 0;
Vector<RID> texture_ids;
struct Version {
- VkFramebuffer framebuffer;
- VkRenderPass render_pass; //this one is owned
+ VkFramebuffer framebuffer = VK_NULL_HANDLE;
+ VkRenderPass render_pass = VK_NULL_HANDLE; //this one is owned
};
Map<VersionKey, Version> framebuffers;
@@ -399,8 +391,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
struct VertexDescriptionCache {
Vector<VertexAttribute> vertex_formats;
- VkVertexInputBindingDescription *bindings;
- VkVertexInputAttributeDescription *attributes;
+ VkVertexInputBindingDescription *bindings = nullptr;
+ VkVertexInputAttributeDescription *attributes = nullptr;
VkPipelineVertexInputStateCreateInfo create_info;
};
@@ -408,9 +400,9 @@ class RenderingDeviceVulkan : public RenderingDevice {
struct VertexArray {
RID buffer;
- VertexFormatID description;
- int vertex_count;
- uint32_t max_instances_allowed;
+ VertexFormatID description = 0;
+ int vertex_count = 0;
+ uint32_t max_instances_allowed = 0;
Vector<VkBuffer> buffers; //not owned, just referenced
Vector<VkDeviceSize> offsets;
@@ -419,21 +411,21 @@ class RenderingDeviceVulkan : public RenderingDevice {
RID_Owner<VertexArray, true> vertex_array_owner;
struct IndexBuffer : public Buffer {
- uint32_t max_index; //used for validation
- uint32_t index_count;
- VkIndexType index_type;
- bool supports_restart_indices;
+ uint32_t max_index = 0; //used for validation
+ uint32_t index_count = 0;
+ VkIndexType index_type = VK_INDEX_TYPE_NONE_NV;
+ bool supports_restart_indices = false;
};
RID_Owner<IndexBuffer, true> index_buffer_owner;
struct IndexArray {
- uint32_t max_index; //remember the maximum index here too, for validation
+ uint32_t max_index = 0; //remember the maximum index here too, for validation
VkBuffer buffer; //not owned, inherited from index buffer
- uint32_t offset;
- uint32_t indices;
- VkIndexType index_type;
- bool supports_restart_indices;
+ uint32_t offset = 0;
+ uint32_t indices = 0;
+ VkIndexType index_type = VK_INDEX_TYPE_NONE_NV;
+ bool supports_restart_indices = false;
};
RID_Owner<IndexArray, true> index_array_owner;
@@ -459,10 +451,10 @@ class RenderingDeviceVulkan : public RenderingDevice {
};
struct UniformInfo {
- UniformType type;
- int binding;
- uint32_t stages;
- int length; //size of arrays (in total elements), or ubos (in bytes * total elements)
+ UniformType type = UniformType::UNIFORM_TYPE_MAX;
+ int binding = 0;
+ uint32_t stages = 0;
+ int length = 0; //size of arrays (in total elements), or ubos (in bytes * total elements)
bool operator!=(const UniformInfo &p_info) const {
return (binding != p_info.binding || type != p_info.type || stages != p_info.stages || length != p_info.length);
@@ -528,25 +520,25 @@ class RenderingDeviceVulkan : public RenderingDevice {
struct Shader {
struct Set {
Vector<UniformInfo> uniform_info;
- VkDescriptorSetLayout descriptor_set_layout;
+ VkDescriptorSetLayout descriptor_set_layout = VK_NULL_HANDLE;
};
- uint32_t vertex_input_mask; //inputs used, this is mostly for validation
- int fragment_outputs;
+ uint32_t vertex_input_mask = 0; //inputs used, this is mostly for validation
+ int fragment_outputs = 0;
struct PushConstant {
- uint32_t push_constant_size;
- uint32_t push_constants_vk_stage;
+ uint32_t push_constant_size = 0;
+ uint32_t push_constants_vk_stage = 0;
};
PushConstant push_constant;
bool is_compute = false;
- int max_output;
+ int max_output = 0;
Vector<Set> sets;
Vector<uint32_t> set_formats;
Vector<VkPipelineShaderStageCreateInfo> pipeline_stages;
- VkPipelineLayout pipeline_layout;
+ VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
};
String _shader_uniform_debug(RID p_shader, int p_set = -1);
@@ -610,7 +602,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
};
Map<DescriptorPoolKey, Set<DescriptorPool *>> descriptor_pools;
- uint32_t max_descriptors_per_pool;
+ uint32_t max_descriptors_per_pool = 0;
DescriptorPool *_descriptor_pool_allocate(const DescriptorPoolKey &p_key);
void _descriptor_pool_free(const DescriptorPoolKey &p_key, DescriptorPool *p_pool);
@@ -621,7 +613,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
//texture buffer needs a view
struct TextureBuffer {
Buffer buffer;
- VkBufferView view;
+ VkBufferView view = VK_NULL_HANDLE;
};
RID_Owner<TextureBuffer, true> texture_buffer_owner;
@@ -635,14 +627,19 @@ class RenderingDeviceVulkan : public RenderingDevice {
// the above restriction is not too serious.
struct UniformSet {
- uint32_t format;
+ uint32_t format = 0;
RID shader_id;
- uint32_t shader_set;
- DescriptorPool *pool;
+ uint32_t shader_set = 0;
+ DescriptorPool *pool = nullptr;
DescriptorPoolKey pool_key;
- VkDescriptorSet descriptor_set;
+ VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
//VkPipelineLayout pipeline_layout; //not owned, inherited from shader
- Vector<RID> attachable_textures; //used for validation
+ struct AttachableTexture {
+ uint32_t bind;
+ RID texture;
+ };
+
+ 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
};
@@ -668,21 +665,21 @@ class RenderingDeviceVulkan : public RenderingDevice {
//Cached values for validation
#ifdef DEBUG_ENABLED
struct Validation {
- FramebufferFormatID framebuffer_format;
- uint32_t dynamic_state;
- VertexFormatID vertex_format;
- bool uses_restart_indices;
- uint32_t primitive_minimum;
- uint32_t primitive_divisor;
+ FramebufferFormatID framebuffer_format = 0;
+ uint32_t dynamic_state = 0;
+ VertexFormatID vertex_format = 0;
+ bool uses_restart_indices = false;
+ uint32_t primitive_minimum = 0;
+ uint32_t primitive_divisor = 0;
} validation;
#endif
//Actual pipeline
RID shader;
Vector<uint32_t> set_formats;
- VkPipelineLayout pipeline_layout; // not owned, needed for push constants
- VkPipeline pipeline;
- uint32_t push_constant_size;
- uint32_t push_constant_stages;
+ VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; // not owned, needed for push constants
+ VkPipeline pipeline = VK_NULL_HANDLE;
+ uint32_t push_constant_size = 0;
+ uint32_t push_constant_stages = 0;
};
RID_Owner<RenderPipeline, true> render_pipeline_owner;
@@ -690,10 +687,10 @@ class RenderingDeviceVulkan : public RenderingDevice {
struct ComputePipeline {
RID shader;
Vector<uint32_t> set_formats;
- VkPipelineLayout pipeline_layout; // not owned, needed for push constants
- VkPipeline pipeline;
- uint32_t push_constant_size;
- uint32_t push_constant_stages;
+ VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; // not owned, needed for push constants
+ VkPipeline pipeline = VK_NULL_HANDLE;
+ uint32_t push_constant_size = 0;
+ uint32_t push_constant_stages = 0;
};
RID_Owner<ComputePipeline, true> compute_pipeline_owner;
@@ -714,14 +711,14 @@ class RenderingDeviceVulkan : public RenderingDevice {
// each needs it's own command pool.
struct SplitDrawListAllocator {
- VkCommandPool command_pool;
+ VkCommandPool command_pool = VK_NULL_HANDLE;
Vector<VkCommandBuffer> command_buffers; //one for each frame
};
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 = VK_NULL_HANDLE; // If persistent, this is owned, otherwise it's shared with the ringbuffer.
Rect2i viewport;
struct SetState {
@@ -755,7 +752,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
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;
+ uint32_t index_array_offset = 0;
Vector<uint32_t> set_formats;
Vector<bool> set_bound;
Vector<RID> set_rids;
@@ -766,8 +763,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
RID pipeline_shader;
uint32_t invalid_set_from = 0;
bool pipeline_uses_restart_indices = false;
- uint32_t pipeline_primitive_divisor;
- uint32_t pipeline_primitive_minimum;
+ uint32_t pipeline_primitive_divisor = 0;
+ uint32_t pipeline_primitive_minimum = 0;
Vector<uint32_t> pipeline_set_formats;
uint32_t pipeline_push_constant_size = 0;
bool pipeline_push_constant_supplied = false;
@@ -781,25 +778,26 @@ class RenderingDeviceVulkan : public RenderingDevice {
#endif
};
- DrawList *draw_list; // One for regular draw lists, multiple for split.
- uint32_t draw_list_count;
- bool draw_list_split;
+ DrawList *draw_list = nullptr; // One for regular draw lists, multiple for split.
+ uint32_t draw_list_count = 0;
+ bool draw_list_split = false;
Vector<RID> draw_list_bound_textures;
Vector<RID> draw_list_storage_textures;
- bool draw_list_unbind_color_textures;
- bool draw_list_unbind_depth_textures;
+ bool draw_list_unbind_color_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);
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, 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);
/**********************/
/**** COMPUTE LIST ****/
/**********************/
struct ComputeList {
- VkCommandBuffer command_buffer; // 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.
struct SetState {
uint32_t pipeline_expected_format = 0;
@@ -836,7 +834,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
#endif
};
- ComputeList *compute_list;
+ ComputeList *compute_list = nullptr;
/**************************/
/**** FRAME MANAGEMENT ****/
@@ -868,46 +866,46 @@ class RenderingDeviceVulkan : public RenderingDevice {
List<RenderPipeline> render_pipelines_to_dispose_of;
List<ComputePipeline> compute_pipelines_to_dispose_of;
- VkCommandPool command_pool;
- 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
+ VkCommandPool command_pool = VK_NULL_HANDLE;
+ VkCommandBuffer setup_command_buffer = VK_NULL_HANDLE; //used at the beginning of every frame for set-up
+ VkCommandBuffer draw_command_buffer = VK_NULL_HANDLE; //used at the beginning of every frame for set-up
struct Timestamp {
String description;
- uint64_t value;
+ uint64_t value = 0;
};
VkQueryPool timestamp_pool;
- String *timestamp_names;
- uint64_t *timestamp_cpu_values;
- uint32_t timestamp_count;
- String *timestamp_result_names;
- uint64_t *timestamp_cpu_result_values;
- uint64_t *timestamp_result_values;
- uint32_t timestamp_result_count;
- uint64_t index;
+ String *timestamp_names = nullptr;
+ uint64_t *timestamp_cpu_values = nullptr;
+ uint32_t timestamp_count = 0;
+ String *timestamp_result_names = nullptr;
+ uint64_t *timestamp_cpu_result_values = nullptr;
+ uint64_t *timestamp_result_values = nullptr;
+ uint32_t timestamp_result_count = 0;
+ uint64_t index = 0;
};
- uint32_t max_timestamp_query_elements;
+ uint32_t max_timestamp_query_elements = 0;
- Frame *frames; //frames available, for main device they are cycled (usually 3), for local devices only 1
- int frame; //current frame
- int frame_count; //total amount of frames
- uint64_t frames_drawn;
+ Frame *frames = nullptr; //frames available, for main device they are cycled (usually 3), for local devices only 1
+ int frame = 0; //current frame
+ int frame_count = 0; //total amount of frames
+ uint64_t frames_drawn = 0;
RID local_device;
bool local_device_processing = false;
void _free_pending_resources(int p_frame);
- VmaAllocator allocator;
+ VmaAllocator allocator = nullptr;
- VulkanContext *context;
+ VulkanContext *context = nullptr;
void _free_internal(RID p_id);
void _flush(bool p_current_frame);
- bool screen_prepared;
+ bool screen_prepared = false;
template <class T>
void _free_rids(T &p_owner, const char *p_type);
@@ -954,7 +952,7 @@ public:
/**** VERTEX ARRAY ****/
/**********************/
- virtual RID vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>());
+ virtual RID vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>(), bool p_use_as_storage = false);
// Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated
virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats);
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 997ed3935f..1f4092745a 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -30,9 +30,9 @@
#include "vulkan_context.h"
-#include "core/engine.h"
-#include "core/project_settings.h"
-#include "core/ustring.h"
+#include "core/config/engine.h"
+#include "core/config/project_settings.h"
+#include "core/string/ustring.h"
#include "core/version.h"
#include "vk_enum_string_helper.h"
@@ -154,7 +154,7 @@ VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char **check_n
}
}
if (!found) {
- ERR_PRINT("Can't find layer: " + String(check_names[i]));
+ WARN_PRINT("Can't find layer: " + String(check_names[i]));
return 0;
}
}
@@ -216,7 +216,6 @@ Error VulkanContext::_create_validation_layers() {
}
Error VulkanContext::_initialize_extensions() {
- VkResult err;
uint32_t instance_extension_count = 0;
enabled_extension_count = 0;
@@ -226,13 +225,13 @@ Error VulkanContext::_initialize_extensions() {
VkBool32 platformSurfaceExtFound = 0;
memset(extension_names, 0, sizeof(extension_names));
- err = vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, nullptr);
- ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
+ VkResult err = vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, nullptr);
+ ERR_FAIL_COND_V(err != VK_SUCCESS && err != VK_INCOMPLETE, ERR_CANT_CREATE);
if (instance_extension_count > 0) {
VkExtensionProperties *instance_extensions = (VkExtensionProperties *)malloc(sizeof(VkExtensionProperties) * instance_extension_count);
err = vkEnumerateInstanceExtensionProperties(nullptr, &instance_extension_count, instance_extensions);
- if (err) {
+ if (err != VK_SUCCESS && err != VK_INCOMPLETE) {
free(instance_extensions);
ERR_FAIL_V(ERR_CANT_CREATE);
}
@@ -302,7 +301,7 @@ Error VulkanContext::_create_physical_device() {
/*flags*/ 0,
/*pApplicationInfo*/ &app,
/*enabledLayerCount*/ enabled_layer_count,
- /*ppEnabledLayerNames*/ (const char *const *)instance_validation_layers,
+ /*ppEnabledLayerNames*/ (const char *const *)enabled_layers,
/*enabledExtensionCount*/ enabled_extension_count,
/*ppEnabledExtensionNames*/ (const char *const *)extension_names,
};
@@ -494,6 +493,8 @@ Error VulkanContext::_create_physical_device() {
// features based on this query
vkGetPhysicalDeviceFeatures(gpu, &physical_device_features);
+ physical_device_features.robustBufferAccess = false; //turn off robust buffer access, which can hamper performance on some hardware
+
#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
{ \
fp##entrypoint = (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint); \
@@ -707,7 +708,8 @@ Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, VkSurfa
// We use a single GPU, but we need a surface to initialize the
// queues, so this process must be deferred until a surface
// is created.
- _initialize_queues(p_surface);
+ Error err = _initialize_queues(p_surface);
+ ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
}
Window window;
@@ -1009,7 +1011,6 @@ Error VulkanContext::_update_swap_chain(Window *window) {
{
const VkAttachmentDescription attachment = {
-
/*flags*/ 0,
/*format*/ format,
/*samples*/ VK_SAMPLE_COUNT_1_BIT,
@@ -1479,23 +1480,6 @@ VkPhysicalDeviceLimits VulkanContext::get_device_limits() const {
return gpu_props.limits;
}
-VulkanContext::VulkanContext() {
- queue_props = nullptr;
- command_buffer_count = 0;
- instance_validation_layers = nullptr;
- use_validation_layers = true;
- VK_KHR_incremental_present_enabled = true;
- VK_GOOGLE_display_timing_enabled = true;
-
- command_buffer_queue.resize(1); //first one is the setup command always
- command_buffer_queue.write[0] = nullptr;
- command_buffer_count = 1;
- queues_initialized = false;
-
- buffers_prepared = false;
- swapchainImageCount = 0;
-}
-
RID VulkanContext::local_device_create() {
LocalDevice ld;
@@ -1583,6 +1567,13 @@ void VulkanContext::local_device_free(RID p_local_device) {
local_device_owner.free(p_local_device);
}
+VulkanContext::VulkanContext() {
+ use_validation_layers = Engine::get_singleton()->is_validation_layers_enabled();
+
+ command_buffer_queue.resize(1); // First one is always the setup command.
+ command_buffer_queue.write[0] = nullptr;
+}
+
VulkanContext::~VulkanContext() {
if (queue_props) {
free(queue_props);
@@ -1596,7 +1587,7 @@ VulkanContext::~VulkanContext() {
vkDestroySemaphore(device, image_ownership_semaphores[i], nullptr);
}
}
- if (inst_initialized) {
+ if (inst_initialized && use_validation_layers) {
DestroyDebugUtilsMessengerEXT(inst, dbg_messenger, nullptr);
}
vkDestroyDevice(device, nullptr);
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index 9ebea42ecb..1aaad29ccd 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -31,12 +31,13 @@
#ifndef VULKAN_CONTEXT_H
#define VULKAN_CONTEXT_H
-#include "core/error_list.h"
-#include "core/map.h"
+#include "core/error/error_list.h"
#include "core/os/mutex.h"
-#include "core/rid_owner.h"
-#include "core/ustring.h"
+#include "core/string/ustring.h"
+#include "core/templates/map.h"
+#include "core/templates/rid_owner.h"
#include "servers/display_server.h"
+
#include <vulkan/vulkan.h>
class VulkanContext {
@@ -46,29 +47,31 @@ class VulkanContext {
FRAME_LAG = 2
};
- VkInstance inst;
- VkSurfaceKHR surface;
- VkPhysicalDevice gpu;
+ VkInstance inst = VK_NULL_HANDLE;
+ VkSurfaceKHR surface = VK_NULL_HANDLE;
+ VkPhysicalDevice gpu = VK_NULL_HANDLE;
VkPhysicalDeviceProperties gpu_props;
- uint32_t queue_family_count;
- VkQueueFamilyProperties *queue_props;
- VkDevice device;
+ uint32_t queue_family_count = 0;
+ VkQueueFamilyProperties *queue_props = nullptr;
+ VkDevice device = VK_NULL_HANDLE;
bool device_initialized = false;
bool inst_initialized = false;
- //present
- bool queues_initialized;
- uint32_t graphics_queue_family_index;
- uint32_t present_queue_family_index;
- bool separate_present_queue;
- VkQueue graphics_queue;
- VkQueue present_queue;
+ bool buffers_prepared = false;
+
+ // Present queue.
+ bool queues_initialized = false;
+ uint32_t graphics_queue_family_index = 0;
+ uint32_t present_queue_family_index = 0;
+ bool separate_present_queue = false;
+ VkQueue graphics_queue = VK_NULL_HANDLE;
+ VkQueue present_queue = VK_NULL_HANDLE;
VkColorSpaceKHR color_space;
VkFormat format;
VkSemaphore image_acquired_semaphores[FRAME_LAG];
VkSemaphore draw_complete_semaphores[FRAME_LAG];
VkSemaphore image_ownership_semaphores[FRAME_LAG];
- int frame_index;
+ int frame_index = 0;
VkFence fences[FRAME_LAG];
VkPhysicalDeviceMemoryProperties memory_properties;
VkPhysicalDeviceFeatures physical_device_features;
@@ -78,7 +81,6 @@ class VulkanContext {
VkCommandBuffer graphics_to_present_cmd;
VkImageView view;
VkFramebuffer framebuffer;
-
} SwapchainImageResources;
struct Window {
@@ -89,32 +91,36 @@ class VulkanContext {
uint32_t current_buffer = 0;
int width = 0;
int height = 0;
- VkCommandPool present_cmd_pool; //for separate present queue
+ VkCommandPool present_cmd_pool = VK_NULL_HANDLE; // For separate present queue.
VkRenderPass render_pass = VK_NULL_HANDLE;
};
struct LocalDevice {
bool waiting = false;
- VkDevice device;
- VkQueue queue;
+ VkDevice device = VK_NULL_HANDLE;
+ VkQueue queue = VK_NULL_HANDLE;
};
RID_Owner<LocalDevice, true> local_device_owner;
Map<DisplayServer::WindowID, Window> windows;
- uint32_t swapchainImageCount;
+ uint32_t swapchainImageCount = 0;
- //commands
+ // Commands.
+
+ bool prepared = false;
+
+ Vector<VkCommandBuffer> command_buffer_queue;
+ int command_buffer_count = 1;
- bool prepared;
+ // Extensions.
- //extensions
- bool VK_KHR_incremental_present_enabled;
- bool VK_GOOGLE_display_timing_enabled;
- const char **instance_validation_layers;
- uint32_t enabled_extension_count;
- uint32_t enabled_layer_count;
+ bool VK_KHR_incremental_present_enabled = true;
+ bool VK_GOOGLE_display_timing_enabled = true;
+ uint32_t enabled_extension_count = 0;
const char *extension_names[MAX_EXTENSIONS];
+
+ uint32_t enabled_layer_count = 0;
const char *enabled_layers[MAX_LAYERS];
PFN_vkCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT;
@@ -136,13 +142,14 @@ class VulkanContext {
PFN_vkGetRefreshCycleDurationGOOGLE fpGetRefreshCycleDurationGOOGLE;
PFN_vkGetPastPresentationTimingGOOGLE fpGetPastPresentationTimingGOOGLE;
- VkDebugUtilsMessengerEXT dbg_messenger;
+ VkDebugUtilsMessengerEXT dbg_messenger = VK_NULL_HANDLE;
Error _create_validation_layers();
Error _initialize_extensions();
VkBool32 _check_layers(uint32_t check_count, const char **check_names, uint32_t layer_count, VkLayerProperties *layers);
- static VKAPI_ATTR VkBool32 VKAPI_CALL _debug_messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ static VKAPI_ATTR VkBool32 VKAPI_CALL _debug_messenger_callback(
+ VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
void *pUserData);
@@ -160,12 +167,11 @@ class VulkanContext {
Error _create_swap_chain();
Error _create_semaphores();
- Vector<VkCommandBuffer> command_buffer_queue;
- int command_buffer_count;
-
protected:
virtual const char *_get_platform_surface_extension() const = 0;
- // virtual VkResult _create_surface(VkSurfaceKHR *surface, VkInstance p_instance) = 0;
+
+ // Enabled via command line argument.
+ bool use_validation_layers = false;
virtual Error _window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height);
@@ -173,10 +179,6 @@ protected:
return inst;
}
- bool buffers_prepared;
-
- bool use_validation_layers;
-
public:
VkDevice get_device();
VkPhysicalDevice get_physical_device();
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index cd1c08b717..67e175d8d1 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -32,8 +32,8 @@
#include "audio_driver_wasapi.h"
+#include "core/config/project_settings.h"
#include "core/os/os.h"
-#include "core/project_settings.h"
#include <functiondiscoverykeys.h>
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index 03e4e30797..197cd1d074 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -33,7 +33,7 @@
#include "dir_access_windows.h"
#include "core/os/memory.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
#include <stdio.h>
#include <wchar.h>
@@ -367,8 +367,6 @@ DirAccessWindows::DirAccessWindows() {
p->h = INVALID_HANDLE_VALUE;
current_dir = ".";
- drive_count = 0;
-
#ifdef UWP_ENABLED
Windows::Storage::StorageFolder ^ install_folder = Windows::ApplicationModel::Package::Current->InstalledLocation;
change_dir(install_folder->Path->Data());
diff --git a/drivers/windows/dir_access_windows.h b/drivers/windows/dir_access_windows.h
index 47aedfecf5..3b059b1626 100644
--- a/drivers/windows/dir_access_windows.h
+++ b/drivers/windows/dir_access_windows.h
@@ -46,16 +46,16 @@ class DirAccessWindows : public DirAccess {
MAX_DRIVES = 26
};
- DirAccessWindowsPrivate *p;
+ DirAccessWindowsPrivate *p = nullptr;
/* Windows stuff */
- char drives[MAX_DRIVES]; // a-z:
- int drive_count;
+ char drives[MAX_DRIVES] = { 0 }; // a-z:
+ int drive_count = 0;
String current_dir;
- bool _cisdir;
- bool _cishidden;
+ bool _cisdir = false;
+ bool _cishidden = false;
public:
virtual Error list_dir_begin(); ///< This starts dir listing
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index dd86061ea7..ec393c98ba 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -33,7 +33,7 @@
#include "file_access_windows.h"
#include "core/os/os.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
#include <shlwapi.h>
#include <windows.h>
diff --git a/drivers/windows/rw_lock_windows.cpp b/drivers/windows/rw_lock_windows.cpp
index 757c7661f5..1007689728 100644
--- a/drivers/windows/rw_lock_windows.cpp
+++ b/drivers/windows/rw_lock_windows.cpp
@@ -32,7 +32,7 @@
#include "rw_lock_windows.h"
-#include "core/error_macros.h"
+#include "core/error/error_macros.h"
#include "core/os/memory.h"
#include <stdio.h>
diff --git a/drivers/windows/thread_windows.h b/drivers/windows/thread_windows.h
index 502c418ce0..939f487fc1 100644
--- a/drivers/windows/thread_windows.h
+++ b/drivers/windows/thread_windows.h
@@ -33,8 +33,8 @@
#ifdef WINDOWS_ENABLED
+#include "core/object/script_language.h"
#include "core/os/thread.h"
-#include "core/script_language.h"
#include <windows.h>
diff --git a/drivers/winmidi/midi_driver_winmidi.cpp b/drivers/winmidi/midi_driver_winmidi.cpp
index 9cbc7f43e2..75f57b3bb9 100644
--- a/drivers/winmidi/midi_driver_winmidi.cpp
+++ b/drivers/winmidi/midi_driver_winmidi.cpp
@@ -32,7 +32,7 @@
#include "midi_driver_winmidi.h"
-#include "core/print_string.h"
+#include "core/string/print_string.h"
void MIDIDriverWinMidi::read(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
if (wMsg == MIM_DATA) {
diff --git a/drivers/winmidi/midi_driver_winmidi.h b/drivers/winmidi/midi_driver_winmidi.h
index 934eb5a493..9ed3fc2faa 100644
--- a/drivers/winmidi/midi_driver_winmidi.h
+++ b/drivers/winmidi/midi_driver_winmidi.h
@@ -34,7 +34,7 @@
#define MIDI_DRIVER_WINMIDI_H
#include "core/os/midi_driver.h"
-#include "core/vector.h"
+#include "core/templates/vector.h"
#include <stdio.h>
#include <windows.h>
diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp
index 421cf6a8cf..c9ad054089 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.cpp
+++ b/drivers/xaudio2/audio_driver_xaudio2.cpp
@@ -30,8 +30,8 @@
#include "audio_driver_xaudio2.h"
+#include "core/config/project_settings.h"
#include "core/os/os.h"
-#include "core/project_settings.h"
const char *AudioDriverXAudio2::get_name() const {
return "XAudio2";
diff --git a/drivers/xaudio2/audio_driver_xaudio2.h b/drivers/xaudio2/audio_driver_xaudio2.h
index 7fc1bb428d..0aed072ec6 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.h
+++ b/drivers/xaudio2/audio_driver_xaudio2.h
@@ -65,28 +65,28 @@ class AudioDriverXAudio2 : public AudioDriver {
Thread *thread = nullptr;
Mutex mutex;
- int32_t *samples_in;
+ int32_t *samples_in = nullptr;
int16_t *samples_out[AUDIO_BUFFERS];
static void thread_func(void *p_udata);
- int buffer_size;
+ int buffer_size = 0;
- unsigned int mix_rate;
- SpeakerMode speaker_mode;
+ unsigned int mix_rate = 0;
+ SpeakerMode speaker_mode = SpeakerMode::SPEAKER_MODE_STEREO;
- int channels;
+ int channels = 0;
- bool active;
- bool thread_exited;
- mutable bool exit_thread;
- bool pcm_open;
+ bool active = false;
+ bool thread_exited = false;
+ mutable bool exit_thread = false;
+ bool pcm_open = false;
WAVEFORMATEX wave_format = { 0 };
Microsoft::WRL::ComPtr<IXAudio2> xaudio;
int current_buffer = 0;
- IXAudio2MasteringVoice *mastering_voice;
+ IXAudio2MasteringVoice *mastering_voice = nullptr;
XAUDIO2_BUFFER xaudio_buffer[AUDIO_BUFFERS];
- IXAudio2SourceVoice *source_voice;
+ IXAudio2SourceVoice *source_voice = nullptr;
XAudio2DriverVoiceCallback voice_callback;
public: