------------------------------------------------------------------------- drawElements Quality Program Test Specification ----------------------------------------------- Copyright 2014 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ------------------------------------------------------------------------- Shader atomic counter tests Tests: + dEQP-GLES31.functional.shaders.atomic_counter.* Includes: + Calls to atomicCounter(), atomicCounterIncrement() and atomicCounterDecrement() - Only in compute shaders - With different number of parallel shaders - With different number of calls per shader - With different combinations of operations - With conditional calls depending on thread and call number + Atomic counters with different offsets + Atomic counters with default layout qualifier and implicit offset and binding + Invalid offsets and bindings in layout qualifier + Invalid offsets and bindings in default layout qualifier Excludes: + Multiple binding points and buffers - Only single binding point is required by specification + Use in other than compute shader - Specification requires zero binding points in other shader types + Usage in multiple shaders at same time + Multiple shader innovocations Description: Test cases perform atomic counter calls and saves results to a SSBO. The SSBO and the atomic counter buffer are read back from the device after executing the shader. Atomic counter values are verified by comparing against the initial value subtracted by total number of calls to atomicCounterDecrement() and incremented by total number of calls to atomicCounterIncrement() performed by the shader. SSBO value verification depends on the set of functions used in the shader. Values returned by call to atomicCounterDecrement() are incremented by one so that all values in the SSBO are values of counter before peforming operation. Atomic counter values returned by different atomic counters are verified separately. Test cases using only atomicCounter() call are verified by checking that all calls returned the same value as set initially to the atomic counter. Test case using either atomicCounterIncrement() or atomicCounterDecrement() call check that each value returned is unique and all values are in continuous range from initial value to the expected result value. Test cases using either atomicCounterIncrement() or atomicCounterDecrement() and atomicCounter() call perform call to atomicCounter() before and after each call to atomicCounterIncrement()/atomicCounterDecrement(). Test cases check that value returned by atomicCounterIncrement()/atomicCounterDecrement() is between values returned by previous and following call to atomicCounter(). Test cases with calls to both atomicCounterIncrement() and atomicCounterDecrement() are verified by counting how many times each value was returned by each function. Using these counts we check that there is possible order in which operations could have been performed. Following pseudo code checks that there is possible order in which increments and decrements could have happened. // Minimum value returned by atomicCounterDecrement() or atomicCounterIncrement() minValue // Maximum value returned by atomicCounterDecrement() or atomicCounterIncrement() maxValue // incrementCounts[value] is how many times value was returned by atomicCounterIncrement() incrementCounts[] // decrementCounts[value] is how many times value-1 was returned by atomicCounterDecrement() decrementCounts[] // Value of counter before any operation has been performed initialValue // Value of counter after executing shader resultValue pos = initialValue while incrementCounts[pos] + decrementCounts[pos] == 0: // Prefer operations that would move away from the result value. if incrementCounts[pos] > 0 and pos > resultValue: incrementCounts[pos]-- pos++ else if decrementCounts[pos]: decrementCounts[pos]-- pos-- else incrementCounts[pos]-- pos++ // Last value might have never been returned by call // to atomicCounterIncrement() or atomicCounterDecrement() // if it's outside of range. if pos < minValue or pos > maxValue: break // Check that incrementCounts and decrementCounts contain only zero values. Test set includes negative shader compilation cases as well. In such cases the compilation is simply expected to fail.