24 const std::vector<ShaderStageIOSlot>& p_inputs,
25 const std::vector<ShaderStageBufferLayout>& layouts) {
26 std::vector<VertexAttribPointer> vertex_attrib_arrays;
27 for (
auto i = 0u; i < p_inputs.size(); i++) {
28 const auto& input = p_inputs[i];
29 const auto& layout = layouts[input.binding];
30 VertexAttribPointer attrib;
31 attrib.index = input.location;
33 if (input.vec_size < 1u || input.vec_size > 4u) {
36 attrib.size = input.vec_size;
38 if (!type.has_value()) {
41 attrib.type = type.value();
42 attrib.normalized = GL_FALSE;
43 attrib.offset = input.offset;
44 attrib.stride = layout.stride;
45 vertex_attrib_arrays.emplace_back(attrib);
47 vertex_attrib_arrays_ = std::move(vertex_attrib_arrays);
53 result.reserve(key.length());
56 result.push_back(toupper(ch));
63 const std::string& member,
66 result.reserve(struct_name.length() + member.length() + (is_array ? 4 : 1));
67 result += struct_name;
68 if (!member.empty()) {
79 const std::string& non_struct_member) {
85 if (!gl.IsProgram(program)) {
88 GLint max_name_size = 0;
89 gl.GetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_size);
91 GLint uniform_count = 0;
92 gl.GetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniform_count);
96 for (GLint i = 0; i < uniform_count; i++) {
97 std::vector<GLchar> name;
98 name.resize(max_name_size);
99 GLsizei written_count = 0u;
100 GLint uniform_var_size = 0u;
101 GLenum uniform_type = GL_FLOAT;
105 gl.GetActiveUniform(program,
113 auto location = gl.GetUniformLocation(program, name.data());
114 if (location == -1) {
115 VALIDATION_LOG <<
"Could not query the location of an active uniform.";
118 if (written_count <= 0) {
119 VALIDATION_LOG <<
"Uniform name could not be read for active uniform.";
123 name.data(),
static_cast<size_t>(written_count)})] = location;
129 size_t vertex_offset)
const {
130 for (
const auto& array : vertex_attrib_arrays_) {
131 gl.EnableVertexAttribArray(array.index);
132 gl.VertexAttribPointer(array.index,
137 reinterpret_cast<const GLvoid*
>(
static_cast<GLsizei
>(
138 vertex_offset + array.offset))
148 const Bindings& fragment_bindings) {
149 for (
const auto& buffer : vertex_bindings.
buffers) {
150 if (!BindUniformBuffer(gl, transients_allocator, buffer.view)) {
154 for (
const auto& buffer : fragment_bindings.
buffers) {
155 if (!BindUniformBuffer(gl, transients_allocator, buffer.view)) {
160 std::optional<size_t> next_unit_index =
162 if (!next_unit_index.has_value()) {
176 for (
const auto& array : vertex_attrib_arrays_) {
177 gl.DisableVertexAttribArray(array.index);
182 GLint BufferBindingsGLES::ComputeTextureLocation(
184 auto location = binding_map_.find(metadata->
name);
185 if (location != binding_map_.end()) {
186 return location->second[0];
188 auto& locations = binding_map_[metadata->
name] = {};
189 auto computed_location =
191 if (computed_location == uniform_locations_.end()) {
192 locations.push_back(-1);
194 locations.push_back(computed_location->second);
199 const std::vector<GLint>& BufferBindingsGLES::ComputeUniformLocations(
200 const ShaderMetadata* metadata) {
201 auto location = binding_map_.find(metadata->name);
202 if (location != binding_map_.end()) {
203 return location->second;
208 auto& locations = binding_map_[metadata->name] = {};
209 for (
const auto& member : metadata->members) {
213 locations.push_back(-1);
217 size_t element_count = member.array_elements.value_or(1);
218 const auto member_key =
220 const auto computed_location = uniform_locations_.find(member_key);
221 if (computed_location == uniform_locations_.end()) {
223 locations.push_back(-1);
226 locations.push_back(computed_location->second);
231 bool BufferBindingsGLES::BindUniformBuffer(
const ProcTableGLES& gl,
232 Allocator& transients_allocator,
234 const auto* metadata = buffer.GetMetadata();
236 buffer.resource.buffer->GetDeviceBuffer(transients_allocator);
237 if (!device_buffer) {
242 const uint8_t* buffer_ptr =
243 device_buffer_gles.GetBufferData() + buffer.resource.range.offset;
245 if (metadata->members.empty()) {
246 VALIDATION_LOG <<
"Uniform buffer had no members. This is currently "
247 "unsupported in the OpenGL ES backend. Use a uniform "
252 const auto& locations = ComputeUniformLocations(metadata);
253 for (
auto i = 0u; i < metadata->members.size(); i++) {
254 const auto& member = metadata->members[i];
255 auto location = locations[i];
257 if (location == -1) {
261 size_t element_count = member.array_elements.value_or(1);
262 size_t element_stride = member.byte_length / element_count;
264 reinterpret_cast<const GLfloat*
>(buffer_ptr + member.offset);
266 std::vector<uint8_t> array_element_buffer;
267 if (element_count > 1) {
271 array_element_buffer.resize(member.size * element_count);
272 for (
size_t element_i = 0; element_i < element_count; element_i++) {
273 std::memcpy(array_element_buffer.data() + element_i * member.size,
274 reinterpret_cast<const char*
>(buffer_data) +
275 element_i * element_stride,
279 reinterpret_cast<const GLfloat*
>(array_element_buffer.data());
282 switch (member.type) {
284 switch (member.size) {
286 gl.UniformMatrix4fv(location,
292 case sizeof(Vector4):
293 gl.Uniform4fv(location,
298 case sizeof(Vector3):
299 gl.Uniform3fv(location,
305 gl.Uniform2fv(location,
311 gl.Uniform1fv(location,
318 <<
" could not be mapped ShaderType::kFloat for key: "
346 std::optional<size_t> BufferBindingsGLES::BindTextures(
347 const ProcTableGLES& gl,
348 const Bindings& bindings,
350 size_t unit_start_index) {
351 size_t active_index = unit_start_index;
352 for (
const auto& data : bindings.sampled_images) {
354 if (data.texture.GetMetadata() ==
nullptr) {
359 auto location = ComputeTextureLocation(data.texture.GetMetadata());
360 if (location == -1) {
367 if (active_index >= gl.GetCapabilities()->GetMaxTextureUnits(stage)) {
368 VALIDATION_LOG <<
"Texture units specified exceed the capabilities for "
369 "this shader stage.";
372 gl.ActiveTexture(GL_TEXTURE0 + active_index);
377 if (!texture_gles.Bind()) {
386 if (!sampler_gles.ConfigureBoundTexture(texture_gles, gl)) {
393 gl.Uniform1i(location, active_index);