From d6144a989937b2829a9fc9813de994c4f514ebae Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Mon, 2 Oct 2017 13:10:20 +0200 Subject: [PATCH] Fix attribute mapping in enhanced layouts tests for input arrays Some tests in KHR-GL45.enhanced_layouts.varying_* (specifically KHR-GL45.enhanced_layouts.varying_array_{locations,components}) use input arrays on the vertex shader, however, the code that uploads vertex data for these (and other test cases) doesn't account for arrays at all. Also, the tests in this category that call TextureTestBase::prepareAttributes to do the VAO setup seem to provide inconsistent values for variable.m_descriptor.m_offset, which also leads to incorrect vertex attribute mappings. Specifically, in the 'component' variants of these tests (such as varying_array_components), two different input variables have m_offset = 0, which has the consequence that we end up computing a vertex buffer with a size that's only big enough to fit one of the inputs and we overwrite the data for the first input with the data for the second input when we setup the VAO, however, the 'location' variants (such as varying_array_locations), see different offsets for different input variables, which leads to a different VAO setup. Components: OpenGL VK-GL-CTS issue: 739 Affects: KHR-GL45.enhanced_layouts.varying_* KHR-GL46.enhanced_layouts.varying_* Change-Id: Icec238a970e2cd67d6109a25fba980f756abb71b --- .../modules/gl/gl4cEnhancedLayoutsTests.cpp | 52 ++++++++++++++++++---- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/external/openglcts/modules/gl/gl4cEnhancedLayoutsTests.cpp b/external/openglcts/modules/gl/gl4cEnhancedLayoutsTests.cpp index 547ea44..f221203 100644 --- a/external/openglcts/modules/gl/gl4cEnhancedLayoutsTests.cpp +++ b/external/openglcts/modules/gl/gl4cEnhancedLayoutsTests.cpp @@ -5509,7 +5509,6 @@ bool TestBase::test() for (GLuint test_case = 0; test_case < n_test_cases; ++test_case) { - #endif /* DEBUG_REPEAT_TEST_CASE */ bool case_result = true; @@ -6731,23 +6730,52 @@ void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramIn 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 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(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 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 buffer_data; - buffer_data.resize(vertex_stride); + buffer_data.resize(buffer_size); GLubyte* ptr = &buffer_data[0]; @@ -6755,13 +6783,19 @@ void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramIn { 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) { @@ -6772,12 +6806,12 @@ void TextureTestBase::prepareAttributes(GLuint test_case_index, Utils::ProgramIn 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 -- 2.7.4