for (GLuint test_case = 0; test_case < n_test_cases; ++test_case)
{
-
#endif /* DEBUG_REPEAT_TEST_CASE */
bool case_result = true;
return;
}
+ const Functions& gl = m_context.getRenderContext().getFunctions();
+
/* Calculate vertex stride and check */
- GLint vertex_stride = 0;
+ GLint max_inputs;
+ gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_inputs);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
+
+ /* dvec3/4 vertex inputs use a single location but require 2x16B slots */
+ GLint max_slots = max_inputs * 2;
+ /* Compute used slots */
+ std::vector<GLint> slot_sizes;
+ slot_sizes.resize(max_slots);
+ std::fill(slot_sizes.begin(), slot_sizes.end(), 0);
for (GLuint i = 0; i < si.m_inputs.size(); ++i)
{
Utils::Variable& variable = *si.m_inputs[i];
GLint variable_size = static_cast<GLuint>(variable.m_data_size);
- GLint ends_at = variable_size + variable.m_descriptor.m_offset;
+ GLint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
+ GLint ends_at = variable.m_descriptor.m_offset % 16 + variable_size;
- vertex_stride = std::max(vertex_stride, ends_at);
+ GLint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements);
+ for (GLint loc = 0; loc < array_length; loc++) {
+ GLint slot = base_slot + loc;
+ slot_sizes[slot] = std::max(slot_sizes[slot], ends_at);
+ }
+ }
+
+ /* Compute the offsets where we need to put vertex buffer data for each slot */
+ std::vector<GLint> slot_offsets;
+ slot_offsets.resize(max_slots);
+ std::fill(slot_offsets.begin(), slot_offsets.end(), -1);
+ GLint buffer_size = 0;
+ for (GLint i = 0; i < max_slots; i++)
+ {
+ if (slot_sizes[i] == 0)
+ continue;
+ slot_offsets[i] = buffer_size;
+ buffer_size += slot_sizes[i];
}
/* Prepare buffer data and set up vao */
std::vector<GLubyte> buffer_data;
- buffer_data.resize(vertex_stride);
+ buffer_data.resize(buffer_size);
GLubyte* ptr = &buffer_data[0];
{
Utils::Variable& variable = *si.m_inputs[i];
- memcpy(ptr + variable.m_descriptor.m_offset, variable.m_data, variable.m_data_size);
+ GLint base_slot = variable.m_descriptor.m_expected_location + variable.m_descriptor.m_offset / 16;
+ GLint variable_offset = variable.m_descriptor.m_offset % 16;
+ GLint array_length = std::max(1u, variable.m_descriptor.m_n_array_elements);
+ for (GLint loc = 0; loc < array_length; loc++) {
+ GLint slot = base_slot + loc;
+ memcpy(ptr + slot_offsets[slot] + variable_offset, variable.m_data, variable.m_data_size);
+ }
if (false == use_component_qualifier)
{
vao.Attribute(variable.m_descriptor.m_expected_location, variable.m_descriptor.m_builtin,
variable.m_descriptor.m_n_array_elements, variable.m_descriptor.m_normalized,
- variable.GetStride(), (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
+ variable.GetStride(), (GLvoid*)(intptr_t)(slot_offsets[base_slot] + variable_offset));
}
else if (0 == variable.m_descriptor.m_expected_component)
{
vao.Attribute(variable.m_descriptor.m_expected_location, type, variable.m_descriptor.m_n_array_elements,
variable.m_descriptor.m_normalized, variable.GetStride(),
- (GLvoid*)(intptr_t)variable.m_descriptor.m_offset);
+ (GLvoid*)(intptr_t)(slot_offsets[base_slot] + variable_offset));
}
}
/* Update buffer */
- buffer.Data(Utils::Buffer::StaticDraw, vertex_stride, ptr);
+ buffer.Data(Utils::Buffer::StaticDraw, buffer_size, ptr);
}
/** Get locations for all outputs with automatic_location