summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp20
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.h14
-rw-r--r--drivers/coremidi/midi_driver_coremidi.h7
-rw-r--r--drivers/gl_context/SCsub2
-rw-r--r--drivers/gles3/effects/copy_effects.cpp1
-rw-r--r--drivers/gles3/effects/copy_effects.h7
-rw-r--r--drivers/gles3/environment/fog.h2
-rw-r--r--drivers/gles3/environment/gi.h2
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp16
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h9
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp2
-rw-r--r--drivers/gles3/rasterizer_gles3.h6
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp670
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h240
-rw-r--r--drivers/gles3/shader_gles3.h11
-rw-r--r--drivers/gles3/shaders/canvas_uniforms_inc.glsl4
-rw-r--r--drivers/gles3/shaders/cubemap_filter.glsl88
-rw-r--r--drivers/gles3/shaders/scene.glsl22
-rw-r--r--drivers/gles3/shaders/sky.glsl4
-rw-r--r--drivers/gles3/storage/config.cpp7
-rw-r--r--drivers/gles3/storage/config.h2
-rw-r--r--drivers/gles3/storage/light_storage.cpp1
-rw-r--r--drivers/gles3/storage/light_storage.h4
-rw-r--r--drivers/gles3/storage/material_storage.cpp628
-rw-r--r--drivers/gles3/storage/material_storage.h66
-rw-r--r--drivers/gles3/storage/mesh_storage.cpp2
-rw-r--r--drivers/gles3/storage/mesh_storage.h2
-rw-r--r--drivers/gles3/storage/particles_storage.h2
-rw-r--r--drivers/gles3/storage/texture_storage.cpp11
-rw-r--r--drivers/gles3/storage/texture_storage.h15
-rw-r--r--drivers/gles3/storage/utilities.cpp2
-rw-r--r--drivers/gles3/storage/utilities.h2
-rw-r--r--drivers/png/image_loader_png.h2
-rw-r--r--drivers/png/png_driver_common.h2
-rw-r--r--drivers/png/resource_saver_png.cpp2
-rw-r--r--drivers/png/resource_saver_png.h2
-rw-r--r--drivers/register_driver_types.h2
-rw-r--r--drivers/unix/dir_access_unix.cpp2
-rw-r--r--drivers/unix/dir_access_unix.h51
-rw-r--r--drivers/unix/file_access_unix.cpp2
-rw-r--r--drivers/unix/file_access_unix.h43
-rw-r--r--drivers/unix/ip_unix.cpp4
-rw-r--r--drivers/unix/ip_unix.h1
-rw-r--r--drivers/unix/net_socket_posix.h6
-rw-r--r--drivers/unix/os_unix.cpp2
-rw-r--r--drivers/unix/os_unix.h4
-rw-r--r--drivers/unix/syslog_logger.h4
-rw-r--r--drivers/unix/thread_posix.h2
-rw-r--r--drivers/vulkan/SCsub8
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp638
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h17
-rw-r--r--drivers/vulkan/vulkan_context.cpp283
-rw-r--r--drivers/vulkan/vulkan_context.h25
-rw-r--r--drivers/vulkan/vulkan_hooks.h2
-rw-r--r--drivers/wasapi/audio_driver_wasapi.h1
-rw-r--r--drivers/windows/dir_access_windows.h38
-rw-r--r--drivers/windows/file_access_windows.h38
-rw-r--r--drivers/winmidi/midi_driver_winmidi.h7
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.h2
59 files changed, 1543 insertions, 1518 deletions
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index 276e69e470..cc38c2352f 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -38,7 +38,7 @@
#define kOutputBus 0
#define kInputBus 1
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
OSStatus AudioDriverCoreAudio::input_device_address_cb(AudioObjectID inObjectID,
UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses,
void *inClientData) {
@@ -72,7 +72,7 @@ Error AudioDriverCoreAudio::init() {
AudioComponentDescription desc;
memset(&desc, 0, sizeof(desc));
desc.componentType = kAudioUnitType_Output;
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
desc.componentSubType = kAudioUnitSubType_HALOutput;
#else
desc.componentSubType = kAudioUnitSubType_RemoteIO;
@@ -85,7 +85,7 @@ Error AudioDriverCoreAudio::init() {
OSStatus result = AudioComponentInstanceNew(comp, &audio_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
@@ -135,7 +135,7 @@ Error AudioDriverCoreAudio::init() {
// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32));
ERR_FAIL_COND_V(result != noErr, FAILED);
#endif
@@ -313,7 +313,7 @@ void AudioDriverCoreAudio::finish() {
ERR_PRINT("AudioUnitUninitialize failed");
}
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
@@ -339,7 +339,7 @@ Error AudioDriverCoreAudio::capture_init() {
AudioComponentDescription desc;
memset(&desc, 0, sizeof(desc));
desc.componentType = kAudioUnitType_Output;
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
desc.componentSubType = kAudioUnitSubType_HALOutput;
#else
desc.componentSubType = kAudioUnitSubType_RemoteIO;
@@ -352,7 +352,7 @@ Error AudioDriverCoreAudio::capture_init() {
OSStatus result = AudioComponentInstanceNew(comp, &input_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultInputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
@@ -370,7 +370,7 @@ Error AudioDriverCoreAudio::capture_init() {
ERR_FAIL_COND_V(result != noErr, FAILED);
UInt32 size;
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
AudioDeviceID deviceId;
size = sizeof(AudioDeviceID);
AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
@@ -447,7 +447,7 @@ void AudioDriverCoreAudio::capture_finish() {
ERR_PRINT("AudioUnitUninitialize failed");
}
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDefaultInputDevice;
prop.mScope = kAudioObjectPropertyScopeGlobal;
@@ -491,7 +491,7 @@ Error AudioDriverCoreAudio::capture_stop() {
return OK;
}
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
Array AudioDriverCoreAudio::_get_device_list(bool capture) {
Array list;
diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h
index f86037f092..7fac8a99ed 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.h
+++ b/drivers/coreaudio/audio_driver_coreaudio.h
@@ -28,15 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef COREAUDIO_ENABLED
-
#ifndef AUDIO_DRIVER_COREAUDIO_H
#define AUDIO_DRIVER_COREAUDIO_H
+#ifdef COREAUDIO_ENABLED
+
#include "servers/audio_server.h"
#import <AudioUnit/AudioUnit.h>
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
#import <CoreAudio/AudioHardware.h>
#endif
@@ -58,7 +58,7 @@ class AudioDriverCoreAudio : public AudioDriver {
Vector<int32_t> samples_in;
Vector<int16_t> input_buf;
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
Array _get_device_list(bool capture = false);
void _set_device(const String &device, bool capture = false);
@@ -106,7 +106,7 @@ public:
bool try_lock();
void stop();
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
virtual Array get_device_list();
virtual String get_device();
virtual void set_device(String device);
@@ -120,6 +120,6 @@ public:
~AudioDriverCoreAudio() {}
};
-#endif
+#endif // COREAUDIO_ENABLED
-#endif
+#endif // AUDIO_DRIVER_COREAUDIO_H
diff --git a/drivers/coremidi/midi_driver_coremidi.h b/drivers/coremidi/midi_driver_coremidi.h
index 0085141c6d..ac2ad99eb3 100644
--- a/drivers/coremidi/midi_driver_coremidi.h
+++ b/drivers/coremidi/midi_driver_coremidi.h
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef COREMIDI_ENABLED
-
#ifndef MIDI_DRIVER_COREMIDI_H
#define MIDI_DRIVER_COREMIDI_H
+#ifdef COREMIDI_ENABLED
+
#include "core/os/midi_driver.h"
#include "core/templates/vector.h"
@@ -57,5 +57,6 @@ public:
virtual ~MIDIDriverCoreMidi();
};
-#endif // MIDI_DRIVER_COREMIDI_H
#endif // COREMIDI_ENABLED
+
+#endif // MIDI_DRIVER_COREMIDI_H
diff --git a/drivers/gl_context/SCsub b/drivers/gl_context/SCsub
index ddeec6f4c6..7e8bd22960 100644
--- a/drivers/gl_context/SCsub
+++ b/drivers/gl_context/SCsub
@@ -2,7 +2,7 @@
Import("env")
-if env["platform"] in ["haiku", "osx", "windows", "linuxbsd"]:
+if env["platform"] in ["haiku", "macos", "windows", "linuxbsd"]:
# Thirdparty source files
thirdparty_dir = "#thirdparty/glad/"
thirdparty_sources = [
diff --git a/drivers/gles3/effects/copy_effects.cpp b/drivers/gles3/effects/copy_effects.cpp
index c8e6c2b476..de0181f887 100644
--- a/drivers/gles3/effects/copy_effects.cpp
+++ b/drivers/gles3/effects/copy_effects.cpp
@@ -111,6 +111,7 @@ CopyEffects::~CopyEffects() {
glDeleteVertexArrays(1, &screen_triangle_array);
glDeleteBuffers(1, &quad);
glDeleteVertexArrays(1, &quad_array);
+ copy.shader.version_free(copy.shader_version);
}
void CopyEffects::copy_to_rect(const Rect2i &p_rect) {
diff --git a/drivers/gles3/effects/copy_effects.h b/drivers/gles3/effects/copy_effects.h
index 1cf1ac9404..b863e76579 100644
--- a/drivers/gles3/effects/copy_effects.h
+++ b/drivers/gles3/effects/copy_effects.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef COPY_GL_H
-#define COPY_GL_H
+#ifndef COPY_EFFECTS_GLES3_H
+#define COPY_EFFECTS_GLES3_H
#ifdef GLES3_ENABLED
@@ -70,4 +70,5 @@ public:
} //namespace GLES3
#endif // GLES3_ENABLED
-#endif // !COPY_GL_H
+
+#endif // COPY_EFFECTS_GLES3_H
diff --git a/drivers/gles3/environment/fog.h b/drivers/gles3/environment/fog.h
index 22bf3bb017..350eb459cf 100644
--- a/drivers/gles3/environment/fog.h
+++ b/drivers/gles3/environment/fog.h
@@ -59,4 +59,4 @@ public:
#endif // GLES3_ENABLED
-#endif // !FOG_GLES3_H
+#endif // FOG_GLES3_H
diff --git a/drivers/gles3/environment/gi.h b/drivers/gles3/environment/gi.h
index b633520784..7a0634f22b 100644
--- a/drivers/gles3/environment/gi.h
+++ b/drivers/gles3/environment/gi.h
@@ -93,4 +93,4 @@ public:
#endif // GLES3_ENABLED
-#endif // !GI_GLES3_H
+#endif // GI_GLES3_H
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 82f7450bc2..83154acd51 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -135,7 +135,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
Size2i ssize = texture_storage->render_target_get_size(p_to_render_target);
Transform3D screen_transform;
- screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f);
+ screen_transform.translate_local(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f);
screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f));
_update_transform_to_mat4(screen_transform, state_buffer.screen_transform);
_update_transform_2d_to_mat4(p_canvas_transform, state_buffer.canvas_transform);
@@ -183,7 +183,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_LOCATION, state.canvas_state_buffer);
glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW);
- GLuint global_buffer = material_storage->global_variables_get_uniform_buffer();
+ GLuint global_buffer = material_storage->global_shader_uniforms_get_uniform_buffer();
glBindBufferBase(GL_UNIFORM_BUFFER, GLOBAL_UNIFORM_LOCATION, global_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
@@ -815,10 +815,8 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item
_bind_canvas_texture(texture, current_filter, current_repeat, r_index);
if (instance_count == 1) {
GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_ATTRIBUTES);
- } else if (instance_count > 1) {
- GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_INSTANCED);
} else {
- ERR_PRINT("Must have at least one mesh instance to draw mesh");
+ GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_INSTANCED);
}
uint32_t surf_count = mesh_storage->mesh_get_surface_count(mesh);
@@ -882,7 +880,7 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item
} else {
glDrawArrays(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(surface));
}
- } else if (instance_count > 1) {
+ } else {
if (use_index_buffer) {
glDrawElementsInstanced(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(surface), mesh_storage->mesh_surface_get_index_type(surface), 0, instance_count);
} else {
@@ -1217,7 +1215,7 @@ void RasterizerCanvasGLES3::reset_canvas() {
void RasterizerCanvasGLES3::canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {
}
-void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) {
+void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, Projection *p_xform_cache) {
}
void RasterizerCanvasGLES3::draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) {
@@ -1570,7 +1568,7 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
glBindBuffer(GL_UNIFORM_BUFFER, 0);
String global_defines;
- global_defines += "#define MAX_GLOBAL_VARIABLES 256\n"; // TODO: this is arbitrary for now
+ global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now
global_defines += "#define MAX_LIGHTS " + itos(state.max_instances_per_batch) + "\n";
global_defines += "#define MAX_DRAW_DATA_INSTANCES " + itos(state.max_instances_per_batch) + "\n";
@@ -1610,6 +1608,8 @@ void fragment() {
RasterizerCanvasGLES3::~RasterizerCanvasGLES3() {
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
+ memdelete_arr(state.instance_data_array);
+
GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_free(state.canvas_shader_default_version);
material_storage->material_free(default_canvas_group_material);
material_storage->shader_free(default_canvas_group_shader);
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index caf649aaf6..f920e37130 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RASTERIZER_CANVAS_OPENGL_H
-#define RASTERIZER_CANVAS_OPENGL_H
+#ifndef RASTERIZER_CANVAS_GLES3_H
+#define RASTERIZER_CANVAS_GLES3_H
#ifdef GLES3_ENABLED
@@ -209,7 +209,7 @@ public:
void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample);
void reset_canvas();
- void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache);
+ void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, Projection *p_xform_cache);
virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override;
@@ -262,4 +262,5 @@ public:
};
#endif // GLES3_ENABLED
-#endif // RASTERIZER_CANVAS_OPENGL_H
+
+#endif // RASTERIZER_CANVAS_GLES3_H
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 613a7f37d9..33303b1e38 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -69,7 +69,7 @@
#endif
#endif
-#if !defined(IPHONE_ENABLED) && !defined(JAVASCRIPT_ENABLED)
+#if !defined(IOS_ENABLED) && !defined(JAVASCRIPT_ENABLED)
// We include EGL below to get debug callback on GLES2 platforms,
// but EGL is not available on iOS.
#define CAN_DEBUG
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index e842b6d70c..97543af0d5 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RASTERIZER_OPENGL_H
-#define RASTERIZER_OPENGL_H
+#ifndef RASTERIZER_GLES3_H
+#define RASTERIZER_GLES3_H
#ifdef GLES3_ENABLED
@@ -112,4 +112,4 @@ public:
#endif // GLES3_ENABLED
-#endif
+#endif // RASTERIZER_GLES3_H
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 989d0de496..7207a6efbb 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/templates/sort_array.h"
#include "servers/rendering/rendering_server_default.h"
+#include "servers/rendering/rendering_server_globals.h"
#include "storage/config.h"
#include "storage/light_storage.h"
#include "storage/mesh_storage.h"
@@ -39,15 +40,9 @@
#ifdef GLES3_ENABLED
-uint64_t RasterizerSceneGLES3::auto_exposure_counter = 2;
-
RasterizerSceneGLES3 *RasterizerSceneGLES3::singleton = nullptr;
-RasterizerSceneGLES3 *RasterizerSceneGLES3::get_singleton() {
- return singleton;
-}
-
-RendererSceneRender::GeometryInstance *RasterizerSceneGLES3::geometry_instance_create(RID p_base) {
+RenderGeometryInstance *RasterizerSceneGLES3::geometry_instance_create(RID p_base) {
RS::InstanceType type = RSG::utilities->get_base_type(p_base);
ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr);
@@ -57,176 +52,36 @@ RendererSceneRender::GeometryInstance *RasterizerSceneGLES3::geometry_instance_c
ginstance->data->base = p_base;
ginstance->data->base_type = type;
- _geometry_instance_mark_dirty(ginstance);
+ ginstance->_mark_dirty();
return ginstance;
}
-void RasterizerSceneGLES3::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->data->skeleton = p_skeleton;
-
- _geometry_instance_mark_dirty(ginstance);
- ginstance->data->dirty_dependencies = true;
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->data->material_override = p_override;
-
- _geometry_instance_mark_dirty(ginstance);
- ginstance->data->dirty_dependencies = true;
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->data->material_overlay = p_overlay;
-
- _geometry_instance_mark_dirty(ginstance);
- ginstance->data->dirty_dependencies = true;
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->data->surface_materials = p_materials;
-
- _geometry_instance_mark_dirty(ginstance);
- ginstance->data->dirty_dependencies = true;
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ERR_FAIL_COND(!ginstance);
- ginstance->mesh_instance = p_mesh_instance;
-
- _geometry_instance_mark_dirty(ginstance);
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->transform = p_transform;
- ginstance->mirror = p_transform.basis.determinant() < 0;
- ginstance->data->aabb = p_aabb;
- ginstance->transformed_aabb = p_transformed_aabb;
-
- Vector3 model_scale_vec = p_transform.basis.get_scale_abs();
- // handle non uniform scale here
-
- float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z));
- float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z));
- ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9;
-
- ginstance->lod_model_scale = max_scale;
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->layer_mask = p_layer_mask;
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->lod_bias = p_lod_bias;
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->force_alpha = CLAMP(1.0 - p_transparency, 0, 1);
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->fade_near = p_enable_near;
- ginstance->fade_near_begin = p_near_begin;
- ginstance->fade_near_end = p_near_end;
- ginstance->fade_far = p_enable_far;
- ginstance->fade_far_begin = p_far_begin;
- ginstance->fade_far_end = p_far_end;
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->parent_fade_alpha = p_alpha;
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->data->use_baked_light = p_enable;
-
- _geometry_instance_mark_dirty(ginstance);
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->data->use_dynamic_gi = p_enable;
- _geometry_instance_mark_dirty(ginstance);
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->shader_parameters_offset = p_offset;
- _geometry_instance_mark_dirty(ginstance);
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
- ginstance->data->cast_double_sided_shadows = p_enable;
- _geometry_instance_mark_dirty(ginstance);
-}
-
uint32_t RasterizerSceneGLES3::geometry_instance_get_pair_mask() {
return (1 << RS::INSTANCE_LIGHT);
}
-void RasterizerSceneGLES3::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
-
+void RasterizerSceneGLES3::GeometryInstanceGLES3::pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) {
GLES3::Config *config = GLES3::Config::get_singleton();
- ginstance->omni_light_count = 0;
- ginstance->spot_light_count = 0;
- ginstance->omni_lights.clear();
- ginstance->spot_lights.clear();
+ omni_light_count = 0;
+ spot_light_count = 0;
+ omni_lights.clear();
+ spot_lights.clear();
for (uint32_t i = 0; i < p_light_instance_count; i++) {
- RS::LightType type = light_instance_get_type(p_light_instances[i]);
+ RS::LightType type = RasterizerSceneGLES3::get_singleton()->light_instance_get_type(p_light_instances[i]);
switch (type) {
case RS::LIGHT_OMNI: {
- if (ginstance->omni_light_count < (uint32_t)config->max_lights_per_object) {
- ginstance->omni_lights.push_back(p_light_instances[i]);
- ginstance->omni_light_count++;
+ if (omni_light_count < (uint32_t)config->max_lights_per_object) {
+ omni_lights.push_back(p_light_instances[i]);
+ omni_light_count++;
}
} break;
case RS::LIGHT_SPOT: {
- if (ginstance->spot_light_count < (uint32_t)config->max_lights_per_object) {
- ginstance->spot_lights.push_back(p_light_instances[i]);
- ginstance->spot_light_count++;
+ if (spot_light_count < (uint32_t)config->max_lights_per_object) {
+ spot_lights.push_back(p_light_instances[i]);
+ spot_light_count++;
}
} break;
default:
@@ -235,21 +90,7 @@ void RasterizerSceneGLES3::geometry_instance_pair_light_instances(GeometryInstan
}
}
-void RasterizerSceneGLES3::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) {
-}
-
-void RasterizerSceneGLES3::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) {
-}
-
-void RasterizerSceneGLES3::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) {
-}
-
-void RasterizerSceneGLES3::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- ERR_FAIL_COND(!ginstance);
-}
-
-void RasterizerSceneGLES3::geometry_instance_free(GeometryInstance *p_geometry_instance) {
+void RasterizerSceneGLES3::geometry_instance_free(RenderGeometryInstance *p_geometry_instance) {
GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
GeometryInstanceSurface *surf = ginstance->surface_caches;
@@ -262,24 +103,29 @@ void RasterizerSceneGLES3::geometry_instance_free(GeometryInstance *p_geometry_i
geometry_instance_alloc.free(ginstance);
}
-void RasterizerSceneGLES3::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) {
- GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
- if (ginstance->dirty_list_element.in_list()) {
+void RasterizerSceneGLES3::GeometryInstanceGLES3::_mark_dirty() {
+ if (dirty_list_element.in_list()) {
return;
}
//clear surface caches
- GeometryInstanceSurface *surf = ginstance->surface_caches;
+ GeometryInstanceSurface *surf = surface_caches;
while (surf) {
GeometryInstanceSurface *next = surf->next;
- geometry_instance_surface_alloc.free(surf);
+ RasterizerSceneGLES3::get_singleton()->geometry_instance_surface_alloc.free(surf);
surf = next;
}
- ginstance->surface_caches = nullptr;
+ surface_caches = nullptr;
- geometry_instance_dirty_list.add(&ginstance->dirty_list_element);
+ RasterizerSceneGLES3::get_singleton()->geometry_instance_dirty_list.add(&dirty_list_element);
+}
+
+void RasterizerSceneGLES3::GeometryInstanceGLES3::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {
+}
+
+void RasterizerSceneGLES3::GeometryInstanceGLES3::set_lightmap_capture(const Color *p_sh9) {
}
void RasterizerSceneGLES3::_update_dirty_geometry_instances() {
@@ -295,7 +141,7 @@ void RasterizerSceneGLES3::_geometry_instance_dependency_changed(Dependency::Dep
case Dependency::DEPENDENCY_CHANGED_PARTICLES:
case Dependency::DEPENDENCY_CHANGED_MULTIMESH:
case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: {
- static_cast<RasterizerSceneGLES3 *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
+ static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty();
} break;
case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata);
@@ -310,7 +156,7 @@ void RasterizerSceneGLES3::_geometry_instance_dependency_changed(Dependency::Dep
}
void RasterizerSceneGLES3::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {
- static_cast<RasterizerSceneGLES3 *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
+ static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty();
}
void RasterizerSceneGLES3::_geometry_instance_add_surface_with_material(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) {
@@ -467,7 +313,7 @@ void RasterizerSceneGLES3::_geometry_instance_add_surface(GeometryInstanceGLES3
}
}
-void RasterizerSceneGLES3::_geometry_instance_update(GeometryInstance *p_geometry_instance) {
+void RasterizerSceneGLES3::_geometry_instance_update(RenderGeometryInstance *p_geometry_instance) {
GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();
GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);
@@ -650,8 +496,7 @@ void RasterizerSceneGLES3::_update_dirty_skys() {
while (sky) {
if (sky->radiance == 0) {
- sky->mipmap_count = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8) + 1;
-
+ sky->mipmap_count = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8) - 1;
// Left uninitialized, will attach a texture at render time
glGenFramebuffers(1, &sky->radiance_framebuffer);
@@ -678,7 +523,7 @@ void RasterizerSceneGLES3::_update_dirty_skys() {
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, sky->mipmap_count);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, sky->mipmap_count - 1);
glGenTextures(1, &sky->raw_radiance);
glBindTexture(GL_TEXTURE_CUBE_MAP, sky->raw_radiance);
@@ -699,7 +544,8 @@ void RasterizerSceneGLES3::_update_dirty_skys() {
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, sky->mipmap_count);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, sky->mipmap_count - 1);
+
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}
@@ -715,13 +561,13 @@ void RasterizerSceneGLES3::_update_dirty_skys() {
dirty_sky_list = nullptr;
}
-void RasterizerSceneGLES3::_setup_sky(Environment *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) {
+void RasterizerSceneGLES3::_setup_sky(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) {
GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
- ERR_FAIL_COND(!p_env);
+ ERR_FAIL_COND(p_env.is_null());
GLES3::SkyMaterialData *material = nullptr;
- Sky *sky = sky_owner.get_or_null(p_env->sky);
+ Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env));
RID sky_material;
@@ -856,22 +702,23 @@ void RasterizerSceneGLES3::_setup_sky(Environment *p_env, RID p_render_buffers,
}
if (!sky->radiance) {
+ _invalidate_sky(sky);
_update_dirty_skys();
}
}
}
-void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform) {
+void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform) {
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
- ERR_FAIL_COND(!p_env);
+ ERR_FAIL_COND(p_env.is_null());
- Sky *sky = sky_owner.get_or_null(p_env->sky);
+ Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env));
ERR_FAIL_COND(!sky);
GLES3::SkyMaterialData *material_data = nullptr;
RID sky_material;
- RS::EnvironmentBG background = p_env->background;
+ RS::EnvironmentBG background = environment_get_background(p_env);
if (sky) {
ERR_FAIL_COND(!sky);
@@ -901,18 +748,18 @@ void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const CameraMatrix &p_p
ERR_FAIL_COND(!shader_data);
// Camera
- CameraMatrix camera;
+ Projection camera;
- if (p_env->sky_custom_fov) {
+ if (environment_get_sky_custom_fov(p_env)) {
float near_plane = p_projection.get_z_near();
float far_plane = p_projection.get_z_far();
float aspect = p_projection.get_aspect();
- camera.set_perspective(p_env->sky_custom_fov, aspect, near_plane, far_plane);
+ camera.set_perspective(environment_get_sky_custom_fov(p_env), aspect, near_plane, far_plane);
} else {
camera = p_projection;
}
- Basis sky_transform = p_env->sky_orientation;
+ Basis sky_transform = environment_get_sky_orientation(p_env);
sky_transform.invert();
sky_transform = p_transform.basis * sky_transform;
@@ -926,17 +773,17 @@ void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const CameraMatrix &p_p
glDrawArrays(GL_TRIANGLES, 0, 3);
}
-void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform) {
+void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform) {
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
- ERR_FAIL_COND(!p_env);
+ ERR_FAIL_COND(p_env.is_null());
- Sky *sky = sky_owner.get_or_null(p_env->sky);
+ Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env));
ERR_FAIL_COND(!sky);
GLES3::SkyMaterialData *material_data = nullptr;
RID sky_material;
- RS::EnvironmentBG background = p_env->background;
+ RS::EnvironmentBG background = environment_get_background(p_env);
if (sky) {
ERR_FAIL_COND(!sky);
@@ -990,7 +837,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const Camera
int max_processing_layer = sky->mipmap_count;
// Update radiance cubemap
- if (sky->reflection_dirty && (sky->processing_layer >= max_processing_layer || update_single_frame)) {
+ if (sky->reflection_dirty && (sky->processing_layer > max_processing_layer || update_single_frame)) {
static const Vector3 view_normals[6] = {
Vector3(+1, 0, 0),
Vector3(-1, 0, 0),
@@ -1008,9 +855,9 @@ void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const Camera
Vector3(0, -1, 0)
};
- CameraMatrix cm;
+ Projection cm;
cm.set_perspective(90, 1, 0.01, 10.0);
- CameraMatrix correction;
+ Projection correction;
correction.set_depth_correction(true);
cm = correction * cm;
@@ -1051,6 +898,45 @@ void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const Camera
}
}
+// Helper functions for IBL filtering
+
+Vector3 importance_sample_GGX(Vector2 xi, float roughness4) {
+ // Compute distribution direction
+ float phi = 2.0 * Math_PI * xi.x;
+ float cos_theta = sqrt((1.0 - xi.y) / (1.0 + (roughness4 - 1.0) * xi.y));
+ float sin_theta = sqrt(1.0 - cos_theta * cos_theta);
+
+ // Convert to spherical direction
+ Vector3 half_vector;
+ half_vector.x = sin_theta * cos(phi);
+ half_vector.y = sin_theta * sin(phi);
+ half_vector.z = cos_theta;
+
+ return half_vector;
+}
+
+float distribution_GGX(float NdotH, float roughness4) {
+ float NdotH2 = NdotH * NdotH;
+ float denom = (NdotH2 * (roughness4 - 1.0) + 1.0);
+ denom = Math_PI * denom * denom;
+
+ return roughness4 / denom;
+}
+
+float radical_inverse_vdC(uint32_t bits) {
+ bits = (bits << 16) | (bits >> 16);
+ bits = ((bits & 0x55555555) << 1) | ((bits & 0xAAAAAAAA) >> 1);
+ bits = ((bits & 0x33333333) << 2) | ((bits & 0xCCCCCCCC) >> 2);
+ bits = ((bits & 0x0F0F0F0F) << 4) | ((bits & 0xF0F0F0F0) >> 4);
+ bits = ((bits & 0x00FF00FF) << 8) | ((bits & 0xFF00FF00) >> 8);
+
+ return float(bits) * 2.3283064365386963e-10;
+}
+
+Vector2 hammersley(uint32_t i, uint32_t N) {
+ return Vector2(float(i) / float(N), radical_inverse_vdC(i));
+}
+
void RasterizerSceneGLES3::_filter_sky_radiance(Sky *p_sky, int p_base_layer) {
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
@@ -1062,27 +948,68 @@ void RasterizerSceneGLES3::_filter_sky_radiance(Sky *p_sky, int p_base_layer) {
if (p_base_layer == 0) {
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
+ // Copy over base layer without filtering.
mode = CubemapFilterShaderGLES3::MODE_COPY;
-
- //Copy over base layer
}
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, sky_globals.radical_inverse_vdc_cache_tex);
int size = p_sky->radiance_size >> p_base_layer;
glViewport(0, 0, size, size);
glBindVertexArray(sky_globals.screen_triangle_array);
material_storage->shaders.cubemap_filter_shader.version_bind_shader(scene_globals.cubemap_filter_shader_version, mode);
- material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::SAMPLE_COUNT, sky_globals.ggx_samples, scene_globals.cubemap_filter_shader_version, mode);
- material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, float(p_base_layer) / (p_sky->mipmap_count - 1.0), scene_globals.cubemap_filter_shader_version, mode);
- material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::FACE_SIZE, float(size), scene_globals.cubemap_filter_shader_version, mode);
+
+ if (p_base_layer > 0) {
+ const uint32_t sample_counts[4] = { 1, sky_globals.ggx_samples / 4, sky_globals.ggx_samples / 2, sky_globals.ggx_samples };
+ uint32_t sample_count = sample_counts[MIN(3, p_base_layer)];
+
+ float roughness = float(p_base_layer) / (p_sky->mipmap_count);
+ float roughness4 = roughness * roughness;
+ roughness4 *= roughness4;
+
+ float solid_angle_texel = 4.0 * Math_PI / float(6 * size * size);
+
+ LocalVector<float> sample_directions;
+ sample_directions.resize(4 * sample_count);
+
+ uint32_t index = 0;
+ float weight = 0.0;
+ for (uint32_t i = 0; i < sample_count; i++) {
+ Vector2 xi = hammersley(i, sample_count);
+ Vector3 dir = importance_sample_GGX(xi, roughness4);
+ Vector3 light_vec = (2.0 * dir.z * dir - Vector3(0.0, 0.0, 1.0));
+
+ if (light_vec.z < 0.0) {
+ continue;
+ }
+
+ sample_directions[index * 4] = light_vec.x;
+ sample_directions[index * 4 + 1] = light_vec.y;
+ sample_directions[index * 4 + 2] = light_vec.z;
+
+ float D = distribution_GGX(dir.z, roughness4);
+ float pdf = D * dir.z / (4.0 * dir.z) + 0.0001;
+
+ float solid_angle_sample = 1.0 / (float(sample_count) * pdf + 0.0001);
+
+ float mip_level = MAX(0.5 * log2(solid_angle_sample / solid_angle_texel) + float(MAX(1, p_base_layer - 3)), 1.0);
+
+ sample_directions[index * 4 + 3] = mip_level;
+ weight += light_vec.z;
+ index++;
+ }
+
+ glUniform4fv(material_storage->shaders.cubemap_filter_shader.version_get_uniform(CubemapFilterShaderGLES3::SAMPLE_DIRECTIONS_MIP, scene_globals.cubemap_filter_shader_version, mode), sample_count, sample_directions.ptr());
+ material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::WEIGHT, weight, scene_globals.cubemap_filter_shader_version, mode);
+ material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::SAMPLE_COUNT, index, scene_globals.cubemap_filter_shader_version, mode);
+ }
for (int i = 0; i < 6; i++) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, p_sky->radiance, p_base_layer);
#ifdef DEBUG_ENABLED
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ WARN_PRINT("Could not bind sky radiance face: " + itos(i) + ", status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));
+ }
#endif
material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::FACE_ID, i, scene_globals.cubemap_filter_shader_version, mode);
@@ -1099,84 +1026,6 @@ Ref<Image> RasterizerSceneGLES3::sky_bake_panorama(RID p_sky, float p_energy, bo
/* ENVIRONMENT API */
-RID RasterizerSceneGLES3::environment_allocate() {
- return environment_owner.allocate_rid();
-}
-
-void RasterizerSceneGLES3::environment_initialize(RID p_rid) {
- environment_owner.initialize_rid(p_rid);
-}
-
-void RasterizerSceneGLES3::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- env->background = p_bg;
-}
-
-void RasterizerSceneGLES3::environment_set_sky(RID p_env, RID p_sky) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- env->sky = p_sky;
-}
-
-void RasterizerSceneGLES3::environment_set_sky_custom_fov(RID p_env, float p_scale) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- env->sky_custom_fov = p_scale;
-}
-
-void RasterizerSceneGLES3::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- env->sky_orientation = p_orientation;
-}
-
-void RasterizerSceneGLES3::environment_set_bg_color(RID p_env, const Color &p_color) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- env->bg_color = p_color;
-}
-
-void RasterizerSceneGLES3::environment_set_bg_energy(RID p_env, float p_energy) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- env->bg_energy = p_energy;
-}
-
-void RasterizerSceneGLES3::environment_set_canvas_max_layer(RID p_env, int p_max_layer) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- env->canvas_max_layer = p_max_layer;
-}
-
-void RasterizerSceneGLES3::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- env->ambient_light = p_color;
- env->ambient_source = p_ambient;
- env->ambient_light_energy = p_energy;
- env->ambient_sky_contribution = p_sky_contribution;
- env->reflection_source = p_reflection_source;
-}
-
-void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7");
- env->glow_enabled = p_enable;
- env->glow_levels = p_levels;
- env->glow_intensity = p_intensity;
- env->glow_strength = p_strength;
- env->glow_mix = p_mix;
- env->glow_bloom = p_bloom_threshold;
- env->glow_blend_mode = p_blend_mode;
- env->glow_hdr_bleed_threshold = p_hdr_bleed_threshold;
- env->glow_hdr_bleed_scale = p_hdr_bleed_scale;
- env->glow_hdr_luminance_cap = p_hdr_luminance_cap;
- env->glow_map_strength = p_glow_map_strength;
- env->glow_map = p_glow_map;
-}
-
void RasterizerSceneGLES3::environment_glow_set_use_bicubic_upscale(bool p_enable) {
glow_bicubic_upscale = p_enable;
}
@@ -1185,35 +1034,15 @@ void RasterizerSceneGLES3::environment_glow_set_use_high_quality(bool p_enable)
glow_high_quality = p_enable;
}
-void RasterizerSceneGLES3::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) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- env->ssr_enabled = p_enable;
- env->ssr_max_steps = p_max_steps;
- env->ssr_fade_in = p_fade_int;
- env->ssr_fade_out = p_fade_out;
- env->ssr_depth_tolerance = p_depth_tolerance;
-}
-
void RasterizerSceneGLES3::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) {
}
-void RasterizerSceneGLES3::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) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
-}
-
void RasterizerSceneGLES3::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) {
}
-void RasterizerSceneGLES3::environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) {
-}
void RasterizerSceneGLES3::environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) {
}
-void RasterizerSceneGLES3::environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {
-}
-
void RasterizerSceneGLES3::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) {
}
@@ -1223,49 +1052,6 @@ void RasterizerSceneGLES3::environment_set_sdfgi_frames_to_converge(RS::Environm
void RasterizerSceneGLES3::environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) {
}
-void RasterizerSceneGLES3::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) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- env->exposure = p_exposure;
- env->tone_mapper = p_tone_mapper;
- if (!env->auto_exposure && p_auto_exposure) {
- env->auto_exposure_version = ++auto_exposure_counter;
- }
- env->auto_exposure = p_auto_exposure;
- env->white = p_white;
- env->min_luminance = p_min_luminance;
- env->max_luminance = p_max_luminance;
- env->auto_exp_speed = p_auto_exp_speed;
- env->auto_exp_scale = p_auto_exp_scale;
-}
-
-void RasterizerSceneGLES3::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) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- env->adjustments_enabled = p_enable;
- env->adjustments_brightness = p_brightness;
- env->adjustments_contrast = p_contrast;
- env->adjustments_saturation = p_saturation;
- env->use_1d_color_correction = p_use_1d_color_correction;
- env->color_correction = p_color_correction;
-}
-
-void RasterizerSceneGLES3::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) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND(!env);
- env->fog_enabled = p_enable;
- env->fog_light_color = p_light_color;
- env->fog_light_energy = p_light_energy;
- env->fog_sun_scatter = p_sun_scatter;
- env->fog_density = p_density;
- env->fog_height = p_height;
- env->fog_height_density = p_height_density;
- env->fog_aerial_perspective = p_aerial_perspective;
-}
-
-void RasterizerSceneGLES3::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) {
-}
-
void RasterizerSceneGLES3::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) {
}
@@ -1273,27 +1059,9 @@ void RasterizerSceneGLES3::environment_set_volumetric_fog_filter_active(bool p_e
}
Ref<Image> RasterizerSceneGLES3::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND_V(!env, Ref<Image>());
return Ref<Image>();
}
-bool RasterizerSceneGLES3::is_environment(RID p_env) const {
- return environment_owner.owns(p_env);
-}
-
-RS::EnvironmentBG RasterizerSceneGLES3::environment_get_background(RID p_env) const {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX);
- return env->background;
-}
-
-int RasterizerSceneGLES3::environment_get_canvas_max_layer(RID p_env) const {
- Environment *env = environment_owner.get_or_null(p_env);
- ERR_FAIL_COND_V(!env, 0);
- return env->canvas_max_layer;
-}
-
RID RasterizerSceneGLES3::camera_effects_allocate() {
return RID();
}
@@ -1313,10 +1081,10 @@ void RasterizerSceneGLES3::camera_effects_set_dof_blur(RID p_camera_effects, boo
void RasterizerSceneGLES3::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) {
}
-void RasterizerSceneGLES3::shadows_quality_set(RS::ShadowQuality p_quality) {
+void RasterizerSceneGLES3::positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) {
}
-void RasterizerSceneGLES3::directional_shadow_quality_set(RS::ShadowQuality p_quality) {
+void RasterizerSceneGLES3::directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) {
}
RID RasterizerSceneGLES3::light_instance_create(RID p_light) {
@@ -1345,7 +1113,7 @@ void RasterizerSceneGLES3::light_instance_set_aabb(RID p_light_instance, const A
light_instance->aabb = p_aabb;
}
-void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {
+void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {
}
void RasterizerSceneGLES3::light_instance_mark_visible(RID p_light_instance) {
@@ -1431,7 +1199,7 @@ bool RasterizerSceneGLES3::voxel_gi_needs_update(RID p_probe) const {
return false;
}
-void RasterizerSceneGLES3::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) {
+void RasterizerSceneGLES3::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) {
}
void RasterizerSceneGLES3::voxel_gi_set_quality(RS::VoxelGIQuality) {
@@ -1608,9 +1376,9 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
// Needs to be called after _setup_lights so that directional_light_count is accurate.
void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_pancake_shadows) {
- CameraMatrix correction;
+ Projection correction;
correction.set_depth_correction(p_flip_y);
- CameraMatrix projection = correction * p_render_data->cam_projection;
+ Projection projection = correction * p_render_data->cam_projection;
//store camera into ubo
GLES3::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix);
GLES3::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
@@ -1633,18 +1401,17 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da
scene_state.ubo.time = time;
if (is_environment(p_render_data->environment)) {
- Environment *env = environment_owner.get_or_null(p_render_data->environment);
- RS::EnvironmentBG env_bg = env->background;
- RS::EnvironmentAmbientSource ambient_src = env->ambient_source;
+ RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment);
+ RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment);
- float bg_energy = env->bg_energy;
+ float bg_energy = environment_get_bg_energy(p_render_data->environment);
scene_state.ubo.ambient_light_color_energy[3] = bg_energy;
- scene_state.ubo.ambient_color_sky_mix = env->ambient_sky_contribution;
+ scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment);
//ambient
if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) {
- Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : env->bg_color;
+ Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment);
color = color.srgb_to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy;
@@ -1653,14 +1420,14 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da
scene_state.ubo.use_ambient_light = true;
scene_state.ubo.use_ambient_cubemap = false;
} else {
- float energy = env->ambient_light_energy;
- Color color = env->ambient_light;
+ float energy = environment_get_ambient_light_energy(p_render_data->environment);
+ Color color = environment_get_ambient_light(p_render_data->environment);
color = color.srgb_to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * energy;
scene_state.ubo.ambient_light_color_energy[1] = color.g * energy;
scene_state.ubo.ambient_light_color_energy[2] = color.b * energy;
- Basis sky_transform = env->sky_orientation;
+ Basis sky_transform = environment_get_sky_orientation(p_render_data->environment);
sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis;
GLES3::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
@@ -1668,27 +1435,27 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da
}
//specular
- RS::EnvironmentReflectionSource ref_src = env->reflection_source;
+ RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_render_data->environment);
if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) {
scene_state.ubo.use_reflection_cubemap = true;
} else {
scene_state.ubo.use_reflection_cubemap = false;
}
- scene_state.ubo.fog_enabled = env->fog_enabled;
- scene_state.ubo.fog_density = env->fog_density;
- scene_state.ubo.fog_height = env->fog_height;
- scene_state.ubo.fog_height_density = env->fog_height_density;
- scene_state.ubo.fog_aerial_perspective = env->fog_aerial_perspective;
+ scene_state.ubo.fog_enabled = environment_get_fog_enabled(p_render_data->environment);
+ scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment);
+ scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment);
+ scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment);
+ scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment);
- Color fog_color = env->fog_light_color.srgb_to_linear();
- float fog_energy = env->fog_light_energy;
+ Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_to_linear();
+ float fog_energy = environment_get_fog_light_energy(p_render_data->environment);
scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy;
scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy;
scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy;
- scene_state.ubo.fog_sun_scatter = env->fog_sun_scatter;
+ scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment);
} else {
}
@@ -1883,7 +1650,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
light_data.specular_amount = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 2.0;
- light_data.shadow_enabled = false;
+ light_data.shadow_opacity = 0.0;
}
// TODO, to avoid stalls, should rotate between 3 buffers based on frame index.
@@ -1905,7 +1672,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
-void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) {
+void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) {
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
GLES3::Config *config = GLES3::Config::get_singleton();
RENDER_TIMESTAMP("Setup 3D Scene");
@@ -1970,7 +1737,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *
// Fill Light lists here
//////////
- GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_variables_get_uniform_buffer();
+ GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_uniforms_get_uniform_buffer();
glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer);
Color clear_color;
@@ -1980,8 +1747,6 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *
clear_color = texture_storage->get_default_clear_color();
}
- Environment *env = environment_owner.get_or_null(p_environment);
-
bool fb_cleared = false;
Size2i screen_size;
@@ -1991,10 +1756,10 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *
bool use_wireframe = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME;
SceneState::TonemapUBO tonemap_ubo;
- if (env) {
- tonemap_ubo.exposure = env->exposure;
- tonemap_ubo.white = env->white;
- tonemap_ubo.tonemapper = int32_t(env->tone_mapper);
+ if (render_data.environment.is_valid()) {
+ tonemap_ubo.exposure = environment_get_exposure(render_data.environment);
+ tonemap_ubo.white = environment_get_white(render_data.environment);
+ tonemap_ubo.tonemapper = int32_t(environment_get_tone_mapper(render_data.environment));
}
if (scene_state.tonemap_buffer == 0) {
@@ -2017,25 +1782,25 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black
- } else if (env) {
- RS::EnvironmentBG bg_mode = env->background;
- float bg_energy = env->bg_energy;
+ } else if (render_data.environment.is_valid()) {
+ RS::EnvironmentBG bg_mode = environment_get_background(render_data.environment);
+ float bg_energy = environment_get_bg_energy(render_data.environment);
switch (bg_mode) {
case RS::ENV_BG_CLEAR_COLOR: {
clear_color.r *= bg_energy;
clear_color.g *= bg_energy;
clear_color.b *= bg_energy;
- if (env->fog_enabled) {
+ if (environment_get_fog_enabled(render_data.environment)) {
draw_sky_fog_only = true;
GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color));
}
} break;
case RS::ENV_BG_COLOR: {
- clear_color = env->bg_color;
+ clear_color = environment_get_bg_color(render_data.environment);
clear_color.r *= bg_energy;
clear_color.g *= bg_energy;
clear_color.b *= bg_energy;
- if (env->fog_enabled) {
+ if (environment_get_fog_enabled(render_data.environment)) {
draw_sky_fog_only = true;
GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color));
}
@@ -2055,20 +1820,20 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *
}
}
// setup sky if used for ambient, reflections, or background
- if (draw_sky || draw_sky_fog_only || env->reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || env->ambient_source == RS::ENV_AMBIENT_SOURCE_SKY) {
+ if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(render_data.environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
RENDER_TIMESTAMP("Setup Sky");
- CameraMatrix projection = render_data.cam_projection;
+ Projection projection = render_data.cam_projection;
if (render_data.reflection_probe.is_valid()) {
- CameraMatrix correction;
+ Projection correction;
correction.set_depth_correction(true);
projection = correction * render_data.cam_projection;
}
- _setup_sky(env, p_render_buffers, *render_data.lights, projection, render_data.cam_transform, screen_size);
+ _setup_sky(render_data.environment, p_render_buffers, *render_data.lights, projection, render_data.cam_transform, screen_size);
- if (env->sky.is_valid()) {
- if (env->reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || env->ambient_source == RS::ENV_AMBIENT_SOURCE_SKY || (env->reflection_source == RS::ENV_REFLECTION_SOURCE_BG && env->background == RS::ENV_BG_SKY)) {
- _update_sky_radiance(env, projection, render_data.cam_transform);
+ if (environment_get_sky(render_data.environment).is_valid()) {
+ if (environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(render_data.environment) == RS::ENV_AMBIENT_SOURCE_SKY || (environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_BG && environment_get_background(render_data.environment) == RS::ENV_BG_SKY)) {
+ _update_sky_radiance(render_data.environment, projection, render_data.cam_transform);
}
} else {
// do not try to draw sky if invalid
@@ -2148,7 +1913,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *
spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_DIRECTIONAL_LIGHTS;
}
- if (!env || (env && !env->fog_enabled)) {
+ if (render_data.environment.is_null() || (render_data.environment.is_valid() && !environment_get_fog_enabled(render_data.environment))) {
spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG;
}
}
@@ -2172,7 +1937,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *
scene_state.current_depth_draw = GLES3::SceneShaderData::DEPTH_DRAW_DISABLED;
scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK;
- _draw_sky(env, render_data.cam_projection, render_data.cam_transform);
+ _draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform);
}
RENDER_TIMESTAMP("Render 3D Transparent Pass");
@@ -2221,11 +1986,10 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
}
if (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {
- Environment *env = environment_owner.get_or_null(p_render_data->environment);
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 2);
GLuint texture_to_bind = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_CUBEMAP_BLACK))->tex_id;
- if (env) {
- Sky *sky = sky_owner.get_or_null(env->sky);
+ if (p_render_data->environment.is_valid()) {
+ Sky *sky = sky_owner.get_or_null(environment_get_sky(p_render_data->environment));
if (sky && sky->radiance != 0) {
texture_to_bind = sky->radiance;
// base_spec_constant |= USE_RADIANCE_MAP;
@@ -2490,10 +2254,10 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
}
}
-void RasterizerSceneGLES3::render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
+void RasterizerSceneGLES3::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
}
-void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) {
+void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) {
}
void RasterizerSceneGLES3::set_time(double p_time, double p_step) {
@@ -2510,7 +2274,7 @@ RID RasterizerSceneGLES3::render_buffers_create() {
return render_buffers_owner.make_rid(rb);
}
-void RasterizerSceneGLES3::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) {
+void RasterizerSceneGLES3::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) {
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
@@ -2543,7 +2307,7 @@ void RasterizerSceneGLES3::render_buffers_configure(RID p_render_buffers, RID p_
glGenTextures(1, &rb->depth_texture);
glBindTexture(GL_TEXTURE_2D, rb->depth_texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -2624,8 +2388,8 @@ TypedArray<Image> RasterizerSceneGLES3::bake_render_uv2(RID p_base, const Vector
}
bool RasterizerSceneGLES3::free(RID p_rid) {
- if (environment_owner.owns(p_rid)) {
- environment_owner.free(p_rid);
+ if (is_environment(p_rid)) {
+ environment_free(p_rid);
} else if (sky_owner.owns(p_rid)) {
Sky *sky = sky_owner.get_or_null(p_rid);
ERR_FAIL_COND_V(!sky, false);
@@ -2661,6 +2425,8 @@ void RasterizerSceneGLES3::light_projectors_set_filter(RS::LightProjectorFilter
}
RasterizerSceneGLES3::RasterizerSceneGLES3() {
+ singleton = this;
+
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
GLES3::Config *config = GLES3::Config::get_singleton();
@@ -2705,7 +2471,7 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() {
{
String global_defines;
- global_defines += "#define MAX_GLOBAL_VARIABLES 256\n"; // TODO: this is arbitrary for now
+ global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now
global_defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(config->max_renderable_lights) + "\n";
global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n";
global_defines += "\n#define MAX_FORWARD_LIGHTS " + itos(config->max_lights_per_object) + "\n";
@@ -2744,13 +2510,17 @@ void fragment() {
sky_globals.ggx_samples = GLOBAL_GET("rendering/reflections/sky_reflections/ggx_samples");
String global_defines;
- global_defines += "#define MAX_GLOBAL_VARIABLES 256\n"; // TODO: this is arbitrary for now
+ global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now
global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(sky_globals.max_directional_lights) + "\n";
material_storage->shaders.sky_shader.initialize(global_defines);
sky_globals.shader_default_version = material_storage->shaders.sky_shader.version_create();
material_storage->shaders.sky_shader.version_bind_shader(sky_globals.shader_default_version, SkyShaderGLES3::MODE_BACKGROUND);
+ }
- material_storage->shaders.cubemap_filter_shader.initialize();
+ {
+ String global_defines;
+ global_defines += "\n#define MAX_SAMPLE_COUNT " + itos(sky_globals.ggx_samples) + "\n";
+ material_storage->shaders.cubemap_filter_shader.initialize(global_defines);
scene_globals.cubemap_filter_shader_version = material_storage->shaders.cubemap_filter_shader.version_create();
material_storage->shaders.cubemap_filter_shader.version_bind_shader(scene_globals.cubemap_filter_shader_version, CubemapFilterShaderGLES3::MODE_DEFAULT);
}
@@ -2820,36 +2590,6 @@ void sky() {
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
}
- // Radical inverse vdc cache texture used for cubemap filtering.
- {
- glGenTextures(1, &sky_globals.radical_inverse_vdc_cache_tex);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, sky_globals.radical_inverse_vdc_cache_tex);
-
- uint8_t radical_inverse[512];
-
- for (uint32_t i = 0; i < 512; i++) {
- uint32_t bits = i;
-
- bits = (bits << 16) | (bits >> 16);
- bits = ((bits & 0x55555555) << 1) | ((bits & 0xAAAAAAAA) >> 1);
- bits = ((bits & 0x33333333) << 2) | ((bits & 0xCCCCCCCC) >> 2);
- bits = ((bits & 0x0F0F0F0F) << 4) | ((bits & 0xF0F0F0F0) >> 4);
- bits = ((bits & 0x00FF00FF) << 8) | ((bits & 0xFF00FF00) >> 8);
-
- float value = float(bits) * 2.3283064365386963e-10;
- radical_inverse[i] = uint8_t(CLAMP(value * 255.0, 0, 255));
- }
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 512, 1, 0, GL_RED, GL_UNSIGNED_BYTE, radical_inverse);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //need this for proper sampling
-
- glBindTexture(GL_TEXTURE_2D, 0);
- }
#ifdef GLES_OVER_GL
glEnable(_EXT_TEXTURE_CUBE_MAP_SEAMLESS);
#endif
@@ -2886,6 +2626,8 @@ RasterizerSceneGLES3::~RasterizerSceneGLES3() {
glDeleteBuffers(1, &sky_globals.directional_light_buffer);
memdelete_arr(sky_globals.directional_lights);
memdelete_arr(sky_globals.last_frame_directional_lights);
+
+ singleton = nullptr;
}
#endif // GLES3_ENABLED
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 53b76011fe..a54d87a3a3 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -28,12 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RASTERIZER_SCENE_OPENGL_H
-#define RASTERIZER_SCENE_OPENGL_H
+#ifndef RASTERIZER_SCENE_GLES3_H
+#define RASTERIZER_SCENE_GLES3_H
#ifdef GLES3_ENABLED
-#include "core/math/camera_matrix.h"
+#include "core/math/projection.h"
#include "core/templates/paged_allocator.h"
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
@@ -96,18 +96,18 @@ struct RenderDataGLES3 {
Transform3D cam_transform = Transform3D();
Transform3D inv_cam_transform = Transform3D();
- CameraMatrix cam_projection = CameraMatrix();
+ Projection cam_projection = Projection();
bool cam_orthogonal = false;
// For stereo rendering
uint32_t view_count = 1;
Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS];
- CameraMatrix view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
+ Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
float z_near = 0.0;
float z_far = 0.0;
- const PagedArray<RendererSceneRender::GeometryInstance *> *instances = nullptr;
+ const PagedArray<RenderGeometryInstance *> *instances = nullptr;
const PagedArray<RID> *lights = nullptr;
const PagedArray<RID> *reflection_probes = nullptr;
RID environment = RID();
@@ -165,7 +165,7 @@ private:
float inv_spot_attenuation;
float cos_spot_angle;
float specular_amount;
- uint32_t shadow_enabled;
+ float shadow_opacity;
};
static_assert(sizeof(LightData) % 16 == 0, "LightData size must be a multiple of 16 bytes");
@@ -210,7 +210,7 @@ private:
mutable RID_Owner<LightInstance> light_instance_owner;
- struct GeometryInstanceGLES3;
+ class GeometryInstanceGLES3;
// Cached data for drawing surfaces
struct GeometryInstanceSurface {
@@ -265,33 +265,16 @@ private:
GeometryInstanceGLES3 *owner = nullptr;
};
- struct GeometryInstanceGLES3 : public GeometryInstance {
+ class GeometryInstanceGLES3 : public RenderGeometryInstanceBase {
+ public:
//used during rendering
- bool mirror = false;
- bool non_uniform_scale = false;
- float lod_bias = 0.0;
- float lod_model_scale = 1.0;
- AABB transformed_aabb; //needed for LOD
- float depth = 0;
- uint32_t flags_cache = 0;
bool store_transform_cache = true;
- int32_t shader_parameters_offset = -1;
- uint32_t layer_mask = 1;
int32_t instance_count = 0;
- RID mesh_instance;
bool can_sdfgi = false;
bool using_projectors = false;
bool using_softshadows = false;
- bool fade_near = false;
- float fade_near_begin = 0;
- float fade_near_end = 0;
- bool fade_far = false;
- float fade_far_begin = 0;
- float fade_far_end = 0;
- float force_alpha = 1.0;
- float parent_fade_alpha = 1.0;
uint32_t omni_light_count = 0;
LocalVector<RID> omni_lights;
@@ -301,35 +284,22 @@ private:
LocalVector<uint32_t> spot_light_gl_cache;
//used during setup
- uint32_t base_flags = 0;
- Transform3D transform;
GeometryInstanceSurface *surface_caches = nullptr;
SelfList<GeometryInstanceGLES3> dirty_list_element;
- struct Data {
- //data used less often goes into regular heap
- RID base;
- RS::InstanceType base_type;
-
- RID skeleton;
- Vector<RID> surface_materials;
- RID material_override;
- RID material_overlay;
- AABB aabb;
-
- bool use_dynamic_gi = false;
- bool use_baked_light = false;
- bool cast_double_sided_shadows = false;
- bool mirror = false;
- bool dirty_dependencies = false;
+ GeometryInstanceGLES3() :
+ dirty_list_element(this) {}
- DependencyTracker dependency_tracker;
- };
+ virtual void _mark_dirty() override;
+ virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
+ virtual void set_lightmap_capture(const Color *p_sh9) override;
- Data *data = nullptr;
+ virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override;
+ virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {}
+ virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override {}
+ virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {}
- GeometryInstanceGLES3() :
- dirty_list_element(this) {}
+ virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override {}
};
enum {
@@ -357,8 +327,7 @@ private:
void _geometry_instance_add_surface_with_material(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
void _geometry_instance_add_surface_with_material_chain(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, RID p_mat_src, RID p_mesh);
void _geometry_instance_add_surface(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, RID p_material, RID p_mesh);
- void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance);
- void _geometry_instance_update(GeometryInstance *p_geometry_instance);
+ void _geometry_instance_update(RenderGeometryInstance *p_geometry_instance);
void _update_dirty_geometry_instances();
struct SceneState {
@@ -570,88 +539,8 @@ protected:
/* Environment */
- struct Environment {
- // BG
- RS::EnvironmentBG background = RS::ENV_BG_CLEAR_COLOR;
- RID sky;
- float sky_custom_fov = 0.0;
- Basis sky_orientation;
- Color bg_color;
- float bg_energy = 1.0;
- int canvas_max_layer = 0;
- RS::EnvironmentAmbientSource ambient_source = RS::ENV_AMBIENT_SOURCE_BG;
- Color ambient_light;
- float ambient_light_energy = 1.0;
- float ambient_sky_contribution = 1.0;
- RS::EnvironmentReflectionSource reflection_source = RS::ENV_REFLECTION_SOURCE_BG;
- Color ao_color;
-
- /// Tonemap
-
- RS::EnvironmentToneMapper tone_mapper;
- float exposure = 1.0;
- float white = 1.0;
- bool auto_exposure = false;
- float min_luminance = 0.2;
- float max_luminance = 8.0;
- float auto_exp_speed = 0.2;
- float auto_exp_scale = 0.5;
- uint64_t auto_exposure_version = 0;
-
- // Fog
- bool fog_enabled = false;
- Color fog_light_color = Color(0.5, 0.6, 0.7);
- float fog_light_energy = 1.0;
- float fog_sun_scatter = 0.0;
- float fog_density = 0.001;
- float fog_height = 0.0;
- float fog_height_density = 0.0; //can be negative to invert effect
- float fog_aerial_perspective = 0.0;
-
- /// Glow
- bool glow_enabled = false;
- Vector<float> glow_levels;
- float glow_intensity = 0.8;
- float glow_strength = 1.0;
- float glow_bloom = 0.0;
- float glow_mix = 0.01;
- RS::EnvironmentGlowBlendMode glow_blend_mode = RS::ENV_GLOW_BLEND_MODE_SOFTLIGHT;
- float glow_hdr_bleed_threshold = 1.0;
- float glow_hdr_luminance_cap = 12.0;
- float glow_hdr_bleed_scale = 2.0;
- float glow_map_strength = 1.0;
- RID glow_map = RID();
-
- /// SSAO
- bool ssao_enabled = false;
- float ssao_radius = 1.0;
- float ssao_intensity = 2.0;
- float ssao_power = 1.5;
- float ssao_detail = 0.5;
- float ssao_horizon = 0.06;
- float ssao_sharpness = 0.98;
- float ssao_direct_light_affect = 0.0;
- float ssao_ao_channel_affect = 0.0;
-
- /// SSR
- bool ssr_enabled = false;
- int ssr_max_steps = 64;
- float ssr_fade_in = 0.15;
- float ssr_fade_out = 2.0;
- float ssr_depth_tolerance = 0.2;
-
- /// Adjustments
- bool adjustments_enabled = false;
- float adjustments_brightness = 1.0f;
- float adjustments_contrast = 1.0f;
- float adjustments_saturation = 1.0f;
- bool use_1d_color_correction = false;
- RID color_correction = RID();
- };
-
RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM;
bool ssao_half_size = false;
- bool ssao_using_half_size = false;
float ssao_adaptive_target = 0.5;
int ssao_blur_passes = 2;
float ssao_fadeout_from = 50.0;
@@ -661,10 +550,6 @@ protected:
bool glow_high_quality = false;
RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGHNESS_QUALITY_LOW;
- static uint64_t auto_exposure_counter;
-
- mutable RID_Owner<Environment, true> environment_owner;
-
/* Sky */
struct SkyGlobals {
@@ -730,44 +615,23 @@ protected:
Sky *dirty_sky_list = nullptr;
mutable RID_Owner<Sky, true> sky_owner;
- void _setup_sky(Environment *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size);
+ void _setup_sky(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size);
void _invalidate_sky(Sky *p_sky);
void _update_dirty_skys();
- void _update_sky_radiance(Environment *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform);
+ void _update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform);
void _filter_sky_radiance(Sky *p_sky, int p_base_layer);
- void _draw_sky(Environment *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform);
+ void _draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform);
void _free_sky_data(Sky *p_sky);
public:
+ static RasterizerSceneGLES3 *get_singleton() { return singleton; }
+
RasterizerCanvasGLES3 *canvas;
- GeometryInstance *geometry_instance_create(RID p_base) override;
- void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override;
- void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override;
- void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) override;
- void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) override;
- void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override;
- void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override;
- void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override;
- void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override;
- void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override;
- void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override;
- void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override;
- void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override;
- void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override;
- void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
- void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override;
- void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override;
- void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override;
+ RenderGeometryInstance *geometry_instance_create(RID p_base) override;
+ void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override;
uint32_t geometry_instance_get_pair_mask() override;
- void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override;
- void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override;
- void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override;
- void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override;
- void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override;
-
- void geometry_instance_free(GeometryInstance *p_geometry_instance) override;
/* SHADOW ATLAS API */
@@ -804,49 +668,24 @@ public:
/* ENVIRONMENT API */
- RID environment_allocate() override;
- void environment_initialize(RID p_rid) override;
- void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) override;
- void environment_set_sky(RID p_env, RID p_sky) override;
- void environment_set_sky_custom_fov(RID p_env, float p_scale) override;
- void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) override;
- void environment_set_bg_color(RID p_env, const Color &p_color) override;
- void environment_set_bg_energy(RID p_env, float p_energy) override;
- void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override;
- void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) override;
-
- void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) override;
void environment_glow_set_use_bicubic_upscale(bool p_enable) override;
void environment_glow_set_use_high_quality(bool p_enable) override;
- 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_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_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) override;
- void environment_set_ssil_quality(RS::EnvironmentSSILQuality 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, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override;
+ void environment_set_ssil_quality(RS::EnvironmentSSILQuality 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_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override;
void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override;
void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) override;
- 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, 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, float p_aerial_perspective) override;
- void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) 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;
Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override;
- bool is_environment(RID p_env) const override;
- RS::EnvironmentBG environment_get_background(RID p_env) const override;
- int environment_get_canvas_max_layer(RID p_env) const override;
-
RID camera_effects_allocate() override;
void camera_effects_initialize(RID p_rid) override;
void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override;
@@ -855,13 +694,13 @@ public:
void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) override;
void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) override;
- void shadows_quality_set(RS::ShadowQuality p_quality) override;
- void directional_shadow_quality_set(RS::ShadowQuality p_quality) override;
+ void positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override;
+ void directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override;
RID light_instance_create(RID p_light) override;
void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override;
void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override;
- void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override;
+ void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override;
void light_instance_mark_visible(RID p_light_instance) override;
_FORCE_INLINE_ RS::LightType light_instance_get_type(RID p_light_instance) {
@@ -900,13 +739,13 @@ public:
RID voxel_gi_instance_create(RID p_voxel_gi) override;
void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override;
bool voxel_gi_needs_update(RID p_probe) const override;
- void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override;
+ void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) override;
void voxel_gi_set_quality(RS::VoxelGIQuality) override;
- void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override;
- void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
- void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override;
+ void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override;
+ void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
+ void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override;
void set_scene_pass(uint64_t p_pass) override {
scene_pass = p_pass;
@@ -923,7 +762,7 @@ public:
}
RID render_buffers_create() override;
- void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override;
+ void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override;
void gi_set_use_half_resolution(bool p_enable) override;
void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override;
@@ -941,11 +780,10 @@ public:
void decals_set_filter(RS::DecalFilter p_filter) override;
void light_projectors_set_filter(RS::LightProjectorFilter p_filter) override;
- static RasterizerSceneGLES3 *get_singleton();
RasterizerSceneGLES3();
~RasterizerSceneGLES3();
};
#endif // GLES3_ENABLED
-#endif // RASTERIZER_SCENE_OPENGL_H
+#endif // RASTERIZER_SCENE_GLES3_H
diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h
index e1385669cd..2b72549b5b 100644
--- a/drivers/gles3/shader_gles3.h
+++ b/drivers/gles3/shader_gles3.h
@@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SHADER_OPENGL_H
-#define SHADER_OPENGL_H
+#ifndef SHADER_GLES3_H
+#define SHADER_GLES3_H
-#include "core/math/camera_matrix.h"
+#include "core/math/projection.h"
#include "core/os/mutex.h"
#include "core/string/string_builder.h"
#include "core/templates/hash_map.h"
@@ -248,5 +248,6 @@ public:
virtual ~ShaderGLES3();
};
-#endif // SHADER_OPENGL_H
-#endif
+#endif // GLES3_ENABLED
+
+#endif // SHADER_GLES3_H
diff --git a/drivers/gles3/shaders/canvas_uniforms_inc.glsl b/drivers/gles3/shaders/canvas_uniforms_inc.glsl
index e08a15e59d..852dccf415 100644
--- a/drivers/gles3/shaders/canvas_uniforms_inc.glsl
+++ b/drivers/gles3/shaders/canvas_uniforms_inc.glsl
@@ -58,8 +58,8 @@ struct DrawData {
uvec4 lights;
};
-layout(std140) uniform GlobalVariableData { //ubo:1
- vec4 global_variables[MAX_GLOBAL_VARIABLES];
+layout(std140) uniform GlobalShaderUniformData { //ubo:1
+ vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS];
};
layout(std140) uniform CanvasData { //ubo:0
diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl
index ebf0c08ec4..88464876f1 100644
--- a/drivers/gles3/shaders/cubemap_filter.glsl
+++ b/drivers/gles3/shaders/cubemap_filter.glsl
@@ -29,19 +29,15 @@ uniform samplerCube source_cube; //texunit:0
/* clang-format on */
uniform int face_id;
-uniform float roughness;
-uniform float face_size;
-uniform int sample_count;
-//Todo, profile on low end hardware to see if fixed loop is faster
-#ifdef USE_FIXED_SAMPLES
-#define FIXED_SAMPLE_COUNT 32
+#ifndef MODE_DIRECT_WRITE
+uniform int sample_count;
+uniform vec4 sample_directions_mip[MAX_SAMPLE_COUNT];
+uniform float weight;
#endif
in highp vec2 uv_interp;
-uniform sampler2D radical_inverse_vdc_cache; // texunit:1
-
layout(location = 0) out vec4 frag_color;
#define M_PI 3.14159265359
@@ -93,48 +89,6 @@ vec3 texelCoordToVec(vec2 uv, int faceID) {
return normalize(result);
}
-vec3 ImportanceSampleGGX(vec2 xi, float roughness4) {
- // Compute distribution direction
- float Phi = 2.0 * M_PI * xi.x;
- float CosTheta = sqrt((1.0 - xi.y) / (1.0 + (roughness4 - 1.0) * xi.y));
- float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
-
- // Convert to spherical direction
- vec3 H;
- H.x = SinTheta * cos(Phi);
- H.y = SinTheta * sin(Phi);
- H.z = CosTheta;
-
- return H;
-}
-
-float DistributionGGX(float NdotH, float roughness4) {
- float NdotH2 = NdotH * NdotH;
- float denom = (NdotH2 * (roughness4 - 1.0) + 1.0);
- denom = M_PI * denom * denom;
-
- return roughness4 / denom;
-}
-
-// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
-float GGX(float NdotV, float a) {
- float k = a / 2.0;
- return NdotV / (NdotV * (1.0 - k) + k);
-}
-
-// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
-float G_Smith(float a, float nDotV, float nDotL) {
- return GGX(nDotL, a * a) * GGX(nDotV, a * a);
-}
-
-float radical_inverse_VdC(int i) {
- return texture(radical_inverse_vdc_cache, vec2(float(i) / 512.0, 0.0)).x;
-}
-
-vec2 Hammersley(int i, int N) {
- return vec2(float(i) / float(N), radical_inverse_VdC(i));
-}
-
void main() {
vec3 color = vec3(0.0);
vec2 uv = uv_interp;
@@ -145,9 +99,6 @@ void main() {
#else
vec4 sum = vec4(0.0);
- float solid_angle_texel = 4.0 * M_PI / (6.0 * face_size * face_size);
- float roughness2 = roughness * roughness;
- float roughness4 = roughness2 * roughness2;
vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
mat3 T;
T[0] = normalize(cross(UpVector, N));
@@ -155,32 +106,15 @@ void main() {
T[2] = N;
for (int sample_num = 0; sample_num < sample_count; sample_num++) {
- vec2 xi = Hammersley(sample_num, sample_count);
-
- vec3 H = T * ImportanceSampleGGX(xi, roughness4);
- float NdotH = dot(N, H);
- vec3 L = (2.0 * NdotH * H - N);
-
- float NdotL = clamp(dot(N, L), 0.0, 1.0);
-
- if (NdotL > 0.0) {
- float D = DistributionGGX(NdotH, roughness4);
- float pdf = D * NdotH / (4.0 * NdotH) + 0.0001;
-
- float solid_angle_sample = 1.0 / (float(sample_count) * pdf + 0.0001);
-
- float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(solid_angle_sample / solid_angle_texel);
-
- vec3 val = textureLod(source_cube, L, mipLevel).rgb;
- // Mix using linear
- val = srgb_to_linear(val);
-
- sum.rgb += val * NdotL;
- sum.a += NdotL;
- }
+ vec4 sample_direction_mip = sample_directions_mip[sample_num];
+ vec3 L = T * sample_direction_mip.xyz;
+ vec3 val = textureLod(source_cube, L, sample_direction_mip.w).rgb;
+ // Mix using linear
+ val = srgb_to_linear(val);
+ sum.rgb += val * sample_direction_mip.z;
}
- sum /= sum.a;
+ sum /= weight;
sum.rgb = linear_to_srgb(sum.rgb);
frag_color = vec4(sum.rgb, 1.0);
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 4f2be8bf60..84daf839e9 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -104,8 +104,8 @@ layout(location = 14) in highp vec4 instance_xform2;
layout(location = 15) in highp uvec4 instance_color_custom_data; // Color packed into xy, Custom data into zw.
#endif
-layout(std140) uniform GlobalVariableData { //ubo:1
- vec4 global_variables[MAX_GLOBAL_VARIABLES];
+layout(std140) uniform GlobalShaderUniformData { //ubo:1
+ vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS];
};
layout(std140) uniform SceneData { // ubo:2
@@ -399,8 +399,8 @@ uniform samplerCube radiance_map; // texunit:-2
#endif
-layout(std140) uniform GlobalVariableData { //ubo:1
- vec4 global_variables[MAX_GLOBAL_VARIABLES];
+layout(std140) uniform GlobalShaderUniformData { //ubo:1
+ vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS];
};
/* Material Uniforms */
@@ -495,7 +495,7 @@ struct LightData { //this structure needs to be as packed as possible
mediump float cone_attenuation;
mediump float cone_angle;
mediump float specular_amount;
- bool shadow_enabled;
+ mediump float shadow_opacity;
};
#ifndef DISABLE_LIGHT_OMNI
layout(std140) uniform OmniLightData { // ubo:5
@@ -686,7 +686,10 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte
#endif // LIGHT_ANISOTROPY_USED
// F
float cLdotH5 = SchlickFresnel(cLdotH);
- vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0);
+ // Calculate Fresnel using cheap approximate specular occlusion term from Filament:
+ // https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion
+ float f90 = clamp(50.0 * f0.g, 0.0, 1.0);
+ vec3 F = f0 + (f90 - f0) * cLdotH5;
vec3 specular_brdf_NL = cNdotL * D * F * G;
@@ -751,7 +754,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f
if (omni_lights[idx].size > 0.0) {
float t = omni_lights[idx].size / max(0.001, light_length);
- size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t));
+ size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t));
}
light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, omni_attenuation, f0, roughness, metallic, omni_lights[idx].specular_amount, albedo, alpha,
@@ -800,7 +803,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 f
if (spot_lights[idx].size > 0.0) {
float t = spot_lights[idx].size / max(0.001, light_length);
- size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t));
+ size_A = max(0.0, 1.0 - 1.0 / sqrt(1.0 + t * t));
}
light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color, spot_attenuation, f0, roughness, metallic, spot_lights[idx].specular_amount, albedo, alpha,
@@ -1049,6 +1052,7 @@ void main() {
#else
vec3 ref_vec = reflect(-view, normal);
#endif
+ ref_vec = mix(ref_vec, normal, roughness * roughness);
float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
ref_vec = scene_data.radiance_inverse_xform * ref_vec;
specular_light = textureLod(radiance_map, ref_vec, roughness * RADIANCE_MAX_LOD).rgb;
@@ -1107,7 +1111,7 @@ void main() {
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
- specular_light *= env.x * f0 + env.y;
+ specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, 0.0, 1.0);
#endif
}
diff --git a/drivers/gles3/shaders/sky.glsl b/drivers/gles3/shaders/sky.glsl
index 50ab38bc31..eb1befe38e 100644
--- a/drivers/gles3/shaders/sky.glsl
+++ b/drivers/gles3/shaders/sky.glsl
@@ -42,8 +42,8 @@ uniform sampler2D half_res; //texunit:-2
uniform sampler2D quarter_res; //texunit:-3
#endif
-layout(std140) uniform GlobalVariableData { //ubo:1
- vec4 global_variables[MAX_GLOBAL_VARIABLES];
+layout(std140) uniform GlobalShaderUniformData { //ubo:1
+ vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS];
};
struct DirectionalLightData {
diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp
index f2809734a9..30b5919526 100644
--- a/drivers/gles3/storage/config.cpp
+++ b/drivers/gles3/storage/config.cpp
@@ -64,7 +64,14 @@ Config::Config() {
#else
float_texture_supported = extensions.has("GL_ARB_texture_float") || extensions.has("GL_OES_texture_float");
etc2_supported = true;
+#if defined(ANDROID_ENABLED) || defined(IPHONE_ENABLED)
+ // Some Android devices report support for S3TC but we don't expect that and don't export the textures.
+ // This could be fixed but so few devices support it that it doesn't seem useful (and makes bigger APKs).
+ // For good measure we do the same hack for iOS, just in case.
+ s3tc_supported = false;
+#else
s3tc_supported = extensions.has("GL_EXT_texture_compression_dxt1") || extensions.has("GL_EXT_texture_compression_s3tc") || extensions.has("WEBGL_compressed_texture_s3tc");
+#endif
rgtc_supported = extensions.has("GL_EXT_texture_compression_rgtc") || extensions.has("GL_ARB_texture_compression_rgtc") || extensions.has("EXT_texture_compression_rgtc");
#endif
diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h
index db76aa79fb..b83c83f425 100644
--- a/drivers/gles3/storage/config.h
+++ b/drivers/gles3/storage/config.h
@@ -90,4 +90,4 @@ public:
#endif // GLES3_ENABLED
-#endif // !CONFIG_GLES3_H
+#endif // CONFIG_GLES3_H
diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp
index 22578c9e91..2e4bfdc15b 100644
--- a/drivers/gles3/storage/light_storage.cpp
+++ b/drivers/gles3/storage/light_storage.cpp
@@ -70,6 +70,7 @@ void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) {
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8;
light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0;
+ light.param[RS::LIGHT_PARAM_SHADOW_OPACITY] = 1.0;
light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0;
light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0;
diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h
index 575ab93eab..857a0261fa 100644
--- a/drivers/gles3/storage/light_storage.h
+++ b/drivers/gles3/storage/light_storage.h
@@ -342,6 +342,6 @@ public:
} // namespace GLES3
-#endif // !GLES3_ENABLED
+#endif // GLES3_ENABLED
-#endif // !LIGHT_STORAGE_GLES3_H
+#endif // LIGHT_STORAGE_GLES3_H
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index aa19826953..26441fc726 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -176,75 +176,86 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
}
} break;
case ShaderLanguage::TYPE_IVEC2: {
- Vector<int> iv = value;
- int s = iv.size();
int32_t *gui = (int32_t *)data;
+ if (p_array_size > 0) {
+ Vector<int> iv = value;
+ int s = iv.size();
+ int count = 2 * p_array_size;
- if (p_array_size <= 0) {
- p_array_size = 1;
- }
- int count = 2 * p_array_size;
-
- const int *r = iv.ptr();
- for (int i = 0, j = 0; i < count; i += 2, j += 4) {
- if (i < s) {
- gui[j] = r[i];
- gui[j + 1] = r[i + 1];
- } else {
- gui[j] = 0;
- gui[j + 1] = 0;
+ const int *r = iv.ptr();
+ for (int i = 0, j = 0; i < count; i += 2, j += 4) {
+ if (i < s) {
+ gui[j] = r[i];
+ gui[j + 1] = r[i + 1];
+ } else {
+ gui[j] = 0;
+ gui[j + 1] = 0;
+ }
+ gui[j + 2] = 0; // ignored
+ gui[j + 3] = 0; // ignored
}
- gui[j + 2] = 0; // ignored
- gui[j + 3] = 0; // ignored
+ } else {
+ Vector2i v = value;
+ gui[0] = v.x;
+ gui[1] = v.y;
}
} break;
case ShaderLanguage::TYPE_IVEC3: {
- Vector<int> iv = value;
- int s = iv.size();
int32_t *gui = (int32_t *)data;
- if (p_array_size <= 0) {
- p_array_size = 1;
- }
- int count = 3 * p_array_size;
-
- const int *r = iv.ptr();
- for (int i = 0, j = 0; i < count; i += 3, j += 4) {
- if (i < s) {
- gui[j] = r[i];
- gui[j + 1] = r[i + 1];
- gui[j + 2] = r[i + 2];
- } else {
- gui[j] = 0;
- gui[j + 1] = 0;
- gui[j + 2] = 0;
+ if (p_array_size > 0) {
+ Vector<int> iv = value;
+ int s = iv.size();
+ int count = 3 * p_array_size;
+
+ const int *r = iv.ptr();
+ for (int i = 0, j = 0; i < count; i += 3, j += 4) {
+ if (i < s) {
+ gui[j] = r[i];
+ gui[j + 1] = r[i + 1];
+ gui[j + 2] = r[i + 2];
+ } else {
+ gui[j] = 0;
+ gui[j + 1] = 0;
+ gui[j + 2] = 0;
+ }
+ gui[j + 3] = 0; // ignored
}
- gui[j + 3] = 0; // ignored
+ } else {
+ Vector3i v = value;
+ gui[0] = v.x;
+ gui[1] = v.y;
+ gui[2] = v.z;
}
} break;
case ShaderLanguage::TYPE_IVEC4: {
- Vector<int> iv = value;
- int s = iv.size();
int32_t *gui = (int32_t *)data;
- if (p_array_size <= 0) {
- p_array_size = 1;
- }
- int count = 4 * p_array_size;
-
- const int *r = iv.ptr();
- for (int i = 0; i < count; i += 4) {
- if (i < s) {
- gui[i] = r[i];
- gui[i + 1] = r[i + 1];
- gui[i + 2] = r[i + 2];
- gui[i + 3] = r[i + 3];
- } else {
- gui[i] = 0;
- gui[i + 1] = 0;
- gui[i + 2] = 0;
- gui[i + 3] = 0;
+ if (p_array_size > 0) {
+ Vector<int> iv = value;
+ int s = iv.size();
+ int count = 4 * p_array_size;
+
+ const int *r = iv.ptr();
+ for (int i = 0; i < count; i += 4) {
+ if (i < s) {
+ gui[i] = r[i];
+ gui[i + 1] = r[i + 1];
+ gui[i + 2] = r[i + 2];
+ gui[i + 3] = r[i + 3];
+ } else {
+ gui[i] = 0;
+ gui[i + 1] = 0;
+ gui[i + 2] = 0;
+ gui[i + 3] = 0;
+ }
}
+ } else {
+ Vector4i v = value;
+ gui[0] = v.x;
+ gui[1] = v.y;
+ gui[2] = v.z;
+ gui[3] = v.w;
}
} break;
case ShaderLanguage::TYPE_UINT: {
@@ -271,75 +282,86 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
}
} break;
case ShaderLanguage::TYPE_UVEC2: {
- Vector<int> iv = value;
- int s = iv.size();
uint32_t *gui = (uint32_t *)data;
+ if (p_array_size > 0) {
+ Vector<int> iv = value;
+ int s = iv.size();
+ int count = 2 * p_array_size;
- if (p_array_size <= 0) {
- p_array_size = 1;
- }
- int count = 2 * p_array_size;
-
- const int *r = iv.ptr();
- for (int i = 0, j = 0; i < count; i += 2, j += 4) {
- if (i < s) {
- gui[j] = r[i];
- gui[j + 1] = r[i + 1];
- } else {
- gui[j] = 0;
- gui[j + 1] = 0;
+ const int *r = iv.ptr();
+ for (int i = 0, j = 0; i < count; i += 2, j += 4) {
+ if (i < s) {
+ gui[j] = r[i];
+ gui[j + 1] = r[i + 1];
+ } else {
+ gui[j] = 0;
+ gui[j + 1] = 0;
+ }
+ gui[j + 2] = 0; // ignored
+ gui[j + 3] = 0; // ignored
}
- gui[j + 2] = 0; // ignored
- gui[j + 3] = 0; // ignored
+ } else {
+ Vector2i v = value;
+ gui[0] = v.x;
+ gui[1] = v.y;
}
} break;
case ShaderLanguage::TYPE_UVEC3: {
- Vector<int> iv = value;
- int s = iv.size();
uint32_t *gui = (uint32_t *)data;
- if (p_array_size <= 0) {
- p_array_size = 1;
- }
- int count = 3 * p_array_size;
-
- const int *r = iv.ptr();
- for (int i = 0, j = 0; i < count; i += 3, j += 4) {
- if (i < s) {
- gui[j] = r[i];
- gui[j + 1] = r[i + 1];
- gui[j + 2] = r[i + 2];
- } else {
- gui[j] = 0;
- gui[j + 1] = 0;
- gui[j + 2] = 0;
+ if (p_array_size > 0) {
+ Vector<int> iv = value;
+ int s = iv.size();
+ int count = 3 * p_array_size;
+
+ const int *r = iv.ptr();
+ for (int i = 0, j = 0; i < count; i += 3, j += 4) {
+ if (i < s) {
+ gui[j] = r[i];
+ gui[j + 1] = r[i + 1];
+ gui[j + 2] = r[i + 2];
+ } else {
+ gui[j] = 0;
+ gui[j + 1] = 0;
+ gui[j + 2] = 0;
+ }
+ gui[j + 3] = 0; // ignored
}
- gui[j + 3] = 0; // ignored
+ } else {
+ Vector3i v = value;
+ gui[0] = v.x;
+ gui[1] = v.y;
+ gui[2] = v.z;
}
} break;
case ShaderLanguage::TYPE_UVEC4: {
- Vector<int> iv = value;
- int s = iv.size();
uint32_t *gui = (uint32_t *)data;
- if (p_array_size <= 0) {
- p_array_size = 1;
- }
- int count = 4 * p_array_size;
-
- const int *r = iv.ptr();
- for (int i = 0; i < count; i++) {
- if (i < s) {
- gui[i] = r[i];
- gui[i + 1] = r[i + 1];
- gui[i + 2] = r[i + 2];
- gui[i + 3] = r[i + 3];
- } else {
- gui[i] = 0;
- gui[i + 1] = 0;
- gui[i + 2] = 0;
- gui[i + 3] = 0;
+ if (p_array_size > 0) {
+ Vector<int> iv = value;
+ int s = iv.size();
+ int count = 4 * p_array_size;
+
+ const int *r = iv.ptr();
+ for (int i = 0; i < count; i++) {
+ if (i < s) {
+ gui[i] = r[i];
+ gui[i + 1] = r[i + 1];
+ gui[i + 2] = r[i + 2];
+ gui[i + 3] = r[i + 3];
+ } else {
+ gui[i] = 0;
+ gui[i + 1] = 0;
+ gui[i + 2] = 0;
+ gui[i + 3] = 0;
+ }
}
+ } else {
+ Vector4i v = value;
+ gui[0] = v.x;
+ gui[1] = v.y;
+ gui[2] = v.z;
+ gui[3] = v.w;
}
} break;
case ShaderLanguage::TYPE_FLOAT: {
@@ -504,6 +526,13 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[1] = v.y;
gui[2] = v.z;
gui[3] = v.w;
+ } else if (value.get_type() == Variant::VECTOR4) {
+ Vector4 v = value;
+
+ gui[0] = v.x;
+ gui[1] = v.y;
+ gui[2] = v.z;
+ gui[3] = v.w;
} else {
Plane v = value;
@@ -660,7 +689,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[i + 15] = 1;
}
}
- } else {
+ } else if (value.get_type() == Variant::TRANSFORM3D) {
Transform3D v = value;
gui[0] = v.basis.rows[0][0];
gui[1] = v.basis.rows[1][0];
@@ -681,6 +710,13 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[13] = v.origin.y;
gui[14] = v.origin.z;
gui[15] = 1;
+ } else {
+ Projection v = value;
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ gui[i * 4 + j] = v.matrix[i][j];
+ }
+ }
}
} break;
default: {
@@ -937,7 +973,7 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag
if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) {
//this is a global variable, get the index to it
- GlobalVariables::Variable *gv = material_storage->global_variables.variables.getptr(E.key);
+ GlobalShaderUniforms::Variable *gv = material_storage->global_shader_uniforms.variables.getptr(E.key);
uint32_t index = 0;
if (gv) {
index = gv->buffer_index;
@@ -993,9 +1029,9 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag
if (uses_global_buffer != (global_buffer_E != nullptr)) {
if (uses_global_buffer) {
- global_buffer_E = material_storage->global_variables.materials_using_buffer.push_back(self);
+ global_buffer_E = material_storage->global_shader_uniforms.materials_using_buffer.push_back(self);
} else {
- material_storage->global_variables.materials_using_buffer.erase(global_buffer_E);
+ material_storage->global_shader_uniforms.materials_using_buffer.erase(global_buffer_E);
global_buffer_E = nullptr;
}
}
@@ -1006,20 +1042,20 @@ MaterialData::~MaterialData() {
if (global_buffer_E) {
//unregister global buffers
- material_storage->global_variables.materials_using_buffer.erase(global_buffer_E);
+ material_storage->global_shader_uniforms.materials_using_buffer.erase(global_buffer_E);
}
if (global_texture_E) {
//unregister global textures
for (const KeyValue<StringName, uint64_t> &E : used_global_textures) {
- GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(E.key);
+ GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(E.key);
if (v) {
v->texture_materials.erase(self);
}
}
//unregister material from those using global textures
- material_storage->global_variables.materials_using_texture.erase(global_texture_E);
+ material_storage->global_shader_uniforms.materials_using_texture.erase(global_texture_E);
}
if (uniform_buffer) {
@@ -1050,7 +1086,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
if (p_texture_uniforms[i].global) {
uses_global_textures = true;
- GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(uniform_name);
+ GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(uniform_name);
if (v) {
if (v->buffer_index >= 0) {
WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!.");
@@ -1120,6 +1156,9 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_BLACK: {
gl_texture = texture_storage->texture_gl_get_default(DEFAULT_GL_TEXTURE_BLACK);
} break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT: {
+ gl_texture = texture_storage->texture_gl_get_default(DEFAULT_GL_TEXTURE_TRANSPARENT);
+ } break;
case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: {
gl_texture = texture_storage->texture_gl_get_default(DEFAULT_GL_TEXTURE_ANISO);
} break;
@@ -1222,7 +1261,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
if (E.value != global_textures_pass) {
to_delete.push_back(E.key);
- GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(E.key);
+ GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(E.key);
if (v) {
v->texture_materials.erase(self);
}
@@ -1236,9 +1275,9 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
//handle registering/unregistering global textures
if (uses_global_textures != (global_texture_E != nullptr)) {
if (uses_global_textures) {
- global_texture_E = material_storage->global_variables.materials_using_texture.push_back(self);
+ global_texture_E = material_storage->global_shader_uniforms.materials_using_texture.push_back(self);
} else {
- material_storage->global_variables.materials_using_texture.erase(global_texture_E);
+ material_storage->global_shader_uniforms.materials_using_texture.erase(global_texture_E);
global_texture_E = nullptr;
}
}
@@ -1305,22 +1344,22 @@ MaterialStorage::MaterialStorage() {
material_data_request_func[RS::SHADER_SKY] = _create_sky_material_func;
material_data_request_func[RS::SHADER_FOG] = nullptr;
- static_assert(sizeof(GlobalVariables::Value) == 16);
+ static_assert(sizeof(GlobalShaderUniforms::Value) == 16);
- global_variables.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size"));
- if (global_variables.buffer_size > uint32_t(Config::get_singleton()->max_uniform_buffer_size)) {
- global_variables.buffer_size = uint32_t(Config::get_singleton()->max_uniform_buffer_size);
+ global_shader_uniforms.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size"));
+ if (global_shader_uniforms.buffer_size > uint32_t(Config::get_singleton()->max_uniform_buffer_size)) {
+ global_shader_uniforms.buffer_size = uint32_t(Config::get_singleton()->max_uniform_buffer_size);
WARN_PRINT("Project setting: rendering/limits/global_shader_variables/buffer_size exceeds maximum uniform buffer size of: " + itos(Config::get_singleton()->max_uniform_buffer_size));
}
- global_variables.buffer_values = memnew_arr(GlobalVariables::Value, global_variables.buffer_size);
- memset(global_variables.buffer_values, 0, sizeof(GlobalVariables::Value) * global_variables.buffer_size);
- global_variables.buffer_usage = memnew_arr(GlobalVariables::ValueUsage, global_variables.buffer_size);
- global_variables.buffer_dirty_regions = memnew_arr(bool, global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE);
- memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE);
- glGenBuffers(1, &global_variables.buffer);
- glBindBuffer(GL_UNIFORM_BUFFER, global_variables.buffer);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(GlobalVariables::Value) * global_variables.buffer_size, nullptr, GL_DYNAMIC_DRAW);
+ global_shader_uniforms.buffer_values = memnew_arr(GlobalShaderUniforms::Value, global_shader_uniforms.buffer_size);
+ memset(global_shader_uniforms.buffer_values, 0, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size);
+ global_shader_uniforms.buffer_usage = memnew_arr(GlobalShaderUniforms::ValueUsage, global_shader_uniforms.buffer_size);
+ global_shader_uniforms.buffer_dirty_regions = memnew_arr(bool, global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE);
+ memset(global_shader_uniforms.buffer_dirty_regions, 0, sizeof(bool) * global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE);
+ glGenBuffers(1, &global_shader_uniforms.buffer);
+ glBindBuffer(GL_UNIFORM_BUFFER, global_shader_uniforms.buffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size, nullptr, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
{
@@ -1378,6 +1417,7 @@ MaterialStorage::MaterialStorage() {
actions.usage_defines["NORMAL"] = "#define NORMAL_USED\n";
actions.usage_defines["NORMAL_MAP"] = "#define NORMAL_MAP_USED\n";
actions.usage_defines["LIGHT"] = "#define LIGHT_SHADER_CODE_USED\n";
+ actions.usage_defines["SPECULAR_SHININESS"] = "#define SPECULAR_SHININESS_USED\n";
actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
@@ -1457,7 +1497,7 @@ MaterialStorage::MaterialStorage() {
actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer";
actions.renames["DEPTH"] = "gl_FragDepth";
actions.renames["OUTPUT_IS_SRGB"] = "true";
- actions.renames["FOG"] = "custom_fog";
+ actions.renames["FOG"] = "fog";
actions.renames["RADIANCE"] = "custom_radiance";
actions.renames["IRRADIANCE"] = "custom_irradiance";
actions.renames["BONE_INDICES"] = "bone_attrib";
@@ -1468,6 +1508,11 @@ MaterialStorage::MaterialStorage() {
actions.renames["CUSTOM3"] = "custom3_attrib";
actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
+ actions.renames["NODE_POSITION_WORLD"] = "model_matrix[3].xyz";
+ actions.renames["CAMERA_POSITION_WORLD"] = "scene_data.inv_view_matrix[3].xyz";
+ actions.renames["CAMERA_DIRECTION_WORLD"] = "scene_data.view_matrix[3].xyz";
+ actions.renames["NODE_POSITION_VIEW"] = "(model_matrix * scene_data.view_matrix)[3].xyz";
+
actions.renames["VIEW_INDEX"] = "ViewIndex";
actions.renames["VIEW_MONO_LEFT"] = "0";
actions.renames["VIEW_RIGHT"] = "1";
@@ -1613,7 +1658,7 @@ ShaderCompiler::DefaultIdentifierActions actions;
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
- actions.global_buffer_array_variable = "global_variables.data";
+ actions.global_buffer_array_variable = "global_shader_uniforms.data";
particles_shader.compiler.initialize(actions);
*/
@@ -1675,25 +1720,25 @@ ShaderCompiler::DefaultIdentifierActions actions;
MaterialStorage::~MaterialStorage() {
//shaders.copy.version_free(shaders.copy_version);
- memdelete_arr(global_variables.buffer_values);
- memdelete_arr(global_variables.buffer_usage);
- memdelete_arr(global_variables.buffer_dirty_regions);
- glDeleteBuffers(1, &global_variables.buffer);
+ memdelete_arr(global_shader_uniforms.buffer_values);
+ memdelete_arr(global_shader_uniforms.buffer_usage);
+ memdelete_arr(global_shader_uniforms.buffer_dirty_regions);
+ glDeleteBuffers(1, &global_shader_uniforms.buffer);
singleton = nullptr;
}
-/* GLOBAL VARIABLE API */
+/* GLOBAL SHADER UNIFORM API */
-int32_t MaterialStorage::_global_variable_allocate(uint32_t p_elements) {
+int32_t MaterialStorage::_global_shader_uniform_allocate(uint32_t p_elements) {
int32_t idx = 0;
- while (idx + p_elements <= global_variables.buffer_size) {
- if (global_variables.buffer_usage[idx].elements == 0) {
+ while (idx + p_elements <= global_shader_uniforms.buffer_size) {
+ if (global_shader_uniforms.buffer_usage[idx].elements == 0) {
bool valid = true;
for (uint32_t i = 1; i < p_elements; i++) {
- if (global_variables.buffer_usage[idx + i].elements > 0) {
+ if (global_shader_uniforms.buffer_usage[idx + i].elements > 0) {
valid = false;
- idx += i + global_variables.buffer_usage[idx + i].elements;
+ idx += i + global_shader_uniforms.buffer_usage[idx + i].elements;
break;
}
}
@@ -1704,17 +1749,17 @@ int32_t MaterialStorage::_global_variable_allocate(uint32_t p_elements) {
return idx;
} else {
- idx += global_variables.buffer_usage[idx].elements;
+ idx += global_shader_uniforms.buffer_usage[idx].elements;
}
}
return -1;
}
-void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) {
+void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value) {
switch (p_type) {
case RS::GLOBAL_VAR_TYPE_BOOL: {
- GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
bool b = p_value;
bv.x = b ? 1.0 : 0.0;
bv.y = 0.0;
@@ -1723,7 +1768,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
} break;
case RS::GLOBAL_VAR_TYPE_BVEC2: {
- GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
uint32_t bvec = p_value;
bv.x = (bvec & 1) ? 1.0 : 0.0;
bv.y = (bvec & 2) ? 1.0 : 0.0;
@@ -1731,7 +1776,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = 0.0;
} break;
case RS::GLOBAL_VAR_TYPE_BVEC3: {
- GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
uint32_t bvec = p_value;
bv.x = (bvec & 1) ? 1.0 : 0.0;
bv.y = (bvec & 2) ? 1.0 : 0.0;
@@ -1739,7 +1784,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = 0.0;
} break;
case RS::GLOBAL_VAR_TYPE_BVEC4: {
- GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
uint32_t bvec = p_value;
bv.x = (bvec & 1) ? 1.0 : 0.0;
bv.y = (bvec & 2) ? 1.0 : 0.0;
@@ -1747,7 +1792,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = (bvec & 8) ? 1.0 : 0.0;
} break;
case RS::GLOBAL_VAR_TYPE_INT: {
- GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
int32_t v = p_value;
bv.x = v;
bv.y = 0;
@@ -1755,7 +1800,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = 0;
} break;
case RS::GLOBAL_VAR_TYPE_IVEC2: {
- GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
Vector2i v = p_value;
bv.x = v.x;
bv.y = v.y;
@@ -1763,7 +1808,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = 0;
} break;
case RS::GLOBAL_VAR_TYPE_IVEC3: {
- GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
Vector3i v = p_value;
bv.x = v.x;
bv.y = v.y;
@@ -1771,7 +1816,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = 0;
} break;
case RS::GLOBAL_VAR_TYPE_IVEC4: {
- GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
Vector<int32_t> v = p_value;
bv.x = v.size() >= 1 ? v[0] : 0;
bv.y = v.size() >= 2 ? v[1] : 0;
@@ -1779,7 +1824,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = v.size() >= 4 ? v[3] : 0;
} break;
case RS::GLOBAL_VAR_TYPE_RECT2I: {
- GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index];
Rect2i v = p_value;
bv.x = v.position.x;
bv.y = v.position.y;
@@ -1787,7 +1832,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = v.size.y;
} break;
case RS::GLOBAL_VAR_TYPE_UINT: {
- GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index];
uint32_t v = p_value;
bv.x = v;
bv.y = 0;
@@ -1795,7 +1840,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = 0;
} break;
case RS::GLOBAL_VAR_TYPE_UVEC2: {
- GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index];
Vector2i v = p_value;
bv.x = v.x;
bv.y = v.y;
@@ -1803,7 +1848,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = 0;
} break;
case RS::GLOBAL_VAR_TYPE_UVEC3: {
- GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index];
Vector3i v = p_value;
bv.x = v.x;
bv.y = v.y;
@@ -1811,7 +1856,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = 0;
} break;
case RS::GLOBAL_VAR_TYPE_UVEC4: {
- GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index];
Vector<int32_t> v = p_value;
bv.x = v.size() >= 1 ? v[0] : 0;
bv.y = v.size() >= 2 ? v[1] : 0;
@@ -1819,7 +1864,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = v.size() >= 4 ? v[3] : 0;
} break;
case RS::GLOBAL_VAR_TYPE_FLOAT: {
- GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
float v = p_value;
bv.x = v;
bv.y = 0;
@@ -1827,7 +1872,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = 0;
} break;
case RS::GLOBAL_VAR_TYPE_VEC2: {
- GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
Vector2 v = p_value;
bv.x = v.x;
bv.y = v.y;
@@ -1835,7 +1880,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = 0;
} break;
case RS::GLOBAL_VAR_TYPE_VEC3: {
- GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
Vector3 v = p_value;
bv.x = v.x;
bv.y = v.y;
@@ -1843,7 +1888,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = 0;
} break;
case RS::GLOBAL_VAR_TYPE_VEC4: {
- GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
Plane v = p_value;
bv.x = v.normal.x;
bv.y = v.normal.y;
@@ -1851,14 +1896,14 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = v.d;
} break;
case RS::GLOBAL_VAR_TYPE_COLOR: {
- GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
Color v = p_value;
bv.x = v.r;
bv.y = v.g;
bv.z = v.b;
bv.w = v.a;
- GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1];
+ GlobalShaderUniforms::Value &bv_linear = global_shader_uniforms.buffer_values[p_index + 1];
//v = v.srgb_to_linear();
bv_linear.x = v.r;
bv_linear.y = v.g;
@@ -1867,7 +1912,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
} break;
case RS::GLOBAL_VAR_TYPE_RECT2: {
- GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
Rect2 v = p_value;
bv.x = v.position.x;
bv.y = v.position.y;
@@ -1875,7 +1920,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
bv.w = v.size.y;
} break;
case RS::GLOBAL_VAR_TYPE_MAT2: {
- GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
Vector<float> m2 = p_value;
if (m2.size() < 4) {
m2.resize(4);
@@ -1892,7 +1937,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
} break;
case RS::GLOBAL_VAR_TYPE_MAT3: {
- GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
Basis v = p_value;
bv[0].x = v.rows[0][0];
bv[0].y = v.rows[1][0];
@@ -1911,7 +1956,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
} break;
case RS::GLOBAL_VAR_TYPE_MAT4: {
- GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
Vector<float> m2 = p_value;
if (m2.size() < 16) {
@@ -1940,7 +1985,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
} break;
case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: {
- GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
Transform2D v = p_value;
bv[0].x = v.columns[0][0];
bv[0].y = v.columns[0][1];
@@ -1959,7 +2004,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
} break;
case RS::GLOBAL_VAR_TYPE_TRANSFORM: {
- GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
+ GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index];
Transform3D v = p_value;
bv[0].x = v.basis.rows[0][0];
bv[0].y = v.basis.rows[1][0];
@@ -1988,15 +2033,15 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
}
}
-void MaterialStorage::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) {
+void MaterialStorage::_global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements) {
int32_t prev_chunk = -1;
for (int32_t i = 0; i < p_elements; i++) {
- int32_t chunk = (p_index + i) / GlobalVariables::BUFFER_DIRTY_REGION_SIZE;
+ int32_t chunk = (p_index + i) / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE;
if (chunk != prev_chunk) {
- if (!global_variables.buffer_dirty_regions[chunk]) {
- global_variables.buffer_dirty_regions[chunk] = true;
- global_variables.buffer_dirty_region_count++;
+ if (!global_shader_uniforms.buffer_dirty_regions[chunk]) {
+ global_shader_uniforms.buffer_dirty_regions[chunk] = true;
+ global_shader_uniforms.buffer_dirty_region_count++;
}
}
@@ -2004,16 +2049,16 @@ void MaterialStorage::_global_variable_mark_buffer_dirty(int32_t p_index, int32_
}
}
-void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) {
- ERR_FAIL_COND(global_variables.variables.has(p_name));
- GlobalVariables::Variable gv;
+void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) {
+ ERR_FAIL_COND(global_shader_uniforms.variables.has(p_name));
+ GlobalShaderUniforms::Variable gv;
gv.type = p_type;
gv.value = p_value;
gv.buffer_index = -1;
if (p_type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) {
//is texture
- global_variables.must_update_texture_materials = true; //normally there are none
+ global_shader_uniforms.must_update_texture_materials = true; //normally there are none
} else {
gv.buffer_elements = 1;
if (p_type == RS::GLOBAL_VAR_TYPE_COLOR || p_type == RS::GLOBAL_VAR_TYPE_MAT2) {
@@ -2030,56 +2075,56 @@ void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVa
}
//is vector, allocate in buffer and update index
- gv.buffer_index = _global_variable_allocate(gv.buffer_elements);
+ gv.buffer_index = _global_shader_uniform_allocate(gv.buffer_elements);
ERR_FAIL_COND_MSG(gv.buffer_index < 0, vformat("Failed allocating global variable '%s' out of buffer memory. Consider increasing it in the Project Settings.", String(p_name)));
- global_variables.buffer_usage[gv.buffer_index].elements = gv.buffer_elements;
- _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value);
- _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements);
+ global_shader_uniforms.buffer_usage[gv.buffer_index].elements = gv.buffer_elements;
+ _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value);
+ _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements);
- global_variables.must_update_buffer_materials = true; //normally there are none
+ global_shader_uniforms.must_update_buffer_materials = true; //normally there are none
}
- global_variables.variables[p_name] = gv;
+ global_shader_uniforms.variables[p_name] = gv;
}
-void MaterialStorage::global_variable_remove(const StringName &p_name) {
- if (!global_variables.variables.has(p_name)) {
+void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) {
+ if (!global_shader_uniforms.variables.has(p_name)) {
return;
}
- GlobalVariables::Variable &gv = global_variables.variables[p_name];
+ GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name];
if (gv.buffer_index >= 0) {
- global_variables.buffer_usage[gv.buffer_index].elements = 0;
- global_variables.must_update_buffer_materials = true;
+ global_shader_uniforms.buffer_usage[gv.buffer_index].elements = 0;
+ global_shader_uniforms.must_update_buffer_materials = true;
} else {
- global_variables.must_update_texture_materials = true;
+ global_shader_uniforms.must_update_texture_materials = true;
}
- global_variables.variables.erase(p_name);
+ global_shader_uniforms.variables.erase(p_name);
}
-Vector<StringName> MaterialStorage::global_variable_get_list() const {
+Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const {
if (!Engine::get_singleton()->is_editor_hint()) {
ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance.");
}
Vector<StringName> names;
- for (const KeyValue<StringName, GlobalVariables::Variable> &E : global_variables.variables) {
+ for (const KeyValue<StringName, GlobalShaderUniforms::Variable> &E : global_shader_uniforms.variables) {
names.push_back(E.key);
}
names.sort_custom<StringName::AlphCompare>();
return names;
}
-void MaterialStorage::global_variable_set(const StringName &p_name, const Variant &p_value) {
- ERR_FAIL_COND(!global_variables.variables.has(p_name));
- GlobalVariables::Variable &gv = global_variables.variables[p_name];
+void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const Variant &p_value) {
+ ERR_FAIL_COND(!global_shader_uniforms.variables.has(p_name));
+ GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name];
gv.value = p_value;
if (gv.override.get_type() == Variant::NIL) {
if (gv.buffer_index >= 0) {
//buffer
- _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value);
- _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements);
+ _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value);
+ _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements);
} else {
//texture
MaterialStorage *material_storage = MaterialStorage::get_singleton();
@@ -2092,26 +2137,26 @@ void MaterialStorage::global_variable_set(const StringName &p_name, const Varian
}
}
-void MaterialStorage::global_variable_set_override(const StringName &p_name, const Variant &p_value) {
- if (!global_variables.variables.has(p_name)) {
+void MaterialStorage::global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) {
+ if (!global_shader_uniforms.variables.has(p_name)) {
return; //variable may not exist
}
ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT);
- GlobalVariables::Variable &gv = global_variables.variables[p_name];
+ GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name];
gv.override = p_value;
if (gv.buffer_index >= 0) {
//buffer
if (gv.override.get_type() == Variant::NIL) {
- _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value);
+ _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value);
} else {
- _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.override);
+ _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.override);
}
- _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements);
+ _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements);
} else {
//texture
MaterialStorage *material_storage = MaterialStorage::get_singleton();
@@ -2123,35 +2168,35 @@ void MaterialStorage::global_variable_set_override(const StringName &p_name, con
}
}
-Variant MaterialStorage::global_variable_get(const StringName &p_name) const {
+Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) const {
if (!Engine::get_singleton()->is_editor_hint()) {
ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance.");
}
- if (!global_variables.variables.has(p_name)) {
+ if (!global_shader_uniforms.variables.has(p_name)) {
return Variant();
}
- return global_variables.variables[p_name].value;
+ return global_shader_uniforms.variables[p_name].value;
}
-RS::GlobalVariableType MaterialStorage::global_variable_get_type_internal(const StringName &p_name) const {
- if (!global_variables.variables.has(p_name)) {
+RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_internal(const StringName &p_name) const {
+ if (!global_shader_uniforms.variables.has(p_name)) {
return RS::GLOBAL_VAR_TYPE_MAX;
}
- return global_variables.variables[p_name].type;
+ return global_shader_uniforms.variables[p_name].type;
}
-RS::GlobalVariableType MaterialStorage::global_variable_get_type(const StringName &p_name) const {
+RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type(const StringName &p_name) const {
if (!Engine::get_singleton()->is_editor_hint()) {
ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance.");
}
- return global_variable_get_type_internal(p_name);
+ return global_shader_uniform_get_type_internal(p_name);
}
-void MaterialStorage::global_variables_load_settings(bool p_load_textures) {
+void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) {
List<PropertyInfo> settings;
ProjectSettings::get_singleton()->get_property_list(&settings);
@@ -2196,11 +2241,11 @@ void MaterialStorage::global_variables_load_settings(bool p_load_textures) {
"samplerCube",
};
- RS::GlobalVariableType gvtype = RS::GLOBAL_VAR_TYPE_MAX;
+ RS::GlobalShaderUniformType gvtype = RS::GLOBAL_VAR_TYPE_MAX;
for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) {
if (global_var_type_names[i] == type) {
- gvtype = RS::GlobalVariableType(i);
+ gvtype = RS::GlobalShaderUniformType(i);
break;
}
}
@@ -2222,47 +2267,47 @@ void MaterialStorage::global_variables_load_settings(bool p_load_textures) {
value = resource;
}
- if (global_variables.variables.has(name)) {
+ if (global_shader_uniforms.variables.has(name)) {
//has it, update it
- global_variable_set(name, value);
+ global_shader_uniform_set(name, value);
} else {
- global_variable_add(name, gvtype, value);
+ global_shader_uniform_add(name, gvtype, value);
}
}
}
}
-void MaterialStorage::global_variables_clear() {
- global_variables.variables.clear();
+void MaterialStorage::global_shader_uniforms_clear() {
+ global_shader_uniforms.variables.clear();
}
-GLuint MaterialStorage::global_variables_get_uniform_buffer() const {
- return global_variables.buffer;
+GLuint MaterialStorage::global_shader_uniforms_get_uniform_buffer() const {
+ return global_shader_uniforms.buffer;
}
-int32_t MaterialStorage::global_variables_instance_allocate(RID p_instance) {
- ERR_FAIL_COND_V(global_variables.instance_buffer_pos.has(p_instance), -1);
- int32_t pos = _global_variable_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES);
- global_variables.instance_buffer_pos[p_instance] = pos; //save anyway
+int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance) {
+ ERR_FAIL_COND_V(global_shader_uniforms.instance_buffer_pos.has(p_instance), -1);
+ int32_t pos = _global_shader_uniform_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES);
+ global_shader_uniforms.instance_buffer_pos[p_instance] = pos; //save anyway
ERR_FAIL_COND_V_MSG(pos < 0, -1, "Too many instances using shader instance variables. Increase buffer size in Project Settings.");
- global_variables.buffer_usage[pos].elements = ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES;
+ global_shader_uniforms.buffer_usage[pos].elements = ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES;
return pos;
}
-void MaterialStorage::global_variables_instance_free(RID p_instance) {
- ERR_FAIL_COND(!global_variables.instance_buffer_pos.has(p_instance));
- int32_t pos = global_variables.instance_buffer_pos[p_instance];
+void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) {
+ ERR_FAIL_COND(!global_shader_uniforms.instance_buffer_pos.has(p_instance));
+ int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance];
if (pos >= 0) {
- global_variables.buffer_usage[pos].elements = 0;
+ global_shader_uniforms.buffer_usage[pos].elements = 0;
}
- global_variables.instance_buffer_pos.erase(p_instance);
+ global_shader_uniforms.instance_buffer_pos.erase(p_instance);
}
-void MaterialStorage::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) {
- if (!global_variables.instance_buffer_pos.has(p_instance)) {
+void MaterialStorage::global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) {
+ if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) {
return; //just not allocated, ignore
}
- int32_t pos = global_variables.instance_buffer_pos[p_instance];
+ int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance];
if (pos < 0) {
return; //again, not allocated, ignore
@@ -2283,11 +2328,14 @@ void MaterialStorage::global_variables_instance_update(RID p_instance, int p_ind
ShaderLanguage::TYPE_VEC3, // vec3
ShaderLanguage::TYPE_IVEC3, //vec3i
ShaderLanguage::TYPE_MAX, //xform2d not supported here
+ ShaderLanguage::TYPE_VEC4, //vec4
+ ShaderLanguage::TYPE_IVEC4, //vec4i
ShaderLanguage::TYPE_VEC4, //plane
ShaderLanguage::TYPE_VEC4, //quat
ShaderLanguage::TYPE_MAX, //aabb not supported here
ShaderLanguage::TYPE_MAX, //basis not supported here
ShaderLanguage::TYPE_MAX, //xform not supported here
+ ShaderLanguage::TYPE_MAX, //projection not supported here
ShaderLanguage::TYPE_VEC4 //color
};
@@ -2297,59 +2345,59 @@ void MaterialStorage::global_variables_instance_update(RID p_instance, int p_ind
pos += p_index;
- _fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_variables.buffer_values[pos]);
- _global_variable_mark_buffer_dirty(pos, 1);
+ _fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_shader_uniforms.buffer_values[pos]);
+ _global_shader_uniform_mark_buffer_dirty(pos, 1);
}
-void MaterialStorage::_update_global_variables() {
+void MaterialStorage::_update_global_shader_uniforms() {
MaterialStorage *material_storage = MaterialStorage::get_singleton();
- if (global_variables.buffer_dirty_region_count > 0) {
- uint32_t total_regions = global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE;
- if (total_regions / global_variables.buffer_dirty_region_count <= 4) {
+ if (global_shader_uniforms.buffer_dirty_region_count > 0) {
+ uint32_t total_regions = global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE;
+ if (total_regions / global_shader_uniforms.buffer_dirty_region_count <= 4) {
// 25% of regions dirty, just update all buffer
- glBindBuffer(GL_UNIFORM_BUFFER, global_variables.buffer);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(GlobalVariables::Value) * global_variables.buffer_size, global_variables.buffer_values, GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_UNIFORM_BUFFER, global_shader_uniforms.buffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size, global_shader_uniforms.buffer_values, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
- memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * total_regions);
+ memset(global_shader_uniforms.buffer_dirty_regions, 0, sizeof(bool) * total_regions);
} else {
- uint32_t region_byte_size = sizeof(GlobalVariables::Value) * GlobalVariables::BUFFER_DIRTY_REGION_SIZE;
- glBindBuffer(GL_UNIFORM_BUFFER, global_variables.buffer);
+ uint32_t region_byte_size = sizeof(GlobalShaderUniforms::Value) * GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE;
+ glBindBuffer(GL_UNIFORM_BUFFER, global_shader_uniforms.buffer);
for (uint32_t i = 0; i < total_regions; i++) {
- if (global_variables.buffer_dirty_regions[i]) {
- glBufferSubData(GL_UNIFORM_BUFFER, i * region_byte_size, region_byte_size, &global_variables.buffer_values[i * GlobalVariables::BUFFER_DIRTY_REGION_SIZE]);
- global_variables.buffer_dirty_regions[i] = false;
+ if (global_shader_uniforms.buffer_dirty_regions[i]) {
+ glBufferSubData(GL_UNIFORM_BUFFER, i * region_byte_size, region_byte_size, &global_shader_uniforms.buffer_values[i * GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE]);
+ global_shader_uniforms.buffer_dirty_regions[i] = false;
}
}
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
- global_variables.buffer_dirty_region_count = 0;
+ global_shader_uniforms.buffer_dirty_region_count = 0;
}
- if (global_variables.must_update_buffer_materials) {
+ if (global_shader_uniforms.must_update_buffer_materials) {
// only happens in the case of a buffer variable added or removed,
// so not often.
- for (const RID &E : global_variables.materials_using_buffer) {
+ for (const RID &E : global_shader_uniforms.materials_using_buffer) {
Material *material = material_storage->get_material(E);
ERR_CONTINUE(!material); //wtf
material_storage->_material_queue_update(material, true, false);
}
- global_variables.must_update_buffer_materials = false;
+ global_shader_uniforms.must_update_buffer_materials = false;
}
- if (global_variables.must_update_texture_materials) {
+ if (global_shader_uniforms.must_update_texture_materials) {
// only happens in the case of a buffer variable added or removed,
// so not often.
- for (const RID &E : global_variables.materials_using_texture) {
+ for (const RID &E : global_shader_uniforms.materials_using_texture) {
Material *material = material_storage->get_material(E);
ERR_CONTINUE(!material); //wtf
material_storage->_material_queue_update(material, false, true);
}
- global_variables.must_update_texture_materials = false;
+ global_shader_uniforms.must_update_texture_materials = false;
}
}
@@ -2461,17 +2509,24 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) {
}
}
+void MaterialStorage::shader_set_path_hint(RID p_shader, const String &p_path) {
+ GLES3::Shader *shader = shader_owner.get_or_null(p_shader);
+ ERR_FAIL_COND(!shader);
+
+ shader->path_hint = p_path;
+}
+
String MaterialStorage::shader_get_code(RID p_shader) const {
const GLES3::Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND_V(!shader, String());
return shader->code;
}
-void MaterialStorage::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
+void MaterialStorage::shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
GLES3::Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND(!shader);
if (shader->data) {
- return shader->data->get_param_list(p_param_list);
+ return shader->data->get_shader_uniform_list(p_param_list);
}
}
@@ -2703,14 +2758,14 @@ bool MaterialStorage::material_casts_shadows(RID p_material) {
return true; //by default everything casts shadows
}
-void MaterialStorage::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) {
+void MaterialStorage::material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) {
GLES3::Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
if (material->shader && material->shader->data) {
material->shader->data->get_instance_param_list(r_parameters);
if (material->next_pass.is_valid()) {
- material_get_instance_shader_parameters(material->next_pass, r_parameters);
+ material_get_instance_shader_uniforms(material->next_pass, r_parameters);
}
}
}
@@ -2818,7 +2873,7 @@ void CanvasShaderData::set_default_texture_param(const StringName &p_name, RID p
}
}
-void CanvasShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+void CanvasShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const {
HashMap<int, StringName> order;
for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
@@ -2832,7 +2887,22 @@ void CanvasShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
}
}
+ String last_group;
for (const KeyValue<int, StringName> &E : order) {
+ String group = uniforms[E.value].group;
+ if (!uniforms[E.value].subgroup.is_empty()) {
+ group += "::" + uniforms[E.value].subgroup;
+ }
+
+ if (group != last_group) {
+ PropertyInfo pi;
+ pi.usage = PROPERTY_USAGE_GROUP;
+ pi.name = group;
+ p_param_list->push_back(pi);
+
+ last_group = group;
+ }
+
PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]);
pi.name = E.value;
p_param_list->push_back(pi);
@@ -3040,7 +3110,7 @@ void SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_te
}
}
-void SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+void SkyShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const {
RBMap<int, StringName> order;
for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
@@ -3055,7 +3125,22 @@ void SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
}
}
+ String last_group;
for (const KeyValue<int, StringName> &E : order) {
+ String group = uniforms[E.value].group;
+ if (!uniforms[E.value].subgroup.is_empty()) {
+ group += "::" + uniforms[E.value].subgroup;
+ }
+
+ if (group != last_group) {
+ PropertyInfo pi;
+ pi.usage = PROPERTY_USAGE_GROUP;
+ pi.name = group;
+ p_param_list->push_back(pi);
+
+ last_group = group;
+ }
+
PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]);
pi.name = E.value;
p_param_list->push_back(pi);
@@ -3350,7 +3435,7 @@ void SceneShaderData::set_default_texture_param(const StringName &p_name, RID p_
}
}
-void SceneShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+void SceneShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const {
RBMap<int, StringName> order;
for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
@@ -3365,7 +3450,22 @@ void SceneShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
}
}
+ String last_group;
for (const KeyValue<int, StringName> &E : order) {
+ String group = uniforms[E.value].group;
+ if (!uniforms[E.value].subgroup.is_empty()) {
+ group += "::" + uniforms[E.value].subgroup;
+ }
+
+ if (group != last_group) {
+ PropertyInfo pi;
+ pi.usage = PROPERTY_USAGE_GROUP;
+ pi.name = group;
+ p_param_list->push_back(pi);
+
+ last_group = group;
+ }
+
PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]);
pi.name = E.value;
p_param_list->push_back(pi);
diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h
index 6ad277c2b9..2ca47351a4 100644
--- a/drivers/gles3/storage/material_storage.h
+++ b/drivers/gles3/storage/material_storage.h
@@ -54,7 +54,7 @@ namespace GLES3 {
struct ShaderData {
virtual void set_code(const String &p_Code) = 0;
virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) = 0;
- virtual void get_param_list(List<PropertyInfo> *p_param_list) const = 0;
+ virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const = 0;
virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const = 0;
virtual bool is_param_texture(const StringName &p_param) const = 0;
@@ -73,6 +73,7 @@ struct Material;
struct Shader {
ShaderData *data = nullptr;
String code;
+ String path_hint;
RS::ShaderMode mode;
HashMap<StringName, HashMap<int, RID>> default_texture_parameter;
HashSet<Material *> owners;
@@ -163,7 +164,7 @@ struct CanvasShaderData : public ShaderData {
virtual void set_code(const String &p_Code);
virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index);
- virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const;
virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const;
virtual bool is_param_texture(const StringName &p_param) const;
@@ -214,7 +215,7 @@ struct SkyShaderData : public ShaderData {
virtual void set_code(const String &p_Code);
virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index);
- virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const;
virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const;
virtual bool is_param_texture(const StringName &p_param) const;
virtual bool is_animated() const;
@@ -334,7 +335,7 @@ struct SceneShaderData : public ShaderData {
virtual void set_code(const String &p_Code);
virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index);
- virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ virtual void get_shader_uniform_list(List<PropertyInfo> *p_param_list) const;
virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const;
virtual bool is_param_texture(const StringName &p_param) const;
@@ -364,15 +365,15 @@ struct SceneMaterialData : public MaterialData {
MaterialData *_create_scene_material_func(ShaderData *p_shader);
-/* Global variable structs */
-struct GlobalVariables {
+/* Global shader uniform structs */
+struct GlobalShaderUniforms {
enum {
BUFFER_DIRTY_REGION_SIZE = 1024
};
struct Variable {
HashSet<RID> texture_materials; // materials using this
- RS::GlobalVariableType type;
+ RS::GlobalShaderUniformType type;
Variant value;
Variant override;
int32_t buffer_index; //for vectors
@@ -428,13 +429,13 @@ private:
friend struct MaterialData;
static MaterialStorage *singleton;
- /* GLOBAL VARIABLE API */
+ /* GLOBAL SHADER UNIFORM API */
- GlobalVariables global_variables;
+ GlobalShaderUniforms global_shader_uniforms;
- int32_t _global_variable_allocate(uint32_t p_elements);
- void _global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value);
- void _global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements);
+ int32_t _global_shader_uniform_allocate(uint32_t p_elements);
+ void _global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value);
+ void _global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements);
/* SHADER API */
@@ -487,7 +488,7 @@ public:
p_array[11] = 0;
}
- static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
+ static _FORCE_INLINE_ void store_camera(const Projection &p_mtx, float *p_array) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
p_array[i * 4 + j] = p_mtx.matrix[i][j];
@@ -507,28 +508,28 @@ public:
ShaderCompiler compiler_sky;
} shaders;
- /* GLOBAL VARIABLE API */
+ /* GLOBAL SHADER UNIFORM API */
- void _update_global_variables();
+ void _update_global_shader_uniforms();
- virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override;
- virtual void global_variable_remove(const StringName &p_name) override;
- virtual Vector<StringName> global_variable_get_list() const override;
+ virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) override;
+ virtual void global_shader_uniform_remove(const StringName &p_name) override;
+ virtual Vector<StringName> global_shader_uniform_get_list() const override;
- virtual void global_variable_set(const StringName &p_name, const Variant &p_value) override;
- virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) override;
- virtual Variant global_variable_get(const StringName &p_name) const override;
- virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override;
- RS::GlobalVariableType global_variable_get_type_internal(const StringName &p_name) const;
+ virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) override;
+ virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) override;
+ virtual Variant global_shader_uniform_get(const StringName &p_name) const override;
+ virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const override;
+ RS::GlobalShaderUniformType global_shader_uniform_get_type_internal(const StringName &p_name) const;
- virtual void global_variables_load_settings(bool p_load_textures = true) override;
- virtual void global_variables_clear() override;
+ virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) override;
+ virtual void global_shader_uniforms_clear() override;
- virtual int32_t global_variables_instance_allocate(RID p_instance) override;
- virtual void global_variables_instance_free(RID p_instance) override;
- virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override;
+ virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) override;
+ virtual void global_shader_uniforms_instance_free(RID p_instance) override;
+ virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) override;
- GLuint global_variables_get_uniform_buffer() const;
+ GLuint global_shader_uniforms_get_uniform_buffer() const;
/* SHADER API */
@@ -542,8 +543,9 @@ public:
virtual void shader_free(RID p_rid) override;
virtual void shader_set_code(RID p_shader, const String &p_code) override;
+ virtual void shader_set_path_hint(RID p_shader, const String &p_path) override;
virtual String shader_get_code(RID p_shader) const override;
- virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override;
+ virtual void shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const override;
virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override;
virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override;
@@ -574,7 +576,7 @@ public:
virtual bool material_is_animated(RID p_material) override;
virtual bool material_casts_shadows(RID p_material) override;
- virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override;
+ virtual void material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) override;
virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override;
@@ -597,4 +599,4 @@ public:
#endif // GLES3_ENABLED
-#endif // !MATERIAL_STORAGE_GLES3_H
+#endif // MATERIAL_STORAGE_GLES3_H
diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp
index 88b81805fa..667ba4f5e6 100644
--- a/drivers/gles3/storage/mesh_storage.cpp
+++ b/drivers/gles3/storage/mesh_storage.cpp
@@ -1347,7 +1347,7 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
_multimesh_mark_all_dirty(multimesh, false, true); //update AABB
} else if (multimesh->mesh.is_valid()) {
//if we have a mesh set, we need to re-generate the AABB from the new data
- const float *data = multimesh->data_cache.ptr();
+ const float *data = p_buffer.ptr();
_multimesh_re_create_aabb(multimesh, data, multimesh->instances);
multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h
index c51cd5dcd6..339380b3b0 100644
--- a/drivers/gles3/storage/mesh_storage.h
+++ b/drivers/gles3/storage/mesh_storage.h
@@ -543,4 +543,4 @@ public:
#endif // GLES3_ENABLED
-#endif // !MESH_STORAGE_GLES3_H
+#endif // MESH_STORAGE_GLES3_H
diff --git a/drivers/gles3/storage/particles_storage.h b/drivers/gles3/storage/particles_storage.h
index cf47ada5d5..84d1f94d8c 100644
--- a/drivers/gles3/storage/particles_storage.h
+++ b/drivers/gles3/storage/particles_storage.h
@@ -137,4 +137,4 @@ public:
#endif // GLES3_ENABLED
-#endif // !PARTICLES_STORAGE_GLES3_H
+#endif // PARTICLES_STORAGE_GLES3_H
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index c05f516548..543638e8ff 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -115,6 +115,17 @@ TextureStorage::TextureStorage() {
texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_BLACK], images, RS::TEXTURE_LAYERED_CUBEMAP);
}
+ { // transparent black
+ Ref<Image> image;
+ image.instantiate();
+ image->create(4, 4, true, Image::FORMAT_RGBA8);
+ image->fill(Color(0, 0, 0, 0));
+ image->generate_mipmaps();
+
+ default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT] = texture_allocate();
+ texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT], image);
+ }
+
{
Ref<Image> image;
image.instantiate();
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index de887f9184..71f713bc9f 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -103,6 +103,7 @@ namespace GLES3 {
enum DefaultGLTexture {
DEFAULT_GL_TEXTURE_WHITE,
DEFAULT_GL_TEXTURE_BLACK,
+ DEFAULT_GL_TEXTURE_TRANSPARENT,
DEFAULT_GL_TEXTURE_NORMAL,
DEFAULT_GL_TEXTURE_ANISO,
DEFAULT_GL_TEXTURE_DEPTH,
@@ -546,6 +547,16 @@ public:
void render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps);
void render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color);
void render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region);
+ virtual void render_target_set_vrs_mode(RID p_render_target, RS::ViewportVRSMode p_mode) override{};
+ virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override{};
+
+ void bind_framebuffer(GLuint framebuffer) {
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ }
+
+ void bind_framebuffer_system() {
+ glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
+ }
String get_framebuffer_error(GLenum p_status);
};
@@ -567,6 +578,6 @@ inline String TextureStorage::get_framebuffer_error(GLenum p_status) {
} // namespace GLES3
-#endif // !GLES3_ENABLED
+#endif // GLES3_ENABLED
-#endif // !TEXTURE_STORAGE_GLES3_H
+#endif // TEXTURE_STORAGE_GLES3_H
diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp
index a00210a2ab..654104722b 100644
--- a/drivers/gles3/storage/utilities.cpp
+++ b/drivers/gles3/storage/utilities.cpp
@@ -293,7 +293,7 @@ void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_de
/* MISC */
void Utilities::update_dirty_resources() {
- MaterialStorage::get_singleton()->_update_global_variables();
+ MaterialStorage::get_singleton()->_update_global_shader_uniforms();
MaterialStorage::get_singleton()->_update_queued_materials();
//MeshStorage::get_singleton()->_update_dirty_skeletons();
MeshStorage::get_singleton()->_update_dirty_multimeshes();
diff --git a/drivers/gles3/storage/utilities.h b/drivers/gles3/storage/utilities.h
index 523033886c..e054f2f816 100644
--- a/drivers/gles3/storage/utilities.h
+++ b/drivers/gles3/storage/utilities.h
@@ -156,4 +156,4 @@ public:
#endif // GLES3_ENABLED
-#endif // !UTILITIES_GLES3_H
+#endif // UTILITIES_GLES3_H
diff --git a/drivers/png/image_loader_png.h b/drivers/png/image_loader_png.h
index 522cc901d4..9bcfb720d3 100644
--- a/drivers/png/image_loader_png.h
+++ b/drivers/png/image_loader_png.h
@@ -45,4 +45,4 @@ public:
ImageLoaderPNG();
};
-#endif
+#endif // IMAGE_LOADER_PNG_H
diff --git a/drivers/png/png_driver_common.h b/drivers/png/png_driver_common.h
index 62302bbdbb..24546d4402 100644
--- a/drivers/png/png_driver_common.h
+++ b/drivers/png/png_driver_common.h
@@ -43,4 +43,4 @@ Error png_to_image(const uint8_t *p_source, size_t p_size, bool p_force_linear,
Error image_to_png(const Ref<Image> &p_image, Vector<uint8_t> &p_buffer);
} // namespace PNGDriverCommon
-#endif
+#endif // PNG_DRIVER_COMMON_H
diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp
index 704ddca726..275f3240d7 100644
--- a/drivers/png/resource_saver_png.cpp
+++ b/drivers/png/resource_saver_png.cpp
@@ -35,7 +35,7 @@
#include "drivers/png/png_driver_common.h"
#include "scene/resources/texture.h"
-Error ResourceSaverPNG::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) {
+Error ResourceSaverPNG::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) {
Ref<ImageTexture> texture = p_resource;
ERR_FAIL_COND_V_MSG(!texture.is_valid(), ERR_INVALID_PARAMETER, "Can't save invalid texture as PNG.");
diff --git a/drivers/png/resource_saver_png.h b/drivers/png/resource_saver_png.h
index 1a681faaec..260a643a1b 100644
--- a/drivers/png/resource_saver_png.h
+++ b/drivers/png/resource_saver_png.h
@@ -39,7 +39,7 @@ public:
static Error save_image(const String &p_path, const Ref<Image> &p_img);
static Vector<uint8_t> save_image_to_buffer(const Ref<Image> &p_img);
- virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0);
+ virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0);
virtual bool recognize(const Ref<Resource> &p_resource) const;
virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const;
diff --git a/drivers/register_driver_types.h b/drivers/register_driver_types.h
index c008d93185..41f95b57e7 100644
--- a/drivers/register_driver_types.h
+++ b/drivers/register_driver_types.h
@@ -37,4 +37,4 @@ void unregister_core_driver_types();
void register_driver_types();
void unregister_driver_types();
-#endif
+#endif // REGISTER_DRIVER_TYPES_H
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 39dbadf3cd..b8b72b8d30 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -516,4 +516,4 @@ DirAccessUnix::~DirAccessUnix() {
list_dir_end();
}
-#endif //posix_enabled
+#endif // UNIX_ENABLED || LIBC_FILEIO_ENABLED
diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h
index 5e2129b74a..f5dca7c282 100644
--- a/drivers/unix/dir_access_unix.h
+++ b/drivers/unix/dir_access_unix.h
@@ -52,43 +52,44 @@ protected:
virtual bool is_hidden(const String &p_name);
public:
- virtual Error list_dir_begin(); ///< This starts dir listing
- virtual String get_next();
- virtual bool current_is_dir() const;
- virtual bool current_is_hidden() const;
+ virtual Error list_dir_begin() override; ///< This starts dir listing
+ virtual String get_next() override;
+ virtual bool current_is_dir() const override;
+ virtual bool current_is_hidden() const override;
- virtual void list_dir_end(); ///<
+ virtual void list_dir_end() override; ///<
- virtual int get_drive_count();
- virtual String get_drive(int p_drive);
- virtual int get_current_drive();
- virtual bool drives_are_shortcuts();
+ virtual int get_drive_count() override;
+ virtual String get_drive(int p_drive) override;
+ virtual int get_current_drive() override;
+ virtual bool drives_are_shortcuts() override;
- virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
- virtual String get_current_dir(bool p_include_drive = true) const; ///< return current dir location
- virtual Error make_dir(String p_dir);
+ virtual Error change_dir(String p_dir) override; ///< can be relative or absolute, return false on success
+ virtual String get_current_dir(bool p_include_drive = true) const override; ///< return current dir location
+ virtual Error make_dir(String p_dir) override;
- virtual bool file_exists(String p_file);
- virtual bool dir_exists(String p_dir);
- virtual bool is_readable(String p_dir);
- virtual bool is_writable(String p_dir);
+ virtual bool file_exists(String p_file) override;
+ virtual bool dir_exists(String p_dir) override;
+ virtual bool is_readable(String p_dir) override;
+ virtual bool is_writable(String p_dir) override;
virtual uint64_t get_modified_time(String p_file);
- virtual Error rename(String p_path, String p_new_path);
- virtual Error remove(String p_path);
+ virtual Error rename(String p_path, String p_new_path) override;
+ virtual Error remove(String p_path) override;
- virtual bool is_link(String p_file);
- virtual String read_link(String p_file);
- virtual Error create_link(String p_source, String p_target);
+ virtual bool is_link(String p_file) override;
+ virtual String read_link(String p_file) override;
+ virtual Error create_link(String p_source, String p_target) override;
- virtual uint64_t get_space_left();
+ virtual uint64_t get_space_left() override;
- virtual String get_filesystem_type() const;
+ virtual String get_filesystem_type() const override;
DirAccessUnix();
~DirAccessUnix();
};
-#endif //UNIX ENABLED
-#endif
+#endif // UNIX_ENABLED || LIBC_FILEIO_ENABLED
+
+#endif // DIR_ACCESS_UNIX_H
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index 99836b7bea..388ad479b9 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -339,4 +339,4 @@ FileAccessUnix::~FileAccessUnix() {
_close();
}
-#endif
+#endif // UNIX_ENABLED || LIBC_FILEIO_ENABLED
diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h
index 0261b8be53..297c34e454 100644
--- a/drivers/unix/file_access_unix.h
+++ b/drivers/unix/file_access_unix.h
@@ -54,37 +54,38 @@ class FileAccessUnix : public FileAccess {
public:
static CloseNotificationFunc close_notification_func;
- virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
- virtual bool is_open() const; ///< true when file is open
+ virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file
+ virtual bool is_open() const override; ///< true when file is open
- virtual String get_path() const; /// returns the path for the current open file
- virtual String get_path_absolute() const; /// returns the absolute path for the current open file
+ virtual String get_path() const override; /// returns the path for the current open file
+ virtual String get_path_absolute() const override; /// returns the absolute path for the current open file
- virtual void seek(uint64_t p_position); ///< seek to a given position
- virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
- virtual uint64_t get_position() const; ///< get position in the file
- virtual uint64_t get_length() const; ///< get size of the file
+ virtual void seek(uint64_t p_position) override; ///< seek to a given position
+ virtual void seek_end(int64_t p_position = 0) override; ///< seek from the end of file
+ virtual uint64_t get_position() const override; ///< get position in the file
+ virtual uint64_t get_length() const override; ///< get size of the file
- virtual bool eof_reached() const; ///< reading passed EOF
+ virtual bool eof_reached() const override; ///< reading passed EOF
- virtual uint8_t get_8() const; ///< get a byte
- virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const;
+ virtual uint8_t get_8() const override; ///< get a byte
+ virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override;
- virtual Error get_error() const; ///< get last error
+ virtual Error get_error() const override; ///< get last error
- virtual void flush();
- virtual void store_8(uint8_t p_dest); ///< store a byte
- virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes
+ virtual void flush() override;
+ virtual void store_8(uint8_t p_dest) override; ///< store a byte
+ virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes
- virtual bool file_exists(const String &p_path); ///< return true if a file exists
+ virtual bool file_exists(const String &p_path) override; ///< return true if a file exists
- virtual uint64_t _get_modified_time(const String &p_file);
- virtual uint32_t _get_unix_permissions(const String &p_file);
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
+ virtual uint64_t _get_modified_time(const String &p_file) override;
+ virtual uint32_t _get_unix_permissions(const String &p_file) override;
+ virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
FileAccessUnix() {}
virtual ~FileAccessUnix();
};
-#endif
-#endif
+#endif // UNIX_ENABLED || LIBC_FILEIO_ENABLED
+
+#endif // FILE_ACCESS_UNIX_H
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp
index 2deeb79957..0dc2efedc1 100644
--- a/drivers/unix/ip_unix.cpp
+++ b/drivers/unix/ip_unix.cpp
@@ -95,12 +95,12 @@ void IPUnix::_resolve_hostname(List<IPAddress> &r_addresses, const String &p_hos
int s = getaddrinfo(p_hostname.utf8().get_data(), nullptr, &hints, &result);
if (s != 0) {
- ERR_PRINT("getaddrinfo failed! Cannot resolve hostname.");
+ print_verbose("getaddrinfo failed! Cannot resolve hostname.");
return;
}
if (result == nullptr || result->ai_addr == nullptr) {
- ERR_PRINT("Invalid response from getaddrinfo");
+ print_verbose("Invalid response from getaddrinfo");
if (result) {
freeaddrinfo(result);
}
diff --git a/drivers/unix/ip_unix.h b/drivers/unix/ip_unix.h
index 06fcdb6e17..798d02095c 100644
--- a/drivers/unix/ip_unix.h
+++ b/drivers/unix/ip_unix.h
@@ -50,4 +50,5 @@ public:
};
#endif
+
#endif // IP_UNIX_H
diff --git a/drivers/unix/net_socket_posix.h b/drivers/unix/net_socket_posix.h
index 867513099a..5558114cb1 100644
--- a/drivers/unix/net_socket_posix.h
+++ b/drivers/unix/net_socket_posix.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef NET_SOCKET_UNIX_H
-#define NET_SOCKET_UNIX_H
+#ifndef NET_SOCKET_POSIX_H
+#define NET_SOCKET_POSIX_H
#include "core/io/net_socket.h"
@@ -104,4 +104,4 @@ public:
~NetSocketPosix();
};
-#endif
+#endif // NET_SOCKET_POSIX_H
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 091287c652..5bf14056ab 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -65,7 +65,7 @@
#include <time.h>
#include <unistd.h>
-#if defined(OSX_ENABLED) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 28)
+#if defined(MACOS_ENABLED) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 28)
// Random location for getentropy. Fitting.
#include <sys/random.h>
#define UNIX_GET_ENTROPY
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index a1ed4bd501..f4609a565b 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -98,6 +98,6 @@ public:
virtual ~UnixTerminalLogger();
};
-#endif
+#endif // UNIX_ENABLED
-#endif
+#endif // OS_UNIX_H
diff --git a/drivers/unix/syslog_logger.h b/drivers/unix/syslog_logger.h
index 697a96a6f9..cc6617eb25 100644
--- a/drivers/unix/syslog_logger.h
+++ b/drivers/unix/syslog_logger.h
@@ -43,6 +43,6 @@ public:
virtual ~SyslogLogger();
};
-#endif
+#endif // UNIX_ENABLED
-#endif
+#endif // SYSLOG_LOGGER_H
diff --git a/drivers/unix/thread_posix.h b/drivers/unix/thread_posix.h
index 9cd3ecbe90..672adcba72 100644
--- a/drivers/unix/thread_posix.h
+++ b/drivers/unix/thread_posix.h
@@ -35,4 +35,4 @@
void init_thread_posix();
#endif
-#endif
+#endif // THREAD_POSIX_H
diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub
index b6ceb1cdea..a076c0ac54 100644
--- a/drivers/vulkan/SCsub
+++ b/drivers/vulkan/SCsub
@@ -15,11 +15,11 @@ if env["use_volk"]:
if env["platform"] == "android":
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_ANDROID_KHR"])
-elif env["platform"] == "iphone":
+elif env["platform"] == "ios":
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_IOS_MVK"])
-elif env["platform"] == "linuxbsd":
+elif env["platform"] == "linuxbsd" and env["x11"]:
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_XLIB_KHR"])
-elif env["platform"] == "osx":
+elif env["platform"] == "macos":
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_MACOS_MVK"])
elif env["platform"] == "windows":
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_WIN32_KHR"])
@@ -40,7 +40,7 @@ elif env["platform"] == "android":
# Our current NDK version only provides old Vulkan headers,
# so we have to limit VMA.
env_thirdparty_vma.AppendUnique(CPPDEFINES=["VMA_VULKAN_VERSION=1000000"])
-elif env["platform"] == "osx" or env["platform"] == "iphone":
+elif env["platform"] == "macos" or env["platform"] == "ios":
# MoltenVK supports only Vulkan 1.1 API, limit VMA to the same version.
env_thirdparty_vma.AppendUnique(CPPDEFINES=["VMA_VULKAN_VERSION=1001000"])
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 9b491be128..89daa2af64 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -36,6 +36,7 @@
#include "core/io/marshalls.h"
#include "core/os/os.h"
#include "core/templates/hashfuncs.h"
+#include "core/version.h"
#include "drivers/vulkan/vulkan_context.h"
#include "thirdparty/misc/smolv.h"
@@ -106,7 +107,7 @@ RenderingDeviceVulkan::Buffer *RenderingDeviceVulkan::_get_buffer_from_owner(RID
return buffer;
}
-static void update_external_dependency_for_store(VkSubpassDependency &dependency, bool is_sampled, bool is_storage, bool is_depth) {
+static void update_external_dependency_for_store(VkSubpassDependency2KHR &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;
@@ -1758,6 +1759,10 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_create_info.usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
}
+ if (p_format.usage_bits & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) {
+ image_create_info.usage |= VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
+ }
+
if (p_format.usage_bits & TEXTURE_USAGE_CAN_UPDATE_BIT) {
image_create_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
}
@@ -1829,6 +1834,11 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
if (p_format.usage_bits & TEXTURE_USAGE_STORAGE_ATOMIC_BIT && !(flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)) {
ERR_FAIL_V_MSG(RID(), "Format " + format_text + " does not support usage as atomic storage image.");
}
+
+ // Validation via VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR fails if VRS attachment is not supported.
+ if (p_format.usage_bits & TEXTURE_USAGE_VRS_ATTACHMENT_BIT && p_format.format != DATA_FORMAT_R8_UINT) {
+ ERR_FAIL_V_MSG(RID(), "Format " + format_text + " does not support usage as VRS attachment.");
+ }
}
//some view validation
@@ -1994,6 +2004,9 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
}
RID id = texture_owner.make_rid(texture);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
if (p_data.size()) {
for (uint32_t i = 0; i < image_create_info.arrayLayers; i++) {
@@ -2123,6 +2136,9 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
texture.owner = p_with_texture;
RID id = texture_owner.make_rid(texture);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
_add_dependency(id, p_with_texture);
return id;
@@ -2242,6 +2258,9 @@ RID RenderingDeviceVulkan::texture_create_from_extension(TextureType p_type, Dat
}
RID id = texture_owner.make_rid(texture);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
return id;
}
@@ -2367,6 +2386,9 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p
texture.owner = p_with_texture;
RID id = texture_owner.make_rid(texture);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
_add_dependency(id, p_with_texture);
return id;
@@ -3349,6 +3371,11 @@ bool RenderingDeviceVulkan::texture_is_format_supported_for_usage(DataFormat p_f
return false;
}
+ // Validation via VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR fails if VRS attachment is not supported.
+ if (p_usage & TEXTURE_USAGE_VRS_ATTACHMENT_BIT && p_format != DATA_FORMAT_R8_UINT) {
+ return false;
+ }
+
return true;
}
@@ -3362,17 +3389,24 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
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
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | // From Section 7.1 of Vulkan API Spec v1.1.148
+ VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR;
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];
+ VkSubpassDependency2KHR dependencies[2] = {
+ { VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR, nullptr, VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, default_access_mask, 0, 0 },
+ { VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR, nullptr, 0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, default_access_mask, 0, 0, 0 }
+ };
+ VkSubpassDependency2KHR &dependency_from_external = dependencies[0];
+ VkSubpassDependency2KHR &dependency_to_external = dependencies[1];
LocalVector<int32_t> attachment_last_pass;
attachment_last_pass.resize(p_attachments.size());
- Vector<VkAttachmentDescription> attachments;
+ // These are only used if we use multiview but we need to define them in scope.
+ const uint32_t view_mask = (1 << p_view_count) - 1;
+ const uint32_t correlation_mask = (1 << p_view_count) - 1;
+
+ Vector<VkAttachmentDescription2KHR> attachments;
Vector<int> attachment_remap;
for (int i = 0; i < p_attachments.size(); i++) {
@@ -3383,10 +3417,12 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
ERR_FAIL_INDEX_V(p_attachments[i].format, DATA_FORMAT_MAX, VK_NULL_HANDLE);
ERR_FAIL_INDEX_V(p_attachments[i].samples, TEXTURE_SAMPLES_MAX, VK_NULL_HANDLE);
- ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)),
- VK_NULL_HANDLE, "Texture format for index (" + itos(i) + ") requires an attachment (color, depth, input or stencil) bit set.");
+ ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT | TEXTURE_USAGE_VRS_ATTACHMENT_BIT)),
+ VK_NULL_HANDLE, "Texture format for index (" + itos(i) + ") requires an attachment (color, depth-stencil, input or VRS) bit set.");
- VkAttachmentDescription description = {};
+ VkAttachmentDescription2KHR description = {};
+ description.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR;
+ description.pNext = nullptr;
description.flags = 0;
description.format = vulkan_formats[p_attachments[i].format];
description.samples = rasterization_sample_count[p_attachments[i].samples];
@@ -3395,83 +3431,95 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
bool is_storage = p_attachments[i].usage_flags & TEXTURE_USAGE_STORAGE_BIT;
bool is_depth = p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_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 synchronization 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 ? p_initial_depth_action : p_initial_action) {
- case INITIAL_ACTION_CLEAR_REGION:
- case INITIAL_ACTION_CLEAR: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
- 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_KEEP: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- 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: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- 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_CLEAR_REGION_CONTINUE:
- case INITIAL_ACTION_CONTINUE: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- description.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- } 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;
+ // We can setup a framebuffer where we write to our VRS texture to set it up.
+ // We make the assumption here that if our texture is actually used as our VRS attachment,
+ // it is used as such for each subpass. This is fairly certain seeing the restrictions on subpasses.
+ bool is_vrs = p_attachments[i].usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT && i == p_passes[0].vrs_attachment;
+
+ if (is_vrs) {
+ // For VRS we only read, there is no writing to this texture
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ description.initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ } else {
+ // 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 synchronization 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 ? p_initial_depth_action : p_initial_action) {
+ case INITIAL_ACTION_CLEAR_REGION:
+ case INITIAL_ACTION_CLEAR: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+ 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_KEEP: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ 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: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ 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_CLEAR_REGION_CONTINUE:
+ case INITIAL_ACTION_CONTINUE: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ description.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ } 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;
+ default: {
+ ERR_FAIL_V(VK_NULL_HANDLE); //should never reach here
}
- } break;
- default: {
- ERR_FAIL_V(VK_NULL_HANDLE); //should never reach here
}
}
@@ -3485,6 +3533,10 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
if (p_passes[last_pass].depth_attachment == i) {
used_last = true;
}
+ } else if (is_vrs) {
+ if (p_passes[last_pass].vrs_attachment == i) {
+ used_last = true;
+ }
} else {
if (p_passes[last_pass].resolve_attachments.size()) {
//if using resolve attachments, check resolve attachments
@@ -3526,58 +3578,69 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
}
- switch (is_depth ? final_depth_action : final_action) {
- case FINAL_ACTION_READ: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- 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_attachments[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: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- 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);
- } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- 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_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
- } 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
- }
- } break;
- case FINAL_ACTION_CONTINUE: {
- if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- description.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- } else if (p_attachments[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 = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- } 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
- }
+ if (is_vrs) {
+ // We don't change our VRS texture during this process
- } break;
- default: {
- ERR_FAIL_V(VK_NULL_HANDLE); //should never reach here
+ description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+ // TODO do we need to update our external dependency ?
+ // update_external_dependency_for_store(dependency_to_external, is_sampled, is_storage, false);
+ } else {
+ switch (is_depth ? final_depth_action : final_action) {
+ case FINAL_ACTION_READ: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ 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_attachments[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: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ 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);
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ 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_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+ } else {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.finalLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ }
+ } break;
+ case FINAL_ACTION_CONTINUE: {
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ } else if (p_attachments[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 = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ } else {
+ description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ description.finalLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ }
+
+ } break;
+ default: {
+ ERR_FAIL_V(VK_NULL_HANDLE); //should never reach here
+ }
}
}
@@ -3586,12 +3649,14 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
attachments.push_back(description);
}
- LocalVector<VkSubpassDescription> subpasses;
- LocalVector<LocalVector<VkAttachmentReference>> color_reference_array;
- LocalVector<LocalVector<VkAttachmentReference>> input_reference_array;
- LocalVector<LocalVector<VkAttachmentReference>> resolve_reference_array;
+ LocalVector<VkSubpassDescription2KHR> subpasses;
+ LocalVector<LocalVector<VkAttachmentReference2KHR>> color_reference_array;
+ LocalVector<LocalVector<VkAttachmentReference2KHR>> input_reference_array;
+ LocalVector<LocalVector<VkAttachmentReference2KHR>> resolve_reference_array;
LocalVector<LocalVector<uint32_t>> preserve_reference_array;
- LocalVector<VkAttachmentReference> depth_reference_array;
+ LocalVector<VkAttachmentReference2KHR> depth_reference_array;
+ LocalVector<VkAttachmentReference2KHR> vrs_reference_array;
+ LocalVector<VkFragmentShadingRateAttachmentInfoKHR> vrs_attachment_info_array;
subpasses.resize(p_passes.size());
color_reference_array.resize(p_passes.size());
@@ -3599,20 +3664,25 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
resolve_reference_array.resize(p_passes.size());
preserve_reference_array.resize(p_passes.size());
depth_reference_array.resize(p_passes.size());
+ vrs_reference_array.resize(p_passes.size());
+ vrs_attachment_info_array.resize(p_passes.size());
- LocalVector<VkSubpassDependency> subpass_dependencies;
+ LocalVector<VkSubpassDependency2KHR> subpass_dependencies;
for (int i = 0; i < p_passes.size(); i++) {
const FramebufferPass *pass = &p_passes[i];
- LocalVector<VkAttachmentReference> &color_references = color_reference_array[i];
+ LocalVector<VkAttachmentReference2KHR> &color_references = color_reference_array[i];
TextureSamples texture_samples = TEXTURE_SAMPLES_1;
bool is_multisample_first = true;
+ void *subpass_nextptr = nullptr;
for (int j = 0; j < pass->color_attachments.size(); j++) {
int32_t attachment = pass->color_attachments[j];
- VkAttachmentReference reference;
+ VkAttachmentReference2KHR reference;
+ reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
+ reference.pNext = nullptr;
if (attachment == FramebufferPass::ATTACHMENT_UNUSED) {
reference.attachment = VK_ATTACHMENT_UNUSED;
reference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -3631,14 +3701,17 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachment_last_pass[attachment] = i;
}
+ reference.aspectMask = 0;
color_references.push_back(reference);
}
- LocalVector<VkAttachmentReference> &input_references = input_reference_array[i];
+ LocalVector<VkAttachmentReference2KHR> &input_references = input_reference_array[i];
for (int j = 0; j < pass->input_attachments.size(); j++) {
int32_t attachment = pass->input_attachments[j];
- VkAttachmentReference reference;
+ VkAttachmentReference2KHR reference;
+ reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
+ reference.pNext = nullptr;
if (attachment == FramebufferPass::ATTACHMENT_UNUSED) {
reference.attachment = VK_ATTACHMENT_UNUSED;
reference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -3650,10 +3723,11 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
reference.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
attachment_last_pass[attachment] = i;
}
+ reference.aspectMask = 0; // TODO we need to set this here, possibly VK_IMAGE_ASPECT_COLOR_BIT ??
input_references.push_back(reference);
}
- LocalVector<VkAttachmentReference> &resolve_references = resolve_reference_array[i];
+ LocalVector<VkAttachmentReference2KHR> &resolve_references = resolve_reference_array[i];
if (pass->resolve_attachments.size() > 0) {
ERR_FAIL_COND_V_MSG(pass->resolve_attachments.size() != pass->color_attachments.size(), VK_NULL_HANDLE, "The amount of resolve attachments (" + itos(pass->resolve_attachments.size()) + ") must match the number of color attachments (" + itos(pass->color_attachments.size()) + ").");
@@ -3661,7 +3735,9 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
for (int j = 0; j < pass->resolve_attachments.size(); j++) {
int32_t attachment = pass->resolve_attachments[j];
- VkAttachmentReference reference;
+ VkAttachmentReference2KHR reference;
+ reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
+ reference.pNext = nullptr;
if (attachment == FramebufferPass::ATTACHMENT_UNUSED) {
reference.attachment = VK_ATTACHMENT_UNUSED;
reference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -3676,10 +3752,13 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
attachment_last_pass[attachment] = i;
}
+ reference.aspectMask = 0;
resolve_references.push_back(reference);
}
- VkAttachmentReference &depth_stencil_reference = depth_reference_array[i];
+ VkAttachmentReference2KHR &depth_stencil_reference = depth_reference_array[i];
+ depth_stencil_reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
+ depth_stencil_reference.pNext = nullptr;
if (pass->depth_attachment != FramebufferPass::ATTACHMENT_UNUSED) {
int32_t attachment = pass->depth_attachment;
@@ -3688,6 +3767,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
depth_stencil_reference.attachment = attachment_remap[attachment];
depth_stencil_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ depth_stencil_reference.aspectMask = 0;
attachment_last_pass[attachment] = i;
if (is_multisample_first) {
@@ -3702,6 +3782,32 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
depth_stencil_reference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
}
+ if (context->get_vrs_capabilities().attachment_vrs_supported && pass->vrs_attachment != FramebufferPass::ATTACHMENT_UNUSED) {
+ int32_t attachment = pass->vrs_attachment;
+ ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer VRS format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), VRS attachment.");
+ ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer VRS format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it's marked as VRS, but it's not a VRS attachment.");
+ ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer VRS attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
+
+ VkAttachmentReference2KHR &vrs_reference = vrs_reference_array[i];
+ vrs_reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
+ vrs_reference.pNext = nullptr;
+ vrs_reference.attachment = attachment_remap[attachment];
+ vrs_reference.layout = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR;
+ vrs_reference.aspectMask = 0;
+
+ Size2i texel_size = context->get_vrs_capabilities().max_texel_size;
+
+ VkFragmentShadingRateAttachmentInfoKHR &vrs_attachment_info = vrs_attachment_info_array[i];
+ vrs_attachment_info.sType = VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR;
+ vrs_attachment_info.pNext = nullptr;
+ vrs_attachment_info.pFragmentShadingRateAttachment = &vrs_reference;
+ vrs_attachment_info.shadingRateAttachmentTexelSize = { uint32_t(texel_size.x), uint32_t(texel_size.y) };
+
+ attachment_last_pass[attachment] = i;
+
+ subpass_nextptr = &vrs_attachment_info;
+ }
+
LocalVector<uint32_t> &preserve_references = preserve_reference_array[i];
for (int j = 0; j < pass->preserve_attachments.size(); j++) {
@@ -3718,9 +3824,17 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
}
- VkSubpassDescription &subpass = subpasses[i];
+ VkSubpassDescription2KHR &subpass = subpasses[i];
+ subpass.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR;
+ subpass.pNext = subpass_nextptr;
subpass.flags = 0;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+ if (p_view_count == 1) {
+ // VUID-VkSubpassDescription2-multiview-06558: If the multiview feature is not enabled, viewMask must be 0.
+ subpass.viewMask = 0;
+ } else {
+ subpass.viewMask = view_mask;
+ }
subpass.inputAttachmentCount = input_references.size();
if (input_references.size()) {
subpass.pInputAttachments = input_references.ptr();
@@ -3757,7 +3871,9 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
if (i > 0) {
- VkSubpassDependency dependency;
+ VkSubpassDependency2KHR dependency;
+ dependency.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR;
+ dependency.pNext = nullptr;
dependency.srcSubpass = i - 1;
dependency.dstSubpass = i;
dependency.srcStageMask = 0;
@@ -3767,6 +3883,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
+ dependency.viewOffset = 0;
subpass_dependencies.push_back(dependency);
}
/*
@@ -3784,10 +3901,11 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
*/
}
- VkRenderPassCreateInfo render_pass_create_info;
- render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+ VkRenderPassCreateInfo2KHR render_pass_create_info;
+ render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR;
render_pass_create_info.pNext = nullptr;
render_pass_create_info.flags = 0;
+
render_pass_create_info.attachmentCount = attachments.size();
render_pass_create_info.pAttachments = attachments.ptr();
render_pass_create_info.subpassCount = subpasses.size();
@@ -3804,13 +3922,21 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
render_pass_create_info.pDependencies = nullptr;
}
- // These are only used if we use multiview but we need to define them in scope.
- const uint32_t view_mask = (1 << p_view_count) - 1;
- const uint32_t correlation_mask = (1 << p_view_count) - 1;
+ if (p_view_count == 1) {
+ // VUID-VkRenderPassCreateInfo2-viewMask-03057: If the VkSubpassDescription2::viewMask member of all elements of pSubpasses is 0, correlatedViewMaskCount must be 0.
+ render_pass_create_info.correlatedViewMaskCount = 0;
+ render_pass_create_info.pCorrelatedViewMasks = nullptr;
+ } else {
+ render_pass_create_info.correlatedViewMaskCount = 1;
+ render_pass_create_info.pCorrelatedViewMasks = &correlation_mask;
+ }
+
Vector<uint32_t> view_masks;
VkRenderPassMultiviewCreateInfo render_pass_multiview_create_info;
if (p_view_count > 1) {
+ // this may no longer be needed with the new settings already including this
+
const VulkanContext::MultiviewCapabilities capabilities = context->get_multiview_capabilities();
// For now this only works with multiview!
@@ -3837,8 +3963,8 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
VkRenderPass render_pass;
- VkResult res = vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass);
- ERR_FAIL_COND_V_MSG(res, VK_NULL_HANDLE, "vkCreateRenderPass failed with error " + itos(res) + ".");
+ VkResult res = context->vkCreateRenderPass2KHR(device, &render_pass_create_info, nullptr, &render_pass);
+ ERR_FAIL_COND_V_MSG(res, VK_NULL_HANDLE, "vkCreateRenderPass2KHR failed with error " + itos(res) + ".");
return render_pass;
}
@@ -3857,7 +3983,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
passes.push_back(pass);
return framebuffer_format_create_multipass(p_format, passes, p_view_count);
}
-RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, Vector<FramebufferPass> &p_passes, uint32_t p_view_count) {
+RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, const Vector<FramebufferPass> &p_passes, uint32_t p_view_count) {
_THREAD_SAFE_METHOD_
FramebufferFormatKey key;
@@ -3899,9 +4025,12 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
return E->get();
}
- VkSubpassDescription subpass;
+ VkSubpassDescription2KHR subpass;
+ subpass.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR;
+ subpass.pNext = nullptr;
subpass.flags = 0;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+ subpass.viewMask = 0;
subpass.inputAttachmentCount = 0; //unsupported for now
subpass.pInputAttachments = nullptr;
subpass.colorAttachmentCount = 0;
@@ -3911,8 +4040,8 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
subpass.preserveAttachmentCount = 0;
subpass.pPreserveAttachments = nullptr;
- VkRenderPassCreateInfo render_pass_create_info;
- render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+ VkRenderPassCreateInfo2KHR render_pass_create_info;
+ render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR;
render_pass_create_info.pNext = nullptr;
render_pass_create_info.flags = 0;
render_pass_create_info.attachmentCount = 0;
@@ -3921,11 +4050,13 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
render_pass_create_info.pSubpasses = &subpass;
render_pass_create_info.dependencyCount = 0;
render_pass_create_info.pDependencies = nullptr;
+ render_pass_create_info.correlatedViewMaskCount = 0;
+ render_pass_create_info.pCorrelatedViewMasks = nullptr;
VkRenderPass render_pass;
- VkResult res = vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass);
+ VkResult res = context->vkCreateRenderPass2KHR(device, &render_pass_create_info, nullptr, &render_pass);
- ERR_FAIL_COND_V_MSG(res, 0, "vkCreateRenderPass for empty fb failed with error " + itos(res) + ".");
+ ERR_FAIL_COND_V_MSG(res, 0, "vkCreateRenderPass2KHR for empty fb failed with error " + itos(res) + ".");
if (render_pass == VK_NULL_HANDLE) { //was likely invalid
return INVALID_ID;
@@ -3963,7 +4094,11 @@ RID RenderingDeviceVulkan::framebuffer_create_empty(const Size2i &p_size, Textur
framebuffer.size = p_size;
framebuffer.view_count = 1;
- return framebuffer_owner.make_rid(framebuffer);
+ RID id = framebuffer_owner.make_rid(framebuffer);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
+ return id;
}
RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check, uint32_t p_view_count) {
@@ -3978,6 +4113,8 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac
if (texture && texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
pass.depth_attachment = i;
+ } else if (texture && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) {
+ pass.vrs_attachment = i;
} else {
pass.color_attachments.push_back(texture ? i : FramebufferPass::ATTACHMENT_UNUSED);
}
@@ -3989,7 +4126,7 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac
return framebuffer_create_multipass(p_texture_attachments, passes, p_format_check, p_view_count);
}
-RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_texture_attachments, Vector<FramebufferPass> &p_passes, FramebufferFormatID p_format_check, uint32_t p_view_count) {
+RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_texture_attachments, const Vector<FramebufferPass> &p_passes, FramebufferFormatID p_format_check, uint32_t p_view_count) {
_THREAD_SAFE_METHOD_
Vector<AttachmentFormat> attachments;
@@ -4008,6 +4145,10 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex
size.width = texture->width;
size.height = texture->height;
size_set = true;
+ } else if (texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) {
+ // If this is not the first attachement we assume this is used as the VRS attachment
+ // in this case this texture will be 1/16th the size of the color attachement.
+ // So we skip the size check
} else {
ERR_FAIL_COND_V_MSG((uint32_t)size.width != texture->width || (uint32_t)size.height != texture->height, RID(),
"All textures in a framebuffer should be the same size.");
@@ -4037,6 +4178,9 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex
framebuffer.view_count = p_view_count;
RID id = framebuffer_owner.make_rid(framebuffer);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
for (int i = 0; i < p_texture_attachments.size(); i++) {
if (p_texture_attachments[i].is_valid()) {
@@ -4056,6 +4200,22 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_get_form
return framebuffer->format_id;
}
+bool RenderingDeviceVulkan::framebuffer_is_valid(RID p_framebuffer) const {
+ _THREAD_SAFE_METHOD_
+
+ return framebuffer_owner.owns(p_framebuffer);
+}
+
+void RenderingDeviceVulkan::framebuffer_set_invalidation_callback(RID p_framebuffer, InvalidationCallback p_callback, void *p_userdata) {
+ _THREAD_SAFE_METHOD_
+
+ Framebuffer *framebuffer = framebuffer_owner.get_or_null(p_framebuffer);
+ ERR_FAIL_COND(!framebuffer);
+
+ framebuffer->invalidated_callback = p_callback;
+ framebuffer->invalidated_callback_userdata = p_userdata;
+}
+
/*****************/
/**** SAMPLER ****/
/*****************/
@@ -4098,7 +4258,11 @@ RID RenderingDeviceVulkan::sampler_create(const SamplerState &p_state) {
VkResult res = vkCreateSampler(device, &sampler_create_info, nullptr, &sampler);
ERR_FAIL_COND_V_MSG(res, RID(), "vkCreateSampler failed with error " + itos(res) + ".");
- return sampler_owner.make_rid(sampler);
+ RID id = sampler_owner.make_rid(sampler);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
+ return id;
}
/**********************/
@@ -4127,7 +4291,11 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vec
_buffer_memory_barrier(buffer.buffer, 0, data_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, false);
}
- return vertex_buffer_owner.make_rid(buffer);
+ RID id = vertex_buffer_owner.make_rid(buffer);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
+ return id;
}
// 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
@@ -4288,7 +4456,11 @@ RID RenderingDeviceVulkan::index_buffer_create(uint32_t p_index_count, IndexBuff
_buffer_update(&index_buffer, 0, r, data_size);
_buffer_memory_barrier(index_buffer.buffer, 0, data_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT, false);
}
- return index_buffer_owner.make_rid(index_buffer);
+ RID id = index_buffer_owner.make_rid(index_buffer);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
+ return id;
}
RID RenderingDeviceVulkan::index_array_create(RID p_index_buffer, uint32_t p_index_offset, uint32_t p_index_count) {
@@ -4556,7 +4728,7 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
#define SHADER_BINARY_VERSION 3
String RenderingDeviceVulkan::shader_get_binary_cache_key() const {
- return "Vulkan-SV" + itos(SHADER_BINARY_VERSION);
+ return "Vulkan-SV" + itos(SHADER_BINARY_VERSION) + "-" + String(VERSION_NUMBER) + "-" + String(VERSION_HASH);
}
struct RenderingDeviceVulkanShaderBinaryDataBinding {
@@ -4730,7 +4902,7 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
}
if (may_be_writable) {
- info.writable = !(bool)(binding.type_description->decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE);
+ info.writable = !(binding.type_description->decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE) && !(binding.block.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE);
} else {
info.writable = false;
}
@@ -4757,6 +4929,10 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
ERR_FAIL_COND_V_MSG(uniform_info[set][k].length != info.length, Vector<uint8_t>(),
"On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different uniform size.");
+ //also, verify that it has the same writability
+ ERR_FAIL_COND_V_MSG(uniform_info[set][k].writable != info.writable, Vector<uint8_t>(),
+ "On shader stage '" + String(shader_stage_names[stage]) + "', uniform '" + binding.name + "' trying to re-use location for set=" + itos(set) + ", binding=" + itos(info.binding) + " with different writability.");
+
//just append stage mask and return
uniform_info.write[set].write[k].stages |= 1 << stage;
exists = true;
@@ -5056,7 +5232,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
ERR_FAIL_COND_V(binptr[0] != 'G' || binptr[1] != 'V' || binptr[2] != 'B' || binptr[3] != 'D', RID());
uint32_t bin_version = decode_uint32(binptr + 4);
- ERR_FAIL_COND_V(bin_version > SHADER_BINARY_VERSION, RID());
+ ERR_FAIL_COND_V(bin_version != SHADER_BINARY_VERSION, RID());
uint32_t bin_data_size = decode_uint32(binptr + 8);
@@ -5381,7 +5557,11 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
ERR_FAIL_V_MSG(RID(), error_text);
}
- return shader_owner.make_rid(shader);
+ RID id = shader_owner.make_rid(shader);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
+ return id;
}
uint32_t RenderingDeviceVulkan::shader_get_vertex_input_attribute_mask(RID p_shader) {
@@ -5414,7 +5594,11 @@ RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Ve
_buffer_update(&buffer, 0, r, data_size);
_buffer_memory_barrier(buffer.buffer, 0, data_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_UNIFORM_READ_BIT, false);
}
- return uniform_buffer_owner.make_rid(buffer);
+ RID id = uniform_buffer_owner.make_rid(buffer);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
+ return id;
}
RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data, uint32_t p_usage) {
@@ -5485,7 +5669,11 @@ RID RenderingDeviceVulkan::texture_buffer_create(uint32_t p_size_elements, DataF
}
//allocate the view
- return texture_buffer_owner.make_rid(texture_buffer);
+ RID id = texture_buffer_owner.make_rid(texture_buffer);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
+ return id;
}
RenderingDeviceVulkan::DescriptorPool *RenderingDeviceVulkan::_descriptor_pool_allocate(const DescriptorPoolKey &p_key) {
@@ -6064,6 +6252,9 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
uniform_set.shader_id = p_shader;
RID id = uniform_set_owner.make_rid(uniform_set);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
//add dependencies
_add_dependency(id, p_shader);
for (uint32_t i = 0; i < uniform_count; i++) {
@@ -6089,7 +6280,7 @@ bool RenderingDeviceVulkan::uniform_set_is_valid(RID p_uniform_set) {
return uniform_set_owner.owns(p_uniform_set);
}
-void RenderingDeviceVulkan::uniform_set_set_invalidation_callback(RID p_uniform_set, UniformSetInvalidatedCallback p_callback, void *p_userdata) {
+void RenderingDeviceVulkan::uniform_set_set_invalidation_callback(RID p_uniform_set, InvalidationCallback p_callback, void *p_userdata) {
UniformSet *us = uniform_set_owner.get_or_null(p_uniform_set);
ERR_FAIL_COND(!us);
us->invalidated_callback = p_callback;
@@ -6552,11 +6743,28 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
dynamic_state_create_info.dynamicStateCount = dynamic_states.size();
dynamic_state_create_info.pDynamicStates = dynamic_states.ptr();
+ void *graphics_pipeline_nextptr = nullptr;
+
+ VkPipelineFragmentShadingRateStateCreateInfoKHR vrs_create_info;
+ if (context->get_vrs_capabilities().attachment_vrs_supported) {
+ // If VRS is used, this defines how the different VRS types are combined.
+ // combinerOps[0] decides how we use the output of pipeline and primitive (drawcall) VRS
+ // combinerOps[1] decides how we use the output of combinerOps[0] and our attachment VRS
+
+ vrs_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR;
+ vrs_create_info.pNext = nullptr;
+ vrs_create_info.fragmentSize = { 4, 4 };
+ vrs_create_info.combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; // We don't use pipeline/primitive VRS so this really doesn't matter
+ vrs_create_info.combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR; // always use the outcome of attachment VRS if enabled
+
+ graphics_pipeline_nextptr = &vrs_create_info;
+ }
+
//finally, pipeline create info
VkGraphicsPipelineCreateInfo graphics_pipeline_create_info;
graphics_pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
- graphics_pipeline_create_info.pNext = nullptr;
+ graphics_pipeline_create_info.pNext = graphics_pipeline_nextptr;
graphics_pipeline_create_info.flags = 0;
Vector<VkPipelineShaderStageCreateInfo> pipeline_stages = shader->pipeline_stages;
@@ -6669,6 +6877,9 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
#endif
//create ID to associate with this pipeline
RID id = render_pipeline_owner.make_rid(pipeline);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
//now add all the dependencies
_add_dependency(id, p_shader);
return id;
@@ -6721,7 +6932,7 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader, const Vector<Pi
const PipelineSpecializationConstant &psc = p_specialization_constants[j];
if (psc.constant_id == sc.constant.constant_id) {
ERR_FAIL_COND_V_MSG(psc.type != sc.constant.type, RID(), "Specialization constant provided for id (" + itos(sc.constant.constant_id) + ") is of the wrong type.");
- data_ptr[i] = sc.constant.int_value;
+ data_ptr[i] = psc.int_value;
break;
}
}
@@ -6758,6 +6969,9 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader, const Vector<Pi
//create ID to associate with this pipeline
RID id = compute_pipeline_owner.make_rid(pipeline);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
//now add all the dependencies
_add_dependency(id, p_shader);
return id;
@@ -6905,8 +7119,10 @@ Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebu
Texture *texture = texture_owner.get_or_null(p_framebuffer->texture_ids[i]);
if (texture) {
attachments.push_back(texture->view);
- ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG);
- ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG);
+ if (!(texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT)) { // VRS attachment will be a different size.
+ ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG);
+ ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG);
+ }
}
}
framebuffer_create_info.attachmentCount = attachments.size();
@@ -7041,7 +7257,6 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
}
void RenderingDeviceVulkan::_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) {
- ERR_FAIL_COND_MSG(p_clear_color && p_clear_colors.size() != framebuffer->texture_ids.size(), "Clear color values supplied (" + itos(p_clear_colors.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(framebuffer->texture_ids.size()) + ").");
Vector<VkClearAttachment> clear_attachments;
int color_index = 0;
int texture_index = 0;
@@ -7130,11 +7345,14 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
}
}
- if (p_initial_color_action == INITIAL_ACTION_CLEAR) { //check clear values
+ if (p_initial_color_action == INITIAL_ACTION_CLEAR || needs_clear_color) { //check clear values
int color_count = 0;
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
- if (!texture || !(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
+ // We only check for our VRS usage bit if this is not the first texture id.
+ // If it is the first we're likely populating our VRS texture.
+ // Bit dirty but..
+ if (!texture || (!(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && !(i != 0 && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT))) {
color_count++;
}
}
@@ -7227,7 +7445,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
}
}
- if (p_initial_color_action == INITIAL_ACTION_CLEAR) { //check clear values
+ if (p_initial_color_action == INITIAL_ACTION_CLEAR || needs_clear_color) { //check clear values
int color_count = 0;
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
@@ -8535,6 +8753,11 @@ void RenderingDeviceVulkan::_free_internal(RID p_id) {
} else if (framebuffer_owner.owns(p_id)) {
Framebuffer *framebuffer = framebuffer_owner.get_or_null(p_id);
frames[frame].framebuffers_to_dispose_of.push_back(*framebuffer);
+
+ if (framebuffer->invalidated_callback != nullptr) {
+ framebuffer->invalidated_callback(framebuffer->invalidated_callback_userdata);
+ }
+
framebuffer_owner.free(p_id);
} else if (sampler_owner.owns(p_id)) {
VkSampler *sampler = sampler_owner.get_or_null(p_id);
@@ -8995,17 +9218,6 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de
{
device_capabilities.version_major = p_context->get_vulkan_major();
device_capabilities.version_minor = p_context->get_vulkan_minor();
-
- // get info about subgroups
- VulkanContext::SubgroupCapabilities subgroup_capabilities = p_context->get_subgroup_capabilities();
- device_capabilities.subgroup_size = subgroup_capabilities.size;
- device_capabilities.subgroup_in_shaders = subgroup_capabilities.supported_stages_flags_rd();
- device_capabilities.subgroup_operations = subgroup_capabilities.supported_operations_flags_rd();
-
- // get info about further features
- VulkanContext::MultiviewCapabilities multiview_capabilies = p_context->get_multiview_capabilities();
- device_capabilities.supports_multiview = multiview_capabilies.is_supported && multiview_capabilies.max_view_count > 1;
- device_capabilities.supports_fsr_half_float = p_context->get_shader_capabilities().shader_float16_is_supported && p_context->get_storage_buffer_capabilities().storage_buffer_16_bit_access_is_supported;
}
context = p_context;
@@ -9354,7 +9566,7 @@ String RenderingDeviceVulkan::get_captured_timestamp_name(uint32_t p_index) cons
return frames[frame].timestamp_result_names[p_index];
}
-uint64_t RenderingDeviceVulkan::limit_get(Limit p_limit) {
+uint64_t RenderingDeviceVulkan::limit_get(Limit p_limit) const {
switch (p_limit) {
case LIMIT_MAX_BOUND_UNIFORM_SETS:
return limits.maxBoundDescriptorSets;
@@ -9424,7 +9636,18 @@ uint64_t RenderingDeviceVulkan::limit_get(Limit p_limit) {
return limits.maxComputeWorkGroupSize[1];
case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z:
return limits.maxComputeWorkGroupSize[2];
-
+ case LIMIT_SUBGROUP_SIZE: {
+ VulkanContext::SubgroupCapabilities subgroup_capabilities = context->get_subgroup_capabilities();
+ return subgroup_capabilities.size;
+ }
+ case LIMIT_SUBGROUP_IN_SHADERS: {
+ VulkanContext::SubgroupCapabilities subgroup_capabilities = context->get_subgroup_capabilities();
+ return subgroup_capabilities.supported_stages_flags_rd();
+ }
+ case LIMIT_SUBGROUP_OPERATIONS: {
+ VulkanContext::SubgroupCapabilities subgroup_capabilities = context->get_subgroup_capabilities();
+ return subgroup_capabilities.supported_operations_flags_rd();
+ }
default:
ERR_FAIL_V(0);
}
@@ -9524,6 +9747,25 @@ RenderingDevice *RenderingDeviceVulkan::create_local_device() {
return rd;
}
+bool RenderingDeviceVulkan::has_feature(const Features p_feature) const {
+ switch (p_feature) {
+ case SUPPORTS_MULTIVIEW: {
+ VulkanContext::MultiviewCapabilities multiview_capabilies = context->get_multiview_capabilities();
+ return multiview_capabilies.is_supported && multiview_capabilies.max_view_count > 1;
+ } break;
+ case SUPPORTS_FSR_HALF_FLOAT: {
+ return context->get_shader_capabilities().shader_float16_is_supported && context->get_storage_buffer_capabilities().storage_buffer_16_bit_access_is_supported;
+ } break;
+ case SUPPORTS_ATTACHMENT_VRS: {
+ VulkanContext::VRSCapabilities vrs_capabilities = context->get_vrs_capabilities();
+ return vrs_capabilities.attachment_vrs_supported;
+ } break;
+ default: {
+ return false;
+ }
+ }
+}
+
RenderingDeviceVulkan::RenderingDeviceVulkan() {
device_capabilities.device_family = DEVICE_VULKAN;
}
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index ec9e864370..d98ac1114b 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -241,6 +241,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
Vector<AttachmentFormat> attachments;
Vector<FramebufferPass> passes;
uint32_t view_count = 1;
+
bool operator<(const FramebufferFormatKey &p_key) const {
if (view_count != p_key.view_count) {
return view_count < p_key.view_count;
@@ -391,6 +392,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t storage_mask = 0;
Vector<RID> texture_ids;
+ InvalidationCallback invalidated_callback = nullptr;
+ void *invalidated_callback_userdata = nullptr;
struct Version {
VkFramebuffer framebuffer = VK_NULL_HANDLE;
@@ -746,7 +749,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
LocalVector<AttachableTexture> attachable_textures; //used for validation
Vector<Texture *> mutable_sampled_textures; //used for layout change
Vector<Texture *> mutable_storage_textures; //used for layout change
- UniformSetInvalidatedCallback invalidated_callback = nullptr;
+ InvalidationCallback invalidated_callback = nullptr;
void *invalidated_callback_userdata = nullptr;
};
@@ -1058,13 +1061,15 @@ public:
/*********************/
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format, uint32_t p_view_count = 1);
- virtual FramebufferFormatID framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, Vector<FramebufferPass> &p_passes, uint32_t p_view_count = 1);
+ virtual FramebufferFormatID framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, const Vector<FramebufferPass> &p_passes, uint32_t p_view_count = 1);
virtual FramebufferFormatID framebuffer_format_create_empty(TextureSamples p_samples = TEXTURE_SAMPLES_1);
virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format, uint32_t p_pass = 0);
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1);
- virtual RID framebuffer_create_multipass(const Vector<RID> &p_texture_attachments, Vector<FramebufferPass> &p_passes, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1);
+ virtual RID framebuffer_create_multipass(const Vector<RID> &p_texture_attachments, const Vector<FramebufferPass> &p_passes, FramebufferFormatID p_format_check = INVALID_ID, uint32_t p_view_count = 1);
virtual RID framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples = TEXTURE_SAMPLES_1, FramebufferFormatID p_format_check = INVALID_ID);
+ virtual bool framebuffer_is_valid(RID p_framebuffer) const;
+ virtual void framebuffer_set_invalidation_callback(RID p_framebuffer, InvalidationCallback p_callback, void *p_userdata);
virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer);
@@ -1109,7 +1114,7 @@ public:
virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set);
virtual bool uniform_set_is_valid(RID p_uniform_set);
- virtual void uniform_set_set_invalidation_callback(RID p_uniform_set, UniformSetInvalidatedCallback p_callback, void *p_userdata);
+ virtual void uniform_set_set_invalidation_callback(RID p_uniform_set, InvalidationCallback p_callback, void *p_userdata);
virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL); //works for any buffer
virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL);
@@ -1203,7 +1208,7 @@ public:
/**** Limits ****/
/****************/
- virtual uint64_t limit_get(Limit p_limit);
+ virtual uint64_t limit_get(Limit p_limit) const;
virtual void prepare_screen_for_drawing();
void initialize(VulkanContext *p_context, bool p_local_device = false);
@@ -1234,6 +1239,8 @@ public:
virtual uint64_t get_driver_resource(DriverResource p_resource, RID p_rid = RID(), uint64_t p_index = 0);
+ virtual bool has_feature(const Features p_feature) const;
+
RenderingDeviceVulkan();
~RenderingDeviceVulkan();
};
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 2bf173a398..a9a8ce68ac 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -48,6 +48,18 @@
VulkanHooks *VulkanContext::vulkan_hooks = nullptr;
+VkResult VulkanContext::vkCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
+ if (fpCreateRenderPass2KHR == nullptr) {
+ fpCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)vkGetInstanceProcAddr(inst, "vkCreateRenderPass2KHR");
+ }
+
+ if (fpCreateRenderPass2KHR == nullptr) {
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ } else {
+ return (fpCreateRenderPass2KHR)(device, pCreateInfo, pAllocator, pRenderPass);
+ }
+}
+
VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
@@ -215,13 +227,13 @@ VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char *const *c
Error VulkanContext::_get_preferred_validation_layers(uint32_t *count, const char *const **names) {
static const LocalVector<LocalVector<const char *>> instance_validation_layers_alt{
- // Preferred set of validation layers
+ // Preferred set of validation layers.
{ "VK_LAYER_KHRONOS_validation" },
- // Alternative (deprecated, removed in SDK 1.1.126.0) set of validation layers
+ // Alternative (deprecated, removed in SDK 1.1.126.0) set of validation layers.
{ "VK_LAYER_LUNARG_standard_validation" },
- // Alternative (deprecated, removed in SDK 1.1.121.1) set of validation layers
+ // Alternative (deprecated, removed in SDK 1.1.121.1) set of validation layers.
{ "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation", "VK_LAYER_GOOGLE_unique_objects" }
};
@@ -269,7 +281,7 @@ typedef VkResult(VKAPI_PTR *_vkEnumerateInstanceVersion)(uint32_t *);
Error VulkanContext::_obtain_vulkan_version() {
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkApplicationInfo.html#_description
- // for Vulkan 1.0 vkEnumerateInstanceVersion is not available, including not in the loader we compile against on Android.
+ // For Vulkan 1.0 vkEnumerateInstanceVersion is not available, including not in the loader we compile against on Android.
_vkEnumerateInstanceVersion func = (_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion");
if (func != nullptr) {
uint32_t api_version;
@@ -279,15 +291,15 @@ Error VulkanContext::_obtain_vulkan_version() {
vulkan_minor = VK_API_VERSION_MINOR(api_version);
vulkan_patch = VK_API_VERSION_PATCH(api_version);
} else {
- // according to the documentation this shouldn't fail with anything except a memory allocation error
- // in which case we're in deep trouble anyway
+ // According to the documentation this shouldn't fail with anything except a memory allocation error
+ // in which case we're in deep trouble anyway.
ERR_FAIL_V(ERR_CANT_CREATE);
}
} else {
print_line("vkEnumerateInstanceVersion not available, assuming Vulkan 1.0.");
}
- // we don't go above 1.2
+ // We don't go above 1.2.
if ((vulkan_major > 1) || (vulkan_major == 1 && vulkan_minor > 2)) {
vulkan_major = 1;
vulkan_minor = 2;
@@ -303,7 +315,7 @@ Error VulkanContext::_initialize_extensions() {
enabled_extension_count = 0;
enabled_debug_utils = false;
enabled_debug_report = false;
- /* Look for instance extensions */
+ // Look for instance extensions.
VkBool32 surfaceExtFound = 0;
VkBool32 platformSurfaceExtFound = 0;
memset(extension_names, 0, sizeof(extension_names));
@@ -403,7 +415,7 @@ String VulkanContext::SubgroupCapabilities::supported_stages_desc() const {
res += ", STAGE_COMPUTE";
}
- /* these are not defined on Android GRMBL */
+ // These are not defined on Android GRMBL.
if (supportedStages & 0x00000100 /* VK_SHADER_STAGE_RAYGEN_BIT_KHR */) {
res += ", STAGE_RAYGEN_KHR";
}
@@ -429,7 +441,7 @@ String VulkanContext::SubgroupCapabilities::supported_stages_desc() const {
res += ", STAGE_MESH_NV";
}
- return res.substr(2); // remove first ", "
+ return res.substr(2); // Remove first ", "
}
uint32_t VulkanContext::SubgroupCapabilities::supported_operations_flags_rd() const {
@@ -494,19 +506,22 @@ String VulkanContext::SubgroupCapabilities::supported_operations_desc() const {
res += ", FEATURE_PARTITIONED_NV";
}
- return res.substr(2); // remove first ", "
+ return res.substr(2); // Remove first ", "
}
Error VulkanContext::_check_capabilities() {
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_multiview.html
// https://www.khronos.org/blog/vulkan-subgroup-tutorial
- // for Vulkan 1.0 vkGetPhysicalDeviceProperties2 is not available, including not in the loader we compile against on Android.
+ // For Vulkan 1.0 vkGetPhysicalDeviceProperties2 is not available, including not in the loader we compile against on Android.
- // so we check if the functions are accessible by getting their function pointers and skipping if not
- // (note that the desktop loader does a better job here but the android loader doesn't)
+ // So we check if the functions are accessible by getting their function pointers and skipping if not
+ // (note that the desktop loader does a better job here but the android loader doesn't.)
- // assume not supported until proven otherwise
+ // Assume not supported until proven otherwise.
+ vrs_capabilities.pipeline_vrs_supported = false;
+ vrs_capabilities.primitive_vrs_supported = false;
+ vrs_capabilities.attachment_vrs_supported = false;
multiview_capabilities.is_supported = false;
multiview_capabilities.geometry_shader_is_supported = false;
multiview_capabilities.tessellation_shader_is_supported = false;
@@ -523,17 +538,25 @@ Error VulkanContext::_check_capabilities() {
storage_buffer_capabilities.storage_push_constant_16_is_supported = false;
storage_buffer_capabilities.storage_input_output_16 = false;
- // check for extended features
+ // Check for extended features.
PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2");
if (vkGetPhysicalDeviceFeatures2_func == nullptr) {
- // In Vulkan 1.0 might be accessible under its original extension name
+ // In Vulkan 1.0 might be accessible under its original extension name.
vkGetPhysicalDeviceFeatures2_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2KHR");
}
if (vkGetPhysicalDeviceFeatures2_func != nullptr) {
- // check our extended features
+ // Check our extended features.
+ VkPhysicalDeviceFragmentShadingRateFeaturesKHR vrs_features = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR,
+ /*pNext*/ nullptr,
+ /*pipelineFragmentShadingRate*/ false,
+ /*primitiveFragmentShadingRate*/ false,
+ /*attachmentFragmentShadingRate*/ false,
+ };
+
VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features = {
/*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR,
- /*pNext*/ nullptr,
+ /*pNext*/ &vrs_features,
/*shaderFloat16*/ false,
/*shaderInt8*/ false,
};
@@ -561,6 +584,10 @@ Error VulkanContext::_check_capabilities() {
vkGetPhysicalDeviceFeatures2_func(gpu, &device_features);
+ vrs_capabilities.pipeline_vrs_supported = vrs_features.pipelineFragmentShadingRate;
+ vrs_capabilities.primitive_vrs_supported = vrs_features.primitiveFragmentShadingRate;
+ vrs_capabilities.attachment_vrs_supported = vrs_features.attachmentFragmentShadingRate;
+
multiview_capabilities.is_supported = multiview_features.multiview;
multiview_capabilities.geometry_shader_is_supported = multiview_features.multiviewGeometryShader;
multiview_capabilities.tessellation_shader_is_supported = multiview_features.multiviewTessellationShader;
@@ -574,31 +601,40 @@ Error VulkanContext::_check_capabilities() {
storage_buffer_capabilities.storage_input_output_16 = storage_feature.storageInputOutput16;
}
- // check extended properties
+ // Check extended properties.
PFN_vkGetPhysicalDeviceProperties2 device_properties_func = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceProperties2");
if (device_properties_func == nullptr) {
- // In Vulkan 1.0 might be accessible under its original extension name
+ // In Vulkan 1.0 might be accessible under its original extension name.
device_properties_func = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceProperties2KHR");
}
if (device_properties_func != nullptr) {
+ VkPhysicalDeviceFragmentShadingRatePropertiesKHR vrsProperties;
VkPhysicalDeviceMultiviewProperties multiviewProperties;
VkPhysicalDeviceSubgroupProperties subgroupProperties;
VkPhysicalDeviceProperties2 physicalDeviceProperties;
+ void *nextptr = nullptr;
subgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
- subgroupProperties.pNext = nullptr;
-
- physicalDeviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+ subgroupProperties.pNext = nextptr;
+ nextptr = &subgroupProperties;
if (multiview_capabilities.is_supported) {
multiviewProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
- multiviewProperties.pNext = &subgroupProperties;
+ multiviewProperties.pNext = nextptr;
- physicalDeviceProperties.pNext = &multiviewProperties;
- } else {
- physicalDeviceProperties.pNext = &subgroupProperties;
+ nextptr = &multiviewProperties;
+ }
+
+ if (vrs_capabilities.attachment_vrs_supported) {
+ vrsProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR;
+ vrsProperties.pNext = nextptr;
+
+ nextptr = &vrsProperties;
}
+ physicalDeviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+ physicalDeviceProperties.pNext = nextptr;
+
device_properties_func(gpu, &physicalDeviceProperties);
subgroup_capabilities.size = subgroupProperties.subgroupSize;
@@ -609,6 +645,28 @@ Error VulkanContext::_check_capabilities() {
// - supportedOperations has VK_SUBGROUP_FEATURE_QUAD_BIT
subgroup_capabilities.quadOperationsInAllStages = subgroupProperties.quadOperationsInAllStages;
+ if (vrs_capabilities.pipeline_vrs_supported || vrs_capabilities.primitive_vrs_supported || vrs_capabilities.attachment_vrs_supported) {
+ print_verbose("- Vulkan Variable Rate Shading supported:");
+ if (vrs_capabilities.pipeline_vrs_supported) {
+ print_verbose(" Pipeline fragment shading rate");
+ }
+ if (vrs_capabilities.primitive_vrs_supported) {
+ print_verbose(" Primitive fragment shading rate");
+ }
+ if (vrs_capabilities.attachment_vrs_supported) {
+ // TODO expose these somehow to the end user
+ vrs_capabilities.min_texel_size.x = vrsProperties.minFragmentShadingRateAttachmentTexelSize.width;
+ vrs_capabilities.min_texel_size.y = vrsProperties.minFragmentShadingRateAttachmentTexelSize.height;
+ vrs_capabilities.max_texel_size.x = vrsProperties.maxFragmentShadingRateAttachmentTexelSize.width;
+ vrs_capabilities.max_texel_size.y = vrsProperties.maxFragmentShadingRateAttachmentTexelSize.height;
+
+ print_verbose(String(" Attachment fragment shading rate") + String(", min texel size: (") + itos(vrs_capabilities.min_texel_size.x) + String(", ") + itos(vrs_capabilities.min_texel_size.y) + String(")") + String(", max texel size: (") + itos(vrs_capabilities.max_texel_size.x) + String(", ") + itos(vrs_capabilities.max_texel_size.y) + String(")"));
+ }
+
+ } else {
+ print_verbose("- Vulkan Variable Rate Shading not supported");
+ }
+
if (multiview_capabilities.is_supported) {
multiview_capabilities.max_view_count = multiviewProperties.maxMultiviewViewCount;
multiview_capabilities.max_instance_count = multiviewProperties.maxMultiviewInstanceIndex;
@@ -635,10 +693,10 @@ Error VulkanContext::_check_capabilities() {
}
Error VulkanContext::_create_instance() {
- /* obtain version */
+ // Obtain Vulkan version.
_obtain_vulkan_version();
- /* initialise extensions */
+ // Initialize extensions.
{
Error err = _initialize_extensions();
if (err != OK) {
@@ -726,8 +784,7 @@ Error VulkanContext::_create_instance() {
#endif
if (enabled_debug_utils) {
- // Setup VK_EXT_debug_utils function pointers always (we use them for
- // debug labels and names).
+ // Setup VK_EXT_debug_utils function pointers always (we use them for debug labels and names).
CreateDebugUtilsMessengerEXT =
(PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(inst, "vkCreateDebugUtilsMessengerEXT");
DestroyDebugUtilsMessengerEXT =
@@ -800,7 +857,7 @@ Error VulkanContext::_create_instance() {
}
Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
- /* Make initial call to query gpu_count, then second call for gpu info*/
+ // Make initial call to query gpu_count, then second call for gpu info.
uint32_t gpu_count = 0;
VkResult err = vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
@@ -836,7 +893,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
return ERR_CANT_CREATE;
}
- // not really needed but nice to print the correct entry
+ // Not really needed but nice to print the correct entry.
for (uint32_t i = 0; i < gpu_count; ++i) {
if (physical_devices[i] == gpu) {
device_index = i;
@@ -948,13 +1005,13 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
free(physical_devices);
- /* Look for device extensions */
+ // Look for device extensions.
uint32_t device_extension_count = 0;
VkBool32 swapchainExtFound = 0;
enabled_extension_count = 0;
memset(extension_names, 0, sizeof(extension_names));
- /* Get identifier properties */
+ // Get identifier properties.
vkGetPhysicalDeviceProperties(gpu, &gpu_props);
device_name = gpu_props.deviceName;
@@ -996,9 +1053,16 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
extension_names[enabled_extension_count++] = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
}
if (!strcmp(VK_KHR_MULTIVIEW_EXTENSION_NAME, device_extensions[i].extensionName)) {
- // if multiview is supported, enable it
+ // If multiview is supported, enable it.
extension_names[enabled_extension_count++] = VK_KHR_MULTIVIEW_EXTENSION_NAME;
}
+ if (!strcmp(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, device_extensions[i].extensionName)) {
+ // if shading rate image is supported, enable it
+ extension_names[enabled_extension_count++] = VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME;
+ }
+ if (!strcmp(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, device_extensions[i].extensionName)) {
+ extension_names[enabled_extension_count++] = VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME;
+ }
if (enabled_extension_count >= MAX_EXTENSIONS) {
free(device_extensions);
ERR_FAIL_V_MSG(ERR_BUG, "Enabled extension count reaches MAX_EXTENSIONS, BUG");
@@ -1049,19 +1113,18 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
" extension.\n\nDo you have a compatible Vulkan installable client driver (ICD) installed?\n"
"vkCreateInstance Failure");
- /* Call with nullptr data to get count */
+ // Call with nullptr data to get count.
vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, nullptr);
ERR_FAIL_COND_V(queue_family_count == 0, ERR_CANT_CREATE);
queue_props = (VkQueueFamilyProperties *)malloc(queue_family_count * sizeof(VkQueueFamilyProperties));
vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, queue_props);
-
// Query fine-grained feature support for this device.
// If app has specific feature requirements it should check supported
// 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
+ physical_device_features.robustBufferAccess = false; // Turn off robust buffer access, which can hamper performance on some hardware.
#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
{ \
@@ -1076,7 +1139,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfacePresentModesKHR);
GET_INSTANCE_PROC_ADDR(inst, GetSwapchainImagesKHR);
- // get info about what our vulkan driver is capable off
+ // Gets capability info for current Vulkan driver.
{
Error res = _check_capabilities();
if (res != OK) {
@@ -1110,11 +1173,23 @@ Error VulkanContext::_create_device() {
};
nextptr = &shader_features;
+ VkPhysicalDeviceFragmentShadingRateFeaturesKHR vrs_features;
+ if (vrs_capabilities.pipeline_vrs_supported || vrs_capabilities.primitive_vrs_supported || vrs_capabilities.attachment_vrs_supported) {
+ // insert into our chain to enable these features if they are available
+ vrs_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR;
+ vrs_features.pNext = nextptr;
+ vrs_features.pipelineFragmentShadingRate = vrs_capabilities.pipeline_vrs_supported;
+ vrs_features.primitiveFragmentShadingRate = vrs_capabilities.primitive_vrs_supported;
+ vrs_features.attachmentFragmentShadingRate = vrs_capabilities.attachment_vrs_supported;
+
+ nextptr = &vrs_features;
+ }
+
VkPhysicalDeviceVulkan11Features vulkan11features;
VkPhysicalDevice16BitStorageFeaturesKHR storage_feature;
VkPhysicalDeviceMultiviewFeatures multiview_features;
if (vulkan_major > 1 || vulkan_minor >= 2) {
- // In Vulkan 1.2 and newer we use a newer struct to enable various features
+ // In Vulkan 1.2 and newer we use a newer struct to enable various features.
vulkan11features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
vulkan11features.pNext = nextptr;
@@ -1132,7 +1207,7 @@ Error VulkanContext::_create_device() {
vulkan11features.shaderDrawParameters = 0;
nextptr = &vulkan11features;
} else {
- // On Vulkan 1.0 and 1.1 we use our older structs to initialise these features
+ // On Vulkan 1.0 and 1.1 we use our older structs to initialise these features.
storage_feature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
storage_feature.pNext = nextptr;
storage_feature.storageBuffer16BitAccess = storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported;
@@ -1161,7 +1236,7 @@ Error VulkanContext::_create_device() {
/*ppEnabledLayerNames*/ nullptr,
/*enabledExtensionCount*/ enabled_extension_count,
/*ppEnabledExtensionNames*/ (const char *const *)extension_names,
- /*pEnabledFeatures*/ &physical_device_features, // If specific features are required, pass them in here
+ /*pEnabledFeatures*/ &physical_device_features, // If specific features are required, pass them in here.
};
if (separate_present_queue) {
queues[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@@ -1193,7 +1268,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
}
// Search for a graphics and a present queue in the array of queue
- // families, try to find one that supports both
+ // families, try to find one that supports both.
uint32_t graphicsQueueFamilyIndex = UINT32_MAX;
uint32_t presentQueueFamilyIndex = UINT32_MAX;
for (uint32_t i = 0; i < queue_family_count; i++) {
@@ -1223,7 +1298,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
free(supportsPresent);
- // Generate error if could not find both a graphics and a present queue
+ // Generate error if could not find both a graphics and a present queue.
ERR_FAIL_COND_V_MSG(graphicsQueueFamilyIndex == UINT32_MAX || presentQueueFamilyIndex == UINT32_MAX, ERR_CANT_CREATE,
"Could not find both graphics and present queues\n");
@@ -1279,7 +1354,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
color_space = surfFormats[0].colorSpace;
} else {
// These should be ordered with the ones we want to use on top and fallback modes further down
- // we want an 32bit RGBA unsigned normalised buffer or similar
+ // we want a 32bit RGBA unsigned normalised buffer or similar.
const VkFormat allowed_formats[] = {
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_R8G8B8A8_UNORM
@@ -1291,7 +1366,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "formatCount less than 1");
}
- // Find the first format that we support
+ // Find the first format that we support.
format = VK_FORMAT_UNDEFINED;
for (uint32_t af = 0; af < allowed_formats_count && format == VK_FORMAT_UNDEFINED; af++) {
for (uint32_t sf = 0; sf < formatCount && format == VK_FORMAT_UNDEFINED; sf++) {
@@ -1323,7 +1398,7 @@ Error VulkanContext::_create_semaphores() {
VkResult err;
// Create semaphores to synchronize acquiring presentable buffers before
- // rendering and waiting for drawing to be complete before presenting
+ // rendering and waiting for drawing to be complete before presenting.
VkSemaphoreCreateInfo semaphoreCreateInfo = {
/*sType*/ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
/*pNext*/ nullptr,
@@ -1331,7 +1406,7 @@ Error VulkanContext::_create_semaphores() {
};
// Create fences that we can use to throttle if we get too far
- // ahead of the image presents
+ // ahead of the image presents.
VkFenceCreateInfo fence_ci = {
/*sType*/ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
/*pNext*/ nullptr,
@@ -1351,7 +1426,7 @@ Error VulkanContext::_create_semaphores() {
}
frame_index = 0;
- // Get Memory information and properties
+ // Get Memory information and properties.
vkGetPhysicalDeviceMemoryProperties(gpu, &memory_properties);
return OK;
@@ -1426,7 +1501,7 @@ bool VulkanContext::window_is_valid_swapchain(DisplayServer::WindowID p_window)
VkRenderPass VulkanContext::window_get_render_pass(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE);
Window *w = &windows[p_window];
- //vulkan use of currentbuffer
+ // Vulkan use of currentbuffer.
return w->render_pass;
}
@@ -1434,7 +1509,7 @@ VkFramebuffer VulkanContext::window_get_framebuffer(DisplayServer::WindowID p_wi
ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE);
ERR_FAIL_COND_V(!buffers_prepared, VK_NULL_HANDLE);
Window *w = &windows[p_window];
- //vulkan use of currentbuffer
+ // Vulkan use of currentbuffer.
if (w->swapchain_image_resources != VK_NULL_HANDLE) {
return w->swapchain_image_resources[w->current_buffer].framebuffer;
} else {
@@ -1459,7 +1534,7 @@ Error VulkanContext::_clean_up_swap_chain(Window *window) {
}
vkDeviceWaitIdle(device);
- //this destroys images associated it seems
+ // This destroys images associated it seems.
fpDestroySwapchainKHR(device, window->swapchain, nullptr);
window->swapchain = VK_NULL_HANDLE;
vkDestroyRenderPass(device, window->render_pass, nullptr);
@@ -1485,7 +1560,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
_clean_up_swap_chain(window);
}
- // Check the surface capabilities and formats
+ // Check the surface capabilities and formats.
VkSurfaceCapabilitiesKHR surfCapabilities;
err = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu, window->surface, &surfCapabilities);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
@@ -1502,7 +1577,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
}
VkExtent2D swapchainExtent;
- // width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF.
+ // Width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF.
if (surfCapabilities.currentExtent.width == 0xFFFFFFFF) {
// If the surface size is undefined, the size is set to the size
// of the images requested, which must fit within the minimum and
@@ -1522,7 +1597,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
swapchainExtent.height = surfCapabilities.maxImageExtent.height;
}
} else {
- // If the surface size is defined, the swap chain size must match
+ // If the surface size is defined, the swap chain size must match.
swapchainExtent = surfCapabilities.currentExtent;
window->width = surfCapabilities.currentExtent.width;
window->height = surfCapabilities.currentExtent.height;
@@ -1530,7 +1605,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
if (window->width == 0 || window->height == 0) {
free(presentModes);
- //likely window minimized, no swapchain created
+ // Likely window minimized, no swapchain created.
return OK;
}
// The FIFO present mode is guaranteed by the spec to be supported
@@ -1591,8 +1666,23 @@ Error VulkanContext::_update_swap_chain(Window *window) {
if (present_mode_available) {
window->presentMode = requested_present_mode;
} else {
- WARN_PRINT("Requested VSync mode is not available!");
- window->vsync_mode = DisplayServer::VSYNC_ENABLED; //Set to default
+ String present_mode_string;
+ switch (window->vsync_mode) {
+ case DisplayServer::VSYNC_MAILBOX:
+ present_mode_string = "Mailbox";
+ break;
+ case DisplayServer::VSYNC_ADAPTIVE:
+ present_mode_string = "Adaptive";
+ break;
+ case DisplayServer::VSYNC_ENABLED:
+ present_mode_string = "Enabled";
+ break;
+ case DisplayServer::VSYNC_DISABLED:
+ present_mode_string = "Disabled";
+ break;
+ }
+ WARN_PRINT(vformat("The requested V-Sync mode %s is not available. Falling back to V-Sync mode Enabled.", present_mode_string));
+ window->vsync_mode = DisplayServer::VSYNC_ENABLED; // Set to default.
}
print_verbose("Using present mode: " + String(string_VkPresentModeKHR(window->presentMode)));
@@ -1601,13 +1691,13 @@ Error VulkanContext::_update_swap_chain(Window *window) {
// Determine the number of VkImages to use in the swap chain.
// Application desires to acquire 3 images at a time for triple
- // buffering
+ // buffering.
uint32_t desiredNumOfSwapchainImages = 3;
if (desiredNumOfSwapchainImages < surfCapabilities.minImageCount) {
desiredNumOfSwapchainImages = surfCapabilities.minImageCount;
}
// If maxImageCount is 0, we can ask for as many images as we want;
- // otherwise we're limited to maxImageCount
+ // otherwise we're limited to maxImageCount.
if ((surfCapabilities.maxImageCount > 0) && (desiredNumOfSwapchainImages > surfCapabilities.maxImageCount)) {
// Application must settle for fewer images than desired:
desiredNumOfSwapchainImages = surfCapabilities.maxImageCount;
@@ -1620,7 +1710,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
preTransform = surfCapabilities.currentTransform;
}
- // Find a supported composite alpha mode - one of these is guaranteed to be set
+ // Find a supported composite alpha mode - one of these is guaranteed to be set.
VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4] = {
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
@@ -1667,7 +1757,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
if (swapchainImageCount == 0) {
- //assign here for the first time.
+ // Assign here for the first time.
swapchainImageCount = sp_image_count;
} else {
ERR_FAIL_COND_V(swapchainImageCount != sp_image_count, ERR_BUG);
@@ -1725,7 +1815,9 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/******** FRAMEBUFFER ************/
{
- const VkAttachmentDescription attachment = {
+ const VkAttachmentDescription2KHR attachment = {
+ /*sType*/ VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR,
+ /*pNext*/ nullptr,
/*flags*/ 0,
/*format*/ format,
/*samples*/ VK_SAMPLE_COUNT_1_BIT,
@@ -1737,14 +1829,20 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*finalLayout*/ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
};
- const VkAttachmentReference color_reference = {
+ const VkAttachmentReference2KHR color_reference = {
+ /*sType*/ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR,
+ /*pNext*/ nullptr,
/*attachment*/ 0,
/*layout*/ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ /*aspectMask*/ 0,
};
- const VkSubpassDescription subpass = {
+ const VkSubpassDescription2KHR subpass = {
+ /*sType*/ VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR,
+ /*pNext*/ nullptr,
/*flags*/ 0,
/*pipelineBindPoint*/ VK_PIPELINE_BIND_POINT_GRAPHICS,
+ /*viewMask*/ 0,
/*inputAttachmentCount*/ 0,
/*pInputAttachments*/ nullptr,
/*colorAttachmentCount*/ 1,
@@ -1754,8 +1852,9 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*preserveAttachmentCount*/ 0,
/*pPreserveAttachments*/ nullptr,
};
- const VkRenderPassCreateInfo rp_info = {
- /*sTyp*/ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+
+ const VkRenderPassCreateInfo2KHR rp_info = {
+ /*sType*/ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR,
/*pNext*/ nullptr,
/*flags*/ 0,
/*attachmentCount*/ 1,
@@ -1764,9 +1863,11 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*pSubpasses*/ &subpass,
/*dependencyCount*/ 0,
/*pDependencies*/ nullptr,
+ /*correlatedViewMaskCount*/ 0,
+ /*pCorrelatedViewMasks*/ nullptr,
};
- err = vkCreateRenderPass(device, &rp_info, nullptr, &window->render_pass);
+ err = vkCreateRenderPass2KHR(device, &rp_info, nullptr, &window->render_pass);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
for (uint32_t i = 0; i < swapchainImageCount; i++) {
@@ -1839,7 +1940,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
}
}
- //reset current buffer
+ // Reset current buffer.
window->current_buffer = 0;
return OK;
@@ -1874,16 +1975,16 @@ void VulkanContext::append_command_buffer(VkCommandBuffer p_command_buffer) {
}
void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
- // ensure everything else pending is executed
+ // Ensure everything else pending is executed.
vkDeviceWaitIdle(device);
- //flush the pending setup buffer
+ // Flush the pending setup buffer.
bool setup_flushable = p_flush_setup && command_buffer_queue[0];
bool pending_flushable = p_flush_pending && command_buffer_count > 1;
if (setup_flushable) {
- //use a fence to wait for everything done
+ // Use a fence to wait for everything done.
VkSubmitInfo submit_info;
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit_info.pNext = nullptr;
@@ -1900,7 +2001,7 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
}
if (pending_flushable) {
- //use a fence to wait for everything done
+ // Use a fence to wait for everything to finish.
VkSubmitInfo submit_info;
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
@@ -1928,7 +2029,7 @@ Error VulkanContext::prepare_buffers() {
VkResult err;
- // Ensure no more than FRAME_LAG renderings are outstanding
+ // Ensure no more than FRAME_LAG renderings are outstanding.
vkWaitForFences(device, 1, &fences[frame_index], VK_TRUE, UINT64_MAX);
vkResetFences(device, 1, &fences[frame_index]);
@@ -1948,13 +2049,13 @@ Error VulkanContext::prepare_buffers() {
w->image_acquired_semaphores[frame_index], VK_NULL_HANDLE, &w->current_buffer);
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
- // swapchain is out of date (e.g. the window was resized) and
+ // Swapchain is out of date (e.g. the window was resized) and
// must be recreated:
print_verbose("Vulkan: Early out of date swapchain, recreating.");
- //resize_notify();
+ // resize_notify();
_update_swap_chain(w);
} else if (err == VK_SUBOPTIMAL_KHR) {
- // swapchain is not as optimal as it could be, but the platform's
+ // Swapchain is not as optimal as it could be, but the platform's
// presentation engine will still present the image correctly.
print_verbose("Vulkan: Early suboptimal swapchain.");
break;
@@ -2001,7 +2102,7 @@ Error VulkanContext::swap_buffers() {
uint32_t commands_to_submit = 0;
if (command_buffer_queue[0] == nullptr) {
- //no setup command, but commands to submit, submit from the first and skip command
+ // No setup command, but commands to submit, submit from the first and skip command.
if (command_buffer_count > 1) {
commands_ptr = command_buffer_queue.ptr() + 1;
commands_to_submit = command_buffer_count - 1;
@@ -2044,7 +2145,7 @@ Error VulkanContext::swap_buffers() {
if (separate_present_queue) {
// If we are using separate queues, change image ownership to the
// present queue before presenting, waiting for the draw complete
- // semaphore and signalling the ownership released semaphore when finished
+ // semaphore and signalling the ownership released semaphore when finished.
VkFence nullFence = VK_NULL_HANDLE;
pipe_stage_flags[0] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
submit_info.waitSemaphoreCount = 1;
@@ -2071,7 +2172,7 @@ Error VulkanContext::swap_buffers() {
}
// If we are using separate queues, we have to wait for image ownership,
- // otherwise wait for draw complete
+ // otherwise wait for draw complete.
VkPresentInfoKHR present = {
/*sType*/ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
/*pNext*/ nullptr,
@@ -2176,12 +2277,12 @@ Error VulkanContext::swap_buffers() {
frame_index %= FRAME_LAG;
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
- // swapchain is out of date (e.g. the window was resized) and
+ // Swapchain is out of date (e.g. the window was resized) and
// must be recreated:
print_verbose("Vulkan: Swapchain is out of date, recreating.");
resize_notify();
} else if (err == VK_SUBOPTIMAL_KHR) {
- // swapchain is not as optimal as it could be, but the platform's
+ // Swapchain is not as optimal as it could be, but the platform's
// presentation engine will still present the image correctly.
print_verbose("Vulkan: Swapchain is suboptimal.");
} else {
@@ -2226,7 +2327,7 @@ VkPhysicalDeviceLimits VulkanContext::get_device_limits() const {
RID VulkanContext::local_device_create() {
LocalDevice ld;
- { //create device
+ { // Create device.
VkResult err;
float queue_priorities[1] = { 0.0 };
VkDeviceQueueCreateInfo queues[2];
@@ -2247,13 +2348,13 @@ RID VulkanContext::local_device_create() {
/*ppEnabledLayerNames */ nullptr,
/*enabledExtensionCount */ enabled_extension_count,
/*ppEnabledExtensionNames */ (const char *const *)extension_names,
- /*pEnabledFeatures */ &physical_device_features, // If specific features are required, pass them in here
+ /*pEnabledFeatures */ &physical_device_features, // If specific features are required, pass them in here.
};
err = vkCreateDevice(gpu, &sdevice, nullptr, &ld.device);
ERR_FAIL_COND_V(err, RID());
}
- { //create graphics queue
+ { // Create graphics queue.
vkGetDeviceQueue(ld.device, graphics_queue_family_index, 0, &ld.queue);
}
@@ -2315,7 +2416,7 @@ void VulkanContext::command_begin_label(VkCommandBuffer p_command_buffer, String
return;
}
- CharString cs = p_label_name.utf8().get_data();
+ CharString cs = p_label_name.utf8();
VkDebugUtilsLabelEXT label;
label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
label.pNext = nullptr;
@@ -2331,7 +2432,7 @@ void VulkanContext::command_insert_label(VkCommandBuffer p_command_buffer, Strin
if (!enabled_debug_utils) {
return;
}
- CharString cs = p_label_name.utf8().get_data();
+ CharString cs = p_label_name.utf8();
VkDebugUtilsLabelEXT label;
label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
label.pNext = nullptr;
@@ -2385,12 +2486,12 @@ String VulkanContext::get_device_pipeline_cache_uuid() const {
}
DisplayServer::VSyncMode VulkanContext::get_vsync_mode(DisplayServer::WindowID p_window) const {
- ERR_FAIL_COND_V_MSG(!windows.has(p_window), DisplayServer::VSYNC_ENABLED, "Could not get VSync mode for window with WindowID " + itos(p_window) + " because it does not exist.");
+ ERR_FAIL_COND_V_MSG(!windows.has(p_window), DisplayServer::VSYNC_ENABLED, "Could not get V-Sync mode for window with WindowID " + itos(p_window) + " because it does not exist.");
return windows[p_window].vsync_mode;
}
void VulkanContext::set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode) {
- ERR_FAIL_COND_MSG(!windows.has(p_window), "Could not set VSync mode for window with WindowID " + itos(p_window) + " because it does not exist.");
+ ERR_FAIL_COND_MSG(!windows.has(p_window), "Could not set V-Sync mode for window with WindowID " + itos(p_window) + " because it does not exist.");
windows[p_window].vsync_mode = p_mode;
_update_swap_chain(&windows[p_window]);
}
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index e96facfacb..35e7ce7db8 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -69,6 +69,15 @@ public:
uint32_t max_instance_count;
};
+ struct VRSCapabilities {
+ bool pipeline_vrs_supported; // We can specify our fragment rate on a pipeline level
+ bool primitive_vrs_supported; // We can specify our fragment rate on each drawcall
+ bool attachment_vrs_supported; // We can provide a density map attachment on our framebuffer
+
+ Size2i min_texel_size;
+ Size2i max_texel_size;
+ };
+
struct ShaderCapabilities {
bool shader_float16_is_supported;
bool shader_int8_is_supported;
@@ -104,6 +113,7 @@ private:
uint32_t vulkan_patch = 0;
SubgroupCapabilities subgroup_capabilities;
MultiviewCapabilities multiview_capabilities;
+ VRSCapabilities vrs_capabilities;
ShaderCapabilities shader_capabilities;
StorageBufferCapabilities storage_buffer_capabilities;
@@ -206,6 +216,7 @@ private:
PFN_vkQueuePresentKHR fpQueuePresentKHR = nullptr;
PFN_vkGetRefreshCycleDurationGOOGLE fpGetRefreshCycleDurationGOOGLE = nullptr;
PFN_vkGetPastPresentationTimingGOOGLE fpGetPastPresentationTimingGOOGLE = nullptr;
+ PFN_vkCreateRenderPass2KHR fpCreateRenderPass2KHR = nullptr;
VkDebugUtilsMessengerEXT dbg_messenger = VK_NULL_HANDLE;
VkDebugReportCallbackEXT dbg_debug_report = VK_NULL_HANDLE;
@@ -256,12 +267,16 @@ protected:
Error _get_preferred_validation_layers(uint32_t *count, const char *const **names);
public:
+ // Extension calls
+ VkResult vkCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass);
+
uint32_t get_vulkan_major() const { return vulkan_major; };
uint32_t get_vulkan_minor() const { return vulkan_minor; };
- SubgroupCapabilities get_subgroup_capabilities() const { return subgroup_capabilities; };
- MultiviewCapabilities get_multiview_capabilities() const { return multiview_capabilities; };
- ShaderCapabilities get_shader_capabilities() const { return shader_capabilities; };
- StorageBufferCapabilities get_storage_buffer_capabilities() const { return storage_buffer_capabilities; };
+ const SubgroupCapabilities &get_subgroup_capabilities() const { return subgroup_capabilities; };
+ const MultiviewCapabilities &get_multiview_capabilities() const { return multiview_capabilities; };
+ const VRSCapabilities &get_vrs_capabilities() const { return vrs_capabilities; };
+ const ShaderCapabilities &get_shader_capabilities() const { return shader_capabilities; };
+ const StorageBufferCapabilities &get_storage_buffer_capabilities() const { return storage_buffer_capabilities; };
VkDevice get_device();
VkPhysicalDevice get_physical_device();
@@ -315,4 +330,4 @@ public:
virtual ~VulkanContext();
};
-#endif // VULKAN_DEVICE_H
+#endif // VULKAN_CONTEXT_H
diff --git a/drivers/vulkan/vulkan_hooks.h b/drivers/vulkan/vulkan_hooks.h
index 3f244b4d45..dec2042d0d 100644
--- a/drivers/vulkan/vulkan_hooks.h
+++ b/drivers/vulkan/vulkan_hooks.h
@@ -45,4 +45,4 @@ public:
virtual ~VulkanHooks(){};
};
-#endif
+#endif // VULKAN_HOOKS_H
diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h
index 89ed90e97b..9058077a1f 100644
--- a/drivers/wasapi/audio_driver_wasapi.h
+++ b/drivers/wasapi/audio_driver_wasapi.h
@@ -120,4 +120,5 @@ public:
};
#endif // WASAPI_ENABLED
+
#endif // AUDIO_DRIVER_WASAPI_H
diff --git a/drivers/windows/dir_access_windows.h b/drivers/windows/dir_access_windows.h
index fbb07ddef8..c2835b3347 100644
--- a/drivers/windows/dir_access_windows.h
+++ b/drivers/windows/dir_access_windows.h
@@ -54,33 +54,33 @@ class DirAccessWindows : public DirAccess {
bool _cishidden = false;
public:
- virtual Error list_dir_begin(); ///< This starts dir listing
- virtual String get_next();
- virtual bool current_is_dir() const;
- virtual bool current_is_hidden() const;
- virtual void list_dir_end(); ///<
+ virtual Error list_dir_begin() override; ///< This starts dir listing
+ virtual String get_next() override;
+ virtual bool current_is_dir() const override;
+ virtual bool current_is_hidden() const override;
+ virtual void list_dir_end() override; ///<
- virtual int get_drive_count();
- virtual String get_drive(int p_drive);
+ virtual int get_drive_count() override;
+ virtual String get_drive(int p_drive) override;
- virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
- virtual String get_current_dir(bool p_include_drive = true) const; ///< return current dir location
+ virtual Error change_dir(String p_dir) override; ///< can be relative or absolute, return false on success
+ virtual String get_current_dir(bool p_include_drive = true) const override; ///< return current dir location
- virtual bool file_exists(String p_file);
- virtual bool dir_exists(String p_dir);
+ virtual bool file_exists(String p_file) override;
+ virtual bool dir_exists(String p_dir) override;
- virtual Error make_dir(String p_dir);
+ virtual Error make_dir(String p_dir) override;
- virtual Error rename(String p_path, String p_new_path);
- virtual Error remove(String p_path);
+ virtual Error rename(String p_path, String p_new_path) override;
+ virtual Error remove(String p_path) override;
- virtual bool is_link(String p_file) { return false; };
- virtual String read_link(String p_file) { return p_file; };
- virtual Error create_link(String p_source, String p_target) { return FAILED; };
+ virtual bool is_link(String p_file) override { return false; };
+ virtual String read_link(String p_file) override { return p_file; };
+ virtual Error create_link(String p_source, String p_target) override { return FAILED; };
- uint64_t get_space_left();
+ uint64_t get_space_left() override;
- virtual String get_filesystem_type() const;
+ virtual String get_filesystem_type() const override;
DirAccessWindows();
~DirAccessWindows();
diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h
index 5d67b6ca4f..8629bb936b 100644
--- a/drivers/windows/file_access_windows.h
+++ b/drivers/windows/file_access_windows.h
@@ -51,33 +51,33 @@ class FileAccessWindows : public FileAccess {
void _close();
public:
- virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
- virtual bool is_open() const; ///< true when file is open
+ virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file
+ virtual bool is_open() const override; ///< true when file is open
- virtual String get_path() const; /// returns the path for the current open file
- virtual String get_path_absolute() const; /// returns the absolute path for the current open file
+ virtual String get_path() const override; /// returns the path for the current open file
+ virtual String get_path_absolute() const override; /// returns the absolute path for the current open file
- virtual void seek(uint64_t p_position); ///< seek to a given position
- virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
- virtual uint64_t get_position() const; ///< get position in the file
- virtual uint64_t get_length() const; ///< get size of the file
+ virtual void seek(uint64_t p_position) override; ///< seek to a given position
+ virtual void seek_end(int64_t p_position = 0) override; ///< seek from the end of file
+ virtual uint64_t get_position() const override; ///< get position in the file
+ virtual uint64_t get_length() const override; ///< get size of the file
- virtual bool eof_reached() const; ///< reading passed EOF
+ virtual bool eof_reached() const override; ///< reading passed EOF
- virtual uint8_t get_8() const; ///< get a byte
- virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const;
+ virtual uint8_t get_8() const override; ///< get a byte
+ virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override;
- virtual Error get_error() const; ///< get last error
+ virtual Error get_error() const override; ///< get last error
- virtual void flush();
- virtual void store_8(uint8_t p_dest); ///< store a byte
- virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes
+ virtual void flush() override;
+ virtual void store_8(uint8_t p_dest) override; ///< store a byte
+ virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes
- virtual bool file_exists(const String &p_name); ///< return true if a file exists
+ virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
- uint64_t _get_modified_time(const String &p_file);
- virtual uint32_t _get_unix_permissions(const String &p_file);
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
+ uint64_t _get_modified_time(const String &p_file) override;
+ virtual uint32_t _get_unix_permissions(const String &p_file) override;
+ virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
FileAccessWindows() {}
virtual ~FileAccessWindows();
diff --git a/drivers/winmidi/midi_driver_winmidi.h b/drivers/winmidi/midi_driver_winmidi.h
index 6572ba0c16..e42f3df4cf 100644
--- a/drivers/winmidi/midi_driver_winmidi.h
+++ b/drivers/winmidi/midi_driver_winmidi.h
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef WINMIDI_ENABLED
-
#ifndef MIDI_DRIVER_WINMIDI_H
#define MIDI_DRIVER_WINMIDI_H
+#ifdef WINMIDI_ENABLED
+
#include "core/os/midi_driver.h"
#include "core/templates/vector.h"
@@ -57,5 +57,6 @@ public:
virtual ~MIDIDriverWinMidi();
};
-#endif // MIDI_DRIVER_WINMIDI_H
#endif // WINMIDI_ENABLED
+
+#endif // MIDI_DRIVER_WINMIDI_H
diff --git a/drivers/xaudio2/audio_driver_xaudio2.h b/drivers/xaudio2/audio_driver_xaudio2.h
index 9072269a0e..81432ceb8e 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.h
+++ b/drivers/xaudio2/audio_driver_xaudio2.h
@@ -106,4 +106,4 @@ public:
~AudioDriverXAudio2() {}
};
-#endif
+#endif // AUDIO_DRIVER_XAUDIO2_H