1------------------------------------------------------------------------- 2drawElements Quality Program Test Specification 3----------------------------------------------- 4 5Copyright 2014 The Android Open Source Project 6 7Licensed under the Apache License, Version 2.0 (the "License"); 8you may not use this file except in compliance with the License. 9You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13Unless required by applicable law or agreed to in writing, software 14distributed under the License is distributed on an "AS IS" BASIS, 15WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16See the License for the specific language governing permissions and 17limitations under the License. 18------------------------------------------------------------------------- 19 Shader image load and store tests 20 21Tests: 22 + dEQP-GLES31.functional.image_load_store.* 23 24Includes: 25 + 2d, cube, 3d, 2d array and buffer (GL_EXT_texture_buffer) textures 26 + Plain imageStore() 27 + imageLoad() followed by imageStore() 28 + imageAtomic*() 29 - Cases for both final result and return values 30 + Basic usage of the "coherent" qualifier along with barrier() and 31 memoryBarrier() 32 - Also identical variants except with "volatile" 33 + Basic sanity case for "restrict" 34 + Format re-interpretation cases 35 + Binding a single layer of a texture 36 + imageSize() 37 + Basic cases for early_fragment_tests, if images supported in fragment shader 38 39Excludes: 40 + Shaders other than compute (except for basic early_fragment_tests cases) 41 + Complex usage, such as complex inter-invocation and inter-call communication 42 + Negative testing 43 44Description: 45 46In all of the cases described below, unless otherwise mentioned, texture 47contents (one layer, slice or cube face at a time) are retrieved from the GL in 48the following manner: 49 - if the texture is of an integer format, it is bound to the color attachment 50 of a FBO and read with glReadPixels(). Texture is verified with exact 51 comparisons, where applicable. 52 - if the texture is of a [half] float or [s]norm format, it is copied by a 53 compute shader (read with texture()) into a SSBO, which is then read with a 54 mapping. Texture is verified with some tolerance. 55 56Texture format and size are set with glTexStorage*(). Any initialization data is 57uploaded with glTexSubImage*(). 58 59Compute shaders use local sizes (1, 1, 1). 60 61The imageStore() cases store results of simple computations into an image. 62The image is of the same format as the texture bound to it. Stored results are 63compared to a reference image. All image formats are tested. The compute shader 64is invoked once for each pixel, in a single glDispatchCompute(). 65 66The cases testing imageLoad() first initialize the contents of a texture with 67API calls. In the compute shader, the contents of the image are read with 68imageLoad() and copied into a second image with imageStore(). The images and 69their corresponding textures all have the same format. The results are compared 70to a reference image. All image formats are tested. The compute shader is 71invoked once for each pixel, in a single glDispatchCompute(). 72 73The atomic operation cases exist in two variants: cases for testing the end 74result in the texture operated on by the atomic functions, as well as cases 75testing the values returned by the atomic function in each shader invocation. 76For both case types, a texture is created, and its pixels initialized. A compute 77shader is dispatched with the dimensions equal to the image size, except that 78the x size is a multiple of the width of the image, so that each pixel is 79operated on by multiple shader invocations. For the return value cases, the 80return value of the atomic function is stored with imageStore() into a second 81image, the size of which equals the dispatch dimensions. The results for the end 82result cases are verified by comparing the pixels of the first image to 83reference values, which may allow one of multiple choices, depending on the type 84of the operation. The results for the return value cases are verified by reading 85the second image and checking that a valid return value sequence was generated 86for each set of related invocations. 87 88The "coherent" cases use an image with a format that allows both reading and 89writing in the same shader (i.e. r32i/r32ui/r32f). In the shader, such an image 90is qualified "coherent". Some computation results are first stored in the image; 91then, in the same shader, after a call to memoryBarrier() and barrier(), pixels 92corresponding to some other invocations are read, an expression is computed 93based on the values read, and after yet another set of barriers, the value of 94this expression is stored to the image. The result is compared to a reference 95image. 96 97The "volatile" cases are otherwise identical to the "coherent" cases, except 98that the "volatile" qualifier is used instead of "coherent". Volatility implies 99coherence, and results should therefore be identical. 100 101The "restrict" case does image loading and storing similar to that in the 102above-described imageLoad()&imageStore() case, except the images are qualified 103"restrict". This is mainly a sanity case to see that the keyword is properly 104recognized. 105 106The format re-interpretation cases are similar to the above-described 107imageLoad()&imageStore() cases. However, the image format is not the same as 108the texture format, but one that is (size-)compatible with the texture format. 109All size-compatible format pairs are tested. 110 111The single-layer cases bind a cube, 3d, or 2d array texture to an image unit 112with the "layered" parameter set to GL_FALSE. The image is operated on by a 113shader with an *image2D image variable. The shader's operation is similar to 114the store or load&store cases (both variants exist). Multiple shader invocations 115with different layer bindings are done to cover the entire texture. The result 116is compared to a reference. 117 118The imageSize() cases read the size of an image in the shader, and store a 119verification result into a 2d r32ui image. The result is trivially verified. 120 121The cases for early_fragment_tests are relevant only if the implementation 122supports images in fragment shaders. Each case either uses or doesn't use 123the early_fragment_tests layout qualifier, and targets either depth or stencil 124test. Conditions are prepared such that approximately half of the fragments of 125a full-viewport quad will fail the specific fragment test. In the fragment 126shader, imageAtomicAdd() is used to increment a shared counter. The case then 127tests the value of the counter; its value should depend on whether 128early_fragment_tests was specified. 129