Merge pull request #59385 from BastiaanOlij/extract_shader_storage

This commit is contained in:
Rémi Verschelde 2022-03-31 19:19:03 +02:00 committed by GitHub
commit 155a94fabe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 4564 additions and 4095 deletions

View file

@ -40,6 +40,7 @@
#include "servers/rendering/rendering_server_default.h"
#include "storage/canvas_texture_storage.h"
#include "storage/config.h"
#include "storage/material_storage.h"
#ifndef GLES_OVER_GL
#define glClearDepth glClearDepthf
@ -212,6 +213,8 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
}
void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) {
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
Item *current_clip = nullptr;
Transform2D canvas_transform_inverse = p_canvas_transform_inverse;
@ -228,14 +231,14 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
Item *ci = items[i];
RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material;
RasterizerStorageGLES3::Material *material_ptr = storage->material_owner.get_or_null(material);
GLES3::Material *material_ptr = material_storage->get_material(material);
if (material.is_null() && ci->canvas_group != nullptr) {
material = default_canvas_group_material;
}
if (material != prev_material) {
RasterizerStorageGLES3::Shader *shader_ptr = nullptr;
GLES3::Shader *shader_ptr = nullptr;
if (material_ptr) {
shader_ptr = material_ptr->shader;
@ -906,6 +909,8 @@ void RasterizerCanvasGLES3::canvas_end() {
}
void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, uint32_t &r_index, RID &r_last_texture, Size2 &r_texpixel_size) {
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
if (p_texture == RID()) {
p_texture = default_canvas_texture;
}
@ -1251,9 +1256,8 @@ void RasterizerCanvasGLES3::_allocate_instance_data_buffer() {
}
void RasterizerCanvasGLES3::initialize() {
// !BAS! shouldn't we be obtaining storage here as well?
canvas_texture_storage = GLES3::CanvasTextureStorage::get_singleton();
texture_storage = GLES3::TextureStorage::get_singleton();
GLES3::CanvasTextureStorage *canvas_texture_storage = GLES3::CanvasTextureStorage::get_singleton();
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
// quad buffer
{
@ -1423,10 +1427,10 @@ void RasterizerCanvasGLES3::initialize() {
//state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false));
{
default_canvas_group_shader = storage->shader_allocate();
storage->shader_initialize(default_canvas_group_shader);
default_canvas_group_shader = material_storage->shader_allocate();
material_storage->shader_initialize(default_canvas_group_shader);
storage->shader_set_code(default_canvas_group_shader, R"(
material_storage->shader_set_code(default_canvas_group_shader, R"(
// Default CanvasGroup shader.
shader_type canvas_item;
@ -1441,10 +1445,10 @@ void fragment() {
COLOR *= c;
}
)");
default_canvas_group_material = storage->material_allocate();
storage->material_initialize(default_canvas_group_material);
default_canvas_group_material = material_storage->material_allocate();
material_storage->material_initialize(default_canvas_group_material);
storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader);
material_storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader);
}
default_canvas_texture = canvas_texture_storage->canvas_texture_allocate();
@ -1456,13 +1460,25 @@ void fragment() {
state.current_shader_version = state.canvas_shader_default_version;
}
RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
RasterizerCanvasGLES3 *RasterizerCanvasGLES3::singleton = nullptr;
RasterizerCanvasGLES3 *RasterizerCanvasGLES3::get_singleton() {
return singleton;
}
RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
singleton = this;
}
RasterizerCanvasGLES3::~RasterizerCanvasGLES3() {
GLES3::CanvasTextureStorage *canvas_texture_storage = GLES3::CanvasTextureStorage::get_singleton();
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
state.canvas_shader.version_free(state.canvas_shader_default_version);
storage->free(default_canvas_group_material);
storage->free(default_canvas_group_shader);
material_storage->material_free(default_canvas_group_material);
material_storage->shader_free(default_canvas_group_shader);
canvas_texture_storage->canvas_texture_free(default_canvas_texture);
singleton = nullptr;
}
void RasterizerCanvasGLES3::finalize() {

View file

@ -38,6 +38,7 @@
#include "servers/rendering/renderer_canvas_render.h"
#include "servers/rendering/renderer_compositor.h"
#include "storage/canvas_texture_storage.h"
#include "storage/material_storage.h"
#include "storage/texture_storage.h"
#include "shaders/canvas.glsl.gen.h"
@ -45,6 +46,8 @@
class RasterizerSceneGLES3;
class RasterizerCanvasGLES3 : public RendererCanvasRender {
static RasterizerCanvasGLES3 *singleton;
_FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4);
_FORCE_INLINE_ void _update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3);
@ -219,8 +222,6 @@ public:
RasterizerSceneGLES3 *scene_render;
GLES3::CanvasTextureStorage *canvas_texture_storage;
GLES3::TextureStorage *texture_storage;
RasterizerStorageGLES3 *storage;
void _set_uniforms();
@ -277,6 +278,8 @@ public:
void initialize();
void finalize();
static RasterizerCanvasGLES3 *get_singleton();
RasterizerCanvasGLES3();
~RasterizerCanvasGLES3();
};

View file

@ -260,9 +260,9 @@ void RasterizerGLES3::initialize() {
RasterizerGLES3::RasterizerGLES3() {
canvas.storage = &storage;
canvas.scene_render = &scene;
storage.canvas = &canvas;
//storage.canvas = &canvas;
//scene.storage = &storage;
storage.scene = &scene;
//storage.scene = &scene;
}
void RasterizerGLES3::prepare_for_blitting_render_targets() {

View file

@ -40,6 +40,7 @@
#include "storage/canvas_texture_storage.h"
#include "storage/config.h"
#include "storage/decal_atlas_storage.h"
#include "storage/material_storage.h"
#include "storage/render_target_storage.h"
#include "storage/texture_storage.h"
@ -55,6 +56,7 @@ protected:
GLES3::CanvasTextureStorage canvas_texture_storage;
GLES3::TextureStorage texture_storage;
GLES3::DecalAtlasStorage decal_atlas_storage;
GLES3::MaterialStorage material_storage;
RasterizerStorageGLES3 storage;
RasterizerCanvasGLES3 canvas;
RasterizerSceneGLES3 scene;
@ -63,6 +65,7 @@ protected:
public:
RendererCanvasTextureStorage *get_canvas_texture_storage() { return &canvas_texture_storage; }
RendererMaterialStorage *get_material_storage() { return &material_storage; }
RendererTextureStorage *get_texture_storage() { return &texture_storage; }
RendererDecalAtlasStorage *get_decal_atlas_storage() { return &decal_atlas_storage; }
RendererStorage *get_storage() { return &storage; }

View file

@ -34,7 +34,7 @@
#include "core/config/project_settings.h"
#include "core/math/transform_3d.h"
#include "rasterizer_canvas_gles3.h"
// #include "rasterizer_canvas_gles3.h"
#include "rasterizer_scene_gles3.h"
#include "servers/rendering/shader_language.h"
@ -58,755 +58,6 @@ RID RasterizerStorageGLES3::sky_create() {
void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size) {
}
/* SHADER API */
RID RasterizerStorageGLES3::shader_allocate() {
Shader *shader = memnew(Shader);
shader->mode = RS::SHADER_CANVAS_ITEM;
//shader->shader = &scene->state.scene_shader;
RID rid = shader_owner.make_rid(shader);
_shader_make_dirty(shader);
shader->self = rid;
return rid;
}
void RasterizerStorageGLES3::shader_initialize(RID p_rid) {
// noop
}
//RID RasterizerStorageGLES3::shader_create() {
// Shader *shader = memnew(Shader);
// shader->mode = RS::SHADER_SPATIAL;
// shader->shader = &scene->state.scene_shader;
// RID rid = shader_owner.make_rid(shader);
// _shader_make_dirty(shader);
// shader->self = rid;
// return rid;
//}
void RasterizerStorageGLES3::_shader_make_dirty(Shader *p_shader) {
if (p_shader->dirty_list.in_list()) {
return;
}
_shader_dirty_list.add(&p_shader->dirty_list);
}
void RasterizerStorageGLES3::shader_set_code(RID p_shader, const String &p_code) {
Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND(!shader);
shader->code = p_code;
String mode_string = ShaderLanguage::get_shader_type(p_code);
RS::ShaderMode mode;
if (mode_string == "canvas_item") {
mode = RS::SHADER_CANVAS_ITEM;
} else if (mode_string == "particles") {
mode = RS::SHADER_PARTICLES;
} else if (mode_string == "sky") {
mode = RS::SHADER_SKY;
} else if (mode_string == "spatial") {
mode = RS::SHADER_SPATIAL;
} else {
mode = RS::SHADER_MAX;
ERR_PRINT("shader type " + mode_string + " not supported in OpenGL renderer");
}
if (shader->version.is_valid() && mode != shader->mode) {
shader->shader->version_free(shader->version);
shader->version = RID();
}
shader->mode = mode;
// TODO handle all shader types
if (mode == RS::SHADER_CANVAS_ITEM) {
shader->shader = &canvas->state.canvas_shader;
} else if (mode == RS::SHADER_SPATIAL) {
//shader->shader = &scene->state.scene_shader;
} else if (mode == RS::SHADER_PARTICLES) {
} else if (mode == RS::SHADER_SKY) {
} else {
return;
}
if (shader->version.is_null() && shader->shader) {
shader->version = shader->shader->version_create();
}
_shader_make_dirty(shader);
}
String RasterizerStorageGLES3::shader_get_code(RID p_shader) const {
const Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND_V(!shader, "");
return shader->code;
}
void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
_shader_dirty_list.remove(&p_shader->dirty_list);
p_shader->valid = false;
p_shader->uniforms.clear();
if (p_shader->code.is_empty()) {
return; //just invalid, but no error
}
ShaderCompiler::GeneratedCode gen_code;
ShaderCompiler::IdentifierActions *actions = nullptr;
switch (p_shader->mode) {
case RS::SHADER_CANVAS_ITEM: {
p_shader->canvas_item.light_mode = Shader::CanvasItem::LIGHT_MODE_NORMAL;
p_shader->canvas_item.blend_mode = Shader::CanvasItem::BLEND_MODE_MIX;
p_shader->canvas_item.uses_screen_texture = false;
p_shader->canvas_item.uses_screen_uv = false;
p_shader->canvas_item.uses_time = false;
p_shader->canvas_item.uses_modulate = false;
p_shader->canvas_item.uses_color = false;
p_shader->canvas_item.uses_vertex = false;
p_shader->canvas_item.uses_model_matrix = false;
p_shader->canvas_item.uses_extra_matrix = false;
p_shader->canvas_item.uses_projection_matrix = false;
p_shader->canvas_item.uses_instance_custom = false;
shaders.actions_canvas.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_ADD);
shaders.actions_canvas.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MIX);
shaders.actions_canvas.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_SUB);
shaders.actions_canvas.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MUL);
shaders.actions_canvas.render_mode_values["blend_premul_alpha"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_PMALPHA);
shaders.actions_canvas.render_mode_values["unshaded"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_UNSHADED);
shaders.actions_canvas.render_mode_values["light_only"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY);
shaders.actions_canvas.usage_flag_pointers["SCREEN_UV"] = &p_shader->canvas_item.uses_screen_uv;
shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv;
shaders.actions_canvas.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->canvas_item.uses_screen_texture;
shaders.actions_canvas.usage_flag_pointers["TIME"] = &p_shader->canvas_item.uses_time;
shaders.actions_canvas.usage_flag_pointers["MODULATE"] = &p_shader->canvas_item.uses_modulate;
shaders.actions_canvas.usage_flag_pointers["COLOR"] = &p_shader->canvas_item.uses_color;
shaders.actions_canvas.usage_flag_pointers["VERTEX"] = &p_shader->canvas_item.uses_vertex;
shaders.actions_canvas.usage_flag_pointers["MODEL_MATRIX"] = &p_shader->canvas_item.uses_model_matrix;
shaders.actions_canvas.usage_flag_pointers["EXTRA_MATRIX"] = &p_shader->canvas_item.uses_extra_matrix;
shaders.actions_canvas.usage_flag_pointers["PROJECTION_MATRIX"] = &p_shader->canvas_item.uses_projection_matrix;
shaders.actions_canvas.usage_flag_pointers["INSTANCE_CUSTOM"] = &p_shader->canvas_item.uses_instance_custom;
actions = &shaders.actions_canvas;
actions->uniforms = &p_shader->uniforms;
} break;
case RS::SHADER_SPATIAL: {
// TODO remove once 3D is added back
return;
p_shader->spatial.blend_mode = Shader::Spatial::BLEND_MODE_MIX;
p_shader->spatial.depth_draw_mode = Shader::Spatial::DEPTH_DRAW_OPAQUE;
p_shader->spatial.cull_mode = Shader::Spatial::CULL_MODE_BACK;
p_shader->spatial.uses_alpha = false;
p_shader->spatial.uses_alpha_scissor = false;
p_shader->spatial.uses_discard = false;
p_shader->spatial.unshaded = false;
p_shader->spatial.no_depth_test = false;
p_shader->spatial.uses_sss = false;
p_shader->spatial.uses_time = false;
p_shader->spatial.uses_vertex_lighting = false;
p_shader->spatial.uses_screen_texture = false;
p_shader->spatial.uses_depth_texture = false;
p_shader->spatial.uses_vertex = false;
p_shader->spatial.uses_tangent = false;
p_shader->spatial.uses_ensure_correct_normals = false;
p_shader->spatial.writes_modelview_or_projection = false;
p_shader->spatial.uses_world_coordinates = false;
shaders.actions_scene.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_ADD);
shaders.actions_scene.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MIX);
shaders.actions_scene.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_SUB);
shaders.actions_scene.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MUL);
shaders.actions_scene.render_mode_values["depth_draw_opaque"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_OPAQUE);
shaders.actions_scene.render_mode_values["depth_draw_always"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_ALWAYS);
shaders.actions_scene.render_mode_values["depth_draw_never"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_NEVER);
shaders.actions_scene.render_mode_values["depth_draw_alpha_prepass"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS);
shaders.actions_scene.render_mode_values["cull_front"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_FRONT);
shaders.actions_scene.render_mode_values["cull_back"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_BACK);
shaders.actions_scene.render_mode_values["cull_disabled"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_DISABLED);
shaders.actions_scene.render_mode_flags["unshaded"] = &p_shader->spatial.unshaded;
shaders.actions_scene.render_mode_flags["depth_test_disable"] = &p_shader->spatial.no_depth_test;
shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting;
shaders.actions_scene.render_mode_flags["world_vertex_coords"] = &p_shader->spatial.uses_world_coordinates;
shaders.actions_scene.render_mode_flags["ensure_correct_normals"] = &p_shader->spatial.uses_ensure_correct_normals;
shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha;
shaders.actions_scene.usage_flag_pointers["ALPHA_SCISSOR"] = &p_shader->spatial.uses_alpha_scissor;
shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss;
shaders.actions_scene.usage_flag_pointers["DISCARD"] = &p_shader->spatial.uses_discard;
shaders.actions_scene.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->spatial.uses_screen_texture;
shaders.actions_scene.usage_flag_pointers["DEPTH_TEXTURE"] = &p_shader->spatial.uses_depth_texture;
shaders.actions_scene.usage_flag_pointers["TIME"] = &p_shader->spatial.uses_time;
// Use of any of these BUILTINS indicate the need for transformed tangents.
// This is needed to know when to transform tangents in software skinning.
shaders.actions_scene.usage_flag_pointers["TANGENT"] = &p_shader->spatial.uses_tangent;
shaders.actions_scene.usage_flag_pointers["NORMALMAP"] = &p_shader->spatial.uses_tangent;
shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex;
actions = &shaders.actions_scene;
actions->uniforms = &p_shader->uniforms;
} break;
default: {
return;
} break;
}
Error err = shaders.compiler.compile(p_shader->mode, p_shader->code, actions, p_shader->path, gen_code);
if (err != OK) {
return;
}
Vector<StringName> texture_uniform_names;
for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
}
p_shader->shader->version_set_code(p_shader->version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
p_shader->texture_uniforms = gen_code.texture_uniforms;
p_shader->uses_vertex_time = gen_code.uses_vertex_time;
p_shader->uses_fragment_time = gen_code.uses_fragment_time;
for (SelfList<Material> *E = p_shader->materials.first(); E; E = E->next()) {
_material_make_dirty(E->self());
}
p_shader->valid = true;
}
void RasterizerStorageGLES3::update_dirty_shaders() {
while (_shader_dirty_list.first()) {
_update_shader(_shader_dirty_list.first()->self());
}
}
void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND(!shader);
if (shader->dirty_list.in_list()) {
_update_shader(shader);
}
Map<int, StringName> order;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) {
if (E->get().texture_order >= 0) {
order[E->get().texture_order + 100000] = E->key();
} else {
order[E->get().order] = E->key();
}
}
for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
PropertyInfo pi;
ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[E->get()];
pi.name = E->get();
switch (u.type) {
case ShaderLanguage::TYPE_VOID: {
pi.type = Variant::NIL;
} break;
case ShaderLanguage::TYPE_BOOL: {
pi.type = Variant::BOOL;
} break;
// bool vectors
case ShaderLanguage::TYPE_BVEC2: {
pi.type = Variant::INT;
pi.hint = PROPERTY_HINT_FLAGS;
pi.hint_string = "x,y";
} break;
case ShaderLanguage::TYPE_BVEC3: {
pi.type = Variant::INT;
pi.hint = PROPERTY_HINT_FLAGS;
pi.hint_string = "x,y,z";
} break;
case ShaderLanguage::TYPE_BVEC4: {
pi.type = Variant::INT;
pi.hint = PROPERTY_HINT_FLAGS;
pi.hint_string = "x,y,z,w";
} break;
// int stuff
case ShaderLanguage::TYPE_UINT:
case ShaderLanguage::TYPE_INT: {
pi.type = Variant::INT;
if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
pi.hint = PROPERTY_HINT_RANGE;
pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]);
}
} break;
case ShaderLanguage::TYPE_IVEC2:
case ShaderLanguage::TYPE_UVEC2:
case ShaderLanguage::TYPE_IVEC3:
case ShaderLanguage::TYPE_UVEC3:
case ShaderLanguage::TYPE_IVEC4:
case ShaderLanguage::TYPE_UVEC4: {
// not sure what this should be in godot 4
// pi.type = Variant::POOL_INT_ARRAY;
pi.type = Variant::PACKED_INT32_ARRAY;
} break;
case ShaderLanguage::TYPE_FLOAT: {
pi.type = Variant::FLOAT;
if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
pi.hint = PROPERTY_HINT_RANGE;
pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]);
}
} break;
case ShaderLanguage::TYPE_VEC2: {
pi.type = Variant::VECTOR2;
} break;
case ShaderLanguage::TYPE_VEC3: {
pi.type = Variant::VECTOR3;
} break;
case ShaderLanguage::TYPE_VEC4: {
if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
pi.type = Variant::COLOR;
} else {
pi.type = Variant::PLANE;
}
} break;
case ShaderLanguage::TYPE_MAT2: {
pi.type = Variant::TRANSFORM2D;
} break;
case ShaderLanguage::TYPE_MAT3: {
pi.type = Variant::BASIS;
} break;
case ShaderLanguage::TYPE_MAT4: {
pi.type = Variant::TRANSFORM3D;
} break;
case ShaderLanguage::TYPE_SAMPLER2D:
// case ShaderLanguage::TYPE_SAMPLEREXT:
case ShaderLanguage::TYPE_ISAMPLER2D:
case ShaderLanguage::TYPE_USAMPLER2D: {
pi.type = Variant::OBJECT;
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
pi.hint_string = "Texture";
} break;
case ShaderLanguage::TYPE_SAMPLERCUBE: {
pi.type = Variant::OBJECT;
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
pi.hint_string = "CubeMap";
} break;
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
case ShaderLanguage::TYPE_USAMPLER2DARRAY:
case ShaderLanguage::TYPE_SAMPLER3D:
case ShaderLanguage::TYPE_ISAMPLER3D:
case ShaderLanguage::TYPE_USAMPLER3D: {
// Not implemented in OpenGL
} break;
// new for godot 4
case ShaderLanguage::TYPE_SAMPLERCUBEARRAY:
case ShaderLanguage::TYPE_STRUCT:
case ShaderLanguage::TYPE_MAX: {
} break;
}
p_param_list->push_back(pi);
}
}
void RasterizerStorageGLES3::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) {
Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND(!shader);
ERR_FAIL_COND(p_texture.is_valid() && !GLES3::TextureStorage::get_singleton()->owns_texture(p_texture));
if (!p_texture.is_valid()) {
if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) {
shader->default_textures[p_name].erase(p_index);
if (shader->default_textures[p_name].is_empty()) {
shader->default_textures.erase(p_name);
}
}
} else {
if (!shader->default_textures.has(p_name)) {
shader->default_textures[p_name] = Map<int, RID>();
}
shader->default_textures[p_name][p_index] = p_texture;
}
_shader_make_dirty(shader);
}
RID RasterizerStorageGLES3::shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const {
const Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND_V(!shader, RID());
if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) {
return shader->default_textures[p_name][p_index];
}
return RID();
}
/* COMMON MATERIAL API */
void RasterizerStorageGLES3::_material_make_dirty(Material *p_material) const {
if (p_material->dirty_list.in_list()) {
return;
}
_material_dirty_list.add(&p_material->dirty_list);
}
RID RasterizerStorageGLES3::material_allocate() {
Material *material = memnew(Material);
return material_owner.make_rid(material);
}
void RasterizerStorageGLES3::material_initialize(RID p_rid) {
}
//RID RasterizerStorageGLES3::material_create() {
// Material *material = memnew(Material);
// return material_owner.make_rid(material);
//}
void RasterizerStorageGLES3::material_set_shader(RID p_material, RID p_shader) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
Shader *shader = shader_owner.get_or_null(p_shader);
if (material->shader) {
// if a shader is present, remove the old shader
material->shader->materials.remove(&material->list);
}
material->shader = shader;
if (shader) {
shader->materials.add(&material->list);
}
_material_make_dirty(material);
}
RID RasterizerStorageGLES3::material_get_shader(RID p_material) const {
const Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, RID());
if (material->shader) {
return material->shader->self;
}
return RID();
}
void RasterizerStorageGLES3::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
if (p_value.get_type() == Variant::NIL) {
material->params.erase(p_param);
} else {
material->params[p_param] = p_value;
}
_material_make_dirty(material);
}
Variant RasterizerStorageGLES3::material_get_param(RID p_material, const StringName &p_param) const {
const Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, RID());
if (material->params.has(p_param)) {
return material->params[p_param];
}
return material_get_param_default(p_material, p_param);
}
Variant RasterizerStorageGLES3::material_get_param_default(RID p_material, const StringName &p_param) const {
const Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, Variant());
if (material->shader) {
if (material->shader->uniforms.has(p_param)) {
ShaderLanguage::ShaderNode::Uniform uniform = material->shader->uniforms[p_param];
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
}
}
return Variant();
}
void RasterizerStorageGLES3::material_set_line_width(RID p_material, float p_width) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
material->line_width = p_width;
}
void RasterizerStorageGLES3::material_set_next_pass(RID p_material, RID p_next_material) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
material->next_pass = p_next_material;
}
bool RasterizerStorageGLES3::material_is_animated(RID p_material) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, false);
if (material->dirty_list.in_list()) {
_update_material(material);
}
bool animated = material->is_animated_cache;
if (!animated && material->next_pass.is_valid()) {
animated = material_is_animated(material->next_pass);
}
return animated;
}
bool RasterizerStorageGLES3::material_casts_shadows(RID p_material) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, false);
if (material->dirty_list.in_list()) {
_update_material(material);
}
bool casts_shadows = material->can_cast_shadow_cache;
if (!casts_shadows && material->next_pass.is_valid()) {
casts_shadows = material_casts_shadows(material->next_pass);
}
return casts_shadows;
}
bool RasterizerStorageGLES3::material_uses_tangents(RID p_material) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, false);
if (!material->shader) {
return false;
}
if (material->shader->dirty_list.in_list()) {
_update_shader(material->shader);
}
return material->shader->spatial.uses_tangent;
}
bool RasterizerStorageGLES3::material_uses_ensure_correct_normals(RID p_material) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, false);
if (!material->shader) {
return false;
}
if (material->shader->dirty_list.in_list()) {
_update_shader(material->shader);
}
return material->shader->spatial.uses_ensure_correct_normals;
}
void RasterizerStorageGLES3::material_add_instance_owner(RID p_material, DependencyTracker *p_instance) {
/*
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
Map<InstanceBaseDependency *, int>::Element *E = material->instance_owners.find(p_instance);
if (E) {
E->get()++;
} else {
material->instance_owners[p_instance] = 1;
}
*/
}
void RasterizerStorageGLES3::material_remove_instance_owner(RID p_material, DependencyTracker *p_instance) {
/*
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
Map<InstanceBaseDependency *, int>::Element *E = material->instance_owners.find(p_instance);
ERR_FAIL_COND(!E);
E->get()--;
if (E->get() == 0) {
material->instance_owners.erase(E);
}
*/
}
void RasterizerStorageGLES3::material_set_render_priority(RID p_material, int priority) {
ERR_FAIL_COND(priority < RS::MATERIAL_RENDER_PRIORITY_MIN);
ERR_FAIL_COND(priority > RS::MATERIAL_RENDER_PRIORITY_MAX);
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
material->render_priority = priority;
}
void RasterizerStorageGLES3::_update_material(Material *p_material) {
if (p_material->dirty_list.in_list()) {
_material_dirty_list.remove(&p_material->dirty_list);
}
if (p_material->shader && p_material->shader->dirty_list.in_list()) {
_update_shader(p_material->shader);
}
if (p_material->shader && !p_material->shader->valid) {
return;
}
{
bool can_cast_shadow = false;
bool is_animated = false;
if (p_material->shader && p_material->shader->mode == RS::SHADER_SPATIAL) {
if (p_material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX &&
(!p_material->shader->spatial.uses_alpha || p_material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) {
can_cast_shadow = true;
}
if (p_material->shader->spatial.uses_discard && p_material->shader->uses_fragment_time) {
is_animated = true;
}
if (p_material->shader->spatial.uses_vertex && p_material->shader->uses_vertex_time) {
is_animated = true;
}
if (can_cast_shadow != p_material->can_cast_shadow_cache || is_animated != p_material->is_animated_cache) {
p_material->can_cast_shadow_cache = can_cast_shadow;
p_material->is_animated_cache = is_animated;
/*
for (Map<Geometry *, int>::Element *E = p_material->geometry_owners.front(); E; E = E->next()) {
E->key()->material_changed_notify();
}
for (Map<InstanceBaseDependency *, int>::Element *E = p_material->instance_owners.front(); E; E = E->next()) {
E->key()->base_changed(false, true);
}
*/
}
}
}
// uniforms and other things will be set in the use_material method in ShaderGLES3
if (p_material->shader && p_material->shader->texture_uniforms.size() > 0) {
p_material->textures.resize(p_material->shader->texture_uniforms.size());
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_material->shader->uniforms.front(); E; E = E->next()) {
if (E->get().texture_order < 0) {
continue; // not a texture, does not go here
}
RID texture;
Map<StringName, Variant>::Element *V = p_material->params.find(E->key());
if (V) {
texture = V->get();
}
if (!texture.is_valid()) {
Map<StringName, Map<int, RID>>::Element *W = p_material->shader->default_textures.find(E->key());
// TODO: make texture uniform array properly works with GLES3
if (W && W->get().has(0)) {
texture = W->get()[0];
}
}
p_material->textures.write[E->get().texture_order] = Pair<StringName, RID>(E->key(), texture);
}
} else {
p_material->textures.clear();
}
}
/*
void RasterizerStorageGLES3::_material_add_geometry(RID p_material, Geometry *p_geometry) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
Map<Geometry *, int>::Element *I = material->geometry_owners.find(p_geometry);
if (I) {
I->get()++;
} else {
material->geometry_owners[p_geometry] = 1;
}
}
void RasterizerStorageGLES3::_material_remove_geometry(RID p_material, Geometry *p_geometry) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
Map<Geometry *, int>::Element *I = material->geometry_owners.find(p_geometry);
ERR_FAIL_COND(!I);
I->get()--;
if (I->get() == 0) {
material->geometry_owners.erase(I);
}
}
*/
void RasterizerStorageGLES3::update_dirty_materials() {
while (_material_dirty_list.first()) {
Material *material = _material_dirty_list.first()->self();
_update_material(material);
}
}
/* MESH API */
RID RasterizerStorageGLES3::mesh_allocate() {
@ -1489,6 +740,10 @@ void RasterizerStorageGLES3::particles_set_canvas_sdf_collision(RID p_particles,
void RasterizerStorageGLES3::update_particles() {
}
bool RasterizerStorageGLES3::particles_is_inactive(RID p_particles) const {
return false;
}
/* PARTICLES COLLISION */
RID RasterizerStorageGLES3::particles_collision_allocate() {
@ -1595,52 +850,6 @@ AABB RasterizerStorageGLES3::visibility_notifier_get_aabb(RID p_notifier) const
void RasterizerStorageGLES3::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) {
}
/* GLOBAL VARIABLES */
void RasterizerStorageGLES3::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) {
}
void RasterizerStorageGLES3::global_variable_remove(const StringName &p_name) {
}
Vector<StringName> RasterizerStorageGLES3::global_variable_get_list() const {
return Vector<StringName>();
}
void RasterizerStorageGLES3::global_variable_set(const StringName &p_name, const Variant &p_value) {
}
void RasterizerStorageGLES3::global_variable_set_override(const StringName &p_name, const Variant &p_value) {
}
Variant RasterizerStorageGLES3::global_variable_get(const StringName &p_name) const {
return Variant();
}
RS::GlobalVariableType RasterizerStorageGLES3::global_variable_get_type(const StringName &p_name) const {
return RS::GLOBAL_VAR_TYPE_MAX;
}
void RasterizerStorageGLES3::global_variables_load_settings(bool p_load_textures) {
}
void RasterizerStorageGLES3::global_variables_clear() {
}
int32_t RasterizerStorageGLES3::global_variables_instance_allocate(RID p_instance) {
return 0;
}
void RasterizerStorageGLES3::global_variables_instance_free(RID p_instance) {
}
void RasterizerStorageGLES3::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) {
}
bool RasterizerStorageGLES3::particles_is_inactive(RID p_particles) const {
return false;
}
/* RENDER TARGET */
void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) {
@ -2594,63 +1803,12 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
memdelete(sky);
return true;
} else if (shader_owner.owns(p_rid)) {
Shader *shader = shader_owner.get_or_null(p_rid);
if (shader->shader && shader->version.is_valid()) {
shader->shader->version_free(shader->version);
}
if (shader->dirty_list.in_list()) {
_shader_dirty_list.remove(&shader->dirty_list);
}
while (shader->materials.first()) {
Material *m = shader->materials.first()->self();
m->shader = nullptr;
_material_make_dirty(m);
shader->materials.remove(shader->materials.first());
}
shader_owner.free(p_rid);
memdelete(shader);
} else if (GLES3::MaterialStorage::get_singleton()->owns_shader(p_rid)) {
GLES3::MaterialStorage::get_singleton()->shader_free(p_rid);
return true;
} else if (material_owner.owns(p_rid)) {
Material *m = material_owner.get_or_null(p_rid);
if (m->shader) {
m->shader->materials.remove(&m->list);
}
/*
for (Map<Geometry *, int>::Element *E = m->geometry_owners.front(); E; E = E->next()) {
Geometry *g = E->key();
g->material = RID();
}
for (Map<InstanceBaseDependency *, int>::Element *E = m->instance_owners.front(); E; E = E->next()) {
InstanceBaseDependency *ins = E->key();
if (ins->material_override == p_rid) {
ins->material_override = RID();
}
for (int i = 0; i < ins->materials.size(); i++) {
if (ins->materials[i] == p_rid) {
ins->materials.write[i] = RID();
}
}
}
*/
material_owner.free(p_rid);
memdelete(m);
} else if (GLES3::MaterialStorage::get_singleton()->owns_material(p_rid)) {
GLES3::MaterialStorage::get_singleton()->material_free(p_rid);
return true;
} else {
return false;
}
@ -2975,13 +2133,6 @@ void RasterizerStorageGLES3::initialize() {
// OR max_vertex_texture_image_units is zero
config->use_skeleton_software = (config->float_texture_supported == false) || (config->max_vertex_texture_image_units == 0);
shaders.copy.initialize();
shaders.copy_version = shaders.copy.version_create(); //TODO
shaders.copy.version_bind_shader(shaders.copy_version, CopyShaderGLES3::MODE_COPY_SECTION);
//shaders.cubemap_filter.init();
//bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx");
//shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq);
{
// quad for copying stuff
@ -3139,8 +2290,8 @@ uint64_t RasterizerStorageGLES3::get_rendering_info(RS::RenderingInfo p_info) {
}
void RasterizerStorageGLES3::update_dirty_resources() {
update_dirty_shaders();
update_dirty_materials();
GLES3::MaterialStorage::get_singleton()->update_dirty_shaders();
GLES3::MaterialStorage::get_singleton()->update_dirty_materials();
// update_dirty_skeletons();
// update_dirty_multimeshes();
}
@ -3150,7 +2301,6 @@ RasterizerStorageGLES3::RasterizerStorageGLES3() {
}
RasterizerStorageGLES3::~RasterizerStorageGLES3() {
shaders.copy.version_free(shaders.copy_version);
}
#endif // GLES3_ENABLED

View file

@ -42,18 +42,17 @@
#include "servers/rendering/shader_language.h"
#include "storage/canvas_texture_storage.h"
#include "storage/config.h"
#include "storage/material_storage.h"
#include "storage/render_target_storage.h"
#include "storage/texture_storage.h"
#include "shaders/copy.glsl.gen.h"
class RasterizerCanvasGLES3;
class RasterizerSceneGLES3;
// class RasterizerCanvasGLES3;
// class RasterizerSceneGLES3;
class RasterizerStorageGLES3 : public RendererStorage {
public:
RasterizerCanvasGLES3 *canvas;
RasterizerSceneGLES3 *scene;
// RasterizerCanvasGLES3 *canvas;
// RasterizerSceneGLES3 *scene;
static GLuint system_fbo;
@ -79,19 +78,6 @@ public:
} resources;
mutable struct Shaders {
ShaderCompiler compiler;
CopyShaderGLES3 copy;
RID copy_version;
//CubemapFilterShaderGLES3 cubemap_filter;
ShaderCompiler::IdentifierActions actions_canvas;
ShaderCompiler::IdentifierActions actions_scene;
ShaderCompiler::IdentifierActions actions_particles;
} shaders;
struct Info {
uint64_t texture_mem = 0;
uint64_t vertex_mem = 0;
@ -146,231 +132,6 @@ public:
RID sky_create();
void sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size);
// SHADER API
struct Material;
struct Shader {
RID self;
RS::ShaderMode mode;
ShaderGLES3 *shader;
String code;
SelfList<Material>::List materials;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
RID version;
SelfList<Shader> dirty_list;
Map<StringName, Map<int, RID>> default_textures;
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
bool valid;
String path;
uint32_t index;
uint64_t last_pass;
struct CanvasItem {
enum BlendMode {
BLEND_MODE_MIX,
BLEND_MODE_ADD,
BLEND_MODE_SUB,
BLEND_MODE_MUL,
BLEND_MODE_PMALPHA,
};
int blend_mode;
enum LightMode {
LIGHT_MODE_NORMAL,
LIGHT_MODE_UNSHADED,
LIGHT_MODE_LIGHT_ONLY
};
int light_mode;
bool uses_screen_texture;
bool uses_screen_uv;
bool uses_time;
bool uses_modulate;
bool uses_color;
bool uses_vertex;
// all these should disable item joining if used in a custom shader
bool uses_model_matrix;
bool uses_extra_matrix;
bool uses_projection_matrix;
bool uses_instance_custom;
} canvas_item;
struct Spatial {
enum BlendMode {
BLEND_MODE_MIX,
BLEND_MODE_ADD,
BLEND_MODE_SUB,
BLEND_MODE_MUL,
};
int blend_mode;
enum DepthDrawMode {
DEPTH_DRAW_OPAQUE,
DEPTH_DRAW_ALWAYS,
DEPTH_DRAW_NEVER,
DEPTH_DRAW_ALPHA_PREPASS,
};
int depth_draw_mode;
enum CullMode {
CULL_MODE_FRONT,
CULL_MODE_BACK,
CULL_MODE_DISABLED,
};
int cull_mode;
bool uses_alpha;
bool uses_alpha_scissor;
bool unshaded;
bool no_depth_test;
bool uses_vertex;
bool uses_discard;
bool uses_sss;
bool uses_screen_texture;
bool uses_depth_texture;
bool uses_time;
bool uses_tangent;
bool uses_ensure_correct_normals;
bool writes_modelview_or_projection;
bool uses_vertex_lighting;
bool uses_world_coordinates;
} spatial;
struct Particles {
} particles;
bool uses_vertex_time;
bool uses_fragment_time;
Shader() :
dirty_list(this) {
shader = nullptr;
valid = false;
version = RID();
last_pass = 0;
}
};
mutable RID_PtrOwner<Shader> shader_owner;
mutable SelfList<Shader>::List _shader_dirty_list;
void _shader_make_dirty(Shader *p_shader);
RID shader_allocate() override;
void shader_initialize(RID p_rid) override;
//RID shader_create() override;
void shader_set_code(RID p_shader, const String &p_code) override;
String shader_get_code(RID p_shader) const override;
void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override;
void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override;
RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override;
RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); };
void _update_shader(Shader *p_shader) const;
void update_dirty_shaders();
// new
Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); }
// COMMON MATERIAL API
struct Material {
RID self;
Shader *shader;
Map<StringName, Variant> params;
SelfList<Material> list;
SelfList<Material> dirty_list;
Vector<Pair<StringName, RID>> textures;
float line_width;
int render_priority;
RID next_pass;
uint32_t index;
uint64_t last_pass;
// Map<Geometry *, int> geometry_owners;
// Map<InstanceBaseDependency *, int> instance_owners;
bool can_cast_shadow_cache;
bool is_animated_cache;
Material() :
list(this),
dirty_list(this) {
can_cast_shadow_cache = false;
is_animated_cache = false;
shader = nullptr;
line_width = 1.0;
last_pass = 0;
render_priority = 0;
}
};
mutable SelfList<Material>::List _material_dirty_list;
void _material_make_dirty(Material *p_material) const;
// void _material_add_geometry(RID p_material, Geometry *p_geometry);
// void _material_remove_geometry(RID p_material, Geometry *p_geometry);
void _update_material(Material *p_material);
mutable RID_PtrOwner<Material> material_owner;
// new
void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {}
void material_update_dependency(RID p_material, DependencyTracker *p_instance) override {}
// old
RID material_allocate() override;
void material_initialize(RID p_rid) override;
//RID material_create() override;
void material_set_shader(RID p_material, RID p_shader) override;
RID material_get_shader(RID p_material) const;
void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override;
Variant material_get_param(RID p_material, const StringName &p_param) const override;
Variant material_get_param_default(RID p_material, const StringName &p_param) const;
void material_set_line_width(RID p_material, float p_width);
void material_set_next_pass(RID p_material, RID p_next_material) override;
bool material_is_animated(RID p_material) override;
bool material_casts_shadows(RID p_material) override;
bool material_uses_tangents(RID p_material);
bool material_uses_ensure_correct_normals(RID p_material);
void material_add_instance_owner(RID p_material, DependencyTracker *p_instance);
void material_remove_instance_owner(RID p_material, DependencyTracker *p_instance);
void material_set_render_priority(RID p_material, int priority) override;
void update_dirty_materials();
/* MESH API */
RID mesh_allocate() override;
@ -694,6 +455,7 @@ public:
void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) override;
void update_particles() override;
bool particles_is_inactive(RID p_particles) const override;
/* PARTICLES COLLISION */
@ -737,26 +499,6 @@ public:
AABB visibility_notifier_get_aabb(RID p_notifier) const override;
void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override;
/* GLOBAL VARIABLES */
void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override;
void global_variable_remove(const StringName &p_name) override;
Vector<StringName> global_variable_get_list() const override;
void global_variable_set(const StringName &p_name, const Variant &p_value) override;
void global_variable_set_override(const StringName &p_name, const Variant &p_value) override;
Variant global_variable_get(const StringName &p_name) const override;
RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override;
void global_variables_load_settings(bool p_load_textures = true) override;
void global_variables_clear() override;
int32_t global_variables_instance_allocate(RID p_instance) override;
void global_variables_instance_free(RID p_instance) override;
void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override;
bool particles_is_inactive(RID p_particles) const override;
// RENDER TARGET
mutable RID_PtrOwner<GLES3::RenderTarget> render_target_owner;

View file

@ -0,0 +1,913 @@
/*************************************************************************/
/* material_storage.cpp */
/*************************************************************************/
/* 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. */
/*************************************************************************/
#ifdef GLES3_ENABLED
#include "material_storage.h"
#include "config.h"
#include "texture_storage.h"
#include "drivers/gles3/rasterizer_canvas_gles3.h"
using namespace GLES3;
MaterialStorage *MaterialStorage::singleton = nullptr;
MaterialStorage *MaterialStorage::get_singleton() {
return singleton;
}
MaterialStorage::MaterialStorage() {
singleton = this;
shaders.copy.initialize();
shaders.copy_version = shaders.copy.version_create(); //TODO
shaders.copy.version_bind_shader(shaders.copy_version, CopyShaderGLES3::MODE_COPY_SECTION);
//shaders.cubemap_filter.init();
//bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx");
//shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq);
}
MaterialStorage::~MaterialStorage() {
shaders.copy.version_free(shaders.copy_version);
singleton = nullptr;
}
/* GLOBAL VARIABLE API */
void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) {
}
void MaterialStorage::global_variable_remove(const StringName &p_name) {
}
Vector<StringName> MaterialStorage::global_variable_get_list() const {
return Vector<StringName>();
}
void MaterialStorage::global_variable_set(const StringName &p_name, const Variant &p_value) {
}
void MaterialStorage::global_variable_set_override(const StringName &p_name, const Variant &p_value) {
}
Variant MaterialStorage::global_variable_get(const StringName &p_name) const {
return Variant();
}
RS::GlobalVariableType MaterialStorage::global_variable_get_type(const StringName &p_name) const {
return RS::GLOBAL_VAR_TYPE_MAX;
}
void MaterialStorage::global_variables_load_settings(bool p_load_textures) {
}
void MaterialStorage::global_variables_clear() {
}
int32_t MaterialStorage::global_variables_instance_allocate(RID p_instance) {
return 0;
}
void MaterialStorage::global_variables_instance_free(RID p_instance) {
}
void MaterialStorage::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) {
}
/* SHADER API */
void MaterialStorage::_shader_make_dirty(Shader *p_shader) {
if (p_shader->dirty_list.in_list()) {
return;
}
_shader_dirty_list.add(&p_shader->dirty_list);
}
RID MaterialStorage::shader_allocate() {
Shader *shader = memnew(Shader);
shader->mode = RS::SHADER_CANVAS_ITEM;
//shader->shader = &scene->state.scene_shader;
RID rid = shader_owner.make_rid(shader);
_shader_make_dirty(shader);
shader->self = rid;
return rid;
}
void MaterialStorage::shader_initialize(RID p_rid) {
// noop
}
//RID MaterialStorage::shader_create() {
// Shader *shader = memnew(Shader);
// shader->mode = RS::SHADER_SPATIAL;
// shader->shader = &scene->state.scene_shader;
// RID rid = shader_owner.make_rid(shader);
// _shader_make_dirty(shader);
// shader->self = rid;
// return rid;
//}
void MaterialStorage::shader_free(RID p_rid) {
Shader *shader = shader_owner.get_or_null(p_rid);
if (shader->shader && shader->version.is_valid()) {
shader->shader->version_free(shader->version);
}
if (shader->dirty_list.in_list()) {
_shader_dirty_list.remove(&shader->dirty_list);
}
while (shader->materials.first()) {
Material *m = shader->materials.first()->self();
m->shader = nullptr;
_material_make_dirty(m);
shader->materials.remove(shader->materials.first());
}
shader_owner.free(p_rid);
memdelete(shader);
}
void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) {
Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND(!shader);
shader->code = p_code;
String mode_string = ShaderLanguage::get_shader_type(p_code);
RS::ShaderMode mode;
if (mode_string == "canvas_item") {
mode = RS::SHADER_CANVAS_ITEM;
} else if (mode_string == "particles") {
mode = RS::SHADER_PARTICLES;
} else if (mode_string == "sky") {
mode = RS::SHADER_SKY;
} else if (mode_string == "spatial") {
mode = RS::SHADER_SPATIAL;
} else {
mode = RS::SHADER_MAX;
ERR_PRINT("shader type " + mode_string + " not supported in OpenGL renderer");
}
if (shader->version.is_valid() && mode != shader->mode) {
shader->shader->version_free(shader->version);
shader->version = RID();
}
shader->mode = mode;
// TODO handle all shader types
if (mode == RS::SHADER_CANVAS_ITEM) {
shader->shader = &RasterizerCanvasGLES3::get_singleton()->state.canvas_shader;
} else if (mode == RS::SHADER_SPATIAL) {
//shader->shader = &scene->state.scene_shader;
} else if (mode == RS::SHADER_PARTICLES) {
} else if (mode == RS::SHADER_SKY) {
} else {
return;
}
if (shader->version.is_null() && shader->shader) {
shader->version = shader->shader->version_create();
}
_shader_make_dirty(shader);
}
String MaterialStorage::shader_get_code(RID p_shader) const {
const Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND_V(!shader, "");
return shader->code;
}
void MaterialStorage::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND(!shader);
if (shader->dirty_list.in_list()) {
_update_shader(shader);
}
Map<int, StringName> order;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) {
if (E->get().texture_order >= 0) {
order[E->get().texture_order + 100000] = E->key();
} else {
order[E->get().order] = E->key();
}
}
for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
PropertyInfo pi;
ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[E->get()];
pi.name = E->get();
switch (u.type) {
case ShaderLanguage::TYPE_VOID: {
pi.type = Variant::NIL;
} break;
case ShaderLanguage::TYPE_BOOL: {
pi.type = Variant::BOOL;
} break;
// bool vectors
case ShaderLanguage::TYPE_BVEC2: {
pi.type = Variant::INT;
pi.hint = PROPERTY_HINT_FLAGS;
pi.hint_string = "x,y";
} break;
case ShaderLanguage::TYPE_BVEC3: {
pi.type = Variant::INT;
pi.hint = PROPERTY_HINT_FLAGS;
pi.hint_string = "x,y,z";
} break;
case ShaderLanguage::TYPE_BVEC4: {
pi.type = Variant::INT;
pi.hint = PROPERTY_HINT_FLAGS;
pi.hint_string = "x,y,z,w";
} break;
// int stuff
case ShaderLanguage::TYPE_UINT:
case ShaderLanguage::TYPE_INT: {
pi.type = Variant::INT;
if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
pi.hint = PROPERTY_HINT_RANGE;
pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]);
}
} break;
case ShaderLanguage::TYPE_IVEC2:
case ShaderLanguage::TYPE_UVEC2:
case ShaderLanguage::TYPE_IVEC3:
case ShaderLanguage::TYPE_UVEC3:
case ShaderLanguage::TYPE_IVEC4:
case ShaderLanguage::TYPE_UVEC4: {
// not sure what this should be in godot 4
// pi.type = Variant::POOL_INT_ARRAY;
pi.type = Variant::PACKED_INT32_ARRAY;
} break;
case ShaderLanguage::TYPE_FLOAT: {
pi.type = Variant::FLOAT;
if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
pi.hint = PROPERTY_HINT_RANGE;
pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]);
}
} break;
case ShaderLanguage::TYPE_VEC2: {
pi.type = Variant::VECTOR2;
} break;
case ShaderLanguage::TYPE_VEC3: {
pi.type = Variant::VECTOR3;
} break;
case ShaderLanguage::TYPE_VEC4: {
if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
pi.type = Variant::COLOR;
} else {
pi.type = Variant::PLANE;
}
} break;
case ShaderLanguage::TYPE_MAT2: {
pi.type = Variant::TRANSFORM2D;
} break;
case ShaderLanguage::TYPE_MAT3: {
pi.type = Variant::BASIS;
} break;
case ShaderLanguage::TYPE_MAT4: {
pi.type = Variant::TRANSFORM3D;
} break;
case ShaderLanguage::TYPE_SAMPLER2D:
// case ShaderLanguage::TYPE_SAMPLEREXT:
case ShaderLanguage::TYPE_ISAMPLER2D:
case ShaderLanguage::TYPE_USAMPLER2D: {
pi.type = Variant::OBJECT;
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
pi.hint_string = "Texture";
} break;
case ShaderLanguage::TYPE_SAMPLERCUBE: {
pi.type = Variant::OBJECT;
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
pi.hint_string = "CubeMap";
} break;
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
case ShaderLanguage::TYPE_USAMPLER2DARRAY:
case ShaderLanguage::TYPE_SAMPLER3D:
case ShaderLanguage::TYPE_ISAMPLER3D:
case ShaderLanguage::TYPE_USAMPLER3D: {
// Not implemented in OpenGL
} break;
// new for godot 4
case ShaderLanguage::TYPE_SAMPLERCUBEARRAY:
case ShaderLanguage::TYPE_STRUCT:
case ShaderLanguage::TYPE_MAX: {
} break;
}
p_param_list->push_back(pi);
}
}
void MaterialStorage::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) {
Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND(!shader);
ERR_FAIL_COND(p_texture.is_valid() && !TextureStorage::get_singleton()->owns_texture(p_texture));
if (!p_texture.is_valid()) {
if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) {
shader->default_textures[p_name].erase(p_index);
if (shader->default_textures[p_name].is_empty()) {
shader->default_textures.erase(p_name);
}
}
} else {
if (!shader->default_textures.has(p_name)) {
shader->default_textures[p_name] = Map<int, RID>();
}
shader->default_textures[p_name][p_index] = p_texture;
}
_shader_make_dirty(shader);
}
RID MaterialStorage::shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const {
const Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND_V(!shader, RID());
if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) {
return shader->default_textures[p_name][p_index];
}
return RID();
}
void MaterialStorage::_update_shader(Shader *p_shader) const {
_shader_dirty_list.remove(&p_shader->dirty_list);
p_shader->valid = false;
p_shader->uniforms.clear();
if (p_shader->code.is_empty()) {
return; //just invalid, but no error
}
ShaderCompiler::GeneratedCode gen_code;
ShaderCompiler::IdentifierActions *actions = nullptr;
switch (p_shader->mode) {
case RS::SHADER_CANVAS_ITEM: {
p_shader->canvas_item.light_mode = Shader::CanvasItem::LIGHT_MODE_NORMAL;
p_shader->canvas_item.blend_mode = Shader::CanvasItem::BLEND_MODE_MIX;
p_shader->canvas_item.uses_screen_texture = false;
p_shader->canvas_item.uses_screen_uv = false;
p_shader->canvas_item.uses_time = false;
p_shader->canvas_item.uses_modulate = false;
p_shader->canvas_item.uses_color = false;
p_shader->canvas_item.uses_vertex = false;
p_shader->canvas_item.uses_model_matrix = false;
p_shader->canvas_item.uses_extra_matrix = false;
p_shader->canvas_item.uses_projection_matrix = false;
p_shader->canvas_item.uses_instance_custom = false;
shaders.actions_canvas.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_ADD);
shaders.actions_canvas.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MIX);
shaders.actions_canvas.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_SUB);
shaders.actions_canvas.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MUL);
shaders.actions_canvas.render_mode_values["blend_premul_alpha"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_PMALPHA);
shaders.actions_canvas.render_mode_values["unshaded"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_UNSHADED);
shaders.actions_canvas.render_mode_values["light_only"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY);
shaders.actions_canvas.usage_flag_pointers["SCREEN_UV"] = &p_shader->canvas_item.uses_screen_uv;
shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv;
shaders.actions_canvas.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->canvas_item.uses_screen_texture;
shaders.actions_canvas.usage_flag_pointers["TIME"] = &p_shader->canvas_item.uses_time;
shaders.actions_canvas.usage_flag_pointers["MODULATE"] = &p_shader->canvas_item.uses_modulate;
shaders.actions_canvas.usage_flag_pointers["COLOR"] = &p_shader->canvas_item.uses_color;
shaders.actions_canvas.usage_flag_pointers["VERTEX"] = &p_shader->canvas_item.uses_vertex;
shaders.actions_canvas.usage_flag_pointers["MODEL_MATRIX"] = &p_shader->canvas_item.uses_model_matrix;
shaders.actions_canvas.usage_flag_pointers["EXTRA_MATRIX"] = &p_shader->canvas_item.uses_extra_matrix;
shaders.actions_canvas.usage_flag_pointers["PROJECTION_MATRIX"] = &p_shader->canvas_item.uses_projection_matrix;
shaders.actions_canvas.usage_flag_pointers["INSTANCE_CUSTOM"] = &p_shader->canvas_item.uses_instance_custom;
actions = &shaders.actions_canvas;
actions->uniforms = &p_shader->uniforms;
} break;
case RS::SHADER_SPATIAL: {
// TODO remove once 3D is added back
return;
p_shader->spatial.blend_mode = Shader::Spatial::BLEND_MODE_MIX;
p_shader->spatial.depth_draw_mode = Shader::Spatial::DEPTH_DRAW_OPAQUE;
p_shader->spatial.cull_mode = Shader::Spatial::CULL_MODE_BACK;
p_shader->spatial.uses_alpha = false;
p_shader->spatial.uses_alpha_scissor = false;
p_shader->spatial.uses_discard = false;
p_shader->spatial.unshaded = false;
p_shader->spatial.no_depth_test = false;
p_shader->spatial.uses_sss = false;
p_shader->spatial.uses_time = false;
p_shader->spatial.uses_vertex_lighting = false;
p_shader->spatial.uses_screen_texture = false;
p_shader->spatial.uses_depth_texture = false;
p_shader->spatial.uses_vertex = false;
p_shader->spatial.uses_tangent = false;
p_shader->spatial.uses_ensure_correct_normals = false;
p_shader->spatial.writes_modelview_or_projection = false;
p_shader->spatial.uses_world_coordinates = false;
shaders.actions_scene.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_ADD);
shaders.actions_scene.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MIX);
shaders.actions_scene.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_SUB);
shaders.actions_scene.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MUL);
shaders.actions_scene.render_mode_values["depth_draw_opaque"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_OPAQUE);
shaders.actions_scene.render_mode_values["depth_draw_always"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_ALWAYS);
shaders.actions_scene.render_mode_values["depth_draw_never"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_NEVER);
shaders.actions_scene.render_mode_values["depth_draw_alpha_prepass"] = Pair<int *, int>(&p_shader->spatial.depth_draw_mode, Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS);
shaders.actions_scene.render_mode_values["cull_front"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_FRONT);
shaders.actions_scene.render_mode_values["cull_back"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_BACK);
shaders.actions_scene.render_mode_values["cull_disabled"] = Pair<int *, int>(&p_shader->spatial.cull_mode, Shader::Spatial::CULL_MODE_DISABLED);
shaders.actions_scene.render_mode_flags["unshaded"] = &p_shader->spatial.unshaded;
shaders.actions_scene.render_mode_flags["depth_test_disable"] = &p_shader->spatial.no_depth_test;
shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting;
shaders.actions_scene.render_mode_flags["world_vertex_coords"] = &p_shader->spatial.uses_world_coordinates;
shaders.actions_scene.render_mode_flags["ensure_correct_normals"] = &p_shader->spatial.uses_ensure_correct_normals;
shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha;
shaders.actions_scene.usage_flag_pointers["ALPHA_SCISSOR"] = &p_shader->spatial.uses_alpha_scissor;
shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss;
shaders.actions_scene.usage_flag_pointers["DISCARD"] = &p_shader->spatial.uses_discard;
shaders.actions_scene.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->spatial.uses_screen_texture;
shaders.actions_scene.usage_flag_pointers["DEPTH_TEXTURE"] = &p_shader->spatial.uses_depth_texture;
shaders.actions_scene.usage_flag_pointers["TIME"] = &p_shader->spatial.uses_time;
// Use of any of these BUILTINS indicate the need for transformed tangents.
// This is needed to know when to transform tangents in software skinning.
shaders.actions_scene.usage_flag_pointers["TANGENT"] = &p_shader->spatial.uses_tangent;
shaders.actions_scene.usage_flag_pointers["NORMALMAP"] = &p_shader->spatial.uses_tangent;
shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex;
actions = &shaders.actions_scene;
actions->uniforms = &p_shader->uniforms;
} break;
default: {
return;
} break;
}
Error err = shaders.compiler.compile(p_shader->mode, p_shader->code, actions, p_shader->path, gen_code);
if (err != OK) {
return;
}
Vector<StringName> texture_uniform_names;
for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
}
p_shader->shader->version_set_code(p_shader->version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
p_shader->texture_uniforms = gen_code.texture_uniforms;
p_shader->uses_vertex_time = gen_code.uses_vertex_time;
p_shader->uses_fragment_time = gen_code.uses_fragment_time;
for (SelfList<Material> *E = p_shader->materials.first(); E; E = E->next()) {
_material_make_dirty(E->self());
}
p_shader->valid = true;
}
void MaterialStorage::update_dirty_shaders() {
while (_shader_dirty_list.first()) {
_update_shader(_shader_dirty_list.first()->self());
}
}
/* MATERIAL API */
void MaterialStorage::_material_make_dirty(Material *p_material) const {
if (p_material->dirty_list.in_list()) {
return;
}
_material_dirty_list.add(&p_material->dirty_list);
}
void MaterialStorage::_update_material(Material *p_material) {
if (p_material->dirty_list.in_list()) {
_material_dirty_list.remove(&p_material->dirty_list);
}
if (p_material->shader && p_material->shader->dirty_list.in_list()) {
_update_shader(p_material->shader);
}
if (p_material->shader && !p_material->shader->valid) {
return;
}
{
bool can_cast_shadow = false;
bool is_animated = false;
if (p_material->shader && p_material->shader->mode == RS::SHADER_SPATIAL) {
if (p_material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX &&
(!p_material->shader->spatial.uses_alpha || p_material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) {
can_cast_shadow = true;
}
if (p_material->shader->spatial.uses_discard && p_material->shader->uses_fragment_time) {
is_animated = true;
}
if (p_material->shader->spatial.uses_vertex && p_material->shader->uses_vertex_time) {
is_animated = true;
}
if (can_cast_shadow != p_material->can_cast_shadow_cache || is_animated != p_material->is_animated_cache) {
p_material->can_cast_shadow_cache = can_cast_shadow;
p_material->is_animated_cache = is_animated;
/*
for (Map<Geometry *, int>::Element *E = p_material->geometry_owners.front(); E; E = E->next()) {
E->key()->material_changed_notify();
}
for (Map<InstanceBaseDependency *, int>::Element *E = p_material->instance_owners.front(); E; E = E->next()) {
E->key()->base_changed(false, true);
}
*/
}
}
}
// uniforms and other things will be set in the use_material method in ShaderGLES3
if (p_material->shader && p_material->shader->texture_uniforms.size() > 0) {
p_material->textures.resize(p_material->shader->texture_uniforms.size());
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_material->shader->uniforms.front(); E; E = E->next()) {
if (E->get().texture_order < 0) {
continue; // not a texture, does not go here
}
RID texture;
Map<StringName, Variant>::Element *V = p_material->params.find(E->key());
if (V) {
texture = V->get();
}
if (!texture.is_valid()) {
Map<StringName, Map<int, RID>>::Element *W = p_material->shader->default_textures.find(E->key());
// TODO: make texture uniform array properly works with GLES3
if (W && W->get().has(0)) {
texture = W->get()[0];
}
}
p_material->textures.write[E->get().texture_order] = Pair<StringName, RID>(E->key(), texture);
}
} else {
p_material->textures.clear();
}
}
RID MaterialStorage::material_allocate() {
Material *material = memnew(Material);
return material_owner.make_rid(material);
}
void MaterialStorage::material_initialize(RID p_rid) {
}
//RID MaterialStorage::material_create() {
// Material *material = memnew(Material);
// return material_owner.make_rid(material);
//}
void MaterialStorage::material_free(RID p_rid) {
Material *m = material_owner.get_or_null(p_rid);
if (m->shader) {
m->shader->materials.remove(&m->list);
}
/*
for (Map<Geometry *, int>::Element *E = m->geometry_owners.front(); E; E = E->next()) {
Geometry *g = E->key();
g->material = RID();
}
for (Map<InstanceBaseDependency *, int>::Element *E = m->instance_owners.front(); E; E = E->next()) {
InstanceBaseDependency *ins = E->key();
if (ins->material_override == p_rid) {
ins->material_override = RID();
}
for (int i = 0; i < ins->materials.size(); i++) {
if (ins->materials[i] == p_rid) {
ins->materials.write[i] = RID();
}
}
}
*/
material_owner.free(p_rid);
memdelete(m);
}
void MaterialStorage::material_set_shader(RID p_material, RID p_shader) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
Shader *shader = get_shader(p_shader);
if (material->shader) {
// if a shader is present, remove the old shader
material->shader->materials.remove(&material->list);
}
material->shader = shader;
if (shader) {
shader->materials.add(&material->list);
}
_material_make_dirty(material);
}
void MaterialStorage::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
if (p_value.get_type() == Variant::NIL) {
material->params.erase(p_param);
} else {
material->params[p_param] = p_value;
}
_material_make_dirty(material);
}
Variant MaterialStorage::material_get_param(RID p_material, const StringName &p_param) const {
const Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, RID());
if (material->params.has(p_param)) {
return material->params[p_param];
}
return material_get_param_default(p_material, p_param);
}
void MaterialStorage::material_set_next_pass(RID p_material, RID p_next_material) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
material->next_pass = p_next_material;
}
void MaterialStorage::material_set_render_priority(RID p_material, int priority) {
ERR_FAIL_COND(priority < RS::MATERIAL_RENDER_PRIORITY_MIN);
ERR_FAIL_COND(priority > RS::MATERIAL_RENDER_PRIORITY_MAX);
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
material->render_priority = priority;
}
bool MaterialStorage::material_is_animated(RID p_material) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, false);
if (material->dirty_list.in_list()) {
_update_material(material);
}
bool animated = material->is_animated_cache;
if (!animated && material->next_pass.is_valid()) {
animated = material_is_animated(material->next_pass);
}
return animated;
}
bool MaterialStorage::material_casts_shadows(RID p_material) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, false);
if (material->dirty_list.in_list()) {
_update_material(material);
}
bool casts_shadows = material->can_cast_shadow_cache;
if (!casts_shadows && material->next_pass.is_valid()) {
casts_shadows = material_casts_shadows(material->next_pass);
}
return casts_shadows;
}
Variant MaterialStorage::material_get_param_default(RID p_material, const StringName &p_param) const {
const Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, Variant());
if (material->shader) {
if (material->shader->uniforms.has(p_param)) {
ShaderLanguage::ShaderNode::Uniform uniform = material->shader->uniforms[p_param];
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
}
}
return Variant();
}
void MaterialStorage::update_dirty_materials() {
while (_material_dirty_list.first()) {
Material *material = _material_dirty_list.first()->self();
_update_material(material);
}
}
/* are these still used? */
RID MaterialStorage::material_get_shader(RID p_material) const {
const Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, RID());
if (material->shader) {
return material->shader->self;
}
return RID();
}
void MaterialStorage::material_set_line_width(RID p_material, float p_width) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
material->line_width = p_width;
}
bool MaterialStorage::material_uses_tangents(RID p_material) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, false);
if (!material->shader) {
return false;
}
if (material->shader->dirty_list.in_list()) {
_update_shader(material->shader);
}
return material->shader->spatial.uses_tangent;
}
bool MaterialStorage::material_uses_ensure_correct_normals(RID p_material) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND_V(!material, false);
if (!material->shader) {
return false;
}
if (material->shader->dirty_list.in_list()) {
_update_shader(material->shader);
}
return material->shader->spatial.uses_ensure_correct_normals;
}
void MaterialStorage::material_add_instance_owner(RID p_material, RendererStorage::DependencyTracker *p_instance) {
/*
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
Map<InstanceBaseDependency *, int>::Element *E = material->instance_owners.find(p_instance);
if (E) {
E->get()++;
} else {
material->instance_owners[p_instance] = 1;
}
*/
}
void MaterialStorage::material_remove_instance_owner(RID p_material, RendererStorage::DependencyTracker *p_instance) {
/*
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
Map<InstanceBaseDependency *, int>::Element *E = material->instance_owners.find(p_instance);
ERR_FAIL_COND(!E);
E->get()--;
if (E->get() == 0) {
material->instance_owners.erase(E);
}
*/
}
/*
void MaterialStorage::_material_add_geometry(RID p_material, Geometry *p_geometry) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
Map<Geometry *, int>::Element *I = material->geometry_owners.find(p_geometry);
if (I) {
I->get()++;
} else {
material->geometry_owners[p_geometry] = 1;
}
}
void MaterialStorage::_material_remove_geometry(RID p_material, Geometry *p_geometry) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
Map<Geometry *, int>::Element *I = material->geometry_owners.find(p_geometry);
ERR_FAIL_COND(!I);
I->get()--;
if (I->get() == 0) {
material->geometry_owners.erase(I);
}
}
*/
#endif // !GLES3_ENABLED

View file

@ -0,0 +1,338 @@
/*************************************************************************/
/* material_storage.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 MATERIAL_STORAGE_GLES3_H
#define MATERIAL_STORAGE_GLES3_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 "servers/rendering/storage/material_storage.h"
#include "drivers/gles3/shaders/copy.glsl.gen.h"
namespace GLES3 {
/* SHADER Structs */
struct Shaders {
ShaderCompiler compiler;
CopyShaderGLES3 copy;
RID copy_version;
//CubemapFilterShaderGLES3 cubemap_filter;
ShaderCompiler::IdentifierActions actions_canvas;
ShaderCompiler::IdentifierActions actions_scene;
ShaderCompiler::IdentifierActions actions_particles;
};
struct Material;
struct Shader {
RID self;
RS::ShaderMode mode;
ShaderGLES3 *shader;
String code;
SelfList<Material>::List materials;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
RID version;
SelfList<Shader> dirty_list;
Map<StringName, Map<int, RID>> default_textures;
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
bool valid;
String path;
uint32_t index;
uint64_t last_pass;
struct CanvasItem {
enum BlendMode {
BLEND_MODE_MIX,
BLEND_MODE_ADD,
BLEND_MODE_SUB,
BLEND_MODE_MUL,
BLEND_MODE_PMALPHA,
};
int blend_mode;
enum LightMode {
LIGHT_MODE_NORMAL,
LIGHT_MODE_UNSHADED,
LIGHT_MODE_LIGHT_ONLY
};
int light_mode;
bool uses_screen_texture;
bool uses_screen_uv;
bool uses_time;
bool uses_modulate;
bool uses_color;
bool uses_vertex;
// all these should disable item joining if used in a custom shader
bool uses_model_matrix;
bool uses_extra_matrix;
bool uses_projection_matrix;
bool uses_instance_custom;
} canvas_item;
struct Spatial {
enum BlendMode {
BLEND_MODE_MIX,
BLEND_MODE_ADD,
BLEND_MODE_SUB,
BLEND_MODE_MUL,
};
int blend_mode;
enum DepthDrawMode {
DEPTH_DRAW_OPAQUE,
DEPTH_DRAW_ALWAYS,
DEPTH_DRAW_NEVER,
DEPTH_DRAW_ALPHA_PREPASS,
};
int depth_draw_mode;
enum CullMode {
CULL_MODE_FRONT,
CULL_MODE_BACK,
CULL_MODE_DISABLED,
};
int cull_mode;
bool uses_alpha;
bool uses_alpha_scissor;
bool unshaded;
bool no_depth_test;
bool uses_vertex;
bool uses_discard;
bool uses_sss;
bool uses_screen_texture;
bool uses_depth_texture;
bool uses_time;
bool uses_tangent;
bool uses_ensure_correct_normals;
bool writes_modelview_or_projection;
bool uses_vertex_lighting;
bool uses_world_coordinates;
} spatial;
struct Particles {
} particles;
bool uses_vertex_time;
bool uses_fragment_time;
Shader() :
dirty_list(this) {
shader = nullptr;
valid = false;
version = RID();
last_pass = 0;
}
};
/* MATERIAL Structs */
struct Material {
RID self;
Shader *shader;
Map<StringName, Variant> params;
SelfList<Material> list;
SelfList<Material> dirty_list;
Vector<Pair<StringName, RID>> textures;
float line_width;
int render_priority;
RID next_pass;
uint32_t index;
uint64_t last_pass;
// Map<Geometry *, int> geometry_owners;
// Map<InstanceBaseDependency *, int> instance_owners;
bool can_cast_shadow_cache;
bool is_animated_cache;
Material() :
list(this),
dirty_list(this) {
can_cast_shadow_cache = false;
is_animated_cache = false;
shader = nullptr;
line_width = 1.0;
last_pass = 0;
render_priority = 0;
}
};
class MaterialStorage : public RendererMaterialStorage {
private:
static MaterialStorage *singleton;
/* SHADER API */
mutable Shaders shaders;
mutable RID_PtrOwner<Shader> shader_owner;
mutable SelfList<Shader>::List _shader_dirty_list;
/* MATERIAL API */
mutable SelfList<Material>::List _material_dirty_list;
mutable RID_PtrOwner<Material> material_owner;
public:
static MaterialStorage *get_singleton();
MaterialStorage();
virtual ~MaterialStorage();
/* GLOBAL VARIABLE API */
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_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;
virtual void global_variables_load_settings(bool p_load_textures = true) override;
virtual void global_variables_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;
/* SHADER API */
Shader *get_shader(RID p_rid) { return shader_owner.get_or_null(p_rid); };
bool owns_shader(RID p_rid) { return shader_owner.owns(p_rid); };
void _shader_make_dirty(Shader *p_shader);
virtual RID shader_allocate() override;
virtual void shader_initialize(RID p_rid) override;
virtual void shader_free(RID p_rid) override;
//RID shader_create() override;
virtual void shader_set_code(RID p_shader, const String &p_code) 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_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;
virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); };
void _update_shader(Shader *p_shader) const;
void update_dirty_shaders();
// new
Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); }
/* MATERIAL API */
Material *get_material(RID p_rid) { return material_owner.get_or_null(p_rid); };
bool owns_material(RID p_rid) { return material_owner.owns(p_rid); };
void _material_make_dirty(Material *p_material) const;
// void _material_add_geometry(RID p_material, Geometry *p_geometry);
// void _material_remove_geometry(RID p_material, Geometry *p_geometry);
void _update_material(Material *p_material);
// new
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {}
virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) override {}
// old
virtual RID material_allocate() override;
virtual void material_initialize(RID p_rid) override;
virtual void material_free(RID p_rid) override;
//RID material_create() override;
virtual void material_set_shader(RID p_material, RID p_shader) override;
virtual RID material_get_shader(RID p_material) const;
virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override;
virtual Variant material_get_param(RID p_material, const StringName &p_param) const override;
virtual Variant material_get_param_default(RID p_material, const StringName &p_param) const;
void material_set_line_width(RID p_material, float p_width);
virtual void material_set_next_pass(RID p_material, RID p_next_material) override;
virtual bool material_is_animated(RID p_material) override;
virtual bool material_casts_shadows(RID p_material) override;
bool material_uses_tangents(RID p_material);
bool material_uses_ensure_correct_normals(RID p_material);
void material_add_instance_owner(RID p_material, RendererStorage::DependencyTracker *p_instance);
void material_remove_instance_owner(RID p_material, RendererStorage::DependencyTracker *p_instance);
void material_set_render_priority(RID p_material, int priority) override;
void update_dirty_materials();
};
} // namespace GLES3
#endif // GLES3_ENABLED
#endif // !MATERIAL_STORAGE_GLES3_H

View file

@ -39,6 +39,7 @@
#include "servers/rendering/dummy/rasterizer_storage_dummy.h"
#include "servers/rendering/dummy/storage/canvas_texture_storage.h"
#include "servers/rendering/dummy/storage/decal_atlas_storage.h"
#include "servers/rendering/dummy/storage/material_storage.h"
#include "servers/rendering/dummy/storage/texture_storage.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
@ -51,6 +52,7 @@ private:
protected:
RasterizerCanvasDummy canvas;
RendererDummy::CanvasTextureStorage canvas_texture_storage;
RendererDummy::MaterialStorage material_storage;
RendererDummy::TextureStorage texture_storage;
RendererDummy::DecalAtlasStorage decal_atlas_storage;
RasterizerStorageDummy storage;
@ -58,6 +60,7 @@ protected:
public:
RendererCanvasTextureStorage *get_canvas_texture_storage() override { return &canvas_texture_storage; };
RendererMaterialStorage *get_material_storage() override { return &material_storage; };
RendererTextureStorage *get_texture_storage() override { return &texture_storage; };
RendererDecalAtlasStorage *get_decal_atlas_storage() override { return &decal_atlas_storage; };
RendererStorage *get_storage() override { return &storage; }

View file

@ -36,37 +36,6 @@
class RasterizerStorageDummy : public RendererStorage {
public:
/* SHADER API */
RID shader_allocate() override { return RID(); }
void shader_initialize(RID p_rid) override {}
void shader_set_code(RID p_shader, const String &p_code) override {}
String shader_get_code(RID p_shader) const override { return ""; }
void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override {}
void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override {}
RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override { return RID(); }
Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); }
RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); };
/* COMMON MATERIAL API */
RID material_allocate() override { return RID(); }
void material_initialize(RID p_rid) override {}
void material_set_render_priority(RID p_material, int priority) override {}
void material_set_shader(RID p_shader_material, RID p_shader) override {}
void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override {}
Variant material_get_param(RID p_material, const StringName &p_param) const override { return Variant(); }
void material_set_next_pass(RID p_material, RID p_next_material) override {}
bool material_is_animated(RID p_material) override { return false; }
bool material_casts_shadows(RID p_material) override { return false; }
void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {}
void material_update_dependency(RID p_material, DependencyTracker *p_instance) override {}
/* MESH API */
RID mesh_allocate() override { return RID(); }
@ -352,6 +321,8 @@ public:
void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) override {}
void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) override {}
bool particles_is_inactive(RID p_particles) const override { return false; }
/* FOG VOLUMES */
RID fog_volume_allocate() override { return RID(); }
@ -372,26 +343,6 @@ public:
virtual AABB visibility_notifier_get_aabb(RID p_notifier) const override { return AABB(); }
virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override {}
/* GLOBAL VARIABLES */
void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override {}
void global_variable_remove(const StringName &p_name) override {}
Vector<StringName> global_variable_get_list() const override { return Vector<StringName>(); }
void global_variable_set(const StringName &p_name, const Variant &p_value) override {}
void global_variable_set_override(const StringName &p_name, const Variant &p_value) override {}
Variant global_variable_get(const StringName &p_name) const override { return Variant(); }
RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override { return RS::GLOBAL_VAR_TYPE_MAX; }
void global_variables_load_settings(bool p_load_textures = true) override {}
void global_variables_clear() override {}
int32_t global_variables_instance_allocate(RID p_instance) override { return 0; }
void global_variables_instance_free(RID p_instance) override {}
void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override {}
bool particles_is_inactive(RID p_particles) const override { return false; }
/* RENDER TARGET */
RID render_target_create() override { return RID(); }

View file

@ -0,0 +1,95 @@
/*************************************************************************/
/* material_storage.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 MATERIAL_STORAGE_DUMMY_H
#define MATERIAL_STORAGE_DUMMY_H
#include "servers/rendering/storage/material_storage.h"
namespace RendererDummy {
class MaterialStorage : public RendererMaterialStorage {
public:
/* GLOBAL VARIABLE API */
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 { return Vector<StringName>(); }
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 { return Variant(); }
virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override { return RS::GLOBAL_VAR_TYPE_MAX; }
virtual void global_variables_load_settings(bool p_load_textures = true) override {}
virtual void global_variables_clear() override {}
virtual int32_t global_variables_instance_allocate(RID p_instance) override { return 0; }
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 {}
/* SHADER API */
virtual RID shader_allocate() override { return RID(); }
virtual void shader_initialize(RID p_rid) override {}
virtual void shader_free(RID p_rid) override{};
virtual void shader_set_code(RID p_shader, const String &p_code) override {}
virtual String shader_get_code(RID p_shader) const override { return ""; }
virtual void shader_get_param_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 { return RID(); }
virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); }
virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); };
/* MATERIAL API */
virtual RID material_allocate() override { return RID(); }
virtual void material_initialize(RID p_rid) override {}
virtual void material_free(RID p_rid) override{};
virtual void material_set_render_priority(RID p_material, int priority) override {}
virtual void material_set_shader(RID p_shader_material, RID p_shader) override {}
virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override {}
virtual Variant material_get_param(RID p_material, const StringName &p_param) const override { return Variant(); }
virtual void material_set_next_pass(RID p_material, RID p_next_material) override {}
virtual bool material_is_animated(RID p_material) override { return false; }
virtual bool material_casts_shadows(RID p_material) override { return false; }
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {}
virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) override {}
};
} // namespace RendererDummy
#endif // !MATERIAL_STORAGE_DUMMY_H

View file

@ -36,6 +36,7 @@
#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/storage/canvas_texture_storage.h"
#include "servers/rendering/storage/decal_atlas_storage.h"
#include "servers/rendering/storage/material_storage.h"
#include "servers/rendering/storage/texture_storage.h"
#include "servers/rendering_server.h"
@ -74,6 +75,7 @@ public:
static RendererCompositor *create();
virtual RendererCanvasTextureStorage *get_canvas_texture_storage() = 0;
virtual RendererMaterialStorage *get_material_storage() = 0;
virtual RendererTextureStorage *get_texture_storage() = 0;
virtual RendererDecalAtlasStorage *get_decal_atlas_storage() = 0;
virtual RendererStorage *get_storage() = 0;

View file

@ -1368,7 +1368,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
clear_color.b *= bg_energy;
if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
}
} break;
case RS::ENV_BG_COLOR: {
@ -1378,7 +1378,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
clear_color.b *= bg_energy;
if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
}
} break;
case RS::ENV_BG_SKY: {
@ -2165,7 +2165,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() {
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 14;
u.append_id(storage->global_variables_get_storage_buffer());
u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer());
uniforms.push_back(u);
}
@ -2182,6 +2182,8 @@ void RenderForwardClustered::_update_render_base_uniform_set() {
}
RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RenderBufferDataForwardClustered *rb = nullptr;
if (p_render_data && p_render_data->render_buffers.is_valid()) {
rb = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers);
@ -2429,6 +2431,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
}
RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
Vector<RD::Uniform> uniforms;
{
@ -2633,7 +2636,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
void *surface_shadow = nullptr;
if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_position && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip) {
flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL;
material_shadow = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(scene_shader.default_material, RendererStorageRD::SHADER_TYPE_3D);
material_shadow = (SceneShaderForwardClustered::MaterialData *)RendererRD::MaterialStorage::get_singleton()->material_get_data(scene_shader.default_material, RendererRD::SHADER_TYPE_3D);
RID shadow_mesh = storage->mesh_get_shadow_mesh(p_mesh);
@ -2688,23 +2691,25 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
void RenderForwardClustered::_geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, RID p_mat_src, RID p_mesh) {
SceneShaderForwardClustered::MaterialData *material = p_material;
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, p_mat_src.get_local_index(), storage->material_get_shader_id(p_mat_src), p_mesh);
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, p_mat_src.get_local_index(), material_storage->material_get_shader_id(p_mat_src), p_mesh);
while (material->next_pass.is_valid()) {
RID next_pass = material->next_pass;
material = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(next_pass, RendererStorageRD::SHADER_TYPE_3D);
material = (SceneShaderForwardClustered::MaterialData *)material_storage->material_get_data(next_pass, RendererRD::SHADER_TYPE_3D);
if (!material || !material->shader_data->valid) {
break;
}
if (ginstance->data->dirty_dependencies) {
storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);
material_storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);
}
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), storage->material_get_shader_id(next_pass), p_mesh);
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), material_storage->material_get_shader_id(next_pass), p_mesh);
}
}
void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
RID m_src;
m_src = ginstance->data->material_override.is_valid() ? ginstance->data->material_override : p_material;
@ -2712,7 +2717,7 @@ void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForw
SceneShaderForwardClustered::MaterialData *material = nullptr;
if (m_src.is_valid()) {
material = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D);
material = (SceneShaderForwardClustered::MaterialData *)material_storage->material_get_data(m_src, RendererRD::SHADER_TYPE_3D);
if (!material || !material->shader_data->valid) {
material = nullptr;
}
@ -2720,10 +2725,10 @@ void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForw
if (material) {
if (ginstance->data->dirty_dependencies) {
storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
material_storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
}
} else {
material = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(scene_shader.default_material, RendererStorageRD::SHADER_TYPE_3D);
material = (SceneShaderForwardClustered::MaterialData *)material_storage->material_get_data(scene_shader.default_material, RendererRD::SHADER_TYPE_3D);
m_src = scene_shader.default_material;
}
@ -2734,10 +2739,10 @@ void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForw
if (ginstance->data->material_overlay.is_valid()) {
m_src = ginstance->data->material_overlay;
material = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D);
material = (SceneShaderForwardClustered::MaterialData *)material_storage->material_get_data(m_src, RendererRD::SHADER_TYPE_3D);
if (material && material->shader_data->valid) {
if (ginstance->data->dirty_dependencies) {
storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
material_storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
}
_geometry_instance_add_surface_with_material_chain(ginstance, p_surface, material, m_src, p_mesh);

View file

@ -33,6 +33,7 @@
#include "core/math/math_defs.h"
#include "render_forward_clustered.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
using namespace RendererSceneRenderImplementation;
@ -384,13 +385,13 @@ void SceneShaderForwardClustered::ShaderData::get_param_list(List<PropertyInfo>
}
}
void SceneShaderForwardClustered::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
void SceneShaderForwardClustered::ShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const {
for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
RendererStorage::InstanceShaderParam p;
RendererMaterialStorage::InstanceShaderParam p;
p.info = ShaderLanguage::uniform_to_property_info(E.value);
p.info.name = E.key; //supply name
p.index = E.value.instance_index;
@ -445,7 +446,7 @@ SceneShaderForwardClustered::ShaderData::~ShaderData() {
}
}
RendererStorageRD::ShaderData *SceneShaderForwardClustered::_create_shader_func() {
RendererRD::ShaderData *SceneShaderForwardClustered::_create_shader_func() {
ShaderData *shader_data = memnew(ShaderData);
singleton->shader_list.add(&shader_data->shader_list_element);
return shader_data;
@ -469,7 +470,7 @@ SceneShaderForwardClustered::MaterialData::~MaterialData() {
free_parameters_uniform_set(uniform_set);
}
RendererStorageRD::MaterialData *SceneShaderForwardClustered::_create_material_func(ShaderData *p_shader) {
RendererRD::MaterialData *SceneShaderForwardClustered::_create_material_func(ShaderData *p_shader) {
MaterialData *material_data = memnew(MaterialData);
material_data->shader_data = p_shader;
//update will happen later anyway so do nothing.
@ -484,17 +485,20 @@ SceneShaderForwardClustered::SceneShaderForwardClustered() {
}
SceneShaderForwardClustered::~SceneShaderForwardClustered() {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
RD::get_singleton()->free(default_vec4_xform_buffer);
RD::get_singleton()->free(shadow_sampler);
storage->free(overdraw_material_shader);
storage->free(default_shader);
material_storage->shader_free(overdraw_material_shader);
material_storage->shader_free(default_shader);
storage->free(overdraw_material);
storage->free(default_material);
material_storage->material_free(overdraw_material);
material_storage->material_free(default_material);
}
void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const String p_defines) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
storage = p_storage;
{
@ -524,8 +528,8 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
}
}
storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_shader_funcs);
storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_material_funcs);
material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_3D, _create_shader_funcs);
material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_3D, _create_material_funcs);
{
//shader compiler
@ -710,9 +714,9 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
{
//default material and shader
default_shader = storage->shader_allocate();
storage->shader_initialize(default_shader);
storage->shader_set_code(default_shader, R"(
default_shader = material_storage->shader_allocate();
material_storage->shader_initialize(default_shader);
material_storage->shader_set_code(default_shader, R"(
// Default 3D material shader (clustered).
shader_type spatial;
@ -727,11 +731,11 @@ void fragment() {
METALLIC = 0.2;
}
)");
default_material = storage->material_allocate();
storage->material_initialize(default_material);
storage->material_set_shader(default_material, default_shader);
default_material = material_storage->material_allocate();
material_storage->material_initialize(default_material);
material_storage->material_set_shader(default_material, default_shader);
MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
MaterialData *md = (MaterialData *)material_storage->material_get_data(default_material, RendererRD::SHADER_TYPE_3D);
default_shader_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS);
default_shader_sdfgi_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_DEPTH_PASS_WITH_SDF);
@ -740,10 +744,10 @@ void fragment() {
}
{
overdraw_material_shader = storage->shader_allocate();
storage->shader_initialize(overdraw_material_shader);
overdraw_material_shader = material_storage->shader_allocate();
material_storage->shader_initialize(overdraw_material_shader);
// Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
storage->shader_set_code(overdraw_material_shader, R"(
material_storage->shader_set_code(overdraw_material_shader, R"(
// 3D editor Overdraw debug draw mode shader (clustered).
shader_type spatial;
@ -755,11 +759,11 @@ void fragment() {
ALPHA = 0.1;
}
)");
overdraw_material = storage->material_allocate();
storage->material_initialize(overdraw_material);
storage->material_set_shader(overdraw_material, overdraw_material_shader);
overdraw_material = material_storage->material_allocate();
material_storage->material_initialize(overdraw_material);
material_storage->material_set_shader(overdraw_material, overdraw_material_shader);
MaterialData *md = (MaterialData *)storage->material_get_data(overdraw_material, RendererStorageRD::SHADER_TYPE_3D);
MaterialData *md = (MaterialData *)material_storage->material_get_data(overdraw_material, RendererRD::SHADER_TYPE_3D);
overdraw_material_shader_ptr = md->shader_data;
overdraw_material_uniform_set = md->uniform_set;
}

View file

@ -93,7 +93,7 @@ public:
SHADER_SPECIALIZATION_DIRECTIONAL_SOFT_SHADOWS = 1 << 3,
};
struct ShaderData : public RendererStorageRD::ShaderData {
struct ShaderData : public RendererRD::ShaderData {
enum BlendMode { //used internally
BLEND_MODE_MIX,
BLEND_MODE_ADD,
@ -180,7 +180,7 @@ public:
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;
void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
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;
@ -195,12 +195,12 @@ public:
SelfList<ShaderData>::List shader_list;
RendererStorageRD::ShaderData *_create_shader_func();
static RendererStorageRD::ShaderData *_create_shader_funcs() {
RendererRD::ShaderData *_create_shader_func();
static RendererRD::ShaderData *_create_shader_funcs() {
return static_cast<SceneShaderForwardClustered *>(singleton)->_create_shader_func();
}
struct MaterialData : public RendererStorageRD::MaterialData {
struct MaterialData : public RendererRD::MaterialData {
ShaderData *shader_data;
RID uniform_set;
uint64_t last_pass = 0;
@ -213,8 +213,8 @@ public:
virtual ~MaterialData();
};
RendererStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
static RendererStorageRD::MaterialData *_create_material_funcs(RendererStorageRD::ShaderData *p_shader) {
RendererRD::MaterialData *_create_material_func(ShaderData *p_shader);
static RendererRD::MaterialData *_create_material_funcs(RendererRD::ShaderData *p_shader) {
return static_cast<SceneShaderForwardClustered *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
}

View file

@ -290,6 +290,8 @@ bool RenderForwardMobile::_render_buffers_can_be_storage() {
}
RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
//there should always be enough uniform buffers for render passes, otherwise bugs
ERR_FAIL_INDEX_V(p_index, (int)scene_state.uniform_buffers.size(), RID());
@ -593,7 +595,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
/*
if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
}
*/
} break;
@ -605,7 +607,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
/*
if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
}
*/
} break;
@ -1300,7 +1302,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 14;
u.append_id(storage->global_variables_get_storage_buffer());
u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer());
uniforms.push_back(u);
}
@ -2326,7 +2328,7 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI
void *surface_shadow = nullptr;
if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip) {
flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL;
material_shadow = (SceneShaderForwardMobile::MaterialData *)storage->material_get_data(scene_shader.default_material, RendererStorageRD::SHADER_TYPE_3D);
material_shadow = (SceneShaderForwardMobile::MaterialData *)RendererRD::MaterialStorage::get_singleton()->material_get_data(scene_shader.default_material, RendererRD::SHADER_TYPE_3D);
RID shadow_mesh = storage->mesh_get_shadow_mesh(p_mesh);
@ -2379,23 +2381,25 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI
void RenderForwardMobile::_geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, RID p_mat_src, RID p_mesh) {
SceneShaderForwardMobile::MaterialData *material = p_material;
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, p_mat_src.get_local_index(), storage->material_get_shader_id(p_mat_src), p_mesh);
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, p_mat_src.get_local_index(), material_storage->material_get_shader_id(p_mat_src), p_mesh);
while (material->next_pass.is_valid()) {
RID next_pass = material->next_pass;
material = (SceneShaderForwardMobile::MaterialData *)storage->material_get_data(next_pass, RendererStorageRD::SHADER_TYPE_3D);
material = (SceneShaderForwardMobile::MaterialData *)material_storage->material_get_data(next_pass, RendererRD::SHADER_TYPE_3D);
if (!material || !material->shader_data->valid) {
break;
}
if (ginstance->data->dirty_dependencies) {
storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);
material_storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);
}
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), storage->material_get_shader_id(next_pass), p_mesh);
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), material_storage->material_get_shader_id(next_pass), p_mesh);
}
}
void RenderForwardMobile::_geometry_instance_add_surface(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, RID p_material, RID p_mesh) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
RID m_src;
m_src = ginstance->data->material_override.is_valid() ? ginstance->data->material_override : p_material;
@ -2403,7 +2407,7 @@ void RenderForwardMobile::_geometry_instance_add_surface(GeometryInstanceForward
SceneShaderForwardMobile::MaterialData *material = nullptr;
if (m_src.is_valid()) {
material = (SceneShaderForwardMobile::MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D);
material = (SceneShaderForwardMobile::MaterialData *)material_storage->material_get_data(m_src, RendererRD::SHADER_TYPE_3D);
if (!material || !material->shader_data->valid) {
material = nullptr;
}
@ -2411,10 +2415,10 @@ void RenderForwardMobile::_geometry_instance_add_surface(GeometryInstanceForward
if (material) {
if (ginstance->data->dirty_dependencies) {
storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
material_storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
}
} else {
material = (SceneShaderForwardMobile::MaterialData *)storage->material_get_data(scene_shader.default_material, RendererStorageRD::SHADER_TYPE_3D);
material = (SceneShaderForwardMobile::MaterialData *)material_storage->material_get_data(scene_shader.default_material, RendererRD::SHADER_TYPE_3D);
m_src = scene_shader.default_material;
}
@ -2425,10 +2429,10 @@ void RenderForwardMobile::_geometry_instance_add_surface(GeometryInstanceForward
if (ginstance->data->material_overlay.is_valid()) {
m_src = ginstance->data->material_overlay;
material = (SceneShaderForwardMobile::MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D);
material = (SceneShaderForwardMobile::MaterialData *)material_storage->material_get_data(m_src, RendererRD::SHADER_TYPE_3D);
if (material && material->shader_data->valid) {
if (ginstance->data->dirty_dependencies) {
storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
material_storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
}
_geometry_instance_add_surface_with_material_chain(ginstance, p_surface, material, m_src, p_mesh);

View file

@ -33,6 +33,7 @@
#include "core/math/math_defs.h"
#include "render_forward_mobile.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
using namespace RendererSceneRenderImplementation;
@ -366,13 +367,13 @@ void SceneShaderForwardMobile::ShaderData::get_param_list(List<PropertyInfo> *p_
}
}
void SceneShaderForwardMobile::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
void SceneShaderForwardMobile::ShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const {
for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
RendererStorage::InstanceShaderParam p;
RendererMaterialStorage::InstanceShaderParam p;
p.info = ShaderLanguage::uniform_to_property_info(E.value);
p.info.name = E.key; //supply name
p.index = E.value.instance_index;
@ -427,7 +428,7 @@ SceneShaderForwardMobile::ShaderData::~ShaderData() {
}
}
RendererStorageRD::ShaderData *SceneShaderForwardMobile::_create_shader_func() {
RendererRD::ShaderData *SceneShaderForwardMobile::_create_shader_func() {
ShaderData *shader_data = memnew(ShaderData);
singleton->shader_list.add(&shader_data->shader_list_element);
return shader_data;
@ -451,7 +452,7 @@ SceneShaderForwardMobile::MaterialData::~MaterialData() {
free_parameters_uniform_set(uniform_set);
}
RendererStorageRD::MaterialData *SceneShaderForwardMobile::_create_material_func(ShaderData *p_shader) {
RendererRD::MaterialData *SceneShaderForwardMobile::_create_material_func(ShaderData *p_shader) {
MaterialData *material_data = memnew(MaterialData);
material_data->shader_data = p_shader;
//update will happen later anyway so do nothing.
@ -469,6 +470,7 @@ SceneShaderForwardMobile::SceneShaderForwardMobile() {
void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p_defines) {
storage = p_storage;
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
/* SCENE SHADER */
@ -494,8 +496,8 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
}
}
storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_shader_funcs);
storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_material_funcs);
material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_3D, _create_shader_funcs);
material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_3D, _create_material_funcs);
{
//shader compiler
@ -677,9 +679,9 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
{
//default material and shader
default_shader = storage->shader_allocate();
storage->shader_initialize(default_shader);
storage->shader_set_code(default_shader, R"(
default_shader = material_storage->shader_allocate();
material_storage->shader_initialize(default_shader);
material_storage->shader_set_code(default_shader, R"(
// Default 3D material shader (mobile).
shader_type spatial;
@ -694,11 +696,11 @@ void fragment() {
METALLIC = 0.2;
}
)");
default_material = storage->material_allocate();
storage->material_initialize(default_material);
storage->material_set_shader(default_material, default_shader);
default_material = material_storage->material_allocate();
material_storage->material_initialize(default_material);
material_storage->material_set_shader(default_material, default_shader);
MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
MaterialData *md = (MaterialData *)material_storage->material_get_data(default_material, RendererRD::SHADER_TYPE_3D);
default_shader_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS);
default_material_shader_ptr = md->shader_data;
@ -706,10 +708,10 @@ void fragment() {
}
{
overdraw_material_shader = storage->shader_allocate();
storage->shader_initialize(overdraw_material_shader);
overdraw_material_shader = material_storage->shader_allocate();
material_storage->shader_initialize(overdraw_material_shader);
// Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
storage->shader_set_code(overdraw_material_shader, R"(
material_storage->shader_set_code(overdraw_material_shader, R"(
// 3D editor Overdraw debug draw mode shader (mobile).
shader_type spatial;
@ -721,11 +723,11 @@ void fragment() {
ALPHA = 0.1;
}
)");
overdraw_material = storage->material_allocate();
storage->material_initialize(overdraw_material);
storage->material_set_shader(overdraw_material, overdraw_material_shader);
overdraw_material = material_storage->material_allocate();
material_storage->material_initialize(overdraw_material);
material_storage->material_set_shader(overdraw_material, overdraw_material_shader);
MaterialData *md = (MaterialData *)storage->material_get_data(overdraw_material, RendererStorageRD::SHADER_TYPE_3D);
MaterialData *md = (MaterialData *)material_storage->material_get_data(overdraw_material, RendererRD::SHADER_TYPE_3D);
overdraw_material_shader_ptr = md->shader_data;
overdraw_material_uniform_set = md->uniform_set;
}
@ -765,12 +767,14 @@ void SceneShaderForwardMobile::set_default_specialization_constants(const Vector
}
SceneShaderForwardMobile::~SceneShaderForwardMobile() {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
RD::get_singleton()->free(default_vec4_xform_buffer);
RD::get_singleton()->free(shadow_sampler);
storage->free(overdraw_material_shader);
storage->free(default_shader);
material_storage->shader_free(overdraw_material_shader);
material_storage->shader_free(default_shader);
storage->free(overdraw_material);
storage->free(default_material);
material_storage->material_free(overdraw_material);
material_storage->material_free(default_material);
}

View file

@ -57,7 +57,7 @@ public:
SHADER_VERSION_MAX
};
struct ShaderData : public RendererStorageRD::ShaderData {
struct ShaderData : public RendererRD::ShaderData {
enum BlendMode { //used internally
BLEND_MODE_MIX,
BLEND_MODE_ADD,
@ -143,7 +143,7 @@ public:
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;
void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
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;
@ -157,12 +157,12 @@ public:
virtual ~ShaderData();
};
RendererStorageRD::ShaderData *_create_shader_func();
static RendererStorageRD::ShaderData *_create_shader_funcs() {
RendererRD::ShaderData *_create_shader_func();
static RendererRD::ShaderData *_create_shader_funcs() {
return static_cast<SceneShaderForwardMobile *>(singleton)->_create_shader_func();
}
struct MaterialData : public RendererStorageRD::MaterialData {
struct MaterialData : public RendererRD::MaterialData {
ShaderData *shader_data;
RID uniform_set;
uint64_t last_pass = 0;
@ -177,8 +177,8 @@ public:
SelfList<ShaderData>::List shader_list;
RendererStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
static RendererStorageRD::MaterialData *_create_material_funcs(RendererStorageRD::ShaderData *p_shader) {
RendererRD::MaterialData *_create_material_func(ShaderData *p_shader);
static RendererRD::MaterialData *_create_material_funcs(RendererRD::ShaderData *p_shader) {
return static_cast<SceneShaderForwardMobile *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
}

View file

@ -35,7 +35,10 @@
#include "core/math/math_defs.h"
#include "core/math/math_funcs.h"
#include "renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_default.h"
void RendererCanvasRenderRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) {
@ -359,7 +362,7 @@ void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RI
bool use_normal;
bool use_specular;
bool success = canvas_texture_storage->canvas_texture_get_uniform_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, uniform_set, size, specular_shininess, use_normal, use_specular);
bool success = RendererRD::CanvasTextureStorage::get_singleton()->canvas_texture_get_uniform_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, uniform_set, size, specular_shininess, use_normal, use_specular);
//something odd happened
if (!success) {
_bind_canvas_texture(p_draw_list, default_canvas_texture, p_base_filter, p_base_repeat, r_last_texture, push_constant, r_texpixel_size);
@ -978,7 +981,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
} else {
screen = storage->render_target_get_rd_backbuffer(p_to_render_target);
if (screen.is_null()) { //unallocated backbuffer
screen = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE);
screen = RendererRD::TextureStorage::get_singleton()->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE);
}
}
u.append_id(screen);
@ -1021,7 +1024,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 9;
u.append_id(storage->global_variables_get_storage_buffer());
u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer());
uniforms.push_back(u);
}
@ -1036,6 +1039,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
}
void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
Item *current_clip = nullptr;
Transform2D canvas_transform_inverse = p_canvas_transform_inverse;
@ -1100,9 +1104,9 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
}
if (material != prev_material) {
MaterialData *material_data = nullptr;
CanvasMaterialData *material_data = nullptr;
if (material.is_valid()) {
material_data = (MaterialData *)storage->material_get_data(material, RendererStorageRD::SHADER_TYPE_2D);
material_data = (CanvasMaterialData *)material_storage->material_get_data(material, RendererRD::SHADER_TYPE_2D);
}
if (material_data) {
@ -1129,6 +1133,8 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
}
void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
r_sdf_used = false;
int item_count = 0;
@ -1364,7 +1370,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material;
if (material.is_valid()) {
MaterialData *md = (MaterialData *)storage->material_get_data(material, RendererStorageRD::SHADER_TYPE_2D);
CanvasMaterialData *md = (CanvasMaterialData *)material_storage->material_get_data(material, RendererRD::SHADER_TYPE_2D);
if (md && md->shader_data->valid) {
if (md->shader_data->uses_screen_texture && canvas_group_owner == nullptr) {
if (!material_screen_texture_found) {
@ -1938,7 +1944,7 @@ void RendererCanvasRenderRD::occluder_polygon_set_cull_mode(RID p_occluder, RS::
oc->cull_mode = p_mode;
}
void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) {
void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
//compile
code = p_code;
@ -2120,7 +2126,7 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) {
valid = true;
}
void RendererCanvasRenderRD::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
void RendererCanvasRenderRD::CanvasShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
if (!p_texture.is_valid()) {
if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) {
default_texture_params[p_name].erase(p_index);
@ -2137,7 +2143,7 @@ void RendererCanvasRenderRD::ShaderData::set_default_texture_param(const StringN
}
}
void RendererCanvasRenderRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
void RendererCanvasRenderRD::CanvasShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
Map<int, StringName> order;
for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
@ -2158,13 +2164,13 @@ void RendererCanvasRenderRD::ShaderData::get_param_list(List<PropertyInfo> *p_pa
}
}
void RendererCanvasRenderRD::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
void RendererCanvasRenderRD::CanvasShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const {
for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
RendererStorage::InstanceShaderParam p;
RendererMaterialStorage::InstanceShaderParam p;
p.info = ShaderLanguage::uniform_to_property_info(E.value);
p.info.name = E.key; //supply name
p.index = E.value.instance_index;
@ -2173,7 +2179,7 @@ void RendererCanvasRenderRD::ShaderData::get_instance_param_list(List<RendererSt
}
}
bool RendererCanvasRenderRD::ShaderData::is_param_texture(const StringName &p_param) const {
bool RendererCanvasRenderRD::CanvasShaderData::is_param_texture(const StringName &p_param) const {
if (!uniforms.has(p_param)) {
return false;
}
@ -2181,15 +2187,15 @@ bool RendererCanvasRenderRD::ShaderData::is_param_texture(const StringName &p_pa
return uniforms[p_param].texture_order >= 0;
}
bool RendererCanvasRenderRD::ShaderData::is_animated() const {
bool RendererCanvasRenderRD::CanvasShaderData::is_animated() const {
return false;
}
bool RendererCanvasRenderRD::ShaderData::casts_shadows() const {
bool RendererCanvasRenderRD::CanvasShaderData::casts_shadows() const {
return false;
}
Variant RendererCanvasRenderRD::ShaderData::get_default_parameter(const StringName &p_parameter) const {
Variant RendererCanvasRenderRD::CanvasShaderData::get_default_parameter(const StringName &p_parameter) const {
if (uniforms.has(p_parameter)) {
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
@ -2198,18 +2204,18 @@ Variant RendererCanvasRenderRD::ShaderData::get_default_parameter(const StringNa
return Variant();
}
RS::ShaderNativeSourceCode RendererCanvasRenderRD::ShaderData::get_native_source_code() const {
RS::ShaderNativeSourceCode RendererCanvasRenderRD::CanvasShaderData::get_native_source_code() const {
RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton;
return canvas_singleton->shader.canvas_shader.version_get_native_source_code(version);
}
RendererCanvasRenderRD::ShaderData::ShaderData() {
RendererCanvasRenderRD::CanvasShaderData::CanvasShaderData() {
valid = false;
uses_screen_texture = false;
uses_sdf = false;
}
RendererCanvasRenderRD::ShaderData::~ShaderData() {
RendererCanvasRenderRD::CanvasShaderData::~CanvasShaderData() {
RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton;
ERR_FAIL_COND(!canvas_singleton);
//pipeline variants will clear themselves if shader is gone
@ -2218,23 +2224,23 @@ RendererCanvasRenderRD::ShaderData::~ShaderData() {
}
}
RendererStorageRD::ShaderData *RendererCanvasRenderRD::_create_shader_func() {
ShaderData *shader_data = memnew(ShaderData);
RendererRD::ShaderData *RendererCanvasRenderRD::_create_shader_func() {
CanvasShaderData *shader_data = memnew(CanvasShaderData);
return shader_data;
}
bool RendererCanvasRenderRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
bool RendererCanvasRenderRD::CanvasMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton;
return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET);
}
RendererCanvasRenderRD::MaterialData::~MaterialData() {
RendererCanvasRenderRD::CanvasMaterialData::~CanvasMaterialData() {
free_parameters_uniform_set(uniform_set);
}
RendererStorageRD::MaterialData *RendererCanvasRenderRD::_create_material_func(ShaderData *p_shader) {
MaterialData *material_data = memnew(MaterialData);
RendererRD::MaterialData *RendererCanvasRenderRD::_create_material_func(CanvasShaderData *p_shader) {
CanvasMaterialData *material_data = memnew(CanvasMaterialData);
material_data->shader_data = p_shader;
//update will happen later anyway so do nothing.
return material_data;
@ -2248,8 +2254,8 @@ void RendererCanvasRenderRD::update() {
}
RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
canvas_texture_storage = RendererRD::CanvasTextureStorage::get_singleton();
texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::CanvasTextureStorage *canvas_texture_storage = RendererRD::CanvasTextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
storage = p_storage;
{ //create default samplers
@ -2586,16 +2592,16 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
state.shadow_texture_size = GLOBAL_GET("rendering/2d/shadow_atlas/size");
//create functions for shader and material
storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_2D, _create_shader_funcs);
storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_2D, _create_material_funcs);
material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_2D, _create_shader_funcs);
material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_2D, _create_material_funcs);
state.time = 0;
{
default_canvas_group_shader = storage->shader_allocate();
storage->shader_initialize(default_canvas_group_shader);
default_canvas_group_shader = material_storage->shader_allocate();
material_storage->shader_initialize(default_canvas_group_shader);
storage->shader_set_code(default_canvas_group_shader, R"(
material_storage->shader_set_code(default_canvas_group_shader, R"(
// Default CanvasGroup shader.
shader_type canvas_item;
@ -2610,10 +2616,10 @@ void fragment() {
COLOR *= c;
}
)");
default_canvas_group_material = storage->material_allocate();
storage->material_initialize(default_canvas_group_material);
default_canvas_group_material = material_storage->material_allocate();
material_storage->material_initialize(default_canvas_group_material);
storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader);
material_storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader);
}
static_assert(sizeof(PushConstant) == 128);
@ -2661,10 +2667,11 @@ void RendererCanvasRenderRD::set_shadow_texture_size(int p_size) {
}
RendererCanvasRenderRD::~RendererCanvasRenderRD() {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
//canvas state
storage->free(default_canvas_group_material);
storage->free(default_canvas_group_shader);
material_storage->material_free(default_canvas_group_material);
material_storage->shader_free(default_canvas_group_shader);
{
if (state.canvas_state_buffer.is_valid()) {
@ -2701,6 +2708,6 @@ RendererCanvasRenderRD::~RendererCanvasRenderRD() {
}
RD::get_singleton()->free(state.shadow_texture);
canvas_texture_storage->canvas_texture_free(default_canvas_texture);
RendererRD::CanvasTextureStorage::get_singleton()->canvas_texture_free(default_canvas_texture);
//pipelines don't need freeing, they are all gone after shaders are gone
}

View file

@ -37,14 +37,10 @@
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/canvas.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl.gen.h"
#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/shader_compiler.h"
class RendererCanvasRenderRD : public RendererCanvasRender {
RendererRD::CanvasTextureStorage *canvas_texture_storage;
RendererRD::TextureStorage *texture_storage;
RendererStorageRD *storage;
enum {
@ -155,7 +151,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
ShaderCompiler compiler;
} shader;
struct ShaderData : public RendererStorageRD::ShaderData {
struct CanvasShaderData : public RendererRD::ShaderData {
enum BlendMode { //used internally
BLEND_MODE_MIX,
BLEND_MODE_ADD,
@ -186,7 +182,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
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_instance_param_list(List<RendererStorage::InstanceShaderParam> *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;
@ -194,28 +190,28 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
virtual Variant get_default_parameter(const StringName &p_parameter) const;
virtual RS::ShaderNativeSourceCode get_native_source_code() const;
ShaderData();
virtual ~ShaderData();
CanvasShaderData();
virtual ~CanvasShaderData();
};
RendererStorageRD::ShaderData *_create_shader_func();
static RendererStorageRD::ShaderData *_create_shader_funcs() {
RendererRD::ShaderData *_create_shader_func();
static RendererRD::ShaderData *_create_shader_funcs() {
return static_cast<RendererCanvasRenderRD *>(singleton)->_create_shader_func();
}
struct MaterialData : public RendererStorageRD::MaterialData {
ShaderData *shader_data;
struct CanvasMaterialData : public RendererRD::MaterialData {
CanvasShaderData *shader_data;
RID uniform_set;
virtual void set_render_priority(int p_priority) {}
virtual void set_next_pass(RID p_pass) {}
virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual ~MaterialData();
virtual ~CanvasMaterialData();
};
RendererStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
static RendererStorageRD::MaterialData *_create_material_funcs(RendererStorageRD::ShaderData *p_shader) {
return static_cast<RendererCanvasRenderRD *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
RendererRD::MaterialData *_create_material_func(CanvasShaderData *p_shader);
static RendererRD::MaterialData *_create_material_funcs(RendererRD::ShaderData *p_shader) {
return static_cast<RendererCanvasRenderRD *>(singleton)->_create_material_func(static_cast<CanvasShaderData *>(p_shader));
}
/**************************/

View file

@ -156,6 +156,7 @@ void RendererCompositorRD::finalize() {
memdelete(canvas);
memdelete(storage);
memdelete(decal_atlas_storage);
memdelete(material_storage);
memdelete(texture_storage);
memdelete(canvas_texture_storage);
@ -289,6 +290,7 @@ RendererCompositorRD::RendererCompositorRD() {
canvas_texture_storage = memnew(RendererRD::CanvasTextureStorage);
texture_storage = memnew(RendererRD::TextureStorage);
decal_atlas_storage = memnew(RendererRD::DecalAtlasStorage);
material_storage = memnew(RendererRD::MaterialStorage);
storage = memnew(RendererStorageRD);
canvas = memnew(RendererCanvasRenderRD(storage));

View file

@ -41,6 +41,7 @@
#include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h"
#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
@ -49,6 +50,7 @@ protected:
UniformSetCacheRD *uniform_set_cache;
RendererCanvasRenderRD *canvas;
RendererRD::CanvasTextureStorage *canvas_texture_storage;
RendererRD::MaterialStorage *material_storage;
RendererRD::TextureStorage *texture_storage;
RendererRD::DecalAtlasStorage *decal_atlas_storage;
RendererStorageRD *storage;
@ -95,8 +97,9 @@ protected:
public:
RendererCanvasTextureStorage *get_canvas_texture_storage() { return canvas_texture_storage; }
RendererTextureStorage *get_texture_storage() { return texture_storage; }
RendererDecalAtlasStorage *get_decal_atlas_storage() { return decal_atlas_storage; }
RendererMaterialStorage *get_material_storage() { return material_storage; };
RendererTextureStorage *get_texture_storage() { return texture_storage; };
RendererStorage *get_storage() { return storage; }
RendererCanvasRender *get_canvas() { return canvas; }
RendererSceneRender *get_scene() { return scene; }

View file

@ -34,6 +34,8 @@
#include "core/os/os.h"
#include "renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_default.h"
void get_vogel_disk(float *r_kernel, int p_sample_count) {
@ -2359,6 +2361,7 @@ void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataR
}
void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers);
ERR_FAIL_COND(!rb);
@ -2571,6 +2574,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
}
void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RD::get_singleton()->draw_command_begin_label("Post Process Subpass");
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers);
@ -2647,6 +2651,7 @@ void RendererSceneRenderRD::_disable_clear_request(const RenderDataRD *p_render_
}
void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
EffectsRD *effects = storage->get_effects();
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
@ -3920,13 +3925,13 @@ void RendererSceneRenderRD::FogShaderData::get_param_list(List<PropertyInfo> *p_
}
}
void RendererSceneRenderRD::FogShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
void RendererSceneRenderRD::FogShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const {
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
RendererStorage::InstanceShaderParam p;
RendererMaterialStorage::InstanceShaderParam p;
p.info = ShaderLanguage::uniform_to_property_info(E->get());
p.info.name = E->key(); //supply name
p.index = E->get().instance_index;
@ -3994,23 +3999,23 @@ RendererSceneRenderRD::FogMaterialData::~FogMaterialData() {
free_parameters_uniform_set(uniform_set);
}
RendererStorageRD::ShaderData *RendererSceneRenderRD::_create_fog_shader_func() {
RendererRD::ShaderData *RendererSceneRenderRD::_create_fog_shader_func() {
FogShaderData *shader_data = memnew(FogShaderData);
return shader_data;
}
RendererStorageRD::ShaderData *RendererSceneRenderRD::_create_fog_shader_funcs() {
RendererRD::ShaderData *RendererSceneRenderRD::_create_fog_shader_funcs() {
return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->_create_fog_shader_func();
};
RendererStorageRD::MaterialData *RendererSceneRenderRD::_create_fog_material_func(FogShaderData *p_shader) {
RendererRD::MaterialData *RendererSceneRenderRD::_create_fog_material_func(FogShaderData *p_shader) {
FogMaterialData *material_data = memnew(FogMaterialData);
material_data->shader_data = p_shader;
//update will happen later anyway so do nothing.
return material_data;
}
RendererStorageRD::MaterialData *RendererSceneRenderRD::_create_fog_material_funcs(RendererStorageRD::ShaderData *p_shader) {
RendererRD::MaterialData *RendererSceneRenderRD::_create_fog_material_funcs(RendererRD::ShaderData *p_shader) {
return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->_create_fog_material_func(static_cast<FogShaderData *>(p_shader));
};
@ -4068,6 +4073,9 @@ Vector3i RendererSceneRenderRD::_point_get_position_in_froxel_volume(const Vecto
}
void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
ERR_FAIL_COND(!is_clustered_enabled()); // can't use volumetric fog without clustered
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND(!rb);
@ -4268,7 +4276,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
FogMaterialData *material = nullptr;
if (fog_material.is_valid()) {
material = (FogMaterialData *)storage->material_get_data(fog_material, RendererStorageRD::SHADER_TYPE_FOG);
material = (FogMaterialData *)material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG);
if (!material || !material->shader_data->valid) {
material = nullptr;
}
@ -4276,7 +4284,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
if (!material) {
fog_material = volumetric_fog.default_material;
material = (FogMaterialData *)storage->material_get_data(fog_material, RendererStorageRD::SHADER_TYPE_FOG);
material = (FogMaterialData *)material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG);
}
ERR_FAIL_COND(!material);
@ -5605,12 +5613,13 @@ uint32_t RendererSceneRenderRD::get_max_elements() const {
}
RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
texture_storage = RendererRD::TextureStorage::get_singleton();
storage = p_storage;
singleton = this;
}
void RendererSceneRenderRD::init() {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
max_cluster_elements = get_max_elements();
directional_shadow.size = GLOBAL_GET("rendering/shadows/directional_shadow/size");
@ -5667,8 +5676,8 @@ void RendererSceneRenderRD::init() {
volumetric_fog_modes.push_back("");
volumetric_fog.shader.initialize(volumetric_fog_modes);
storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_FOG, _create_fog_shader_funcs);
storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_FOG, _create_fog_material_funcs);
material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_shader_funcs);
material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_material_funcs);
volumetric_fog.volume_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::VolumeUBO));
}
@ -5707,9 +5716,9 @@ void RendererSceneRenderRD::init() {
{
// default material and shader for fog shader
volumetric_fog.default_shader = storage->shader_allocate();
storage->shader_initialize(volumetric_fog.default_shader);
storage->shader_set_code(volumetric_fog.default_shader, R"(
volumetric_fog.default_shader = material_storage->shader_allocate();
material_storage->shader_initialize(volumetric_fog.default_shader);
material_storage->shader_set_code(volumetric_fog.default_shader, R"(
// Default fog shader.
shader_type fog;
@ -5719,11 +5728,11 @@ void fog() {
ALBEDO = vec3(1.0);
}
)");
volumetric_fog.default_material = storage->material_allocate();
storage->material_initialize(volumetric_fog.default_material);
storage->material_set_shader(volumetric_fog.default_material, volumetric_fog.default_shader);
volumetric_fog.default_material = material_storage->material_allocate();
material_storage->material_initialize(volumetric_fog.default_material);
material_storage->material_set_shader(volumetric_fog.default_material, volumetric_fog.default_shader);
FogMaterialData *md = (FogMaterialData *)storage->material_get_data(volumetric_fog.default_material, RendererStorageRD::SHADER_TYPE_FOG);
FogMaterialData *md = (FogMaterialData *)material_storage->material_get_data(volumetric_fog.default_material, RendererRD::SHADER_TYPE_FOG);
volumetric_fog.default_shader_rd = volumetric_fog.shader.version_get_shader(md->shader_data->version, 0);
Vector<RD::Uniform> uniforms;
@ -5753,7 +5762,7 @@ void fog() {
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 2;
u.append_id(storage->global_variables_get_storage_buffer());
u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer());
uniforms.push_back(u);
}
@ -5822,6 +5831,8 @@ void fog() {
}
RendererSceneRenderRD::~RendererSceneRenderRD() {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
for (const KeyValue<int, ShadowCubemap> &E : shadow_cubemaps) {
RD::get_singleton()->free(E.value.cubemap);
}
@ -5838,20 +5849,10 @@ RendererSceneRenderRD::~RendererSceneRenderRD() {
volumetric_fog.process_shader.version_free(volumetric_fog.process_shader_version);
RD::get_singleton()->free(volumetric_fog.volume_ubo);
RD::get_singleton()->free(volumetric_fog.params_ubo);
storage->free(volumetric_fog.default_shader);
storage->free(volumetric_fog.default_material);
material_storage->shader_free(volumetric_fog.default_shader);
material_storage->material_free(volumetric_fog.default_material);
}
RendererSceneSkyRD::SkyMaterialData *md = (RendererSceneSkyRD::SkyMaterialData *)storage->material_get_data(sky.sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY);
sky.sky_shader.shader.version_free(md->shader_data->version);
RD::get_singleton()->free(sky.sky_scene_state.directional_light_buffer);
RD::get_singleton()->free(sky.sky_scene_state.uniform_buffer);
memdelete_arr(sky.sky_scene_state.directional_lights);
memdelete_arr(sky.sky_scene_state.last_frame_directional_lights);
storage->free(sky.sky_shader.default_shader);
storage->free(sky.sky_shader.default_material);
storage->free(sky.sky_scene_state.fog_shader);
storage->free(sky.sky_scene_state.fog_material);
memdelete_arr(directional_penumbra_shadow_kernel);
memdelete_arr(directional_soft_shadow_kernel);
memdelete_arr(penumbra_shadow_kernel);

View file

@ -41,7 +41,6 @@
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl.gen.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/renderer_scene.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
@ -93,7 +92,6 @@ class RendererSceneRenderRD : public RendererSceneRender {
friend RendererSceneGIRD;
protected:
RendererRD::TextureStorage *texture_storage;
RendererStorageRD *storage;
double time;
double time_step = 0;
@ -909,7 +907,7 @@ private:
void _volumetric_fog_erase(RenderBuffers *rb);
void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes);
struct FogShaderData : public RendererStorageRD::ShaderData {
struct FogShaderData : public RendererRD::ShaderData {
bool valid;
RID version;
@ -929,7 +927,7 @@ private:
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_instance_param_list(List<RendererStorage::InstanceShaderParam> *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;
virtual bool casts_shadows() const;
@ -939,7 +937,7 @@ private:
virtual ~FogShaderData();
};
struct FogMaterialData : public RendererStorageRD::MaterialData {
struct FogMaterialData : public RendererRD::MaterialData {
FogShaderData *shader_data;
RID uniform_set;
bool uniform_set_updated;
@ -950,11 +948,11 @@ private:
virtual ~FogMaterialData();
};
RendererStorageRD::ShaderData *_create_fog_shader_func();
static RendererStorageRD::ShaderData *_create_fog_shader_funcs();
RendererRD::ShaderData *_create_fog_shader_func();
static RendererRD::ShaderData *_create_fog_shader_funcs();
RendererStorageRD::MaterialData *_create_fog_material_func(FogShaderData *p_shader);
static RendererStorageRD::MaterialData *_create_fog_material_funcs(RendererStorageRD::ShaderData *p_shader);
RendererRD::MaterialData *_create_fog_material_func(FogShaderData *p_shader);
static RendererRD::MaterialData *_create_fog_material_funcs(RendererRD::ShaderData *p_shader);
RID shadow_sampler;

View file

@ -33,6 +33,7 @@
#include "core/math/math_defs.h"
#include "renderer_scene_render_rd.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_default.h"
@ -177,13 +178,13 @@ void RendererSceneSkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_par
}
}
void RendererSceneSkyRD::SkyShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
void RendererSceneSkyRD::SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const {
for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
RendererStorage::InstanceShaderParam p;
RendererMaterialStorage::InstanceShaderParam p;
p.info = ShaderLanguage::uniform_to_property_info(E.value);
p.info.name = E.key; //supply name
p.index = E.value.instance_index;
@ -767,24 +768,24 @@ Ref<Image> RendererSceneSkyRD::Sky::bake_panorama(RendererStorageRD *p_storage,
////////////////////////////////////////////////////////////////////////////////
// RendererSceneSkyRD
RendererStorageRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_func() {
RendererRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_func() {
SkyShaderData *shader_data = memnew(SkyShaderData);
return shader_data;
}
RendererStorageRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_funcs() {
RendererRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_funcs() {
// !BAS! Why isn't _create_sky_shader_func not just static too?
return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_shader_func();
};
RendererStorageRD::MaterialData *RendererSceneSkyRD::_create_sky_material_func(SkyShaderData *p_shader) {
RendererRD::MaterialData *RendererSceneSkyRD::_create_sky_material_func(SkyShaderData *p_shader) {
SkyMaterialData *material_data = memnew(SkyMaterialData);
material_data->shader_data = p_shader;
//update will happen later anyway so do nothing.
return material_data;
}
RendererStorageRD::MaterialData *RendererSceneSkyRD::_create_sky_material_funcs(RendererStorageRD::ShaderData *p_shader) {
RendererRD::MaterialData *RendererSceneSkyRD::_create_sky_material_funcs(RendererRD::ShaderData *p_shader) {
// !BAS! same here, we could just make _create_sky_material_func static?
return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_material_func(static_cast<SkyShaderData *>(p_shader));
};
@ -797,6 +798,7 @@ RendererSceneSkyRD::RendererSceneSkyRD() {
void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
storage = p_storage;
{
@ -833,8 +835,8 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
}
// register our shader funds
storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_shader_funcs);
storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_material_funcs);
material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_SKY, _create_sky_shader_funcs);
material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_SKY, _create_sky_material_funcs);
{
ShaderCompiler::DefaultIdentifierActions actions;
@ -896,10 +898,10 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
{
// default material and shader for sky shader
sky_shader.default_shader = storage->shader_allocate();
storage->shader_initialize(sky_shader.default_shader);
sky_shader.default_shader = material_storage->shader_allocate();
material_storage->shader_initialize(sky_shader.default_shader);
storage->shader_set_code(sky_shader.default_shader, R"(
material_storage->shader_set_code(sky_shader.default_shader, R"(
// Default sky shader.
shader_type sky;
@ -909,12 +911,12 @@ void sky() {
}
)");
sky_shader.default_material = storage->material_allocate();
storage->material_initialize(sky_shader.default_material);
sky_shader.default_material = material_storage->material_allocate();
material_storage->material_initialize(sky_shader.default_material);
storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader);
material_storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader);
SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY);
SkyMaterialData *md = (SkyMaterialData *)material_storage->material_get_data(sky_shader.default_material, RendererRD::SHADER_TYPE_SKY);
sky_shader.default_shader_rd = sky_shader.shader.version_get_shader(md->shader_data->version, SKY_VERSION_BACKGROUND);
sky_scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkySceneState::UBO));
@ -947,7 +949,7 @@ void sky() {
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 1;
u.append_id(storage->global_variables_get_storage_buffer());
u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer());
uniforms.push_back(u);
}
@ -986,10 +988,10 @@ void sky() {
{
// Need defaults for using fog with clear color
sky_scene_state.fog_shader = storage->shader_allocate();
storage->shader_initialize(sky_scene_state.fog_shader);
sky_scene_state.fog_shader = material_storage->shader_allocate();
material_storage->shader_initialize(sky_scene_state.fog_shader);
storage->shader_set_code(sky_scene_state.fog_shader, R"(
material_storage->shader_set_code(sky_scene_state.fog_shader, R"(
// Default clear color sky shader.
shader_type sky;
@ -1000,10 +1002,10 @@ void sky() {
COLOR = clear_color.rgb;
}
)");
sky_scene_state.fog_material = storage->material_allocate();
storage->material_initialize(sky_scene_state.fog_material);
sky_scene_state.fog_material = material_storage->material_allocate();
material_storage->material_initialize(sky_scene_state.fog_material);
storage->material_set_shader(sky_scene_state.fog_material, sky_scene_state.fog_shader);
material_storage->material_set_shader(sky_scene_state.fog_material, sky_scene_state.fog_shader);
Vector<RD::Uniform> uniforms;
{
@ -1054,7 +1056,19 @@ void RendererSceneSkyRD::set_texture_format(RD::DataFormat p_texture_format) {
}
RendererSceneSkyRD::~RendererSceneSkyRD() {
// TODO cleanup anything created in init...
// cleanup anything created in init...
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
SkyMaterialData *md = (SkyMaterialData *)material_storage->material_get_data(sky_shader.default_material, RendererRD::SHADER_TYPE_SKY);
sky_shader.shader.version_free(md->shader_data->version);
RD::get_singleton()->free(sky_scene_state.directional_light_buffer);
RD::get_singleton()->free(sky_scene_state.uniform_buffer);
memdelete_arr(sky_scene_state.directional_lights);
memdelete_arr(sky_scene_state.last_frame_directional_lights);
material_storage->shader_free(sky_shader.default_shader);
material_storage->material_free(sky_shader.default_material);
material_storage->shader_free(sky_scene_state.fog_shader);
material_storage->material_free(sky_scene_state.fog_material);
if (RD::get_singleton()->uniform_set_is_valid(sky_scene_state.uniform_set)) {
RD::get_singleton()->free(sky_scene_state.uniform_set);
@ -1072,6 +1086,7 @@ RendererSceneSkyRD::~RendererSceneSkyRD() {
}
void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
ERR_FAIL_COND(!p_env);
SkyMaterialData *material = nullptr;
@ -1085,7 +1100,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b
sky_material = sky_get_material(p_env->sky);
if (sky_material.is_valid()) {
material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
material = (SkyMaterialData *)material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY);
if (!material || !material->shader_data->valid) {
material = nullptr;
}
@ -1093,7 +1108,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b
if (!material) {
sky_material = sky_shader.default_material;
material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
material = (SkyMaterialData *)material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY);
}
ERR_FAIL_COND(!material);
@ -1282,6 +1297,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b
}
void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
ERR_FAIL_COND(!p_env);
Sky *sky = get_sky(p_env->sky);
@ -1292,7 +1308,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
SkyMaterialData *material = nullptr;
if (sky_material.is_valid()) {
material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
material = (SkyMaterialData *)material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY);
if (!material || !material->shader_data->valid) {
material = nullptr;
}
@ -1300,7 +1316,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
if (!material) {
sky_material = sky_shader.default_material;
material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
material = (SkyMaterialData *)material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY);
}
ERR_FAIL_COND(!material);
@ -1450,6 +1466,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
}
void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
ERR_FAIL_COND(!p_env);
ERR_FAIL_COND(p_view_count == 0);
@ -1467,7 +1484,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
sky_material = sky_get_material(p_env->sky);
if (sky_material.is_valid()) {
material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
material = (SkyMaterialData *)material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY);
if (!material || !material->shader_data->valid) {
material = nullptr;
}
@ -1475,13 +1492,13 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
if (!material) {
sky_material = sky_shader.default_material;
material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
material = (SkyMaterialData *)material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY);
}
}
if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {
sky_material = sky_scene_state.fog_material;
material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
material = (SkyMaterialData *)material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY);
}
ERR_FAIL_COND(!material);
@ -1556,6 +1573,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
}
void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
ERR_FAIL_COND(!p_env);
ERR_FAIL_COND(p_view_count == 0);
@ -1570,7 +1588,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u
sky_material = sky_get_material(p_env->sky);
if (sky_material.is_valid()) {
material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
material = (SkyMaterialData *)material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY);
if (!material || !material->shader_data->valid) {
material = nullptr;
}
@ -1578,7 +1596,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u
if (!material) {
sky_material = sky_shader.default_material;
material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
material = (SkyMaterialData *)material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY);
}
ERR_FAIL_COND(!material);
@ -1640,6 +1658,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u
}
void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
ERR_FAIL_COND(!p_env);
ERR_FAIL_COND(p_view_count == 0);
@ -1657,7 +1676,7 @@ void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironme
sky_material = sky_get_material(p_env->sky);
if (sky_material.is_valid()) {
material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
material = (SkyMaterialData *)material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY);
if (!material || !material->shader_data->valid) {
material = nullptr;
}
@ -1665,13 +1684,13 @@ void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironme
if (!material) {
sky_material = sky_shader.default_material;
material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
material = (SkyMaterialData *)material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY);
}
}
if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {
sky_material = sky_scene_state.fog_material;
material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
material = (SkyMaterialData *)material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY);
}
ERR_FAIL_COND(!material);

View file

@ -105,7 +105,7 @@ private:
// 128 is the max size of a push constant. We can replace "pad" but we can't add any more.
};
struct SkyShaderData : public RendererStorageRD::ShaderData {
struct SkyShaderData : public RendererRD::ShaderData {
bool valid;
RID version;
@ -129,7 +129,7 @@ private:
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_instance_param_list(List<RendererStorage::InstanceShaderParam> *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;
virtual bool casts_shadows() const;
@ -227,7 +227,7 @@ public:
RID default_shader_rd;
} sky_shader;
struct SkyMaterialData : public RendererStorageRD::MaterialData {
struct SkyMaterialData : public RendererRD::MaterialData {
SkyShaderData *shader_data;
RID uniform_set;
bool uniform_set_updated;
@ -281,11 +281,11 @@ public:
mutable RID_Owner<Sky, true> sky_owner;
int roughness_layers;
RendererStorageRD::ShaderData *_create_sky_shader_func();
static RendererStorageRD::ShaderData *_create_sky_shader_funcs();
RendererRD::ShaderData *_create_sky_shader_func();
static RendererRD::ShaderData *_create_sky_shader_funcs();
RendererStorageRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader);
static RendererStorageRD::MaterialData *_create_sky_material_funcs(RendererStorageRD::ShaderData *p_shader);
RendererRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader);
static RendererRD::MaterialData *_create_sky_material_funcs(RendererRD::ShaderData *p_shader);
RendererSceneSkyRD();
void init(RendererStorageRD *p_storage);

File diff suppressed because it is too large Load diff

View file

@ -42,6 +42,8 @@
#include "servers/rendering/renderer_rd/shaders/skeleton.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl.gen.h"
#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
@ -127,61 +129,6 @@ public:
}
}
enum ShaderType {
SHADER_TYPE_2D,
SHADER_TYPE_3D,
SHADER_TYPE_PARTICLES,
SHADER_TYPE_SKY,
SHADER_TYPE_FOG,
SHADER_TYPE_MAX
};
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_instance_param_list(List<InstanceShaderParam> *p_param_list) const = 0;
virtual bool is_param_texture(const StringName &p_param) const = 0;
virtual bool is_animated() const = 0;
virtual bool casts_shadows() const = 0;
virtual Variant get_default_parameter(const StringName &p_parameter) const = 0;
virtual RS::ShaderNativeSourceCode get_native_source_code() const { return RS::ShaderNativeSourceCode(); }
virtual ~ShaderData() {}
};
typedef ShaderData *(*ShaderDataRequestFunction)();
struct MaterialData {
void update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color);
void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
virtual void set_render_priority(int p_priority) = 0;
virtual void set_next_pass(RID p_pass) = 0;
virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0;
virtual ~MaterialData();
//to be used internally by update_parameters, in the most common configuration of material parameters
bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
void free_parameters_uniform_set(RID p_uniform_set);
private:
friend class RendererStorageRD;
RID self;
List<RID>::Element *global_buffer_E = nullptr;
List<RID>::Element *global_texture_E = nullptr;
uint64_t global_textures_pass = 0;
Map<StringName, uint64_t> used_global_textures;
//internally by update_parameters_uniform_set
Vector<uint8_t> ubo_data;
RID uniform_buffer;
Vector<RID> texture_cache;
};
typedef MaterialData *(*MaterialDataRequestFunction)(ShaderData *);
static void _material_uniform_set_erased(void *p_material);
enum DefaultRDBuffer {
DEFAULT_RD_BUFFER_VERTEX,
DEFAULT_RD_BUFFER_NORMAL,
@ -205,50 +152,6 @@ private:
RID custom_rd_samplers[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX];
RID default_rd_storage_buffer;
/* SHADER */
struct Material;
struct Shader {
ShaderData *data;
String code;
ShaderType type;
Map<StringName, Map<int, RID>> default_texture_parameter;
Set<Material *> owners;
};
ShaderDataRequestFunction shader_data_request_func[SHADER_TYPE_MAX];
mutable RID_Owner<Shader, true> shader_owner;
/* Material */
struct Material {
RID self;
MaterialData *data = nullptr;
Shader *shader = nullptr;
//shortcut to shader data and type
ShaderType shader_type = SHADER_TYPE_MAX;
uint32_t shader_id = 0;
bool uniform_dirty = false;
bool texture_dirty = false;
Map<StringName, Variant> params;
int32_t priority = 0;
RID next_pass;
SelfList<Material> update_element;
Dependency dependency;
Material() :
update_element(this) {}
};
MaterialDataRequestFunction material_data_request_func[SHADER_TYPE_MAX];
mutable RID_Owner<Material, true> material_owner;
SelfList<Material>::List material_update_list;
void _material_queue_update(Material *material, bool p_uniform, bool p_texture);
void _update_queued_materials();
/* Mesh */
struct MeshInstance;
@ -714,7 +617,7 @@ private:
Particles *particle_update_list = nullptr;
struct ParticlesShaderData : public ShaderData {
struct ParticlesShaderData : public RendererRD::ShaderData {
bool valid;
RID version;
bool uses_collision = false;
@ -740,7 +643,7 @@ private:
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_instance_param_list(List<RendererStorage::InstanceShaderParam> *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;
virtual bool casts_shadows() const;
@ -751,12 +654,12 @@ private:
virtual ~ParticlesShaderData();
};
ShaderData *_create_particles_shader_func();
static RendererStorageRD::ShaderData *_create_particles_shader_funcs() {
RendererRD::ShaderData *_create_particles_shader_func();
static RendererRD::ShaderData *_create_particles_shader_funcs() {
return base_singleton->_create_particles_shader_func();
}
struct ParticlesMaterialData : public MaterialData {
struct ParticlesMaterialData : public RendererRD::MaterialData {
ParticlesShaderData *shader_data = nullptr;
RID uniform_set;
@ -766,8 +669,8 @@ private:
virtual ~ParticlesMaterialData();
};
MaterialData *_create_particles_material_func(ParticlesShaderData *p_shader);
static RendererStorageRD::MaterialData *_create_particles_material_funcs(ShaderData *p_shader) {
RendererRD::MaterialData *_create_particles_material_func(ParticlesShaderData *p_shader);
static RendererRD::MaterialData *_create_particles_material_funcs(RendererRD::ShaderData *p_shader) {
return base_singleton->_create_particles_material_func(static_cast<ParticlesShaderData *>(p_shader));
}
@ -1054,72 +957,6 @@ private:
RID pipelines[SHADER_MAX];
} rt_sdf;
/* GLOBAL SHADER VARIABLES */
struct GlobalVariables {
enum {
BUFFER_DIRTY_REGION_SIZE = 1024
};
struct Variable {
Set<RID> texture_materials; // materials using this
RS::GlobalVariableType type;
Variant value;
Variant override;
int32_t buffer_index; //for vectors
int32_t buffer_elements; //for vectors
};
HashMap<StringName, Variable> variables;
struct Value {
float x;
float y;
float z;
float w;
};
struct ValueInt {
int32_t x;
int32_t y;
int32_t z;
int32_t w;
};
struct ValueUInt {
uint32_t x;
uint32_t y;
uint32_t z;
uint32_t w;
};
struct ValueUsage {
uint32_t elements = 0;
};
List<RID> materials_using_buffer;
List<RID> materials_using_texture;
RID buffer;
Value *buffer_values;
ValueUsage *buffer_usage;
bool *buffer_dirty_regions;
uint32_t buffer_dirty_region_count = 0;
uint32_t buffer_size;
bool must_update_texture_materials = false;
bool must_update_buffer_materials = false;
HashMap<RID, int32_t> instance_buffer_pos;
} global_variables;
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);
void _update_global_variables();
/* EFFECTS */
EffectsRD *effects = nullptr;
@ -1138,58 +975,6 @@ public:
void sampler_rd_set_default(float p_mipmap_bias);
/* SHADER API */
RID shader_allocate();
void shader_initialize(RID p_shader);
void shader_set_code(RID p_shader, const String &p_code);
String shader_get_code(RID p_shader) const;
void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const;
void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index);
RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const;
Variant shader_get_param_default(RID p_shader, const StringName &p_param) const;
void shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function);
virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const;
/* COMMON MATERIAL API */
RID material_allocate();
void material_initialize(RID p_material);
void material_set_shader(RID p_material, RID p_shader);
void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value);
Variant material_get_param(RID p_material, const StringName &p_param) const;
void material_set_next_pass(RID p_material, RID p_next_material);
void material_set_render_priority(RID p_material, int priority);
bool material_is_animated(RID p_material);
bool material_casts_shadows(RID p_material);
void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters);
void material_update_dependency(RID p_material, DependencyTracker *p_instance);
void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function);
_FORCE_INLINE_ uint32_t material_get_shader_id(RID p_material) {
Material *material = material_owner.get_or_null(p_material);
return material->shader_id;
}
_FORCE_INLINE_ MaterialData *material_get_data(RID p_material, ShaderType p_shader_type) {
Material *material = material_owner.get_or_null(p_material);
if (!material || material->shader_type != p_shader_type) {
return nullptr;
} else {
return material->data;
}
}
/* MESH API */
RID mesh_allocate();
@ -1972,27 +1757,6 @@ public:
virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform);
virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active);
/* GLOBAL VARIABLES API */
virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value);
virtual void global_variable_remove(const StringName &p_name);
virtual Vector<StringName> global_variable_get_list() const;
virtual void global_variable_set(const StringName &p_name, const Variant &p_value);
virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value);
virtual Variant global_variable_get(const StringName &p_name) const;
virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const;
RS::GlobalVariableType global_variable_get_type_internal(const StringName &p_name) const;
virtual void global_variables_load_settings(bool p_load_textures = true);
virtual void global_variables_clear();
virtual int32_t global_variables_instance_allocate(RID p_instance);
virtual void global_variables_instance_free(RID p_instance);
virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value);
RID global_variables_get_storage_buffer() const;
/* RENDER TARGET API */
RID render_target_create();

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,315 @@
/*************************************************************************/
/* material_storage.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 MATERIAL_STORAGE_RD_H
#define MATERIAL_STORAGE_RD_H
#include "core/templates/local_vector.h"
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "servers/rendering/shader_compiler.h"
#include "servers/rendering/shader_language.h"
#include "servers/rendering/storage/material_storage.h"
namespace RendererRD {
class MaterialStorage;
/* SHADER Structs */
enum ShaderType {
SHADER_TYPE_2D,
SHADER_TYPE_3D,
SHADER_TYPE_PARTICLES,
SHADER_TYPE_SKY,
SHADER_TYPE_FOG,
SHADER_TYPE_MAX
};
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_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const = 0;
virtual bool is_param_texture(const StringName &p_param) const = 0;
virtual bool is_animated() const = 0;
virtual bool casts_shadows() const = 0;
virtual Variant get_default_parameter(const StringName &p_parameter) const = 0;
virtual RS::ShaderNativeSourceCode get_native_source_code() const { return RS::ShaderNativeSourceCode(); }
virtual ~ShaderData() {}
};
typedef ShaderData *(*ShaderDataRequestFunction)();
struct Material;
struct Shader {
ShaderData *data;
String code;
ShaderType type;
Map<StringName, Map<int, RID>> default_texture_parameter;
Set<Material *> owners;
};
/* Material structs */
struct MaterialData {
void update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color);
void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
virtual void set_render_priority(int p_priority) = 0;
virtual void set_next_pass(RID p_pass) = 0;
virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0;
virtual ~MaterialData();
//to be used internally by update_parameters, in the most common configuration of material parameters
bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
void free_parameters_uniform_set(RID p_uniform_set);
private:
friend class MaterialStorage;
RID self;
List<RID>::Element *global_buffer_E = nullptr;
List<RID>::Element *global_texture_E = nullptr;
uint64_t global_textures_pass = 0;
Map<StringName, uint64_t> used_global_textures;
//internally by update_parameters_uniform_set
Vector<uint8_t> ubo_data;
RID uniform_buffer;
Vector<RID> texture_cache;
};
typedef MaterialData *(*MaterialDataRequestFunction)(ShaderData *);
struct Material {
RID self;
MaterialData *data = nullptr;
Shader *shader = nullptr;
//shortcut to shader data and type
ShaderType shader_type = SHADER_TYPE_MAX;
uint32_t shader_id = 0;
bool uniform_dirty = false;
bool texture_dirty = false;
Map<StringName, Variant> params;
int32_t priority = 0;
RID next_pass;
SelfList<Material> update_element;
RendererStorage::Dependency dependency;
Material() :
update_element(this) {}
};
/* Global variable structs */
struct GlobalVariables {
enum {
BUFFER_DIRTY_REGION_SIZE = 1024
};
struct Variable {
Set<RID> texture_materials; // materials using this
RS::GlobalVariableType type;
Variant value;
Variant override;
int32_t buffer_index; //for vectors
int32_t buffer_elements; //for vectors
};
HashMap<StringName, Variable> variables;
struct Value {
float x;
float y;
float z;
float w;
};
struct ValueInt {
int32_t x;
int32_t y;
int32_t z;
int32_t w;
};
struct ValueUInt {
uint32_t x;
uint32_t y;
uint32_t z;
uint32_t w;
};
struct ValueUsage {
uint32_t elements = 0;
};
List<RID> materials_using_buffer;
List<RID> materials_using_texture;
RID buffer;
Value *buffer_values;
ValueUsage *buffer_usage;
bool *buffer_dirty_regions;
uint32_t buffer_dirty_region_count = 0;
uint32_t buffer_size;
bool must_update_texture_materials = false;
bool must_update_buffer_materials = false;
HashMap<RID, int32_t> instance_buffer_pos;
};
class MaterialStorage : public RendererMaterialStorage {
private:
friend struct MaterialData;
static MaterialStorage *singleton;
/* GLOBAL VARIABLE API */
GlobalVariables global_variables;
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);
/* SHADER API */
ShaderDataRequestFunction shader_data_request_func[SHADER_TYPE_MAX];
mutable RID_Owner<Shader, true> shader_owner;
/* MATERIAL API */
MaterialDataRequestFunction material_data_request_func[SHADER_TYPE_MAX];
mutable RID_Owner<Material, true> material_owner;
SelfList<Material>::List material_update_list;
static void _material_uniform_set_erased(void *p_material);
public:
static MaterialStorage *get_singleton();
MaterialStorage();
virtual ~MaterialStorage();
/* GLOBAL VARIABLE API */
void _update_global_variables();
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_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_variables_load_settings(bool p_load_textures = true) override;
virtual void global_variables_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;
RID global_variables_get_storage_buffer() const;
/* SHADER API */
Shader *get_shader(RID p_rid) { return shader_owner.get_or_null(p_rid); };
bool owns_shader(RID p_rid) { return shader_owner.owns(p_rid); };
virtual RID shader_allocate() override;
virtual void shader_initialize(RID p_shader) override;
virtual void shader_free(RID p_rid) override;
virtual void shader_set_code(RID p_shader, const String &p_code) 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_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;
virtual Variant shader_get_param_default(RID p_shader, const StringName &p_param) const override;
void shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function);
virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override;
/* MATERIAL API */
Material *get_material(RID p_rid) { return material_owner.get_or_null(p_rid); };
bool owns_material(RID p_rid) { return material_owner.owns(p_rid); };
void _material_queue_update(Material *material, bool p_uniform, bool p_texture);
void _update_queued_materials();
virtual RID material_allocate() override;
virtual void material_initialize(RID p_material) override;
virtual void material_free(RID p_rid) override;
virtual void material_set_shader(RID p_material, RID p_shader) override;
virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) override;
virtual Variant material_get_param(RID p_material, const StringName &p_param) const override;
virtual void material_set_next_pass(RID p_material, RID p_next_material) override;
virtual void material_set_render_priority(RID p_material, int priority) override;
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_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) override;
void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function);
MaterialDataRequestFunction material_get_data_request_function(ShaderType p_shader_type);
_FORCE_INLINE_ uint32_t material_get_shader_id(RID p_material) {
Material *material = material_owner.get_or_null(p_material);
return material->shader_id;
}
_FORCE_INLINE_ MaterialData *material_get_data(RID p_material, ShaderType p_shader_type) {
Material *material = material_owner.get_or_null(p_material);
if (!material || material->shader_type != p_shader_type) {
return nullptr;
} else {
return material->data;
}
}
};
} // namespace RendererRD
#endif // !MATERIAL_STORAGE_RD_H

View file

@ -949,7 +949,7 @@ void TextureStorage::texture_set_path(RID p_texture, const String &p_path) {
}
String TextureStorage::texture_get_path(RID p_texture) const {
RendererRD::Texture *tex = texture_owner.get_or_null(p_texture);
Texture *tex = texture_owner.get_or_null(p_texture);
ERR_FAIL_COND_V(!tex, String());
return tex->path;

View file

@ -1438,7 +1438,7 @@ void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, c
E->get().value = p_value;
if (E->get().index >= 0 && instance->instance_allocated_shader_parameters) {
//update directly
RSG::storage->global_variables_instance_update(p_instance, E->get().index, p_value);
RSG::material_storage->global_variables_instance_update(p_instance, E->get().index, p_value);
}
}
}
@ -3627,9 +3627,9 @@ void RendererSceneCull::render_particle_colliders() {
}
void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) {
List<RendererStorage::InstanceShaderParam> plist;
RSG::storage->material_get_instance_shader_parameters(p_material, &plist);
for (const RendererStorage::InstanceShaderParam &E : plist) {
List<RendererMaterialStorage::InstanceShaderParam> plist;
RSG::material_storage->material_get_instance_shader_parameters(p_material, &plist);
for (const RendererMaterialStorage::InstanceShaderParam &E : plist) {
StringName name = E.info.name;
if (isparams.has(name)) {
if (isparams[name].info.type != E.info.type) {
@ -3667,11 +3667,11 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
}
if (p_instance->material_override.is_valid()) {
RSG::storage->material_update_dependency(p_instance->material_override, &p_instance->dependency_tracker);
RSG::material_storage->material_update_dependency(p_instance->material_override, &p_instance->dependency_tracker);
}
if (p_instance->material_overlay.is_valid()) {
RSG::storage->material_update_dependency(p_instance->material_overlay, &p_instance->dependency_tracker);
RSG::material_storage->material_update_dependency(p_instance->material_overlay, &p_instance->dependency_tracker);
}
if (p_instance->base_type == RS::INSTANCE_MESH) {
@ -3688,7 +3688,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
RID particle_material = RSG::storage->particles_get_process_material(p_instance->base);
if (particle_material.is_valid()) {
RSG::storage->material_update_dependency(particle_material, &p_instance->dependency_tracker);
RSG::material_storage->material_update_dependency(particle_material, &p_instance->dependency_tracker);
}
}
@ -3704,10 +3704,10 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
}
if (p_instance->material_override.is_valid()) {
if (!RSG::storage->material_casts_shadows(p_instance->material_override)) {
if (!RSG::material_storage->material_casts_shadows(p_instance->material_override)) {
can_cast_shadows = false;
}
is_animated = RSG::storage->material_is_animated(p_instance->material_override);
is_animated = RSG::material_storage->material_is_animated(p_instance->material_override);
_update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, p_instance->material_override);
} else {
if (p_instance->base_type == RS::INSTANCE_MESH) {
@ -3722,17 +3722,17 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
if (!mat.is_valid()) {
cast_shadows = true;
} else {
if (RSG::storage->material_casts_shadows(mat)) {
if (RSG::material_storage->material_casts_shadows(mat)) {
cast_shadows = true;
}
if (RSG::storage->material_is_animated(mat)) {
if (RSG::material_storage->material_is_animated(mat)) {
is_animated = true;
}
_update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker);
RSG::material_storage->material_update_dependency(mat, &p_instance->dependency_tracker);
}
}
@ -3754,16 +3754,16 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
cast_shadows = true;
} else {
if (RSG::storage->material_casts_shadows(mat)) {
if (RSG::material_storage->material_casts_shadows(mat)) {
cast_shadows = true;
}
if (RSG::storage->material_is_animated(mat)) {
if (RSG::material_storage->material_is_animated(mat)) {
is_animated = true;
}
_update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker);
RSG::material_storage->material_update_dependency(mat, &p_instance->dependency_tracker);
}
}
@ -3791,17 +3791,17 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
if (!mat.is_valid()) {
cast_shadows = true;
} else {
if (RSG::storage->material_casts_shadows(mat)) {
if (RSG::material_storage->material_casts_shadows(mat)) {
cast_shadows = true;
}
if (RSG::storage->material_is_animated(mat)) {
if (RSG::material_storage->material_is_animated(mat)) {
is_animated = true;
}
_update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker);
RSG::material_storage->material_update_dependency(mat, &p_instance->dependency_tracker);
}
}
}
@ -3813,8 +3813,8 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
}
if (p_instance->material_overlay.is_valid()) {
can_cast_shadows = can_cast_shadows || RSG::storage->material_casts_shadows(p_instance->material_overlay);
is_animated = is_animated || RSG::storage->material_is_animated(p_instance->material_overlay);
can_cast_shadows = can_cast_shadows || RSG::material_storage->material_casts_shadows(p_instance->material_overlay);
is_animated = is_animated || RSG::material_storage->material_is_animated(p_instance->material_overlay);
_update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, p_instance->material_overlay);
}
@ -3834,16 +3834,16 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
if (p_instance->instance_allocated_shader_parameters != (p_instance->instance_shader_parameters.size() > 0)) {
p_instance->instance_allocated_shader_parameters = (p_instance->instance_shader_parameters.size() > 0);
if (p_instance->instance_allocated_shader_parameters) {
p_instance->instance_allocated_shader_parameters_offset = RSG::storage->global_variables_instance_allocate(p_instance->self);
p_instance->instance_allocated_shader_parameters_offset = RSG::material_storage->global_variables_instance_allocate(p_instance->self);
scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, p_instance->instance_allocated_shader_parameters_offset);
for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_parameters) {
if (E.value.value.get_type() != Variant::NIL) {
RSG::storage->global_variables_instance_update(p_instance->self, E.value.index, E.value.value);
RSG::material_storage->global_variables_instance_update(p_instance->self, E.value.index, E.value.value);
}
}
} else {
RSG::storage->global_variables_instance_free(p_instance->self);
RSG::material_storage->global_variables_instance_free(p_instance->self);
p_instance->instance_allocated_shader_parameters_offset = -1;
scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, -1);
}
@ -3939,7 +3939,7 @@ bool RendererSceneCull::free(RID p_rid) {
if (instance->instance_allocated_shader_parameters) {
//free the used shader parameters
RSG::storage->global_variables_instance_free(instance->self);
RSG::material_storage->global_variables_instance_free(instance->self);
}
update_dirty_instances(); //in case something changed this

View file

@ -65,7 +65,6 @@ public:
Map<DependencyTracker *, uint32_t> instances;
};
public:
struct DependencyTracker {
void *userdata = nullptr;
typedef void (*ChangedCallback)(DependencyChangedNotification, DependencyTracker *);
@ -120,47 +119,6 @@ public:
Set<Dependency *> dependencies;
};
/* SHADER API */
virtual RID shader_allocate() = 0;
virtual void shader_initialize(RID p_rid) = 0;
virtual void shader_set_code(RID p_shader, const String &p_code) = 0;
virtual String shader_get_code(RID p_shader) const = 0;
virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0;
virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) = 0;
virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const = 0;
virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const = 0;
virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const = 0;
/* COMMON MATERIAL API */
virtual RID material_allocate() = 0;
virtual void material_initialize(RID p_rid) = 0;
virtual void material_set_render_priority(RID p_material, int priority) = 0;
virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0;
virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) = 0;
virtual Variant material_get_param(RID p_material, const StringName &p_param) const = 0;
virtual void material_set_next_pass(RID p_material, RID p_next_material) = 0;
virtual bool material_is_animated(RID p_material) = 0;
virtual bool material_casts_shadows(RID p_material) = 0;
struct InstanceShaderParam {
PropertyInfo info;
int index;
Variant default_value;
};
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0;
virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) = 0;
/* MESH API */
virtual RID mesh_allocate() = 0;
@ -491,24 +449,6 @@ public:
virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) = 0;
virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) = 0;
/* GLOBAL VARIABLES */
virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0;
virtual void global_variable_remove(const StringName &p_name) = 0;
virtual Vector<StringName> global_variable_get_list() const = 0;
virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0;
virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0;
virtual Variant global_variable_get(const StringName &p_name) const = 0;
virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0;
virtual void global_variables_load_settings(bool p_load_textures = true) = 0;
virtual void global_variables_clear() = 0;
virtual int32_t global_variables_instance_allocate(RID p_instance) = 0;
virtual void global_variables_instance_free(RID p_instance) = 0;
virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0;
/* RENDER TARGET */
enum RenderTargetFlags {

View file

@ -400,6 +400,7 @@ RenderingServerDefault::RenderingServerDefault(bool p_create_thread) :
RSG::rasterizer = RendererCompositor::create();
RSG::canvas_texture_storage = RSG::rasterizer->get_canvas_texture_storage();
RSG::decal_atlas_storage = RSG::rasterizer->get_decal_atlas_storage();
RSG::material_storage = RSG::rasterizer->get_material_storage();
RSG::texture_storage = RSG::rasterizer->get_texture_storage();
RSG::storage = RSG::rasterizer->get_storage();
RSG::canvas_render = RSG::rasterizer->get_canvas();

View file

@ -213,14 +213,13 @@ public:
FUNC2(texture_set_force_redraw_if_visible, RID, bool)
//from now on, calls forwarded to this singleton
/* SHADER API */
#undef ServerName
#undef server_name
#define ServerName RendererStorage
#define server_name RSG::storage
/* SHADER API */
#define ServerName RendererMaterialStorage
#define server_name RSG::material_storage
FUNCRIDSPLIT(shader)
@ -249,6 +248,13 @@ public:
/* MESH API */
//from now on, calls forwarded to this singleton
#undef ServerName
#undef server_name
#define ServerName RendererStorage
#define server_name RSG::storage
virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) override {
RID mesh = RSG::storage->mesh_allocate();
@ -870,8 +876,8 @@ public:
#undef server_name
#undef ServerName
//from now on, calls forwarded to this singleton
#define ServerName RendererStorage
#define server_name RSG::storage
#define ServerName RendererMaterialStorage
#define server_name RSG::material_storage
FUNC3(global_variable_add, const StringName &, GlobalVariableType, const Variant &)
FUNC1(global_variable_remove, const StringName &)

View file

@ -34,6 +34,7 @@ bool RenderingServerGlobals::threaded = false;
RendererCanvasTextureStorage *RenderingServerGlobals::canvas_texture_storage = nullptr;
RendererDecalAtlasStorage *RenderingServerGlobals::decal_atlas_storage = nullptr;
RendererMaterialStorage *RenderingServerGlobals::material_storage = nullptr;
RendererTextureStorage *RenderingServerGlobals::texture_storage = nullptr;
RendererStorage *RenderingServerGlobals::storage = nullptr;
RendererCanvasRender *RenderingServerGlobals::canvas_render = nullptr;

View file

@ -36,6 +36,7 @@
#include "servers/rendering/renderer_scene.h"
#include "servers/rendering/storage/canvas_texture_storage.h"
#include "servers/rendering/storage/decal_atlas_storage.h"
#include "servers/rendering/storage/material_storage.h"
#include "servers/rendering/storage/texture_storage.h"
class RendererCanvasCull;
@ -47,6 +48,7 @@ public:
static bool threaded;
static RendererCanvasTextureStorage *canvas_texture_storage;
static RendererMaterialStorage *material_storage;
static RendererTextureStorage *texture_storage;
static RendererDecalAtlasStorage *decal_atlas_storage;
static RendererStorage *storage;

View file

@ -0,0 +1,101 @@
/*************************************************************************/
/* material_storage.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 MATERIAL_STORAGE_H
#define MATERIAL_STORAGE_H
#include "servers/rendering/renderer_storage.h"
#include "servers/rendering_server.h"
class RendererMaterialStorage {
public:
virtual ~RendererMaterialStorage(){};
/* GLOBAL VARIABLE API */
virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0;
virtual void global_variable_remove(const StringName &p_name) = 0;
virtual Vector<StringName> global_variable_get_list() const = 0;
virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0;
virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0;
virtual Variant global_variable_get(const StringName &p_name) const = 0;
virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0;
virtual void global_variables_load_settings(bool p_load_textures = true) = 0;
virtual void global_variables_clear() = 0;
virtual int32_t global_variables_instance_allocate(RID p_instance) = 0;
virtual void global_variables_instance_free(RID p_instance) = 0;
virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0;
/* SHADER API */
virtual RID shader_allocate() = 0;
virtual void shader_initialize(RID p_rid) = 0;
virtual void shader_free(RID p_rid) = 0;
virtual void shader_set_code(RID p_shader, const String &p_code) = 0;
virtual String shader_get_code(RID p_shader) const = 0;
virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0;
virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) = 0;
virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const = 0;
virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const = 0;
virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const = 0;
/* MATERIAL API */
virtual RID material_allocate() = 0;
virtual void material_initialize(RID p_rid) = 0;
virtual void material_free(RID p_rid) = 0;
virtual void material_set_render_priority(RID p_material, int priority) = 0;
virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0;
virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) = 0;
virtual Variant material_get_param(RID p_material, const StringName &p_param) const = 0;
virtual void material_set_next_pass(RID p_material, RID p_next_material) = 0;
virtual bool material_is_animated(RID p_material) = 0;
virtual bool material_casts_shadows(RID p_material) = 0;
struct InstanceShaderParam {
PropertyInfo info;
int index;
Variant default_value;
};
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0;
virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) = 0;
};
#endif // !MATERIAL_STORAGE_H