diff options
author | Juan Linietsky <reduzio@gmail.com> | 2020-04-20 22:03:11 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-20 22:03:11 -0300 |
commit | 40b2aea222807ab50a31c7ca718bfca76080caa0 (patch) | |
tree | 94c9b2cc850eb2fb0608a52c05fb389e1cd35234 /servers | |
parent | 6d8e1aea892dc80e2fb01729b9a532a447f0760d (diff) | |
parent | ae09b55a19c956cf6dafd446c71178f6bbffd91d (diff) |
Merge pull request #38032 from reduz/rendering-device-binds
Exposed RenderingDevice to script API
Diffstat (limited to 'servers')
-rw-r--r-- | servers/register_server_types.cpp | 19 | ||||
-rw-r--r-- | servers/rendering/rendering_device.cpp | 737 | ||||
-rw-r--r-- | servers/rendering/rendering_device.h | 83 | ||||
-rw-r--r-- | servers/rendering/rendering_device_binds.cpp | 167 | ||||
-rw-r--r-- | servers/rendering/rendering_device_binds.h | 628 |
5 files changed, 1627 insertions, 7 deletions
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index dd11f9260c..1efa3d83a3 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -62,7 +62,10 @@ #include "physics_3d/physics_server_3d_sw.h" #include "physics_server_2d.h" #include "physics_server_3d.h" +#include "rendering/rasterizer.h" #include "rendering/rendering_device.h" +#include "rendering/rendering_device_binds.h" + #include "rendering_server.h" #include "servers/rendering/shader_types.h" #include "xr/xr_interface.h" @@ -162,6 +165,22 @@ void register_server_types() { ClassDB::register_virtual_class<AudioEffectSpectrumAnalyzerInstance>(); } + ClassDB::register_virtual_class<RenderingDevice>(); + ClassDB::register_class<RDTextureFormat>(); + ClassDB::register_class<RDTextureView>(); + ClassDB::register_class<RDAttachmentFormat>(); + ClassDB::register_class<RDSamplerState>(); + ClassDB::register_class<RDVertexDescription>(); + ClassDB::register_class<RDUniform>(); + ClassDB::register_class<RDPipelineRasterizationState>(); + ClassDB::register_class<RDPipelineMultisampleState>(); + ClassDB::register_class<RDPipelineDepthStencilState>(); + ClassDB::register_class<RDPipelineColorBlendStateAttachment>(); + ClassDB::register_class<RDPipelineColorBlendState>(); + ClassDB::register_class<RDShaderSource>(); + ClassDB::register_class<RDShaderBytecode>(); + ClassDB::register_class<RDShaderFile>(); + ClassDB::register_class<CameraFeed>(); ClassDB::register_virtual_class<PhysicsDirectBodyState2D>(); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 75ef38354a..0c15d4645b 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -29,6 +29,8 @@ /*************************************************************************/ #include "rendering_device.h" +#include "core/method_bind_ext.gen.inc" +#include "rendering_device_binds.h" RenderingDevice *RenderingDevice::singleton = nullptr; @@ -59,6 +61,741 @@ Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage, return compile_function(p_stage, p_source_code, p_language, r_error); } +RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const Array &p_data) { + + ERR_FAIL_COND_V(p_format.is_null(), RID()); + ERR_FAIL_COND_V(p_view.is_null(), RID()); + Vector<Vector<uint8_t>> data; + for (int i = 0; i < p_data.size(); i++) { + Vector<uint8_t> byte_slice = p_data[i]; + ERR_FAIL_COND_V(byte_slice.empty(), RID()); + data.push_back(byte_slice); + } + return texture_create(p_format->base, p_view->base, data); +} + +RID RenderingDevice::_texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture) { + ERR_FAIL_COND_V(p_view.is_null(), RID()); + + return texture_create_shared(p_view->base, p_with_texture); +} + +RID RenderingDevice::_texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type) { + ERR_FAIL_COND_V(p_view.is_null(), RID()); + + return texture_create_shared_from_slice(p_view->base, p_with_texture, p_layer, p_mipmap, p_slice_type); +} + +RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const Array &p_attachments) { + + Vector<AttachmentFormat> attachments; + attachments.resize(p_attachments.size()); + + for (int i = 0; i < p_attachments.size(); i++) { + Ref<RDAttachmentFormat> af = p_attachments[i]; + ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID); + attachments.write[i] = af->base; + } + return framebuffer_format_create(attachments); +} + +RID RenderingDevice::_framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check) { + + Vector<RID> textures = Variant(p_textures); + return framebuffer_create(textures, p_format_check); +} + +RID RenderingDevice::_sampler_create(const Ref<RDSamplerState> &p_state) { + ERR_FAIL_COND_V(p_state.is_null(), RID()); + + return sampler_create(p_state->base); +} + +RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const Array &p_vertex_formats) { + + Vector<VertexDescription> descriptions; + descriptions.resize(p_vertex_formats.size()); + + for (int i = 0; i < p_vertex_formats.size(); i++) { + Ref<RDVertexDescription> af = p_vertex_formats[i]; + ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID); + descriptions.write[i] = af->base; + } + return vertex_format_create(descriptions); +} + +RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Array &p_src_buffers) { + + Vector<RID> buffers = Variant(p_src_buffers); + + return vertex_array_create(p_vertex_count, p_vertex_format, buffers); +} + +Ref<RDShaderBytecode> RenderingDevice::_shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache) { + ERR_FAIL_COND_V(p_source.is_null(), Ref<RDShaderBytecode>()); + + Ref<RDShaderBytecode> bytecode; + bytecode.instance(); + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + String error; + + ShaderStage stage = ShaderStage(i); + Vector<uint8_t> spirv = shader_compile_from_source(stage, p_source->get_stage_source(stage), p_source->get_language(), &error, p_allow_cache); + bytecode->set_stage_bytecode(stage, spirv); + bytecode->set_stage_compile_error(stage, error); + } + return bytecode; +} + +RID RenderingDevice::_shader_create(const Ref<RDShaderBytecode> &p_bytecode) { + ERR_FAIL_COND_V(p_bytecode.is_null(), RID()); + + Vector<ShaderStageData> stage_data; + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + ShaderStage stage = ShaderStage(i); + ShaderStageData sd; + sd.shader_stage = stage; + String error = p_bytecode->get_stage_compile_error(stage); + ERR_FAIL_COND_V_MSG(error != String(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode."); + sd.spir_v = p_bytecode->get_stage_bytecode(stage); + if (sd.spir_v.empty()) { + continue; + } + stage_data.push_back(sd); + } + + return shader_create(stage_data); +} + +RID RenderingDevice::_uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set) { + + Vector<Uniform> uniforms; + uniforms.resize(p_uniforms.size()); + for (int i = 0; i < p_uniforms.size(); i++) { + Ref<RDUniform> uniform = p_uniforms[i]; + ERR_FAIL_COND_V(!uniform.is_valid(), RID()); + uniforms.write[i] = uniform->base; + } + return uniform_set_create(uniforms, p_shader, p_shader_set); +} + +Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw) { + + return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_sync_with_draw); +} + +RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags) { + + PipelineRasterizationState rasterization_state; + if (p_rasterization_state.is_valid()) { + rasterization_state = p_rasterization_state->base; + } + + PipelineMultisampleState multisample_state; + if (p_multisample_state.is_valid()) { + multisample_state = p_multisample_state->base; + } + + PipelineDepthStencilState depth_stencil_state; + if (p_depth_stencil_state.is_valid()) { + depth_stencil_state = p_depth_stencil_state->base; + } + + PipelineColorBlendState color_blend_state; + if (p_blend_state.is_valid()) { + color_blend_state = p_blend_state->base; + } + + return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags); +} + +Vector<int64_t> RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) { + + Vector<DrawListID> splits; + splits.resize(p_splits); + draw_list_begin_split(p_framebuffer, p_splits, splits.ptrw(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region); + + Vector<int64_t> split_ids; + split_ids.resize(splits.size()); + for (int i = 0; i < splits.size(); i++) { + split_ids.write[i] = splits[i]; + } + + return split_ids; +} + +void RenderingDevice::_draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) { + ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size); + draw_list_set_push_constant(p_list, p_data.ptr(), p_data_size); +} + +void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) { + ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size); + compute_list_set_push_constant(p_list, p_data.ptr(), p_data_size); +} + +void RenderingDevice::_bind_methods() { + + ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array())); + ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared); + ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(TEXTURE_SLICE_2D)); + + ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "sync_with_draw"), &RenderingDevice::texture_update, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "layer"), &RenderingDevice::texture_get_data); + + ClassDB::bind_method(D_METHOD("texture_is_format_supported_for_usage", "format", "usage_flags"), &RenderingDevice::texture_is_format_supported_for_usage); + + ClassDB::bind_method(D_METHOD("texture_is_shared", "texture"), &RenderingDevice::texture_is_shared); + ClassDB::bind_method(D_METHOD("texture_is_valid", "texture"), &RenderingDevice::texture_is_valid); + + ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "sync_with_draw"), &RenderingDevice::texture_copy, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "sync_with_draw"), &RenderingDevice::texture_clear, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "sync_with_draw"), &RenderingDevice::texture_resolve_multisample, DEFVAL(false)); + + ClassDB::bind_method(D_METHOD("framebuffer_format_create", "attachments"), &RenderingDevice::_framebuffer_format_create); + ClassDB::bind_method(D_METHOD("framebuffer_format_get_texture_samples", "format"), &RenderingDevice::framebuffer_format_get_texture_samples); + ClassDB::bind_method(D_METHOD("framebuffer_create", "textures", "validate_with_format"), &RenderingDevice::_framebuffer_create, DEFVAL(INVALID_FORMAT_ID)); + ClassDB::bind_method(D_METHOD("framebuffer_get_format", "framebuffer"), &RenderingDevice::framebuffer_get_format); + + ClassDB::bind_method(D_METHOD("sampler_create", "state"), &RenderingDevice::_sampler_create); + + ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create); + + ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create); + + ClassDB::bind_method(D_METHOD("shader_compile_from_source", "shader_source", "allow_cache"), &RenderingDevice::_shader_compile_from_source, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("shader_create", "shader_data"), &RenderingDevice::_shader_create); + ClassDB::bind_method(D_METHOD("shader_get_vertex_input_attribute_mask", "shader"), &RenderingDevice::shader_get_vertex_input_attribute_mask); + + ClassDB::bind_method(D_METHOD("uniform_buffer_create", "size_bytes", "data"), &RenderingDevice::uniform_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("storage_buffer_create", "size_bytes", "data"), &RenderingDevice::storage_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("texture_buffer_create", "size_bytes", "format", "data"), &RenderingDevice::texture_buffer_create, DEFVAL(Vector<uint8_t>())); + + ClassDB::bind_method(D_METHOD("uniform_set_create", "uniforms", "shader", "shader_set"), &RenderingDevice::_uniform_set_create); + ClassDB::bind_method(D_METHOD("uniform_set_is_valid", "uniform_set"), &RenderingDevice::uniform_set_is_valid); + + ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "sync_with_draw"), &RenderingDevice::_buffer_update, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data); + + ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags"), &RenderingDevice::_render_pipeline_create, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid); + + ClassDB::bind_method(D_METHOD("compute_pipeline_create", "shader"), &RenderingDevice::compute_pipeline_create); + ClassDB::bind_method(D_METHOD("compute_pipeline_is_valid", "compute_pieline"), &RenderingDevice::compute_pipeline_is_valid); + + ClassDB::bind_method(D_METHOD("screen_get_width", "screen"), &RenderingDevice::screen_get_width, DEFVAL(DisplayServer::MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("screen_get_height", "screen"), &RenderingDevice::screen_get_height, DEFVAL(DisplayServer::MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("screen_get_framebuffer_format"), &RenderingDevice::screen_get_framebuffer_format); + + ClassDB::bind_method(D_METHOD("draw_list_begin_for_screen", "screen", "clear_color"), &RenderingDevice::draw_list_begin_for_screen, DEFVAL(DisplayServer::MAIN_WINDOW_ID), DEFVAL(Color())); + + ClassDB::bind_method(D_METHOD("draw_list_begin", "framebuffer", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::draw_list_begin, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2i())); + ClassDB::bind_method(D_METHOD("draw_list_begin_split", "framebuffer", "splits", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::_draw_list_begin_split, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2i())); + + ClassDB::bind_method(D_METHOD("draw_list_bind_render_pipeline", "draw_list", "render_pipeline"), &RenderingDevice::draw_list_bind_render_pipeline); + ClassDB::bind_method(D_METHOD("draw_list_bind_uniform_set", "draw_list", "uniform_set", "set_index"), &RenderingDevice::draw_list_bind_uniform_set); + ClassDB::bind_method(D_METHOD("draw_list_bind_vertex_array", "draw_list", "vertex_array"), &RenderingDevice::draw_list_bind_vertex_array); + ClassDB::bind_method(D_METHOD("draw_list_bind_index_array", "draw_list", "index_array"), &RenderingDevice::draw_list_bind_index_array); + ClassDB::bind_method(D_METHOD("draw_list_set_push_constant", "draw_list", "buffer", "size_bytes"), &RenderingDevice::_draw_list_set_push_constant); + + ClassDB::bind_method(D_METHOD("draw_list_draw", "draw_list", "use_indices", "instances", "procedural_vertex_count"), &RenderingDevice::draw_list_draw, DEFVAL(0)); + + ClassDB::bind_method(D_METHOD("draw_list_enable_scissor", "draw_list", "rect"), &RenderingDevice::draw_list_enable_scissor, DEFVAL(Rect2i())); + ClassDB::bind_method(D_METHOD("draw_list_disable_scissor", "draw_list"), &RenderingDevice::draw_list_disable_scissor); + + ClassDB::bind_method(D_METHOD("draw_list_end"), &RenderingDevice::draw_list_end); + + ClassDB::bind_method(D_METHOD("compute_list_begin"), &RenderingDevice::compute_list_begin); + ClassDB::bind_method(D_METHOD("compute_list_bind_compute_pipeline", "compute_list", "compute_pipeline"), &RenderingDevice::compute_list_bind_compute_pipeline); + ClassDB::bind_method(D_METHOD("compute_list_set_push_constant", "compute_list", "buffer", "size_bytes"), &RenderingDevice::_compute_list_set_push_constant); + ClassDB::bind_method(D_METHOD("compute_list_bind_uniform_set", "compute_list", "uniform_set", "set_index"), &RenderingDevice::compute_list_bind_uniform_set); + ClassDB::bind_method(D_METHOD("compute_list_dispatch", "compute_list", "x_groups", "y_groups", "z_groups"), &RenderingDevice::compute_list_dispatch); + ClassDB::bind_method(D_METHOD("compute_list_add_barrier", "compute_list"), &RenderingDevice::compute_list_add_barrier); + ClassDB::bind_method(D_METHOD("compute_list_end"), &RenderingDevice::compute_list_end); + + ClassDB::bind_method(D_METHOD("free", "rid"), &RenderingDevice::free); + + ClassDB::bind_method(D_METHOD("capture_timestamp", "name", "sync_to_draw"), &RenderingDevice::capture_timestamp); + ClassDB::bind_method(D_METHOD("get_captured_timestamps_count"), &RenderingDevice::get_captured_timestamps_count); + ClassDB::bind_method(D_METHOD("get_captured_timestamps_frame"), &RenderingDevice::get_captured_timestamps_frame); + ClassDB::bind_method(D_METHOD("get_captured_timestamp_gpu_time", "index"), &RenderingDevice::get_captured_timestamp_gpu_time); + ClassDB::bind_method(D_METHOD("get_captured_timestamp_cpu_time", "index"), &RenderingDevice::get_captured_timestamp_cpu_time); + ClassDB::bind_method(D_METHOD("get_captured_timestamp_name", "index"), &RenderingDevice::get_captured_timestamp_name); + + ClassDB::bind_method(D_METHOD("limit_get", "limit"), &RenderingDevice::limit_get); + ClassDB::bind_method(D_METHOD("get_frame_delay"), &RenderingDevice::get_frame_delay); + ClassDB::bind_method(D_METHOD("submit"), &RenderingDevice::submit); + ClassDB::bind_method(D_METHOD("sync"), &RenderingDevice::sync); + + ClassDB::bind_method(D_METHOD("create_local_device"), &RenderingDevice::create_local_device); + + BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4_UNORM_PACK8); + BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4B4A4_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B4G4R4A4_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R5G6B5_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B5G6R5_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R5G5B5A1_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B5G5R5A1_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_A1R5G5B5_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_USCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SSCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_UINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SRGB_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_USCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SSCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_UINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_USCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SSCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_UINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B10G11R11_UFLOAT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_D16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_X8_D24_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_D32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_D16_UNORM_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_D24_UNORM_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_D32_SFLOAT_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGB_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGB_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGBA_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGBA_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC2_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC2_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC3_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC3_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC4_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC4_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC5_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC6H_UFLOAT_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC6H_SFLOAT_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC7_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC7_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11G11_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11G11_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_4x4_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_4x4_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x4_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x4_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x6_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x6_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x6_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x6_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x6_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x6_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x10_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x10_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x10_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x10_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x12_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x12_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8B8G8R8_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8G8_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6G10X6_UNORM_2PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4G12X4_UNORM_2PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16B16G16R16_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B16G16R16G16_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_3D); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBE); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D_ARRAY); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D_ARRAY); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBE_ARRAY); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_1); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_2); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_4); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_8); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_16); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_32); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_64); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_USAGE_SAMPLING_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_ATOMIC_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CPU_READ_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_UPDATE_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_FROM_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_TO_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT); + + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_IDENTITY); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ZERO); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ONE); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_R); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_G); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_B); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_A); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_SLICE_2D); + BIND_ENUM_CONSTANT(TEXTURE_SLICE_CUBEMAP); + BIND_ENUM_CONSTANT(TEXTURE_SLICE_3D); + + BIND_ENUM_CONSTANT(SAMPLER_FILTER_NEAREST); + BIND_ENUM_CONSTANT(SAMPLER_FILTER_LINEAR); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_REPEAT); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MIRRORED_REPEAT); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MAX); + + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_TRANSPARENT_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_OPAQUE_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_WHITE); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_OPAQUE_WHITE); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_MAX); + + BIND_ENUM_CONSTANT(VERTEX_FREQUENCY_VERTEX); + BIND_ENUM_CONSTANT(VERTEX_FREQUENCY_INSTANCE); + + BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT16); + BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT32); + + BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER); //for sampling only (sampler GLSL type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE); // for sampling only); but includes a texture); (samplerXX GLSL type)); first a sampler then a texture + BIND_ENUM_CONSTANT(UNIFORM_TYPE_TEXTURE); //only texture); (textureXX GLSL type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_IMAGE); // storage image (imageXX GLSL type)); for compute mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_TEXTURE_BUFFER); // buffer texture (or TBO); textureBuffer type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER); // buffer texture with a sampler(or TBO); samplerBuffer type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_IMAGE_BUFFER); //texel buffer); (imageBuffer type)); for compute mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_UNIFORM_BUFFER); //regular uniform buffer (or UBO). + BIND_ENUM_CONSTANT(UNIFORM_TYPE_STORAGE_BUFFER); //storage buffer ("buffer" qualifier) like UBO); but supports storage); for compute mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_INPUT_ATTACHMENT); //used for sub-pass read/write); for mobile mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_MAX); + + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_POINTS); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINES); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINES_WITH_ADJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINESTRIPS); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINESTRIPS_WITH_ADJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLES); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLES_WITH_ADJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_AJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TESSELATION_PATCH); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_MAX); + + BIND_ENUM_CONSTANT(POLYGON_CULL_DISABLED); + BIND_ENUM_CONSTANT(POLYGON_CULL_FRONT); + BIND_ENUM_CONSTANT(POLYGON_CULL_BACK); + + BIND_ENUM_CONSTANT(POLYGON_FRONT_FACE_CLOCKWISE); + BIND_ENUM_CONSTANT(POLYGON_FRONT_FACE_COUNTER_CLOCKWISE); + + BIND_ENUM_CONSTANT(STENCIL_OP_KEEP); + BIND_ENUM_CONSTANT(STENCIL_OP_ZERO); + BIND_ENUM_CONSTANT(STENCIL_OP_REPLACE); + BIND_ENUM_CONSTANT(STENCIL_OP_INCREMENT_AND_CLAMP); + BIND_ENUM_CONSTANT(STENCIL_OP_DECREMENT_AND_CLAMP); + BIND_ENUM_CONSTANT(STENCIL_OP_INVERT); + BIND_ENUM_CONSTANT(STENCIL_OP_INCREMENT_AND_WRAP); + BIND_ENUM_CONSTANT(STENCIL_OP_DECREMENT_AND_WRAP); + BIND_ENUM_CONSTANT(STENCIL_OP_MAX); //not an actual operator); just the amount of operators :D + + BIND_ENUM_CONSTANT(COMPARE_OP_NEVER); + BIND_ENUM_CONSTANT(COMPARE_OP_LESS); + BIND_ENUM_CONSTANT(COMPARE_OP_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_LESS_OR_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_GREATER); + BIND_ENUM_CONSTANT(COMPARE_OP_NOT_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_GREATER_OR_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_ALWAYS); + BIND_ENUM_CONSTANT(COMPARE_OP_MAX); + + BIND_ENUM_CONSTANT(LOGIC_OP_CLEAR); + BIND_ENUM_CONSTANT(LOGIC_OP_AND); + BIND_ENUM_CONSTANT(LOGIC_OP_AND_REVERSE); + BIND_ENUM_CONSTANT(LOGIC_OP_COPY); + BIND_ENUM_CONSTANT(LOGIC_OP_AND_INVERTED); + BIND_ENUM_CONSTANT(LOGIC_OP_NO_OP); + BIND_ENUM_CONSTANT(LOGIC_OP_XOR); + BIND_ENUM_CONSTANT(LOGIC_OP_OR); + BIND_ENUM_CONSTANT(LOGIC_OP_NOR); + BIND_ENUM_CONSTANT(LOGIC_OP_EQUIVALENT); + BIND_ENUM_CONSTANT(LOGIC_OP_INVERT); + BIND_ENUM_CONSTANT(LOGIC_OP_OR_REVERSE); + BIND_ENUM_CONSTANT(LOGIC_OP_COPY_INVERTED); + BIND_ENUM_CONSTANT(LOGIC_OP_OR_INVERTED); + BIND_ENUM_CONSTANT(LOGIC_OP_NAND); + BIND_ENUM_CONSTANT(LOGIC_OP_SET); + BIND_ENUM_CONSTANT(LOGIC_OP_MAX); //not an actual operator); just the amount of operators :D + + BIND_ENUM_CONSTANT(BLEND_FACTOR_ZERO); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_DST_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_DST_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_DST_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_DST_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_CONSTANT_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_CONSTANT_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_ALPHA_SATURATE); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC1_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC1_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC1_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_MAX); + + BIND_ENUM_CONSTANT(BLEND_OP_ADD); + BIND_ENUM_CONSTANT(BLEND_OP_SUBTRACT); + BIND_ENUM_CONSTANT(BLEND_OP_REVERSE_SUBTRACT); + BIND_ENUM_CONSTANT(BLEND_OP_MINIMUM); + BIND_ENUM_CONSTANT(BLEND_OP_MAXIMUM); + BIND_ENUM_CONSTANT(BLEND_OP_MAX); + + BIND_ENUM_CONSTANT(DYNAMIC_STATE_LINE_WIDTH); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BIAS); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_BLEND_CONSTANTS); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BOUNDS); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_COMPARE_MASK); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_WRITE_MASK); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE); + + BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params) + BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP); //start rendering); but keep attached color texture contents (depth will be cleared) + BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP); //start rendering); ignore what is there); just write above it + BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE); //continue rendering (framebuffer must have been left in "continue" state as final action previously) + BIND_ENUM_CONSTANT(INITIAL_ACTION_MAX); + + BIND_ENUM_CONSTANT(FINAL_ACTION_READ); //will no longer render to it); allows attached textures to be read again); but depth buffer contents will be dropped (Can't be read from) + BIND_ENUM_CONSTANT(FINAL_ACTION_DISCARD); // discard contents after rendering + BIND_ENUM_CONSTANT(FINAL_ACTION_CONTINUE); //will continue rendering later); attached textures can't be read until re-bound with "finish" + BIND_ENUM_CONSTANT(FINAL_ACTION_MAX); + + BIND_ENUM_CONSTANT(SHADER_STAGE_VERTEX); + BIND_ENUM_CONSTANT(SHADER_STAGE_FRAGMENT); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_CONTROL); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_EVALUATION); + BIND_ENUM_CONSTANT(SHADER_STAGE_COMPUTE); + BIND_ENUM_CONSTANT(SHADER_STAGE_MAX); + BIND_ENUM_CONSTANT(SHADER_STAGE_VERTEX_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_FRAGMENT_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_CONTROL_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_EVALUATION_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_COMPUTE_BIT); + + BIND_ENUM_CONSTANT(SHADER_LANGUAGE_GLSL); + BIND_ENUM_CONSTANT(SHADER_LANGUAGE_HLSL); + + BIND_ENUM_CONSTANT(LIMIT_MAX_BOUND_UNIFORM_SETS); + BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_DRAW_INDEXED_INDEX); + BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_HEIGHT); + BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_WIDTH); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_ARRAY_LAYERS); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_1D); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_2D); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_3D); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_CUBE); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_PUSH_CONSTANT_SIZE); + BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFER_SIZE); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_BINDINGS); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE); + BIND_ENUM_CONSTANT(LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z); + + BIND_CONSTANT(INVALID_ID); + BIND_CONSTANT(INVALID_FORMAT_ID); +} + RenderingDevice::RenderingDevice() { if (singleton == nullptr) { // there may be more rendering devices later singleton = this; diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 6c58b8fd57..6de83c9b5b 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -34,6 +34,19 @@ #include "core/object.h" #include "servers/display_server.h" +class RDTextureFormat; +class RDTextureView; +class RDAttachments; +class RDSamplerState; +class RDVertexDescriptions; +class RDShaderSource; +class RDShaderBytecode; +class RDUniforms; +class RDPipelineRasterizationState; +class RDPipelineMultisampleState; +class RDPipelineDepthStencilState; +class RDPipelineColorBlendState; + class RenderingDevice : public Object { GDCLASS(RenderingDevice, Object) public: @@ -65,10 +78,14 @@ private: static RenderingDevice *singleton; +protected: + static void _bind_methods(); + public: //base numeric ID for all types enum { - INVALID_ID = -1 + INVALID_ID = -1, + INVALID_FORMAT_ID = -1 }; /*****************/ @@ -595,7 +612,7 @@ public: UNIFORM_TYPE_IMAGE_BUFFER, //texel buffer, (imageBuffer type), for compute mostly UNIFORM_TYPE_UNIFORM_BUFFER, //regular uniform buffer (or UBO). UNIFORM_TYPE_STORAGE_BUFFER, //storage buffer ("buffer" qualifier) like UBO, but supports storage, for compute mostly - UNIFORM_TYPE_INPUT_ATTACHMENT, //used for sub-pass read/write, for compute mostly + UNIFORM_TYPE_INPUT_ATTACHMENT, //used for sub-pass read/write, for mobile mostly UNIFORM_TYPE_MAX }; @@ -796,8 +813,8 @@ public: } }; - StencilOperationState stencil_operation_front; - StencilOperationState stencil_operation_back; + StencilOperationState front_op; + StencilOperationState back_op; PipelineDepthStencilState() { enable_depth_test = false; @@ -884,8 +901,8 @@ public: DYNAMIC_STATE_STENCIL_REFERENCE = (1 << 6), }; - virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0; virtual bool render_pipeline_is_valid(RID p_pipeline) = 0; + virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0; /**************************/ /**** COMPUTE PIPELINE ****/ @@ -932,7 +949,7 @@ public: virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array) = 0; virtual void draw_list_bind_index_array(DrawListID p_list, RID p_index_array) = 0; virtual void draw_list_set_line_width(DrawListID p_list, float p_width) = 0; - virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size) = 0; + virtual void draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size) = 0; virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1, uint32_t p_procedural_vertices = 0) = 0; @@ -950,7 +967,7 @@ public: virtual ComputeListID compute_list_begin() = 0; virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline) = 0; virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index) = 0; - virtual void compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size) = 0; + virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) = 0; virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) = 0; virtual void compute_list_add_barrier(ComputeListID p_list) = 0; @@ -1031,8 +1048,60 @@ public: static RenderingDevice *get_singleton(); RenderingDevice(); + +protected: + //binders to script API + RID _texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const Array &p_data = Array()); + RID _texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture); + RID _texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D); + + FramebufferFormatID _framebuffer_format_create(const Array &p_attachments); + RID _framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check = INVALID_ID); + RID _sampler_create(const Ref<RDSamplerState> &p_state); + VertexFormatID _vertex_format_create(const Array &p_vertex_formats); + RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Array &p_src_buffers); + + Ref<RDShaderBytecode> _shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache = true); + RID _shader_create(const Ref<RDShaderBytecode> &p_bytecode); + + RID _uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set); + + Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false); + + RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags = 0); + + Vector<int64_t> _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()); + void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size); + void _compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size); }; +VARIANT_ENUM_CAST(RenderingDevice::ShaderStage) +VARIANT_ENUM_CAST(RenderingDevice::ShaderLanguage) +VARIANT_ENUM_CAST(RenderingDevice::CompareOperator) +VARIANT_ENUM_CAST(RenderingDevice::DataFormat) +VARIANT_ENUM_CAST(RenderingDevice::TextureType) +VARIANT_ENUM_CAST(RenderingDevice::TextureSamples) +VARIANT_ENUM_CAST(RenderingDevice::TextureUsageBits) +VARIANT_ENUM_CAST(RenderingDevice::TextureSwizzle) +VARIANT_ENUM_CAST(RenderingDevice::TextureSliceType) +VARIANT_ENUM_CAST(RenderingDevice::SamplerFilter) +VARIANT_ENUM_CAST(RenderingDevice::SamplerRepeatMode) +VARIANT_ENUM_CAST(RenderingDevice::SamplerBorderColor) +VARIANT_ENUM_CAST(RenderingDevice::VertexFrequency) +VARIANT_ENUM_CAST(RenderingDevice::IndexBufferFormat) +VARIANT_ENUM_CAST(RenderingDevice::UniformType) +VARIANT_ENUM_CAST(RenderingDevice::RenderPrimitive) +VARIANT_ENUM_CAST(RenderingDevice::PolygonCullMode) +VARIANT_ENUM_CAST(RenderingDevice::PolygonFrontFace) +VARIANT_ENUM_CAST(RenderingDevice::StencilOperation) +VARIANT_ENUM_CAST(RenderingDevice::LogicOperation) +VARIANT_ENUM_CAST(RenderingDevice::BlendFactor) +VARIANT_ENUM_CAST(RenderingDevice::BlendOperation) +VARIANT_ENUM_CAST(RenderingDevice::PipelineDynamicStateFlags) +VARIANT_ENUM_CAST(RenderingDevice::InitialAction) +VARIANT_ENUM_CAST(RenderingDevice::FinalAction) +VARIANT_ENUM_CAST(RenderingDevice::Limit) + typedef RenderingDevice RD; #endif // RENDERING_DEVICE_H diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp new file mode 100644 index 0000000000..111755eba3 --- /dev/null +++ b/servers/rendering/rendering_device_binds.cpp @@ -0,0 +1,167 @@ +#include "rendering_device_binds.h" + +Error RDShaderFile::parse_versions_from_text(const String &p_text, OpenIncludeFunction p_include_func, void *p_include_func_userdata) { + + Vector<String> lines = p_text.split("\n"); + + bool reading_versions = false; + bool stage_found[RD::SHADER_STAGE_MAX] = { false, false, false, false, false }; + RD::ShaderStage stage = RD::SHADER_STAGE_MAX; + static const char *stage_str[RD::SHADER_STAGE_MAX] = { + "vertex", + "fragment", + "tesselation_control", + "tesselation_evaluation", + "compute" + }; + String stage_code[RD::SHADER_STAGE_MAX]; + int stages_found = 0; + Map<StringName, String> version_texts; + + versions.clear(); + base_error = ""; + + for (int lidx = 0; lidx < lines.size(); lidx++) { + String line = lines[lidx]; + + { + String ls = line.strip_edges(); + if (ls.begins_with("[") && ls.ends_with("]")) { + String section = ls.substr(1, ls.length() - 2).strip_edges(); + if (section == "versions") { + if (stages_found) { + base_error = "Invalid shader file, [version] must be the first section found."; + break; + } + reading_versions = true; + } else { + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + if (section == stage_str[i]) { + if (stage_found[i]) { + base_error = "Invalid shader file, stage appears twice: " + section; + break; + } + + stage_found[i] = true; + stages_found++; + + stage = RD::ShaderStage(i); + reading_versions = false; + break; + } + } + + if (base_error != String()) { + break; + } + } + + continue; + } + } + + if (reading_versions) { + String l = line.strip_edges(); + if (l != "") { + int eqpos = l.find("="); + if (eqpos == -1) { + base_error = "Version syntax is version=\"<defines with C escaping>\"."; + break; + } + String version = l.get_slice("=", 0).strip_edges(); + if (!version.is_valid_identifier()) { + base_error = "Version names must be valid identifiers, found '" + version + "' instead."; + break; + } + String define = l.get_slice("=", 1).strip_edges(); + if (!define.begins_with("\"") || !define.ends_with("\"")) { + base_error = "Version text must be quoted using \"\", instead found '" + define + "'."; + break; + } + define = "\n" + define.substr(1, define.length() - 2).c_unescape() + "\n"; //add newline before and after jsut in case + + version_texts[version] = define; + } + } else { + if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") { + base_error = "Text was found that does not belong to a valid section: " + line; + break; + } + + if (stage != RD::SHADER_STAGE_MAX) { + if (line.strip_edges().begins_with("#include")) { + if (p_include_func) { + //process include + String include = line.replace("#include", "").strip_edges(); + if (!include.begins_with("\"") || !include.ends_with("\"")) { + base_error = "Malformed #include syntax, expected #include \"<path>\", found instad: " + include; + break; + } + include = include.substr(1, include.length() - 2).strip_edges(); + String include_text = p_include_func(include, p_include_func_userdata); + if (include_text != String()) { + stage_code[stage] += "\n" + include_text + "\n"; + } else { + base_error = "#include failed for file '" + include + "'"; + } + } else { + base_error = "#include used, but no include function provided."; + } + } else { + + stage_code[stage] += line + "\n"; + } + } + } + } + + Ref<RDShaderFile> shader_file; + shader_file.instance(); + + if (base_error == "") { + + if (stage_found[RD::SHADER_STAGE_COMPUTE] && stages_found > 1) { + ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "When writing compute shaders, [compute] mustbe the only stage present."); + } + + if (version_texts.empty()) { + version_texts[""] = ""; //make sure a default version exists + } + + bool errors_found = false; + + /* STEP 2, Compile the versions, add to shader file */ + + for (Map<StringName, String>::Element *E = version_texts.front(); E; E = E->next()) { + + Ref<RDShaderBytecode> bytecode; + bytecode.instance(); + + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + String code = stage_code[i]; + if (code == String()) { + continue; + } + code = code.replace("VERSION_DEFINES", E->get()); + String error; + Vector<uint8_t> spirv = RenderingDevice::get_singleton()->shader_compile_from_source(RD::ShaderStage(i), code, RD::SHADER_LANGUAGE_GLSL, &error, false); + bytecode->set_stage_bytecode(RD::ShaderStage(i), spirv); + if (error != "") { + error += String() + "\n\nStage '" + stage_str[i] + "' source code: \n\n"; + Vector<String> sclines = code.split("\n"); + for (int j = 0; j < sclines.size(); j++) { + error += itos(j + 1) + "\t\t" + sclines[j] + "\n"; + } + errors_found = true; + } + bytecode->set_stage_compile_error(RD::ShaderStage(i), error); + } + + set_bytecode(bytecode, E->key()); + } + + return errors_found ? ERR_PARSE_ERROR : OK; + } else { + return ERR_PARSE_ERROR; + } +} diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h new file mode 100644 index 0000000000..b3d943be79 --- /dev/null +++ b/servers/rendering/rendering_device_binds.h @@ -0,0 +1,628 @@ +#ifndef RENDERING_DEVICE_BINDS_H +#define RENDERING_DEVICE_BINDS_H + +#include "servers/rendering/rendering_device.h" + +#define RD_SETGET(m_type, m_member) \ + void set_##m_member(m_type p_##m_member) { base.m_member = p_##m_member; } \ + m_type get_##m_member() const { return base.m_member; } + +#define RD_BIND(m_variant_type, m_class, m_member) \ + ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_member); \ + ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_member)), &m_class::get_##m_member); \ + ADD_PROPERTY(PropertyInfo(m_variant_type, #m_member), "set_" _MKSTR(m_member), "get_" _MKSTR(m_member)) + +#define RD_SETGET_SUB(m_type, m_sub, m_member) \ + void set_##m_sub##_##m_member(m_type p_##m_member) { base.m_sub.m_member = p_##m_member; } \ + m_type get_##m_sub##_##m_member() const { return base.m_sub.m_member; } + +#define RD_BIND_SUB(m_variant_type, m_class, m_sub, m_member) \ + ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_sub##_##m_member); \ + ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_sub) "_" _MKSTR(m_member)), &m_class::get_##m_sub##_##m_member); \ + ADD_PROPERTY(PropertyInfo(m_variant_type, _MKSTR(m_sub) "_" _MKSTR(m_member)), "set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "get_" _MKSTR(m_sub) "_" _MKSTR(m_member)) + +class RDTextureFormat : public Reference { + GDCLASS(RDTextureFormat, Reference) + friend class RenderingDevice; + + RD::TextureFormat base; + +public: + RD_SETGET(RD::DataFormat, format) + RD_SETGET(uint32_t, width) + RD_SETGET(uint32_t, height) + RD_SETGET(uint32_t, depth) + RD_SETGET(uint32_t, array_layers) + RD_SETGET(uint32_t, mipmaps) + RD_SETGET(RD::TextureType, type) + RD_SETGET(RD::TextureSamples, samples) + RD_SETGET(uint32_t, usage_bits) + + void add_shareable_format(RD::DataFormat p_format) { base.shareable_formats.push_back(p_format); } + void remove_shareable_format(RD::DataFormat p_format) { base.shareable_formats.erase(p_format); } + +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDTextureFormat, format); + RD_BIND(Variant::INT, RDTextureFormat, width); + RD_BIND(Variant::INT, RDTextureFormat, height); + RD_BIND(Variant::INT, RDTextureFormat, depth); + RD_BIND(Variant::INT, RDTextureFormat, array_layers); + RD_BIND(Variant::INT, RDTextureFormat, mipmaps); + RD_BIND(Variant::INT, RDTextureFormat, type); + RD_BIND(Variant::INT, RDTextureFormat, samples); + RD_BIND(Variant::INT, RDTextureFormat, usage_bits); + ClassDB::bind_method(D_METHOD("add_shareable_format", "format"), &RDTextureFormat::add_shareable_format); + ClassDB::bind_method(D_METHOD("remove_shareable_format", "format"), &RDTextureFormat::remove_shareable_format); + } +}; + +class RDTextureView : public Reference { + GDCLASS(RDTextureView, Reference) + + friend class RenderingDevice; + + RD::TextureView base; + +public: + RD_SETGET(RD::DataFormat, format_override) + RD_SETGET(RD::TextureSwizzle, swizzle_r) + RD_SETGET(RD::TextureSwizzle, swizzle_g) + RD_SETGET(RD::TextureSwizzle, swizzle_b) + RD_SETGET(RD::TextureSwizzle, swizzle_a) +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDTextureView, format_override); + RD_BIND(Variant::INT, RDTextureView, swizzle_r); + RD_BIND(Variant::INT, RDTextureView, swizzle_g); + RD_BIND(Variant::INT, RDTextureView, swizzle_b); + RD_BIND(Variant::INT, RDTextureView, swizzle_a); + } +}; + +class RDAttachmentFormat : public Reference { + GDCLASS(RDAttachmentFormat, Reference) + friend class RenderingDevice; + + RD::AttachmentFormat base; + +public: + RD_SETGET(RD::DataFormat, format) + RD_SETGET(RD::TextureSamples, samples) + RD_SETGET(uint32_t, usage_flags) +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDAttachmentFormat, format); + RD_BIND(Variant::INT, RDAttachmentFormat, samples); + RD_BIND(Variant::INT, RDAttachmentFormat, usage_flags); + } +}; + +class RDSamplerState : public Reference { + GDCLASS(RDSamplerState, Reference) + friend class RenderingDevice; + + RD::SamplerState base; + +public: + RD_SETGET(RD::SamplerFilter, mag_filter) + RD_SETGET(RD::SamplerFilter, min_filter) + RD_SETGET(RD::SamplerFilter, mip_filter) + RD_SETGET(RD::SamplerRepeatMode, repeat_u) + RD_SETGET(RD::SamplerRepeatMode, repeat_v) + RD_SETGET(RD::SamplerRepeatMode, repeat_w) + RD_SETGET(float, lod_bias) + RD_SETGET(bool, use_anisotropy) + RD_SETGET(float, anisotropy_max) + RD_SETGET(bool, enable_compare) + RD_SETGET(RD::CompareOperator, compare_op) + RD_SETGET(float, min_lod) + RD_SETGET(float, max_lod) + RD_SETGET(RD::SamplerBorderColor, border_color) + RD_SETGET(bool, unnormalized_uvw) + +protected: + static void _bind_methods() { + + RD_BIND(Variant::INT, RDSamplerState, mag_filter); + RD_BIND(Variant::INT, RDSamplerState, min_filter); + RD_BIND(Variant::INT, RDSamplerState, mip_filter); + RD_BIND(Variant::INT, RDSamplerState, repeat_u); + RD_BIND(Variant::INT, RDSamplerState, repeat_v); + RD_BIND(Variant::INT, RDSamplerState, repeat_w); + RD_BIND(Variant::FLOAT, RDSamplerState, lod_bias); + RD_BIND(Variant::BOOL, RDSamplerState, use_anisotropy); + RD_BIND(Variant::FLOAT, RDSamplerState, anisotropy_max); + RD_BIND(Variant::BOOL, RDSamplerState, enable_compare); + RD_BIND(Variant::INT, RDSamplerState, compare_op); + RD_BIND(Variant::FLOAT, RDSamplerState, min_lod); + RD_BIND(Variant::FLOAT, RDSamplerState, max_lod); + RD_BIND(Variant::INT, RDSamplerState, border_color); + RD_BIND(Variant::BOOL, RDSamplerState, unnormalized_uvw); + } +}; + +class RDVertexDescription : public Reference { + GDCLASS(RDVertexDescription, Reference) + friend class RenderingDevice; + RD::VertexDescription base; + +public: + RD_SETGET(uint32_t, location) + RD_SETGET(uint32_t, offset) + RD_SETGET(RD::DataFormat, format) + RD_SETGET(uint32_t, stride) + RD_SETGET(RD::VertexFrequency, frequency) + +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDVertexDescription, location); + RD_BIND(Variant::INT, RDVertexDescription, offset); + RD_BIND(Variant::INT, RDVertexDescription, format); + RD_BIND(Variant::INT, RDVertexDescription, stride); + RD_BIND(Variant::INT, RDVertexDescription, frequency); + } +}; +class RDShaderSource : public Reference { + GDCLASS(RDShaderSource, Reference) + String source[RD::SHADER_STAGE_MAX]; + RD::ShaderLanguage language = RD::SHADER_LANGUAGE_GLSL; + +public: + void set_stage_source(RD::ShaderStage p_stage, const String &p_source) { + ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); + source[p_stage] = p_source; + } + + String get_stage_source(RD::ShaderStage p_stage) const { + ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String()); + return source[p_stage]; + } + + void set_language(RD::ShaderLanguage p_language) { + language = p_language; + } + + RD::ShaderLanguage get_language() const { + return language; + } + +protected: + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_stage_source", "stage", "source"), &RDShaderSource::set_stage_source); + ClassDB::bind_method(D_METHOD("get_stage_source", "stage"), &RDShaderSource::get_stage_source); + + ClassDB::bind_method(D_METHOD("set_language", "language"), &RDShaderSource::set_language); + ClassDB::bind_method(D_METHOD("get_language"), &RDShaderSource::get_language); + + ADD_GROUP("Source", "source_"); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_vertex"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_VERTEX); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_fragment"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_FRAGMENT); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_control"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_CONTROL); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_evaluation"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_EVALUATION); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_compute"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_COMPUTE); + ADD_GROUP("Syntax", "source_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "language", PROPERTY_HINT_RANGE, "GLSL,HLSL"), "set_language", "get_language"); + } +}; + +class RDShaderBytecode : public Resource { + GDCLASS(RDShaderBytecode, Resource) + + Vector<uint8_t> bytecode[RD::SHADER_STAGE_MAX]; + String compile_error[RD::SHADER_STAGE_MAX]; + +public: + void set_stage_bytecode(RD::ShaderStage p_stage, const Vector<uint8_t> &p_bytecode) { + ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); + bytecode[p_stage] = p_bytecode; + } + + Vector<uint8_t> get_stage_bytecode(RD::ShaderStage p_stage) const { + ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, Vector<uint8_t>()); + return bytecode[p_stage]; + } + + void set_stage_compile_error(RD::ShaderStage p_stage, const String &p_compile_error) { + ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); + compile_error[p_stage] = p_compile_error; + } + + String get_stage_compile_error(RD::ShaderStage p_stage) const { + ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String()); + return compile_error[p_stage]; + } + +protected: + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_stage_bytecode", "stage", "bytecode"), &RDShaderBytecode::set_stage_bytecode); + ClassDB::bind_method(D_METHOD("get_stage_bytecode", "stage"), &RDShaderBytecode::get_stage_bytecode); + + ClassDB::bind_method(D_METHOD("set_stage_compile_error", "stage", "compile_error"), &RDShaderBytecode::set_stage_compile_error); + ClassDB::bind_method(D_METHOD("get_stage_compile_error", "stage"), &RDShaderBytecode::get_stage_compile_error); + + ADD_GROUP("Bytecode", "bytecode_"); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_vertex"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_VERTEX); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_fragment"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_FRAGMENT); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_control"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_CONTROL); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_evaluation"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_EVALUATION); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_compute"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_COMPUTE); + ADD_GROUP("Compile Error", "compile_error_"); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_vertex"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_VERTEX); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_fragment"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_FRAGMENT); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_control"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_CONTROL); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_evaluation"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_EVALUATION); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_compute"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_COMPUTE); + } +}; + +class RDShaderFile : public Resource { + GDCLASS(RDShaderFile, Resource) + + Map<StringName, Ref<RDShaderBytecode>> versions; + String base_error; + +public: + void set_bytecode(const Ref<RDShaderBytecode> &p_bytecode, const StringName &p_version = StringName()) { + ERR_FAIL_COND(p_bytecode.is_null()); + versions[p_version] = p_bytecode; + emit_changed(); + } + + Ref<RDShaderBytecode> get_bytecode(const StringName &p_version = StringName()) const { + ERR_FAIL_COND_V(!versions.has(p_version), Ref<RDShaderBytecode>()); + return versions[p_version]; + } + + Vector<StringName> get_version_list() const { + Vector<StringName> vnames; + for (Map<StringName, Ref<RDShaderBytecode>>::Element *E = versions.front(); E; E = E->next()) { + vnames.push_back(E->key()); + } + vnames.sort_custom<StringName::AlphCompare>(); + return vnames; + } + + void set_base_error(const String &p_error) { + base_error = p_error; + emit_changed(); + } + + String get_base_error() const { + return base_error; + } + + typedef String (*OpenIncludeFunction)(const String &, void *userdata); + Error parse_versions_from_text(const String &p_text, OpenIncludeFunction p_include_func = nullptr, void *p_include_func_userdata = nullptr); + +protected: + Dictionary _get_versions() const { + Vector<StringName> vnames = get_version_list(); + Dictionary ret; + for (int i = 0; i < vnames.size(); i++) { + ret[vnames[i]] = versions[vnames[i]]; + } + return ret; + } + void _set_versions(const Dictionary &p_versions) { + versions.clear(); + List<Variant> keys; + p_versions.get_key_list(&keys); + for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + StringName name = E->get(); + Ref<RDShaderBytecode> bc = p_versions[E->get()]; + ERR_CONTINUE(bc.is_null()); + versions[name] = bc; + } + + emit_changed(); + } + + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_bytecode", "bytecode", "version"), &RDShaderFile::set_bytecode, DEFVAL(StringName())); + ClassDB::bind_method(D_METHOD("get_bytecode", "version"), &RDShaderFile::get_bytecode, DEFVAL(StringName())); + ClassDB::bind_method(D_METHOD("get_version_list"), &RDShaderFile::get_version_list); + + ClassDB::bind_method(D_METHOD("set_base_error", "error"), &RDShaderFile::set_base_error); + ClassDB::bind_method(D_METHOD("get_base_error"), &RDShaderFile::get_base_error); + + ClassDB::bind_method(D_METHOD("_set_versions", "versions"), &RDShaderFile::_set_versions); + ClassDB::bind_method(D_METHOD("_get_versions"), &RDShaderFile::_get_versions); + + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_versions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_versions", "_get_versions"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_error"), "set_base_error", "get_base_error"); + } +}; + +class RDUniform : public Reference { + GDCLASS(RDUniform, Reference) + friend class RenderingDevice; + RD::Uniform base; + +public: + RD_SETGET(RD::UniformType, type) + RD_SETGET(int32_t, binding) + + void add_id(const RID &p_id) { base.ids.push_back(p_id); } + void clear_ids() { base.ids.clear(); } + Array get_ids() const { + Array ids; + for (int i = 0; i < base.ids.size(); i++) { + ids.push_back(base.ids[i]); + } + return ids; + } + +protected: + void _set_ids(const Array &p_ids) { + base.ids.clear(); + for (int i = 0; i < p_ids.size(); i++) { + RID id = p_ids[i]; + ERR_FAIL_COND(id.is_null()); + base.ids.push_back(id); + } + } + static void _bind_methods() { + RD_BIND(Variant::INT, RDUniform, type); + RD_BIND(Variant::INT, RDUniform, binding); + ClassDB::bind_method(D_METHOD("add_id", "id"), &RDUniform::add_id); + ClassDB::bind_method(D_METHOD("clear_ids"), &RDUniform::clear_ids); + ClassDB::bind_method(D_METHOD("_set_ids", "ids"), &RDUniform::_set_ids); + ClassDB::bind_method(D_METHOD("get_ids"), &RDUniform::get_ids); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_ids", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_ids", "get_ids"); + } +}; +class RDPipelineRasterizationState : public Reference { + GDCLASS(RDPipelineRasterizationState, Reference) + friend class RenderingDevice; + + RD::PipelineRasterizationState base; + +public: + RD_SETGET(bool, enable_depth_clamp) + RD_SETGET(bool, discard_primitives) + RD_SETGET(bool, wireframe) + RD_SETGET(RD::PolygonCullMode, cull_mode) + RD_SETGET(RD::PolygonFrontFace, front_face) + RD_SETGET(bool, depth_bias_enable) + RD_SETGET(float, depth_bias_constant_factor) + RD_SETGET(float, depth_bias_clamp) + RD_SETGET(float, depth_bias_slope_factor) + RD_SETGET(float, line_width) + RD_SETGET(uint32_t, patch_control_points) + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, enable_depth_clamp); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, discard_primitives); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, wireframe); + RD_BIND(Variant::INT, RDPipelineRasterizationState, cull_mode); + RD_BIND(Variant::INT, RDPipelineRasterizationState, front_face); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, depth_bias_enable); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_constant_factor); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_clamp); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_slope_factor); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, line_width); + RD_BIND(Variant::INT, RDPipelineRasterizationState, patch_control_points); + } +}; + +class RDPipelineMultisampleState : public Reference { + GDCLASS(RDPipelineMultisampleState, Reference) + friend class RenderingDevice; + + RD::PipelineMultisampleState base; + +public: + RD_SETGET(RD::TextureSamples, sample_count) + RD_SETGET(bool, enable_sample_shading) + RD_SETGET(float, min_sample_shading) + RD_SETGET(bool, enable_alpha_to_coverage) + RD_SETGET(bool, enable_alpha_to_one) + + void add_sample_mask(uint32_t p_sample_mask) { base.sample_mask.push_back(p_sample_mask); } + void clear_sample_masks() { base.sample_mask.clear(); } + Vector<int64_t> get_sample_masks() const { + Vector<int64_t> sample_masks; + for (int i = 0; i < base.sample_mask.size(); i++) { + sample_masks.push_back(base.sample_mask[i]); + } + return sample_masks; + } + +protected: + void _set_sample_masks(const Vector<int64_t> &p_masks) { + base.sample_mask.clear(); + for (int i = 0; i < p_masks.size(); i++) { + int64_t mask = p_masks[i]; + base.sample_mask.push_back(mask); + } + } + static void _bind_methods() { + RD_BIND(Variant::INT, RDPipelineMultisampleState, sample_count); + RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_sample_shading); + RD_BIND(Variant::FLOAT, RDPipelineMultisampleState, min_sample_shading); + RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_coverage); + RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_one); + + ClassDB::bind_method(D_METHOD("add_sample_mask", "mask"), &RDPipelineMultisampleState::add_sample_mask); + ClassDB::bind_method(D_METHOD("clear_sample_masks"), &RDPipelineMultisampleState::clear_sample_masks); + ClassDB::bind_method(D_METHOD("_set_sample_masks", "sample_masks"), &RDPipelineMultisampleState::_set_sample_masks); + ClassDB::bind_method(D_METHOD("get_sample_masks"), &RDPipelineMultisampleState::get_sample_masks); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT64_ARRAY, "_sample_masks", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_sample_masks", "get_sample_masks"); + } +}; + +class RDPipelineDepthStencilState : public Reference { + GDCLASS(RDPipelineDepthStencilState, Reference) + friend class RenderingDevice; + + RD::PipelineDepthStencilState base; + +public: + RD_SETGET(bool, enable_depth_test) + RD_SETGET(bool, enable_depth_write) + RD_SETGET(RD::CompareOperator, depth_compare_operator) + RD_SETGET(bool, enable_depth_range) + RD_SETGET(float, depth_range_min) + RD_SETGET(float, depth_range_max) + RD_SETGET(bool, enable_stencil) + + RD_SETGET_SUB(RD::StencilOperation, front_op, fail) + RD_SETGET_SUB(RD::StencilOperation, front_op, pass) + RD_SETGET_SUB(RD::StencilOperation, front_op, depth_fail) + RD_SETGET_SUB(RD::CompareOperator, front_op, compare) + RD_SETGET_SUB(uint32_t, front_op, compare_mask) + RD_SETGET_SUB(uint32_t, front_op, write_mask) + RD_SETGET_SUB(uint32_t, front_op, reference) + + RD_SETGET_SUB(RD::StencilOperation, back_op, fail) + RD_SETGET_SUB(RD::StencilOperation, back_op, pass) + RD_SETGET_SUB(RD::StencilOperation, back_op, depth_fail) + RD_SETGET_SUB(RD::CompareOperator, back_op, compare) + RD_SETGET_SUB(uint32_t, back_op, compare_mask) + RD_SETGET_SUB(uint32_t, back_op, write_mask) + RD_SETGET_SUB(uint32_t, back_op, reference) + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_test); + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_write); + RD_BIND(Variant::INT, RDPipelineDepthStencilState, depth_compare_operator); + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_range); + RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_min); + RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_max); + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_stencil); + + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, pass); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, depth_fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, write_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, reference); + + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, pass); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, depth_fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, write_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, reference); + } +}; + +class RDPipelineColorBlendStateAttachment : public Reference { + GDCLASS(RDPipelineColorBlendStateAttachment, Reference) + RD::PipelineColorBlendState::Attachment base; + +public: + RD_SETGET(bool, enable_blend) + RD_SETGET(RD::BlendFactor, src_color_blend_factor) + RD_SETGET(RD::BlendFactor, dst_color_blend_factor) + RD_SETGET(RD::BlendOperation, color_blend_op) + RD_SETGET(RD::BlendFactor, src_alpha_blend_factor) + RD_SETGET(RD::BlendFactor, dst_alpha_blend_factor) + RD_SETGET(RD::BlendOperation, alpha_blend_op) + RD_SETGET(bool, write_r) + RD_SETGET(bool, write_g) + RD_SETGET(bool, write_b) + RD_SETGET(bool, write_a) + + void set_as_disabled() { + base = RD::PipelineColorBlendState::Attachment(); + } + + void set_as_mix() { + + base = RD::PipelineColorBlendState::Attachment(); + base.enable_blend = true; + base.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA; + base.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + base.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA; + base.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + } + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, enable_blend); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_color_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_color_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, color_blend_op); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_alpha_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_alpha_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, alpha_blend_op); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_r); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_g); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_b); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_a); + } +}; + +class RDPipelineColorBlendState : public Reference { + GDCLASS(RDPipelineColorBlendState, Reference) + friend class RenderingDevice; + RD::PipelineColorBlendState base; + + Vector<Ref<RDPipelineColorBlendStateAttachment>> attachments; + +public: + RD_SETGET(bool, enable_logic_op) + RD_SETGET(RD::LogicOperation, logic_op) + RD_SETGET(Color, blend_constant) + + void add_attachment(const Ref<RDPipelineColorBlendStateAttachment> &p_attachment) { + attachments.push_back(p_attachment); + } + + void add_no_blend_attachment() { + Ref<RDPipelineColorBlendStateAttachment> attachment; + attachment.instance(); + attachment->set_as_disabled(); + add_attachment(attachment); + } + + void add_blend_mix_attachment() { + Ref<RDPipelineColorBlendStateAttachment> attachment; + attachment.instance(); + attachment->set_as_mix(); + add_attachment(attachment); + } + + void clear_attachments() { + attachments.clear(); + } + + Array get_attachments() const { + Array ret; + for (int i = 0; i < attachments.size(); i++) { + ret.push_back(attachments[i]); + } + return ret; + } + void _set_attachments(const Array &p_attachments) { + attachments.clear(); + for (int i = 0; i < p_attachments.size(); i++) { + Ref<RDPipelineColorBlendStateAttachment> attachment = p_attachments[i]; + ERR_FAIL_COND(!attachment.is_valid()); + attachments.push_back(attachment); + } + } + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineColorBlendState, enable_logic_op); + RD_BIND(Variant::INT, RDPipelineColorBlendState, logic_op); + RD_BIND(Variant::COLOR, RDPipelineColorBlendState, blend_constant); + + ClassDB::bind_method(D_METHOD("add_attachment", "atachment"), &RDPipelineColorBlendState::add_attachment); + ClassDB::bind_method(D_METHOD("add_no_blend_attachment"), &RDPipelineColorBlendState::add_no_blend_attachment); + ClassDB::bind_method(D_METHOD("add_blend_mix_attachment"), &RDPipelineColorBlendState::add_blend_mix_attachment); + ClassDB::bind_method(D_METHOD("clear_attachments"), &RDPipelineColorBlendState::clear_attachments); + ClassDB::bind_method(D_METHOD("_set_attachments", "attachments"), &RDPipelineColorBlendState::_set_attachments); + ClassDB::bind_method(D_METHOD("get_attachments"), &RDPipelineColorBlendState::get_attachments); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_attachments", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_attachments", "get_attachments"); + } +}; + +#endif // RENDERING_DEVICE_BINDS_H |