diff options
author | Juan Linietsky <reduzio@gmail.com> | 2020-04-19 23:19:21 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2020-04-20 21:21:58 -0300 |
commit | ae09b55a19c956cf6dafd446c71178f6bbffd91d (patch) | |
tree | 94c9b2cc850eb2fb0608a52c05fb389e1cd35234 /servers/rendering | |
parent | 6d8e1aea892dc80e2fb01729b9a532a447f0760d (diff) |
Exposed RenderingDevice to script API
Also added an easier way to load native GLSL shaders.
Extras:
Had to fix no-cache for subresources in resource loader, it was not properly working, making shaders not properly reload.
Note:
The precommit hooks are broken because they don't seem to support enums from one class being used in another.
Feel free to fix this after merging this PR.
Diffstat (limited to 'servers/rendering')
-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 |
4 files changed, 1608 insertions, 7 deletions
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 |