129 lines
6.5 KiB
Plaintext
129 lines
6.5 KiB
Plaintext
-------------------------------------------------------------------------
|
|
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 image load and store tests
|
|
|
|
Tests:
|
|
+ dEQP-GLES31.functional.image_load_store.*
|
|
|
|
Includes:
|
|
+ 2d, cube, 3d, 2d array and buffer (GL_EXT_texture_buffer) textures
|
|
+ Plain imageStore()
|
|
+ imageLoad() followed by imageStore()
|
|
+ imageAtomic*()
|
|
- Cases for both final result and return values
|
|
+ Basic usage of the "coherent" qualifier along with barrier() and
|
|
memoryBarrier()
|
|
- Also identical variants except with "volatile"
|
|
+ Basic sanity case for "restrict"
|
|
+ Format re-interpretation cases
|
|
+ Binding a single layer of a texture
|
|
+ imageSize()
|
|
+ Basic cases for early_fragment_tests, if images supported in fragment shader
|
|
|
|
Excludes:
|
|
+ Shaders other than compute (except for basic early_fragment_tests cases)
|
|
+ Complex usage, such as complex inter-invocation and inter-call communication
|
|
+ Negative testing
|
|
|
|
Description:
|
|
|
|
In all of the cases described below, unless otherwise mentioned, texture
|
|
contents (one layer, slice or cube face at a time) are retrieved from the GL in
|
|
the following manner:
|
|
- if the texture is of an integer format, it is bound to the color attachment
|
|
of a FBO and read with glReadPixels(). Texture is verified with exact
|
|
comparisons, where applicable.
|
|
- if the texture is of a [half] float or [s]norm format, it is copied by a
|
|
compute shader (read with texture()) into a SSBO, which is then read with a
|
|
mapping. Texture is verified with some tolerance.
|
|
|
|
Texture format and size are set with glTexStorage*(). Any initialization data is
|
|
uploaded with glTexSubImage*().
|
|
|
|
Compute shaders use local sizes (1, 1, 1).
|
|
|
|
The imageStore() cases store results of simple computations into an image.
|
|
The image is of the same format as the texture bound to it. Stored results are
|
|
compared to a reference image. All image formats are tested. The compute shader
|
|
is invoked once for each pixel, in a single glDispatchCompute().
|
|
|
|
The cases testing imageLoad() first initialize the contents of a texture with
|
|
API calls. In the compute shader, the contents of the image are read with
|
|
imageLoad() and copied into a second image with imageStore(). The images and
|
|
their corresponding textures all have the same format. The results are compared
|
|
to a reference image. All image formats are tested. The compute shader is
|
|
invoked once for each pixel, in a single glDispatchCompute().
|
|
|
|
The atomic operation cases exist in two variants: cases for testing the end
|
|
result in the texture operated on by the atomic functions, as well as cases
|
|
testing the values returned by the atomic function in each shader invocation.
|
|
For both case types, a texture is created, and its pixels initialized. A compute
|
|
shader is dispatched with the dimensions equal to the image size, except that
|
|
the x size is a multiple of the width of the image, so that each pixel is
|
|
operated on by multiple shader invocations. For the return value cases, the
|
|
return value of the atomic function is stored with imageStore() into a second
|
|
image, the size of which equals the dispatch dimensions. The results for the end
|
|
result cases are verified by comparing the pixels of the first image to
|
|
reference values, which may allow one of multiple choices, depending on the type
|
|
of the operation. The results for the return value cases are verified by reading
|
|
the second image and checking that a valid return value sequence was generated
|
|
for each set of related invocations.
|
|
|
|
The "coherent" cases use an image with a format that allows both reading and
|
|
writing in the same shader (i.e. r32i/r32ui/r32f). In the shader, such an image
|
|
is qualified "coherent". Some computation results are first stored in the image;
|
|
then, in the same shader, after a call to memoryBarrier() and barrier(), pixels
|
|
corresponding to some other invocations are read, an expression is computed
|
|
based on the values read, and after yet another set of barriers, the value of
|
|
this expression is stored to the image. The result is compared to a reference
|
|
image.
|
|
|
|
The "volatile" cases are otherwise identical to the "coherent" cases, except
|
|
that the "volatile" qualifier is used instead of "coherent". Volatility implies
|
|
coherence, and results should therefore be identical.
|
|
|
|
The "restrict" case does image loading and storing similar to that in the
|
|
above-described imageLoad()&imageStore() case, except the images are qualified
|
|
"restrict". This is mainly a sanity case to see that the keyword is properly
|
|
recognized.
|
|
|
|
The format re-interpretation cases are similar to the above-described
|
|
imageLoad()&imageStore() cases. However, the image format is not the same as
|
|
the texture format, but one that is (size-)compatible with the texture format.
|
|
All size-compatible format pairs are tested.
|
|
|
|
The single-layer cases bind a cube, 3d, or 2d array texture to an image unit
|
|
with the "layered" parameter set to GL_FALSE. The image is operated on by a
|
|
shader with an *image2D image variable. The shader's operation is similar to
|
|
the store or load&store cases (both variants exist). Multiple shader invocations
|
|
with different layer bindings are done to cover the entire texture. The result
|
|
is compared to a reference.
|
|
|
|
The imageSize() cases read the size of an image in the shader, and store a
|
|
verification result into a 2d r32ui image. The result is trivially verified.
|
|
|
|
The cases for early_fragment_tests are relevant only if the implementation
|
|
supports images in fragment shaders. Each case either uses or doesn't use
|
|
the early_fragment_tests layout qualifier, and targets either depth or stencil
|
|
test. Conditions are prepared such that approximately half of the fragments of
|
|
a full-viewport quad will fail the specific fragment test. In the fragment
|
|
shader, imageAtomicAdd() is used to increment a shared counter. The case then
|
|
tests the value of the counter; its value should depend on whether
|
|
early_fragment_tests was specified.
|