Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/drivers/metal/rendering_shader_container_metal.h
21826 views
1
/**************************************************************************/
2
/* rendering_shader_container_metal.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
#pragma once
32
33
#include "metal_device_profile.h"
34
#include "sha256_digest.h"
35
36
#include "servers/rendering/rendering_device_driver.h"
37
#include "servers/rendering/rendering_shader_container.h"
38
39
constexpr uint32_t R32UI_ALIGNMENT_CONSTANT_ID = 65535;
40
/// Metal buffer index for the view mask when rendering multi-view.
41
const uint32_t VIEW_MASK_BUFFER_INDEX = 24;
42
43
class RenderingShaderContainerFormatMetal;
44
45
class RenderingShaderContainerMetal : public RenderingShaderContainer {
46
GDSOFTCLASS(RenderingShaderContainerMetal, RenderingShaderContainer);
47
48
public:
49
struct HeaderData {
50
enum Flags : uint32_t {
51
NONE = 0,
52
NEEDS_VIEW_MASK_BUFFER = 1 << 0,
53
USES_ARGUMENT_BUFFERS = 1 << 1,
54
NEEDS_DEBUG_LOGGING = 1 << 2,
55
};
56
57
/// The base profile that was used to generate this shader.
58
MetalDeviceProfile profile;
59
60
/// The Metal language version specified when compiling SPIR-V to MSL.
61
/// Format is major * 10000 + minor * 100 + patch.
62
uint32_t msl_version = UINT32_MAX;
63
/*! @brief The minimum supported OS version for shaders baked to a `.metallib`.
64
*
65
* NOTE: This property is only valid when shaders are baked to a .metalllib
66
*
67
* Format is major * 10000 + minor * 100 + patch.
68
*/
69
MinOsVersion os_min_version;
70
uint32_t flags = NONE;
71
uint32_t push_constant_binding = UINT32_MAX; ///< Metal binding slot for the push constant data
72
73
/// @brief Returns `true` if the shader is compiled with multi-view support.
74
bool needs_view_mask_buffer() const {
75
return flags & NEEDS_VIEW_MASK_BUFFER;
76
}
77
78
void set_needs_view_mask_buffer(bool p_value) {
79
if (p_value) {
80
flags |= NEEDS_VIEW_MASK_BUFFER;
81
} else {
82
flags &= ~NEEDS_VIEW_MASK_BUFFER;
83
}
84
}
85
86
/// @brief Returns `true` if the shader was compiled with argument buffer support.
87
bool uses_argument_buffers() const {
88
return flags & USES_ARGUMENT_BUFFERS;
89
}
90
91
void set_uses_argument_buffers(bool p_value) {
92
if (p_value) {
93
flags |= USES_ARGUMENT_BUFFERS;
94
} else {
95
flags &= ~USES_ARGUMENT_BUFFERS;
96
}
97
}
98
99
/// Returns `true` if the shader was compiled with the GL_EXT_debug_printf extension enabled.
100
bool needs_debug_logging() const {
101
return flags & NEEDS_DEBUG_LOGGING;
102
}
103
104
void set_needs_debug_logging(bool p_value) {
105
if (p_value) {
106
flags |= NEEDS_DEBUG_LOGGING;
107
} else {
108
flags &= ~NEEDS_DEBUG_LOGGING;
109
}
110
}
111
};
112
113
struct StageData {
114
uint32_t vertex_input_binding_mask = 0;
115
uint32_t is_position_invariant = 0; ///< <c>true</c> if the position output is invariant
116
uint32_t supports_fast_math = 0;
117
SHA256Digest hash; ///< SHA 256 hash of the shader code
118
uint32_t source_size = 0; ///< size of the source code in the returned bytes
119
uint32_t library_size = 0; ///< size of the compiled library in the returned bytes, 0 if it is not compiled
120
};
121
122
struct UniformData {
123
uint32_t active_stages = 0;
124
uint32_t uniform_type = 0; // UniformType
125
uint32_t data_type = 0; // MTLDataTypeNone
126
uint32_t access = 0; // MTLBindingAccessReadOnly
127
uint32_t usage = 0; // MTLResourceUsage (none)
128
uint32_t texture_type = 2; // MTLTextureType2D
129
uint32_t image_format = 0;
130
uint32_t array_length = 0;
131
uint32_t is_multisampled = 0;
132
133
struct Indexes {
134
uint32_t buffer = UINT32_MAX;
135
uint32_t texture = UINT32_MAX;
136
uint32_t sampler = UINT32_MAX;
137
};
138
Indexes slot;
139
Indexes arg_buffer;
140
141
enum class IndexType {
142
SLOT,
143
ARG,
144
};
145
146
_FORCE_INLINE_ Indexes &get_indexes(IndexType p_type) {
147
switch (p_type) {
148
case IndexType::SLOT:
149
return slot;
150
case IndexType::ARG:
151
return arg_buffer;
152
}
153
}
154
};
155
156
HeaderData mtl_reflection_data; // compliment to reflection_data
157
Vector<StageData> mtl_shaders; // compliment to shaders
158
159
private:
160
struct ToolchainProperties {
161
MinOsVersion os_version_min_required;
162
uint32_t metal_version = UINT32_MAX;
163
164
_FORCE_INLINE_ bool is_null() const { return os_version_min_required.is_null() || metal_version == UINT32_MAX; }
165
_FORCE_INLINE_ bool is_valid() const { return !is_null(); }
166
};
167
168
ToolchainProperties compiler_props;
169
170
void _initialize_toolchain_properties();
171
172
private:
173
const MetalDeviceProfile *device_profile = nullptr;
174
bool export_mode = false;
175
176
Vector<UniformData> mtl_reflection_binding_set_uniforms_data; // compliment to reflection_binding_set_uniforms_data
177
178
Error compile_metal_source(const char *p_source, const StageData &p_stage_data, Vector<uint8_t> &r_binary_data);
179
180
Error reflect_spirv(const ReflectShader &p_shader);
181
182
public:
183
static constexpr uint32_t FORMAT_VERSION = 2;
184
185
void set_export_mode(bool p_export_mode) { export_mode = p_export_mode; }
186
void set_device_profile(const MetalDeviceProfile *p_device_profile) { device_profile = p_device_profile; }
187
188
struct MetalShaderReflection {
189
Vector<Vector<UniformData>> uniform_sets;
190
};
191
192
MetalShaderReflection get_metal_shader_reflection() const;
193
194
protected:
195
virtual uint32_t _from_bytes_reflection_extra_data(const uint8_t *p_bytes) override;
196
virtual uint32_t _from_bytes_reflection_binding_uniform_extra_data_start(const uint8_t *p_bytes) override;
197
virtual uint32_t _from_bytes_reflection_binding_uniform_extra_data(const uint8_t *p_bytes, uint32_t p_index) override;
198
virtual uint32_t _from_bytes_shader_extra_data_start(const uint8_t *p_bytes) override;
199
virtual uint32_t _from_bytes_shader_extra_data(const uint8_t *p_bytes, uint32_t p_index) override;
200
201
virtual uint32_t _to_bytes_reflection_extra_data(uint8_t *p_bytes) const override;
202
virtual uint32_t _to_bytes_reflection_binding_uniform_extra_data(uint8_t *p_bytes, uint32_t p_index) const override;
203
virtual uint32_t _to_bytes_shader_extra_data(uint8_t *p_bytes, uint32_t p_index) const override;
204
205
virtual uint32_t _format() const override;
206
virtual uint32_t _format_version() const override;
207
virtual bool _set_code_from_spirv(const ReflectShader &p_shader) override;
208
};
209
210
class RenderingShaderContainerFormatMetal : public RenderingShaderContainerFormat {
211
bool export_mode = false;
212
213
const MetalDeviceProfile *device_profile = nullptr;
214
215
public:
216
virtual Ref<RenderingShaderContainer> create_container() const override;
217
virtual ShaderLanguageVersion get_shader_language_version() const override;
218
virtual ShaderSpirvVersion get_shader_spirv_version() const override;
219
RenderingShaderContainerFormatMetal(const MetalDeviceProfile *p_device_profile, bool p_export = false);
220
virtual ~RenderingShaderContainerFormatMetal() = default;
221
};
222
223