diff options
Diffstat (limited to 'drivers/gles3/rasterizer_storage_gles3.h')
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h new file mode 100644 index 0000000000..da1dd0e66b --- /dev/null +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -0,0 +1,324 @@ +/*************************************************************************/ +/* rasterizer_storage_gles3.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef RASTERIZER_STORAGE_OPENGL_H +#define RASTERIZER_STORAGE_OPENGL_H + +#ifdef GLES3_ENABLED + +#include "core/templates/local_vector.h" +#include "core/templates/rid_owner.h" +#include "core/templates/self_list.h" +#include "servers/rendering/renderer_compositor.h" +#include "servers/rendering/renderer_storage.h" +#include "servers/rendering/shader_compiler.h" +#include "servers/rendering/shader_language.h" +#include "storage/config.h" +#include "storage/material_storage.h" +#include "storage/texture_storage.h" + +// class RasterizerCanvasGLES3; +// class RasterizerSceneGLES3; + +class RasterizerStorageGLES3 : public RendererStorage { +public: + // RasterizerCanvasGLES3 *canvas; + // RasterizerSceneGLES3 *scene; + + GLES3::Config *config; + + struct Resources { + GLuint white_tex; + GLuint black_tex; + GLuint normal_tex; + GLuint aniso_tex; + + GLuint mipmap_blur_fbo; + GLuint mipmap_blur_color; + + GLuint radical_inverse_vdc_cache_tex; + bool use_rgba_2d_shadows; + + GLuint quadie; + + size_t skeleton_transform_buffer_size; + GLuint skeleton_transform_buffer; + LocalVector<float> skeleton_transform_cpu_buffer; + + } resources; + + struct Info { + uint64_t texture_mem = 0; + uint64_t vertex_mem = 0; + + struct Render { + uint32_t object_count; + uint32_t draw_call_count; + uint32_t material_switch_count; + uint32_t surface_switch_count; + uint32_t shader_rebind_count; + uint32_t vertices_count; + uint32_t _2d_item_count; + uint32_t _2d_draw_call_count; + + void reset() { + object_count = 0; + draw_call_count = 0; + material_switch_count = 0; + surface_switch_count = 0; + shader_rebind_count = 0; + vertices_count = 0; + _2d_item_count = 0; + _2d_draw_call_count = 0; + } + } render, render_final, snap; + + Info() { + render.reset(); + render_final.reset(); + } + + } info; + + void bind_quad_array() const; + + ///////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////API//////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + +public: + virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) override; + + /* SKY API */ + // not sure if used in godot 4? + struct Sky { + RID self; + RID panorama; + GLuint radiance; + int radiance_size; + }; + + mutable RID_PtrOwner<Sky> sky_owner; + + RID sky_create(); + void sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size); + + /* VOXEL GI API */ + + RID voxel_gi_allocate() override; + void voxel_gi_initialize(RID p_rid) override; + void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override; + + AABB voxel_gi_get_bounds(RID p_voxel_gi) const override; + Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const override; + Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const override; + Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const override; + Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const override; + + Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const override; + Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const override; + + void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) override; + float voxel_gi_get_dynamic_range(RID p_voxel_gi) const override; + + void voxel_gi_set_propagation(RID p_voxel_gi, float p_range) override; + float voxel_gi_get_propagation(RID p_voxel_gi) const override; + + void voxel_gi_set_energy(RID p_voxel_gi, float p_range) override; + float voxel_gi_get_energy(RID p_voxel_gi) const override; + + void voxel_gi_set_bias(RID p_voxel_gi, float p_range) override; + float voxel_gi_get_bias(RID p_voxel_gi) const override; + + void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range) override; + float voxel_gi_get_normal_bias(RID p_voxel_gi) const override; + + void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) override; + bool voxel_gi_is_interior(RID p_voxel_gi) const override; + + void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) override; + bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const override; + + void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) override; + float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const override; + + uint32_t voxel_gi_get_version(RID p_voxel_gi) override; + + /* OCCLUDER */ + + void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices); + + /* FOG VOLUMES */ + + RID fog_volume_allocate() override; + void fog_volume_initialize(RID p_rid) override; + + void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override; + void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override; + void fog_volume_set_material(RID p_fog_volume, RID p_material) override; + AABB fog_volume_get_aabb(RID p_fog_volume) const override; + RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override; + + /* VISIBILITY NOTIFIER */ + RID visibility_notifier_allocate() override; + void visibility_notifier_initialize(RID p_notifier) override; + void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) override; + void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) override; + + AABB visibility_notifier_get_aabb(RID p_notifier) const override; + void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override; + + // access from canvas + // GLES3::RenderTarget * render_target_get(RID p_render_target); + + /* CANVAS SHADOW */ + + struct CanvasLightShadow { + RID self; + int size; + int height; + GLuint fbo; + GLuint depth; + GLuint distance; //for older devices + }; + + RID_PtrOwner<CanvasLightShadow> canvas_light_shadow_owner; + + RID canvas_light_shadow_buffer_create(int p_width); + + /* LIGHT SHADOW MAPPING */ + /* + struct CanvasOccluder { + RID self; + + GLuint vertex_id; // 0 means, unconfigured + GLuint index_id; // 0 means, unconfigured + LocalVector<Vector2> lines; + int len; + }; + + RID_Owner<CanvasOccluder> canvas_occluder_owner; + + RID canvas_light_occluder_create(); + void canvas_light_occluder_set_polylines(RID p_occluder, const LocalVector<Vector2> &p_lines); +*/ + + RS::InstanceType get_base_type(RID p_rid) const override; + + bool free(RID p_rid) override; + + void initialize(); + void finalize(); + + void _copy_screen(); + + void update_memory_info() override; + uint64_t get_rendering_info(RS::RenderingInfo p_info) override; + + bool has_os_feature(const String &p_feature) const override; + + void update_dirty_resources() override; + + void set_debug_generate_wireframes(bool p_generate) override; + + // void render_info_begin_capture() override; + // void render_info_end_capture() override; + // int get_captured_render_info(RS::RenderInfo p_info) override; + + // int get_render_info(RS::RenderInfo p_info) override; + String get_video_adapter_name() const override; + String get_video_adapter_vendor() const override; + RenderingDevice::DeviceType get_video_adapter_type() const override; + + void capture_timestamps_begin() override {} + void capture_timestamp(const String &p_name) override {} + uint32_t get_captured_timestamps_count() const override { + return 0; + } + uint64_t get_captured_timestamps_frame() const override { + return 0; + } + uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const override { + return 0; + } + uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const override { + return 0; + } + String get_captured_timestamp_name(uint32_t p_index) const override { + return String(); + } + + void buffer_orphan_and_upload(unsigned int p_buffer_size, unsigned int p_offset, unsigned int p_data_size, const void *p_data, GLenum p_target = GL_ARRAY_BUFFER, GLenum p_usage = GL_DYNAMIC_DRAW, bool p_optional_orphan = false) const; + bool safe_buffer_sub_data(unsigned int p_total_buffer_size, GLenum p_target, unsigned int p_offset, unsigned int p_data_size, const void *p_data, unsigned int &r_offset_after) const; + + RasterizerStorageGLES3(); + ~RasterizerStorageGLES3(); +}; + +inline bool RasterizerStorageGLES3::safe_buffer_sub_data(unsigned int p_total_buffer_size, GLenum p_target, unsigned int p_offset, unsigned int p_data_size, const void *p_data, unsigned int &r_offset_after) const { + r_offset_after = p_offset + p_data_size; +#ifdef DEBUG_ENABLED + // we are trying to write across the edge of the buffer + if (r_offset_after > p_total_buffer_size) { + return false; + } +#endif + glBufferSubData(p_target, p_offset, p_data_size, p_data); + return true; +} + +// standardize the orphan / upload in one place so it can be changed per platform as necessary, and avoid future +// bugs causing pipeline stalls +inline void RasterizerStorageGLES3::buffer_orphan_and_upload(unsigned int p_buffer_size, unsigned int p_offset, unsigned int p_data_size, const void *p_data, GLenum p_target, GLenum p_usage, bool p_optional_orphan) const { + // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData + // Was previously #ifndef GLES_OVER_GL however this causes stalls on desktop mac also (and possibly other) + if (!p_optional_orphan || (config->should_orphan)) { + glBufferData(p_target, p_buffer_size, nullptr, p_usage); +#ifdef RASTERIZER_EXTRA_CHECKS + // fill with garbage off the end of the array + if (p_buffer_size) { + unsigned int start = p_offset + p_data_size; + unsigned int end = start + 1024; + if (end < p_buffer_size) { + uint8_t *garbage = (uint8_t *)alloca(1024); + for (int n = 0; n < 1024; n++) { + garbage[n] = Math::random(0, 255); + } + glBufferSubData(p_target, start, 1024, garbage); + } + } +#endif + } + glBufferSubData(p_target, p_offset, p_data_size, p_data); +} + +#endif // GLES3_ENABLED + +#endif // RASTERIZER_STORAGE_OPENGL_H |