summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/d3d12/rendering_context_driver_d3d12.cpp41
-rw-r--r--drivers/d3d12/rendering_context_driver_d3d12.h3
-rw-r--r--drivers/d3d12/rendering_device_driver_d3d12.cpp108
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp25
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h2
-rw-r--r--drivers/gles3/shaders/scene.glsl4
-rw-r--r--drivers/gles3/storage/light_storage.cpp4
-rw-r--r--drivers/gles3/storage/light_storage.h1
-rw-r--r--drivers/gles3/storage/particles_storage.cpp2
-rw-r--r--drivers/gles3/storage/texture_storage.cpp4
-rw-r--r--drivers/unix/file_access_unix.cpp4
-rw-r--r--drivers/vulkan/rendering_device_driver_vulkan.cpp54
12 files changed, 152 insertions, 100 deletions
diff --git a/drivers/d3d12/rendering_context_driver_d3d12.cpp b/drivers/d3d12/rendering_context_driver_d3d12.cpp
index ad3b793305..726be064bd 100644
--- a/drivers/d3d12/rendering_context_driver_d3d12.cpp
+++ b/drivers/d3d12/rendering_context_driver_d3d12.cpp
@@ -58,9 +58,10 @@
#endif
// Note: symbols are not available in MinGW and old MSVC import libraries.
-const CLSID CLSID_D3D12DeviceFactoryGodot = __uuidof(ID3D12DeviceFactory);
-const CLSID CLSID_D3D12DebugGodot = __uuidof(ID3D12Debug);
-const CLSID CLSID_D3D12SDKConfigurationGodot = __uuidof(ID3D12SDKConfiguration);
+// GUID values from https://github.com/microsoft/DirectX-Headers/blob/7a9f4d06911d30eecb56a4956dab29dcca2709ed/include/directx/d3d12.idl#L5877-L5881
+const GUID CLSID_D3D12DeviceFactoryGodot = { 0x114863bf, 0xc386, 0x4aee, { 0xb3, 0x9d, 0x8f, 0x0b, 0xbb, 0x06, 0x29, 0x55 } };
+const GUID CLSID_D3D12DebugGodot = { 0xf2352aeb, 0xdd84, 0x49fe, { 0xb9, 0x7b, 0xa9, 0xdc, 0xfd, 0xcc, 0x1b, 0x4f } };
+const GUID CLSID_D3D12SDKConfigurationGodot = { 0x7cda6aca, 0xa03e, 0x49c8, { 0x94, 0x58, 0x03, 0x34, 0xd2, 0x0e, 0x07, 0xce } };
extern "C" {
char godot_nir_arch_name[32];
@@ -83,17 +84,28 @@ RenderingContextDriverD3D12::RenderingContextDriverD3D12() {
}
RenderingContextDriverD3D12::~RenderingContextDriverD3D12() {
+ if (lib_d3d12) {
+ FreeLibrary(lib_d3d12);
+ }
+ if (lib_dxgi) {
+ FreeLibrary(lib_dxgi);
+ }
}
Error RenderingContextDriverD3D12::_init_device_factory() {
uint32_t agility_sdk_version = GLOBAL_GET("rendering/rendering_device/d3d12/agility_sdk_version");
String agility_sdk_path = String(".\\") + Engine::get_singleton()->get_architecture_name();
+ lib_d3d12 = LoadLibraryW(L"D3D12.dll");
+ ERR_FAIL_NULL_V(lib_d3d12, ERR_CANT_CREATE);
+
+ lib_dxgi = LoadLibraryW(L"DXGI.dll");
+ ERR_FAIL_NULL_V(lib_dxgi, ERR_CANT_CREATE);
+
// Note: symbol is not available in MinGW import library.
- PFN_D3D12_GET_INTERFACE d3d_D3D12GetInterface = (PFN_D3D12_GET_INTERFACE)GetProcAddress(LoadLibraryW(L"D3D12.dll"), "D3D12GetInterface");
- if (d3d_D3D12GetInterface == nullptr) {
- // FIXME: Is it intended for this to silently return when it fails to find the symbol?
- return OK;
+ PFN_D3D12_GET_INTERFACE d3d_D3D12GetInterface = (PFN_D3D12_GET_INTERFACE)(void *)GetProcAddress(lib_d3d12, "D3D12GetInterface");
+ if (!d3d_D3D12GetInterface) {
+ return OK; // Fallback to the system loader.
}
ID3D12SDKConfiguration *sdk_config = nullptr;
@@ -109,18 +121,22 @@ Error RenderingContextDriverD3D12::_init_device_factory() {
}
sdk_config->Release();
}
-
return OK;
}
Error RenderingContextDriverD3D12::_initialize_debug_layers() {
ComPtr<ID3D12Debug> debug_controller;
HRESULT res;
+
if (device_factory) {
res = device_factory->GetConfigurationInterface(CLSID_D3D12DebugGodot, IID_PPV_ARGS(&debug_controller));
} else {
- res = D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller));
+ PFN_D3D12_GET_DEBUG_INTERFACE d3d_D3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)(void *)GetProcAddress(lib_d3d12, "D3D12GetDebugInterface");
+ ERR_FAIL_NULL_V(d3d_D3D12GetDebugInterface, ERR_CANT_CREATE);
+
+ res = d3d_D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller));
}
+
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_QUERY_FAILED);
debug_controller->EnableDebugLayer();
return OK;
@@ -128,7 +144,12 @@ Error RenderingContextDriverD3D12::_initialize_debug_layers() {
Error RenderingContextDriverD3D12::_initialize_devices() {
const UINT dxgi_factory_flags = use_validation_layers() ? DXGI_CREATE_FACTORY_DEBUG : 0;
- HRESULT res = CreateDXGIFactory2(dxgi_factory_flags, IID_PPV_ARGS(&dxgi_factory));
+
+ typedef HRESULT(WINAPI * PFN_DXGI_CREATE_DXGI_FACTORY2)(UINT, REFIID, void **);
+ PFN_DXGI_CREATE_DXGI_FACTORY2 dxgi_CreateDXGIFactory2 = (PFN_DXGI_CREATE_DXGI_FACTORY2)(void *)GetProcAddress(lib_dxgi, "CreateDXGIFactory2");
+ ERR_FAIL_NULL_V(dxgi_CreateDXGIFactory2, ERR_CANT_CREATE);
+
+ HRESULT res = dxgi_CreateDXGIFactory2(dxgi_factory_flags, IID_PPV_ARGS(&dxgi_factory));
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
// Enumerate all possible adapters.
diff --git a/drivers/d3d12/rendering_context_driver_d3d12.h b/drivers/d3d12/rendering_context_driver_d3d12.h
index 694d0b3e4c..f74105ed3d 100644
--- a/drivers/d3d12/rendering_context_driver_d3d12.h
+++ b/drivers/d3d12/rendering_context_driver_d3d12.h
@@ -107,6 +107,9 @@ public:
bool needs_resize = false;
};
+ HMODULE lib_d3d12 = nullptr;
+ HMODULE lib_dxgi = nullptr;
+
IDXGIAdapter1 *create_adapter(uint32_t p_adapter_index) const;
ID3D12DeviceFactory *device_factory_get() const;
IDXGIFactory2 *dxgi_factory_get() const;
diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp
index 381d022a55..49ab4f179f 100644
--- a/drivers/d3d12/rendering_device_driver_d3d12.cpp
+++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp
@@ -3222,7 +3222,7 @@ Vector<uint8_t> RenderingDeviceDriverD3D12::shader_compile_binary_from_spirv(Vec
root_sig_desc.Init_1_1(root_params.size(), root_params.ptr(), 0, nullptr, root_sig_flags);
ComPtr<ID3DBlob> error_blob;
- HRESULT res = D3DX12SerializeVersionedRootSignature(&root_sig_desc, D3D_ROOT_SIGNATURE_VERSION_1_1, root_sig_blob.GetAddressOf(), error_blob.GetAddressOf());
+ HRESULT res = D3DX12SerializeVersionedRootSignature(context_driver->lib_d3d12, &root_sig_desc, D3D_ROOT_SIGNATURE_VERSION_1_1, root_sig_blob.GetAddressOf(), error_blob.GetAddressOf());
ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), Vector<uint8_t>(),
"Serialization of root signature failed with error " + vformat("0x%08ux", (uint64_t)res) + " and the following message:\n" + String((char *)error_blob->GetBufferPointer(), error_blob->GetBufferSize()));
@@ -3246,10 +3246,7 @@ Vector<uint8_t> RenderingDeviceDriverD3D12::shader_compile_binary_from_spirv(Vec
compressed_stages.push_back(zstd);
uint32_t s = compressed_stages[i].size();
- if (s % 4 != 0) {
- s += 4 - (s % 4);
- }
- stages_binary_size += s;
+ stages_binary_size += STEPIFY(s, 4);
}
CharString shader_name_utf = p_shader_name.utf8();
@@ -3259,10 +3256,7 @@ Vector<uint8_t> RenderingDeviceDriverD3D12::shader_compile_binary_from_spirv(Vec
uint32_t total_size = sizeof(uint32_t) * 3; // Header + version + main datasize;.
total_size += sizeof(ShaderBinary::Data);
- total_size += binary_data.shader_name_len;
- if ((binary_data.shader_name_len % 4) != 0) { // Alignment rules are really strange.
- total_size += 4 - (binary_data.shader_name_len % 4);
- }
+ total_size += STEPIFY(binary_data.shader_name_len, 4);
for (int i = 0; i < sets_bindings.size(); i++) {
total_size += sizeof(uint32_t);
@@ -3294,13 +3288,17 @@ Vector<uint8_t> RenderingDeviceDriverD3D12::shader_compile_binary_from_spirv(Vec
memcpy(binptr + offset, &binary_data, sizeof(ShaderBinary::Data));
offset += sizeof(ShaderBinary::Data);
+#define ADVANCE_OFFSET_WITH_ALIGNMENT(m_bytes) \
+ { \
+ offset += m_bytes; \
+ uint32_t padding = STEPIFY(m_bytes, 4) - m_bytes; \
+ memset(binptr + offset, 0, padding); /* Avoid garbage data. */ \
+ offset += padding; \
+ }
+
if (binary_data.shader_name_len > 0) {
memcpy(binptr + offset, shader_name_utf.ptr(), binary_data.shader_name_len);
- offset += binary_data.shader_name_len;
-
- if ((binary_data.shader_name_len % 4) != 0) { // Alignment rules are really strange.
- offset += 4 - (binary_data.shader_name_len % 4);
- }
+ ADVANCE_OFFSET_WITH_ALIGNMENT(binary_data.shader_name_len);
}
for (int i = 0; i < sets_bindings.size(); i++) {
@@ -3326,14 +3324,7 @@ Vector<uint8_t> RenderingDeviceDriverD3D12::shader_compile_binary_from_spirv(Vec
encode_uint32(zstd_size[i], binptr + offset);
offset += sizeof(uint32_t);
memcpy(binptr + offset, compressed_stages[i].ptr(), compressed_stages[i].size());
-
- uint32_t s = compressed_stages[i].size();
-
- if (s % 4 != 0) {
- s += 4 - (s % 4);
- }
-
- offset += s;
+ ADVANCE_OFFSET_WITH_ALIGNMENT(compressed_stages[i].size());
}
memcpy(binptr + offset, root_sig_blob->GetBufferPointer(), root_sig_blob->GetBufferSize());
@@ -3382,10 +3373,7 @@ RDD::ShaderID RenderingDeviceDriverD3D12::shader_create_from_bytecode(const Vect
if (binary_data.shader_name_len) {
r_name.parse_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len);
- read_offset += binary_data.shader_name_len;
- if ((binary_data.shader_name_len % 4) != 0) { // Alignment rules are really strange.
- read_offset += 4 - (binary_data.shader_name_len % 4);
- }
+ read_offset += STEPIFY(binary_data.shader_name_len, 4);
}
r_shader_desc.uniform_sets.resize(binary_data.set_count);
@@ -3458,6 +3446,7 @@ RDD::ShaderID RenderingDeviceDriverD3D12::shader_create_from_bytecode(const Vect
for (uint32_t i = 0; i < binary_data.stage_count; i++) {
ERR_FAIL_COND_V(read_offset + sizeof(uint32_t) * 3 >= binsize, ShaderID());
+
uint32_t stage = decode_uint32(binptr + read_offset);
read_offset += sizeof(uint32_t);
uint32_t dxil_size = decode_uint32(binptr + read_offset);
@@ -3472,18 +3461,17 @@ RDD::ShaderID RenderingDeviceDriverD3D12::shader_create_from_bytecode(const Vect
ERR_FAIL_COND_V(dec_dxil_size != (int32_t)dxil_size, ShaderID());
shader_info_in.stages_bytecode[ShaderStage(stage)] = dxil;
- if (zstd_size % 4 != 0) {
- zstd_size += 4 - (zstd_size % 4);
- }
-
- ERR_FAIL_COND_V(read_offset + zstd_size > binsize, ShaderID());
-
+ zstd_size = STEPIFY(zstd_size, 4);
read_offset += zstd_size;
+ ERR_FAIL_COND_V(read_offset > binsize, ShaderID());
}
const uint8_t *root_sig_data_ptr = binptr + read_offset;
- HRESULT res = D3D12CreateRootSignatureDeserializer(root_sig_data_ptr, binary_data.root_signature_len, IID_PPV_ARGS(shader_info_in.root_signature_deserializer.GetAddressOf()));
+ PFN_D3D12_CREATE_ROOT_SIGNATURE_DESERIALIZER d3d_D3D12CreateRootSignatureDeserializer = (PFN_D3D12_CREATE_ROOT_SIGNATURE_DESERIALIZER)(void *)GetProcAddress(context_driver->lib_d3d12, "D3D12CreateRootSignatureDeserializer");
+ ERR_FAIL_NULL_V(d3d_D3D12CreateRootSignatureDeserializer, ShaderID());
+
+ HRESULT res = d3d_D3D12CreateRootSignatureDeserializer(root_sig_data_ptr, binary_data.root_signature_len, IID_PPV_ARGS(shader_info_in.root_signature_deserializer.GetAddressOf()));
ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ShaderID(), "D3D12CreateRootSignatureDeserializer failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
read_offset += binary_data.root_signature_len;
@@ -6033,17 +6021,23 @@ Error RenderingDeviceDriverD3D12::_initialize_device() {
HRESULT res;
if (is_in_developer_mode()) {
+ typedef HRESULT(WINAPI * PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES)(_In_ UINT, _In_count_(NumFeatures) const IID *, _In_opt_count_(NumFeatures) void *, _In_opt_count_(NumFeatures) UINT *);
+ PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES d3d_D3D12EnableExperimentalFeatures = (PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES)(void *)GetProcAddress(context_driver->lib_d3d12, "D3D12EnableExperimentalFeatures");
+ ERR_FAIL_NULL_V(d3d_D3D12EnableExperimentalFeatures, ERR_CANT_CREATE);
+
UUID experimental_features[] = { D3D12ExperimentalShaderModels };
- D3D12EnableExperimentalFeatures(1, experimental_features, nullptr, nullptr);
+ d3d_D3D12EnableExperimentalFeatures(1, experimental_features, nullptr, nullptr);
}
ID3D12DeviceFactory *device_factory = context_driver->device_factory_get();
if (device_factory != nullptr) {
res = device_factory->CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(device.GetAddressOf()));
} else {
- res = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(device.GetAddressOf()));
- }
+ PFN_D3D12_CREATE_DEVICE d3d_D3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)(void *)GetProcAddress(context_driver->lib_d3d12, "D3D12CreateDevice");
+ ERR_FAIL_NULL_V(d3d_D3D12CreateDevice, ERR_CANT_CREATE);
+ res = d3d_D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(device.GetAddressOf()));
+ }
ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_CANT_CREATE, "D3D12CreateDevice failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
if (context_driver->use_validation_layers()) {
@@ -6142,20 +6136,44 @@ Error RenderingDeviceDriverD3D12::_check_capabilities() {
multiview_capabilities.is_supported = false;
subgroup_capabilities.size = 0;
subgroup_capabilities.wave_ops_supported = false;
- shader_capabilities.shader_model = D3D_SHADER_MODEL_6_0;
+ shader_capabilities.shader_model = (D3D_SHADER_MODEL)0;
shader_capabilities.native_16bit_ops = false;
storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported = false;
format_capabilities.relaxed_casting_supported = false;
- // Check shader model.
- D3D12_FEATURE_DATA_SHADER_MODEL shader_model = {};
- shader_model.HighestShaderModel = MIN(D3D_HIGHEST_SHADER_MODEL, D3D_SHADER_MODEL_6_6);
- res = device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shader_model, sizeof(shader_model));
- ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_CANT_CREATE, "CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
+ {
+ static const D3D_SHADER_MODEL SMS_TO_CHECK[] = {
+ D3D_SHADER_MODEL_6_6,
+ D3D_SHADER_MODEL_6_5,
+ D3D_SHADER_MODEL_6_4,
+ D3D_SHADER_MODEL_6_3,
+ D3D_SHADER_MODEL_6_2,
+ D3D_SHADER_MODEL_6_1,
+ D3D_SHADER_MODEL_6_0, // Determined by NIR (dxil_min_shader_model).
+ };
+
+ D3D12_FEATURE_DATA_SHADER_MODEL shader_model = {};
+ for (uint32_t i = 0; i < ARRAY_SIZE(SMS_TO_CHECK); i++) {
+ shader_model.HighestShaderModel = SMS_TO_CHECK[i];
+ res = device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shader_model, sizeof(shader_model));
+ if (SUCCEEDED(res)) {
+ shader_capabilities.shader_model = shader_model.HighestShaderModel;
+ break;
+ }
+ if (res == E_INVALIDARG) {
+ continue; // Must assume the device doesn't know about the SM just checked.
+ }
+ ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_CANT_CREATE, "CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
+ }
- shader_capabilities.shader_model = shader_model.HighestShaderModel;
- print_verbose("- Shader:");
- print_verbose(" model: " + itos(shader_capabilities.shader_model >> 4) + "." + itos(shader_capabilities.shader_model & 0xf));
+#define D3D_SHADER_MODEL_TO_STRING(m_sm) vformat("%d.%d", (m_sm >> 4), (m_sm & 0xf))
+
+ ERR_FAIL_COND_V_MSG(!shader_capabilities.shader_model, ERR_UNAVAILABLE,
+ vformat("No support for any of the suitable shader models (%s-%s) has been found.", D3D_SHADER_MODEL_TO_STRING(SMS_TO_CHECK[ARRAY_SIZE(SMS_TO_CHECK) - 1]), D3D_SHADER_MODEL_TO_STRING(SMS_TO_CHECK[0])));
+
+ print_verbose("- Shader:");
+ print_verbose(" model: " + D3D_SHADER_MODEL_TO_STRING(shader_capabilities.shader_model));
+ }
D3D12_FEATURE_DATA_D3D12_OPTIONS options = {};
res = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options));
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 198160939a..de990a4222 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -634,7 +634,23 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
GLES3::CanvasShaderData::BlendMode blend_mode = shader_data_cache ? shader_data_cache->blend_mode : GLES3::CanvasShaderData::BLEND_MODE_MIX;
- _record_item_commands(ci, p_to_render_target, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index, batch_broken, r_sdf_used);
+ if (!ci->repeat_size.x && !ci->repeat_size.y) {
+ _record_item_commands(ci, p_to_render_target, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index, batch_broken, r_sdf_used, Point2());
+ } else {
+ Point2 start_pos = ci->repeat_size * -(ci->repeat_times / 2);
+ Point2 end_pos = ci->repeat_size * ci->repeat_times + ci->repeat_size + start_pos;
+ Point2 pos = start_pos;
+
+ do {
+ do {
+ _record_item_commands(ci, p_to_render_target, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index, batch_broken, r_sdf_used, pos);
+ pos.y += ci->repeat_size.y;
+ } while (pos.y < end_pos.y);
+
+ pos.x += ci->repeat_size.x;
+ pos.y = start_pos.y;
+ } while (pos.x < end_pos.x);
+ }
}
if (index == 0) {
@@ -784,7 +800,7 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
state.last_item_index += index;
}
-void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_batch_broken, bool &r_sdf_used) {
+void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_batch_broken, bool &r_sdf_used, const Point2 &p_offset) {
RenderingServer::CanvasItemTextureFilter texture_filter = p_item->texture_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? state.default_filter : p_item->texture_filter;
if (texture_filter != state.canvas_instance_batches[state.current_batch_index].filter) {
@@ -802,6 +818,11 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
}
Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform;
+
+ if (p_offset.x || p_offset.y) {
+ base_transform *= Transform2D(0, p_offset / p_item->xform.get_scale());
+ }
+
Transform2D draw_transform; // Used by transform command
Color base_color = p_item->final_modulate;
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index 88befa7883..a3762e828e 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -357,7 +357,7 @@ public:
void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used, RenderingMethod::RenderInfo *r_render_info = nullptr) override;
void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer = false, RenderingMethod::RenderInfo *r_render_info = nullptr);
- void _record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_break_batch, bool &r_sdf_used);
+ void _record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_break_batch, bool &r_sdf_used, const Point2 &p_offset);
void _render_batch(Light *p_lights, uint32_t p_index, RenderingMethod::RenderInfo *r_render_info = nullptr);
bool _bind_material(GLES3::CanvasMaterialData *p_material_data, CanvasShaderGLES3::ShaderVariant p_variant, uint64_t p_specialization);
void _new_batch(bool &r_batch_broken);
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index a6db90c3f5..d73407d674 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -913,8 +913,7 @@ ivec2 multiview_uv(ivec2 uv) {
uniform highp mat4 world_transform;
uniform mediump float opaque_prepass_threshold;
-#ifndef MODE_RENDER_DEPTH
-#ifdef RENDER_MATERIAL
+#if defined(RENDER_MATERIAL)
layout(location = 0) out vec4 albedo_output_buffer;
layout(location = 1) out vec4 normal_output_buffer;
layout(location = 2) out vec4 orm_output_buffer;
@@ -925,7 +924,6 @@ layout(location = 3) out vec4 emission_output_buffer;
layout(location = 0) out vec4 frag_color;
#endif // !RENDER_MATERIAL
-#endif // !MODE_RENDER_DEPTH
vec3 F0(float metallic, float specular, vec3 albedo) {
float dielectric = 0.16 * specular * specular;
diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp
index 2259c61e5b..f5d1f8dabd 100644
--- a/drivers/gles3/storage/light_storage.cpp
+++ b/drivers/gles3/storage/light_storage.cpp
@@ -541,6 +541,10 @@ void LightStorage::reflection_probe_instance_free(RID p_instance) {
void LightStorage::reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) {
}
+bool LightStorage::reflection_probe_has_atlas_index(RID p_instance) {
+ return false;
+}
+
void LightStorage::reflection_probe_release_atlas_index(RID p_instance) {
}
diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h
index a6b236f3ec..51c5c48106 100644
--- a/drivers/gles3/storage/light_storage.h
+++ b/drivers/gles3/storage/light_storage.h
@@ -601,6 +601,7 @@ public:
virtual RID reflection_probe_instance_create(RID p_probe) override;
virtual void reflection_probe_instance_free(RID p_instance) override;
virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) override;
+ virtual bool reflection_probe_has_atlas_index(RID p_instance) override;
virtual void reflection_probe_release_atlas_index(RID p_instance) override;
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) override;
virtual bool reflection_probe_instance_has_reflection(RID p_instance) override;
diff --git a/drivers/gles3/storage/particles_storage.cpp b/drivers/gles3/storage/particles_storage.cpp
index 8e48d0695a..b72b4eaf8d 100644
--- a/drivers/gles3/storage/particles_storage.cpp
+++ b/drivers/gles3/storage/particles_storage.cpp
@@ -395,7 +395,7 @@ AABB ParticlesStorage::particles_get_current_aabb(RID p_particles) {
bool first = true;
const uint8_t *data_ptr = (const uint8_t *)buffer.ptr();
- uint32_t particle_data_size = sizeof(ParticleInstanceData3D) + sizeof(float) * particles->userdata_count;
+ uint32_t particle_data_size = sizeof(ParticleInstanceData3D);
for (int i = 0; i < total_amount; i++) {
const ParticleInstanceData3D &particle_data = *(const ParticleInstanceData3D *)&data_ptr[particle_data_size * i];
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index ffbad4c83b..5d2bc44377 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -1183,7 +1183,7 @@ Ref<Image> TextureStorage::texture_2d_layer_get(RID p_texture, int p_layer) cons
return image;
}
-Vector<Ref<Image>> TextureStorage::_texture_3d_read_framebuffer(Texture *p_texture) const {
+Vector<Ref<Image>> TextureStorage::_texture_3d_read_framebuffer(GLES3::Texture *p_texture) const {
ERR_FAIL_NULL_V(p_texture, Vector<Ref<Image>>());
Vector<Ref<Image>> ret;
@@ -1610,7 +1610,7 @@ void TextureStorage::_texture_set_3d_data(RID p_texture, const Vector<Ref<Image>
#endif
}
-void TextureStorage::_texture_set_swizzle(Texture *p_texture, Image::Format p_real_format) {
+void TextureStorage::_texture_set_swizzle(GLES3::Texture *p_texture, Image::Format p_real_format) {
#ifndef WEB_ENABLED
switch (p_texture->format) {
case Image::FORMAT_L8: {
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index d1e4d207e7..a35d8bfdde 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -395,7 +395,7 @@ Error FileAccessUnix::_set_unix_permissions(const String &p_file, BitField<FileA
}
bool FileAccessUnix::_get_hidden_attribute(const String &p_file) {
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
String file = fix_path(p_file);
struct stat st = {};
@@ -409,7 +409,7 @@ bool FileAccessUnix::_get_hidden_attribute(const String &p_file) {
}
Error FileAccessUnix::_set_hidden_attribute(const String &p_file, bool p_hidden) {
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
String file = fix_path(p_file);
struct stat st = {};
diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp
index 21cf54b4be..297407da41 100644
--- a/drivers/vulkan/rendering_device_driver_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp
@@ -2957,10 +2957,7 @@ Vector<uint8_t> RenderingDeviceDriverVulkan::shader_compile_binary_from_spirv(Ve
}
}
uint32_t s = compressed_stages[i].size();
- if (s % 4 != 0) {
- s += 4 - (s % 4);
- }
- stages_binary_size += s;
+ stages_binary_size += STEPIFY(s, 4);
}
binary_data.specialization_constants_count = specialization_constants.size();
@@ -2974,11 +2971,7 @@ Vector<uint8_t> RenderingDeviceDriverVulkan::shader_compile_binary_from_spirv(Ve
uint32_t total_size = sizeof(uint32_t) * 3; // Header + version + main datasize;.
total_size += sizeof(ShaderBinary::Data);
- total_size += binary_data.shader_name_len;
-
- if ((binary_data.shader_name_len % 4) != 0) { // Alignment rules are really strange.
- total_size += 4 - (binary_data.shader_name_len % 4);
- }
+ total_size += STEPIFY(binary_data.shader_name_len, 4);
for (int i = 0; i < uniforms.size(); i++) {
total_size += sizeof(uint32_t);
@@ -3007,13 +3000,17 @@ Vector<uint8_t> RenderingDeviceDriverVulkan::shader_compile_binary_from_spirv(Ve
memcpy(binptr + offset, &binary_data, sizeof(ShaderBinary::Data));
offset += sizeof(ShaderBinary::Data);
+#define ADVANCE_OFFSET_WITH_ALIGNMENT(m_bytes) \
+ { \
+ offset += m_bytes; \
+ uint32_t padding = STEPIFY(m_bytes, 4) - m_bytes; \
+ memset(binptr + offset, 0, padding); /* Avoid garbage data. */ \
+ offset += padding; \
+ }
+
if (binary_data.shader_name_len > 0) {
memcpy(binptr + offset, shader_name_utf.ptr(), binary_data.shader_name_len);
- offset += binary_data.shader_name_len;
-
- if ((binary_data.shader_name_len % 4) != 0) { // Alignment rules are really strange.
- offset += 4 - (binary_data.shader_name_len % 4);
- }
+ ADVANCE_OFFSET_WITH_ALIGNMENT(binary_data.shader_name_len);
}
for (int i = 0; i < uniforms.size(); i++) {
@@ -3039,14 +3036,7 @@ Vector<uint8_t> RenderingDeviceDriverVulkan::shader_compile_binary_from_spirv(Ve
encode_uint32(zstd_size[i], binptr + offset);
offset += sizeof(uint32_t);
memcpy(binptr + offset, compressed_stages[i].ptr(), compressed_stages[i].size());
-
- uint32_t s = compressed_stages[i].size();
-
- if (s % 4 != 0) {
- s += 4 - (s % 4);
- }
-
- offset += s;
+ ADVANCE_OFFSET_WITH_ALIGNMENT(compressed_stages[i].size());
}
DEV_ASSERT(offset == (uint32_t)ret.size());
@@ -3090,10 +3080,7 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec
if (binary_data.shader_name_len) {
r_name.parse_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len);
- read_offset += binary_data.shader_name_len;
- if ((binary_data.shader_name_len % 4) != 0) { // Alignment rules are really strange.
- read_offset += 4 - (binary_data.shader_name_len % 4);
- }
+ read_offset += STEPIFY(binary_data.shader_name_len, 4);
}
Vector<Vector<VkDescriptorSetLayoutBinding>> vk_set_bindings;
@@ -3192,6 +3179,7 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec
for (uint32_t i = 0; i < binary_data.stage_count; i++) {
ERR_FAIL_COND_V(read_offset + sizeof(uint32_t) * 3 >= binsize, ShaderID());
+
uint32_t stage = decode_uint32(binptr + read_offset);
read_offset += sizeof(uint32_t);
uint32_t smolv_size = decode_uint32(binptr + read_offset);
@@ -3223,16 +3211,12 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec
r_shader_desc.stages.set(i, ShaderStage(stage));
- if (buf_size % 4 != 0) {
- buf_size += 4 - (buf_size % 4);
- }
-
- DEV_ASSERT(read_offset + buf_size <= binsize);
-
+ buf_size = STEPIFY(buf_size, 4);
read_offset += buf_size;
+ ERR_FAIL_COND_V(read_offset > binsize, ShaderID());
}
- DEV_ASSERT(read_offset == binsize);
+ ERR_FAIL_COND_V(read_offset != binsize, ShaderID());
// Modules.
@@ -3828,7 +3812,9 @@ bool RenderingDeviceDriverVulkan::pipeline_cache_create(const Vector<uint8_t> &p
// Parse.
{
- if (p_data.size() <= (int)sizeof(PipelineCacheHeader)) {
+ if (p_data.is_empty()) {
+ // No pre-existing cache, just create it.
+ } else if (p_data.size() <= (int)sizeof(PipelineCacheHeader)) {
WARN_PRINT("Invalid/corrupt pipelines cache.");
} else {
const PipelineCacheHeader *loaded_header = reinterpret_cast<const PipelineCacheHeader *>(p_data.ptr());