1/**************************************************************************/
2/* rendering_device_binds.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef RENDERING_DEVICE_BINDS_H
32#define RENDERING_DEVICE_BINDS_H
33
34#include "servers/rendering/rendering_device.h"
35
36#define RD_SETGET(m_type, m_member) \
37 void set_##m_member(m_type p_##m_member) { base.m_member = p_##m_member; } \
38 m_type get_##m_member() const { return base.m_member; }
39
40#define RD_BIND(m_variant_type, m_class, m_member) \
41 ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_member); \
42 ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_member)), &m_class::get_##m_member); \
43 ADD_PROPERTY(PropertyInfo(m_variant_type, #m_member), "set_" _MKSTR(m_member), "get_" _MKSTR(m_member))
44
45#define RD_SETGET_SUB(m_type, m_sub, m_member) \
46 void set_##m_sub##_##m_member(m_type p_##m_member) { base.m_sub.m_member = p_##m_member; } \
47 m_type get_##m_sub##_##m_member() const { return base.m_sub.m_member; }
48
49#define RD_BIND_SUB(m_variant_type, m_class, m_sub, m_member) \
50 ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_sub##_##m_member); \
51 ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_sub) "_" _MKSTR(m_member)), &m_class::get_##m_sub##_##m_member); \
52 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))
53
54class RDTextureFormat : public RefCounted {
55 GDCLASS(RDTextureFormat, RefCounted)
56
57 friend class RenderingDevice;
58 friend class RenderSceneBuffersRD;
59
60 RD::TextureFormat base;
61
62public:
63 RD_SETGET(RD::DataFormat, format)
64 RD_SETGET(uint32_t, width)
65 RD_SETGET(uint32_t, height)
66 RD_SETGET(uint32_t, depth)
67 RD_SETGET(uint32_t, array_layers)
68 RD_SETGET(uint32_t, mipmaps)
69 RD_SETGET(RD::TextureType, texture_type)
70 RD_SETGET(RD::TextureSamples, samples)
71 RD_SETGET(BitField<RenderingDevice::TextureUsageBits>, usage_bits)
72
73 void add_shareable_format(RD::DataFormat p_format) { base.shareable_formats.push_back(p_format); }
74 void remove_shareable_format(RD::DataFormat p_format) { base.shareable_formats.erase(p_format); }
75
76protected:
77 static void _bind_methods() {
78 RD_BIND(Variant::INT, RDTextureFormat, format);
79 RD_BIND(Variant::INT, RDTextureFormat, width);
80 RD_BIND(Variant::INT, RDTextureFormat, height);
81 RD_BIND(Variant::INT, RDTextureFormat, depth);
82 RD_BIND(Variant::INT, RDTextureFormat, array_layers);
83 RD_BIND(Variant::INT, RDTextureFormat, mipmaps);
84 RD_BIND(Variant::INT, RDTextureFormat, texture_type);
85 RD_BIND(Variant::INT, RDTextureFormat, samples);
86 RD_BIND(Variant::INT, RDTextureFormat, usage_bits);
87 ClassDB::bind_method(D_METHOD("add_shareable_format", "format"), &RDTextureFormat::add_shareable_format);
88 ClassDB::bind_method(D_METHOD("remove_shareable_format", "format"), &RDTextureFormat::remove_shareable_format);
89 }
90};
91
92class RDTextureView : public RefCounted {
93 GDCLASS(RDTextureView, RefCounted)
94
95 friend class RenderingDevice;
96 friend class RenderSceneBuffersRD;
97
98 RD::TextureView base;
99
100public:
101 RD_SETGET(RD::DataFormat, format_override)
102 RD_SETGET(RD::TextureSwizzle, swizzle_r)
103 RD_SETGET(RD::TextureSwizzle, swizzle_g)
104 RD_SETGET(RD::TextureSwizzle, swizzle_b)
105 RD_SETGET(RD::TextureSwizzle, swizzle_a)
106protected:
107 static void _bind_methods() {
108 RD_BIND(Variant::INT, RDTextureView, format_override);
109 RD_BIND(Variant::INT, RDTextureView, swizzle_r);
110 RD_BIND(Variant::INT, RDTextureView, swizzle_g);
111 RD_BIND(Variant::INT, RDTextureView, swizzle_b);
112 RD_BIND(Variant::INT, RDTextureView, swizzle_a);
113 }
114};
115
116class RDAttachmentFormat : public RefCounted {
117 GDCLASS(RDAttachmentFormat, RefCounted)
118 friend class RenderingDevice;
119
120 RD::AttachmentFormat base;
121
122public:
123 RD_SETGET(RD::DataFormat, format)
124 RD_SETGET(RD::TextureSamples, samples)
125 RD_SETGET(uint32_t, usage_flags)
126protected:
127 static void _bind_methods() {
128 RD_BIND(Variant::INT, RDAttachmentFormat, format);
129 RD_BIND(Variant::INT, RDAttachmentFormat, samples);
130 RD_BIND(Variant::INT, RDAttachmentFormat, usage_flags);
131 }
132};
133
134class RDFramebufferPass : public RefCounted {
135 GDCLASS(RDFramebufferPass, RefCounted)
136 friend class RenderingDevice;
137
138 RD::FramebufferPass base;
139
140public:
141 RD_SETGET(PackedInt32Array, color_attachments)
142 RD_SETGET(PackedInt32Array, input_attachments)
143 RD_SETGET(PackedInt32Array, resolve_attachments)
144 RD_SETGET(PackedInt32Array, preserve_attachments)
145 RD_SETGET(int32_t, depth_attachment)
146protected:
147 enum {
148 ATTACHMENT_UNUSED = -1
149 };
150
151 static void _bind_methods() {
152 RD_BIND(Variant::PACKED_INT32_ARRAY, RDFramebufferPass, color_attachments);
153 RD_BIND(Variant::PACKED_INT32_ARRAY, RDFramebufferPass, input_attachments);
154 RD_BIND(Variant::PACKED_INT32_ARRAY, RDFramebufferPass, resolve_attachments);
155 RD_BIND(Variant::PACKED_INT32_ARRAY, RDFramebufferPass, preserve_attachments);
156 RD_BIND(Variant::INT, RDFramebufferPass, depth_attachment);
157
158 BIND_CONSTANT(ATTACHMENT_UNUSED);
159 }
160};
161
162class RDSamplerState : public RefCounted {
163 GDCLASS(RDSamplerState, RefCounted)
164 friend class RenderingDevice;
165
166 RD::SamplerState base;
167
168public:
169 RD_SETGET(RD::SamplerFilter, mag_filter)
170 RD_SETGET(RD::SamplerFilter, min_filter)
171 RD_SETGET(RD::SamplerFilter, mip_filter)
172 RD_SETGET(RD::SamplerRepeatMode, repeat_u)
173 RD_SETGET(RD::SamplerRepeatMode, repeat_v)
174 RD_SETGET(RD::SamplerRepeatMode, repeat_w)
175 RD_SETGET(float, lod_bias)
176 RD_SETGET(bool, use_anisotropy)
177 RD_SETGET(float, anisotropy_max)
178 RD_SETGET(bool, enable_compare)
179 RD_SETGET(RD::CompareOperator, compare_op)
180 RD_SETGET(float, min_lod)
181 RD_SETGET(float, max_lod)
182 RD_SETGET(RD::SamplerBorderColor, border_color)
183 RD_SETGET(bool, unnormalized_uvw)
184
185protected:
186 static void _bind_methods() {
187 RD_BIND(Variant::INT, RDSamplerState, mag_filter);
188 RD_BIND(Variant::INT, RDSamplerState, min_filter);
189 RD_BIND(Variant::INT, RDSamplerState, mip_filter);
190 RD_BIND(Variant::INT, RDSamplerState, repeat_u);
191 RD_BIND(Variant::INT, RDSamplerState, repeat_v);
192 RD_BIND(Variant::INT, RDSamplerState, repeat_w);
193 RD_BIND(Variant::FLOAT, RDSamplerState, lod_bias);
194 RD_BIND(Variant::BOOL, RDSamplerState, use_anisotropy);
195 RD_BIND(Variant::FLOAT, RDSamplerState, anisotropy_max);
196 RD_BIND(Variant::BOOL, RDSamplerState, enable_compare);
197 RD_BIND(Variant::INT, RDSamplerState, compare_op);
198 RD_BIND(Variant::FLOAT, RDSamplerState, min_lod);
199 RD_BIND(Variant::FLOAT, RDSamplerState, max_lod);
200 RD_BIND(Variant::INT, RDSamplerState, border_color);
201 RD_BIND(Variant::BOOL, RDSamplerState, unnormalized_uvw);
202 }
203};
204
205class RDVertexAttribute : public RefCounted {
206 GDCLASS(RDVertexAttribute, RefCounted)
207 friend class RenderingDevice;
208 RD::VertexAttribute base;
209
210public:
211 RD_SETGET(uint32_t, location)
212 RD_SETGET(uint32_t, offset)
213 RD_SETGET(RD::DataFormat, format)
214 RD_SETGET(uint32_t, stride)
215 RD_SETGET(RD::VertexFrequency, frequency)
216
217protected:
218 static void _bind_methods() {
219 RD_BIND(Variant::INT, RDVertexAttribute, location);
220 RD_BIND(Variant::INT, RDVertexAttribute, offset);
221 RD_BIND(Variant::INT, RDVertexAttribute, format);
222 RD_BIND(Variant::INT, RDVertexAttribute, stride);
223 RD_BIND(Variant::INT, RDVertexAttribute, frequency);
224 }
225};
226class RDShaderSource : public RefCounted {
227 GDCLASS(RDShaderSource, RefCounted)
228 String source[RD::SHADER_STAGE_MAX];
229 RD::ShaderLanguage language = RD::SHADER_LANGUAGE_GLSL;
230
231public:
232 void set_stage_source(RD::ShaderStage p_stage, const String &p_source) {
233 ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX);
234 source[p_stage] = p_source;
235 }
236
237 String get_stage_source(RD::ShaderStage p_stage) const {
238 ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String());
239 return source[p_stage];
240 }
241
242 void set_language(RD::ShaderLanguage p_language) {
243 language = p_language;
244 }
245
246 RD::ShaderLanguage get_language() const {
247 return language;
248 }
249
250protected:
251 static void _bind_methods() {
252 ClassDB::bind_method(D_METHOD("set_stage_source", "stage", "source"), &RDShaderSource::set_stage_source);
253 ClassDB::bind_method(D_METHOD("get_stage_source", "stage"), &RDShaderSource::get_stage_source);
254
255 ClassDB::bind_method(D_METHOD("set_language", "language"), &RDShaderSource::set_language);
256 ClassDB::bind_method(D_METHOD("get_language"), &RDShaderSource::get_language);
257
258 ADD_GROUP("Source", "source_");
259 ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_vertex"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_VERTEX);
260 ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_fragment"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_FRAGMENT);
261 ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_control"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_CONTROL);
262 ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_evaluation"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_EVALUATION);
263 ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_compute"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_COMPUTE);
264 ADD_GROUP("Syntax", "source_");
265 ADD_PROPERTY(PropertyInfo(Variant::INT, "language", PROPERTY_HINT_RANGE, "GLSL,HLSL"), "set_language", "get_language");
266 }
267};
268
269class RDShaderSPIRV : public Resource {
270 GDCLASS(RDShaderSPIRV, Resource)
271
272 Vector<uint8_t> bytecode[RD::SHADER_STAGE_MAX];
273 String compile_error[RD::SHADER_STAGE_MAX];
274
275public:
276 void set_stage_bytecode(RD::ShaderStage p_stage, const Vector<uint8_t> &p_bytecode) {
277 ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX);
278 bytecode[p_stage] = p_bytecode;
279 }
280
281 Vector<uint8_t> get_stage_bytecode(RD::ShaderStage p_stage) const {
282 ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, Vector<uint8_t>());
283 return bytecode[p_stage];
284 }
285
286 Vector<RD::ShaderStageSPIRVData> get_stages() const {
287 Vector<RD::ShaderStageSPIRVData> stages;
288 for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
289 if (bytecode[i].size()) {
290 RD::ShaderStageSPIRVData stage;
291 stage.shader_stage = RD::ShaderStage(i);
292 stage.spir_v = bytecode[i];
293 stages.push_back(stage);
294 }
295 }
296 return stages;
297 }
298
299 void set_stage_compile_error(RD::ShaderStage p_stage, const String &p_compile_error) {
300 ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX);
301 compile_error[p_stage] = p_compile_error;
302 }
303
304 String get_stage_compile_error(RD::ShaderStage p_stage) const {
305 ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String());
306 return compile_error[p_stage];
307 }
308
309protected:
310 static void _bind_methods() {
311 ClassDB::bind_method(D_METHOD("set_stage_bytecode", "stage", "bytecode"), &RDShaderSPIRV::set_stage_bytecode);
312 ClassDB::bind_method(D_METHOD("get_stage_bytecode", "stage"), &RDShaderSPIRV::get_stage_bytecode);
313
314 ClassDB::bind_method(D_METHOD("set_stage_compile_error", "stage", "compile_error"), &RDShaderSPIRV::set_stage_compile_error);
315 ClassDB::bind_method(D_METHOD("get_stage_compile_error", "stage"), &RDShaderSPIRV::get_stage_compile_error);
316
317 ADD_GROUP("Bytecode", "bytecode_");
318 ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_vertex"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_VERTEX);
319 ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_fragment"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_FRAGMENT);
320 ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_control"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_CONTROL);
321 ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_evaluation"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_EVALUATION);
322 ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_compute"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_COMPUTE);
323 ADD_GROUP("Compile Error", "compile_error_");
324 ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_vertex"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_VERTEX);
325 ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_fragment"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_FRAGMENT);
326 ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_control"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_CONTROL);
327 ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_evaluation"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_EVALUATION);
328 ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_compute"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_COMPUTE);
329 }
330};
331
332class RDShaderFile : public Resource {
333 GDCLASS(RDShaderFile, Resource)
334
335 HashMap<StringName, Ref<RDShaderSPIRV>> versions;
336 String base_error;
337
338public:
339 void set_bytecode(const Ref<RDShaderSPIRV> &p_bytecode, const StringName &p_version = StringName()) {
340 ERR_FAIL_COND(p_bytecode.is_null());
341 versions[p_version] = p_bytecode;
342 emit_changed();
343 }
344
345 Ref<RDShaderSPIRV> get_spirv(const StringName &p_version = StringName()) const {
346 ERR_FAIL_COND_V(!versions.has(p_version), Ref<RDShaderSPIRV>());
347 return versions[p_version];
348 }
349
350 Vector<RD::ShaderStageSPIRVData> get_spirv_stages(const StringName &p_version = StringName()) const {
351 ERR_FAIL_COND_V(!versions.has(p_version), Vector<RD::ShaderStageSPIRVData>());
352 return versions[p_version]->get_stages();
353 }
354
355 TypedArray<StringName> get_version_list() const {
356 Vector<StringName> vnames;
357 for (const KeyValue<StringName, Ref<RDShaderSPIRV>> &E : versions) {
358 vnames.push_back(E.key);
359 }
360 vnames.sort_custom<StringName::AlphCompare>();
361 TypedArray<StringName> ret;
362 ret.resize(vnames.size());
363 for (int i = 0; i < vnames.size(); i++) {
364 ret[i] = vnames[i];
365 }
366 return ret;
367 }
368
369 void set_base_error(const String &p_error) {
370 base_error = p_error;
371 emit_changed();
372 }
373
374 String get_base_error() const {
375 return base_error;
376 }
377
378 void print_errors(const String &p_file) {
379 if (!base_error.is_empty()) {
380 ERR_PRINT("Error parsing shader '" + p_file + "':\n\n" + base_error);
381 } else {
382 for (KeyValue<StringName, Ref<RDShaderSPIRV>> &E : versions) {
383 for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
384 String error = E.value->get_stage_compile_error(RD::ShaderStage(i));
385 if (!error.is_empty()) {
386 static const char *stage_str[RD::SHADER_STAGE_MAX] = {
387 "vertex",
388 "fragment",
389 "tesselation_control",
390 "tesselation_evaluation",
391 "compute"
392 };
393
394 ERR_PRINT("Error parsing shader '" + p_file + "', version '" + String(E.key) + "', stage '" + stage_str[i] + "':\n\n" + error);
395 }
396 }
397 }
398 }
399 }
400
401 typedef String (*OpenIncludeFunction)(const String &, void *userdata);
402 Error parse_versions_from_text(const String &p_text, const String p_defines = String(), OpenIncludeFunction p_include_func = nullptr, void *p_include_func_userdata = nullptr);
403
404protected:
405 Dictionary _get_versions() const {
406 TypedArray<StringName> vnames = get_version_list();
407 Dictionary ret;
408 for (int i = 0; i < vnames.size(); i++) {
409 ret[vnames[i]] = versions[vnames[i]];
410 }
411 return ret;
412 }
413 void _set_versions(const Dictionary &p_versions) {
414 versions.clear();
415 List<Variant> keys;
416 p_versions.get_key_list(&keys);
417 for (const Variant &E : keys) {
418 StringName vname = E;
419 Ref<RDShaderSPIRV> bc = p_versions[E];
420 ERR_CONTINUE(bc.is_null());
421 versions[vname] = bc;
422 }
423
424 emit_changed();
425 }
426
427 static void _bind_methods() {
428 ClassDB::bind_method(D_METHOD("set_bytecode", "bytecode", "version"), &RDShaderFile::set_bytecode, DEFVAL(StringName()));
429 ClassDB::bind_method(D_METHOD("get_spirv", "version"), &RDShaderFile::get_spirv, DEFVAL(StringName()));
430 ClassDB::bind_method(D_METHOD("get_version_list"), &RDShaderFile::get_version_list);
431
432 ClassDB::bind_method(D_METHOD("set_base_error", "error"), &RDShaderFile::set_base_error);
433 ClassDB::bind_method(D_METHOD("get_base_error"), &RDShaderFile::get_base_error);
434
435 ClassDB::bind_method(D_METHOD("_set_versions", "versions"), &RDShaderFile::_set_versions);
436 ClassDB::bind_method(D_METHOD("_get_versions"), &RDShaderFile::_get_versions);
437
438 ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_versions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_versions", "_get_versions");
439 ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_error"), "set_base_error", "get_base_error");
440 }
441};
442
443class RDUniform : public RefCounted {
444 GDCLASS(RDUniform, RefCounted)
445 friend class RenderingDevice;
446 RD::Uniform base;
447
448public:
449 RD_SETGET(RD::UniformType, uniform_type)
450 RD_SETGET(int32_t, binding)
451
452 void add_id(const RID &p_id) { base.append_id(p_id); }
453 void clear_ids() { base.clear_ids(); }
454 TypedArray<RID> get_ids() const {
455 TypedArray<RID> ids;
456 for (uint32_t i = 0; i < base.get_id_count(); i++) {
457 ids.push_back(base.get_id(i));
458 }
459 return ids;
460 }
461
462protected:
463 void _set_ids(const TypedArray<RID> &p_ids) {
464 base.clear_ids();
465 for (int i = 0; i < p_ids.size(); i++) {
466 RID id = p_ids[i];
467 ERR_FAIL_COND(id.is_null());
468 base.append_id(id);
469 }
470 }
471 static void _bind_methods() {
472 RD_BIND(Variant::INT, RDUniform, uniform_type);
473 RD_BIND(Variant::INT, RDUniform, binding);
474 ClassDB::bind_method(D_METHOD("add_id", "id"), &RDUniform::add_id);
475 ClassDB::bind_method(D_METHOD("clear_ids"), &RDUniform::clear_ids);
476 ClassDB::bind_method(D_METHOD("_set_ids", "ids"), &RDUniform::_set_ids);
477 ClassDB::bind_method(D_METHOD("get_ids"), &RDUniform::get_ids);
478 ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_ids", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_ids", "get_ids");
479 }
480};
481
482class RDPipelineSpecializationConstant : public RefCounted {
483 GDCLASS(RDPipelineSpecializationConstant, RefCounted)
484 friend class RenderingDevice;
485
486 Variant value = false;
487 uint32_t constant_id = 0;
488
489public:
490 void set_value(const Variant &p_value) {
491 ERR_FAIL_COND(p_value.get_type() != Variant::BOOL && p_value.get_type() != Variant::INT && p_value.get_type() != Variant::FLOAT);
492 value = p_value;
493 }
494 Variant get_value() const { return value; }
495
496 void set_constant_id(uint32_t p_id) {
497 constant_id = p_id;
498 }
499 uint32_t get_constant_id() const {
500 return constant_id;
501 }
502
503protected:
504 static void _bind_methods() {
505 ClassDB::bind_method(D_METHOD("set_value", "value"), &RDPipelineSpecializationConstant::set_value);
506 ClassDB::bind_method(D_METHOD("get_value"), &RDPipelineSpecializationConstant::get_value);
507
508 ClassDB::bind_method(D_METHOD("set_constant_id", "constant_id"), &RDPipelineSpecializationConstant::set_constant_id);
509 ClassDB::bind_method(D_METHOD("get_constant_id"), &RDPipelineSpecializationConstant::get_constant_id);
510
511 ADD_PROPERTY(PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_value", "get_value");
512 ADD_PROPERTY(PropertyInfo(Variant::INT, "constant_id", PROPERTY_HINT_RANGE, "0,65535,0"), "set_constant_id", "get_constant_id");
513 }
514};
515
516class RDPipelineRasterizationState : public RefCounted {
517 GDCLASS(RDPipelineRasterizationState, RefCounted)
518 friend class RenderingDevice;
519
520 RD::PipelineRasterizationState base;
521
522public:
523 RD_SETGET(bool, enable_depth_clamp)
524 RD_SETGET(bool, discard_primitives)
525 RD_SETGET(bool, wireframe)
526 RD_SETGET(RD::PolygonCullMode, cull_mode)
527 RD_SETGET(RD::PolygonFrontFace, front_face)
528 RD_SETGET(bool, depth_bias_enabled)
529 RD_SETGET(float, depth_bias_constant_factor)
530 RD_SETGET(float, depth_bias_clamp)
531 RD_SETGET(float, depth_bias_slope_factor)
532 RD_SETGET(float, line_width)
533 RD_SETGET(uint32_t, patch_control_points)
534
535protected:
536 static void _bind_methods() {
537 RD_BIND(Variant::BOOL, RDPipelineRasterizationState, enable_depth_clamp);
538 RD_BIND(Variant::BOOL, RDPipelineRasterizationState, discard_primitives);
539 RD_BIND(Variant::BOOL, RDPipelineRasterizationState, wireframe);
540 RD_BIND(Variant::INT, RDPipelineRasterizationState, cull_mode);
541 RD_BIND(Variant::INT, RDPipelineRasterizationState, front_face);
542 RD_BIND(Variant::BOOL, RDPipelineRasterizationState, depth_bias_enabled);
543 RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_constant_factor);
544 RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_clamp);
545 RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_slope_factor);
546 RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, line_width);
547 RD_BIND(Variant::INT, RDPipelineRasterizationState, patch_control_points);
548 }
549};
550
551class RDPipelineMultisampleState : public RefCounted {
552 GDCLASS(RDPipelineMultisampleState, RefCounted)
553 friend class RenderingDevice;
554
555 RD::PipelineMultisampleState base;
556 TypedArray<int64_t> sample_masks;
557
558public:
559 RD_SETGET(RD::TextureSamples, sample_count)
560 RD_SETGET(bool, enable_sample_shading)
561 RD_SETGET(float, min_sample_shading)
562 RD_SETGET(bool, enable_alpha_to_coverage)
563 RD_SETGET(bool, enable_alpha_to_one)
564
565 void set_sample_masks(const TypedArray<int64_t> &p_masks) { sample_masks = p_masks; }
566 TypedArray<int64_t> get_sample_masks() const { return sample_masks; }
567
568protected:
569 static void _bind_methods() {
570 RD_BIND(Variant::INT, RDPipelineMultisampleState, sample_count);
571 RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_sample_shading);
572 RD_BIND(Variant::FLOAT, RDPipelineMultisampleState, min_sample_shading);
573 RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_coverage);
574 RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_one);
575
576 ClassDB::bind_method(D_METHOD("set_sample_masks", "masks"), &RDPipelineMultisampleState::set_sample_masks);
577 ClassDB::bind_method(D_METHOD("get_sample_masks"), &RDPipelineMultisampleState::get_sample_masks);
578 ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "sample_masks", PROPERTY_HINT_ARRAY_TYPE, "int"), "set_sample_masks", "get_sample_masks");
579 }
580};
581
582class RDPipelineDepthStencilState : public RefCounted {
583 GDCLASS(RDPipelineDepthStencilState, RefCounted)
584 friend class RenderingDevice;
585
586 RD::PipelineDepthStencilState base;
587
588public:
589 RD_SETGET(bool, enable_depth_test)
590 RD_SETGET(bool, enable_depth_write)
591 RD_SETGET(RD::CompareOperator, depth_compare_operator)
592 RD_SETGET(bool, enable_depth_range)
593 RD_SETGET(float, depth_range_min)
594 RD_SETGET(float, depth_range_max)
595 RD_SETGET(bool, enable_stencil)
596
597 RD_SETGET_SUB(RD::StencilOperation, front_op, fail)
598 RD_SETGET_SUB(RD::StencilOperation, front_op, pass)
599 RD_SETGET_SUB(RD::StencilOperation, front_op, depth_fail)
600 RD_SETGET_SUB(RD::CompareOperator, front_op, compare)
601 RD_SETGET_SUB(uint32_t, front_op, compare_mask)
602 RD_SETGET_SUB(uint32_t, front_op, write_mask)
603 RD_SETGET_SUB(uint32_t, front_op, reference)
604
605 RD_SETGET_SUB(RD::StencilOperation, back_op, fail)
606 RD_SETGET_SUB(RD::StencilOperation, back_op, pass)
607 RD_SETGET_SUB(RD::StencilOperation, back_op, depth_fail)
608 RD_SETGET_SUB(RD::CompareOperator, back_op, compare)
609 RD_SETGET_SUB(uint32_t, back_op, compare_mask)
610 RD_SETGET_SUB(uint32_t, back_op, write_mask)
611 RD_SETGET_SUB(uint32_t, back_op, reference)
612
613protected:
614 static void _bind_methods() {
615 RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_test);
616 RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_write);
617 RD_BIND(Variant::INT, RDPipelineDepthStencilState, depth_compare_operator);
618 RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_range);
619 RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_min);
620 RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_max);
621 RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_stencil);
622
623 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, fail);
624 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, pass);
625 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, depth_fail);
626 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare);
627 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare_mask);
628 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, write_mask);
629 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, reference);
630
631 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, fail);
632 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, pass);
633 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, depth_fail);
634 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare);
635 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare_mask);
636 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, write_mask);
637 RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, reference);
638 }
639};
640
641class RDPipelineColorBlendStateAttachment : public RefCounted {
642 GDCLASS(RDPipelineColorBlendStateAttachment, RefCounted)
643 friend class RenderingDevice;
644 RD::PipelineColorBlendState::Attachment base;
645
646public:
647 RD_SETGET(bool, enable_blend)
648 RD_SETGET(RD::BlendFactor, src_color_blend_factor)
649 RD_SETGET(RD::BlendFactor, dst_color_blend_factor)
650 RD_SETGET(RD::BlendOperation, color_blend_op)
651 RD_SETGET(RD::BlendFactor, src_alpha_blend_factor)
652 RD_SETGET(RD::BlendFactor, dst_alpha_blend_factor)
653 RD_SETGET(RD::BlendOperation, alpha_blend_op)
654 RD_SETGET(bool, write_r)
655 RD_SETGET(bool, write_g)
656 RD_SETGET(bool, write_b)
657 RD_SETGET(bool, write_a)
658
659 void set_as_mix() {
660 base = RD::PipelineColorBlendState::Attachment();
661 base.enable_blend = true;
662 base.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
663 base.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
664 base.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
665 base.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
666 }
667
668protected:
669 static void _bind_methods() {
670 ClassDB::bind_method(D_METHOD("set_as_mix"), &RDPipelineColorBlendStateAttachment::set_as_mix);
671
672 RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, enable_blend);
673 RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_color_blend_factor);
674 RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_color_blend_factor);
675 RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, color_blend_op);
676 RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_alpha_blend_factor);
677 RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_alpha_blend_factor);
678 RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, alpha_blend_op);
679 RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_r);
680 RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_g);
681 RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_b);
682 RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_a);
683 }
684};
685
686class RDPipelineColorBlendState : public RefCounted {
687 GDCLASS(RDPipelineColorBlendState, RefCounted)
688 friend class RenderingDevice;
689 RD::PipelineColorBlendState base;
690
691 TypedArray<RDPipelineColorBlendStateAttachment> attachments;
692
693public:
694 RD_SETGET(bool, enable_logic_op)
695 RD_SETGET(RD::LogicOperation, logic_op)
696 RD_SETGET(Color, blend_constant)
697
698 void set_attachments(const TypedArray<RDPipelineColorBlendStateAttachment> &p_attachments) {
699 attachments = p_attachments;
700 }
701
702 TypedArray<RDPipelineColorBlendStateAttachment> get_attachments() const {
703 return attachments;
704 }
705
706protected:
707 static void _bind_methods() {
708 RD_BIND(Variant::BOOL, RDPipelineColorBlendState, enable_logic_op);
709 RD_BIND(Variant::INT, RDPipelineColorBlendState, logic_op);
710 RD_BIND(Variant::COLOR, RDPipelineColorBlendState, blend_constant);
711
712 ClassDB::bind_method(D_METHOD("set_attachments", "attachments"), &RDPipelineColorBlendState::set_attachments);
713 ClassDB::bind_method(D_METHOD("get_attachments"), &RDPipelineColorBlendState::get_attachments);
714 ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "attachments", PROPERTY_HINT_ARRAY_TYPE, "RDPipelineColorBlendStateAttachment"), "set_attachments", "get_attachments");
715 }
716};
717
718#endif // RENDERING_DEVICE_BINDS_H
719