1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.1 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2017 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Negative Sample Variables Tests 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es31fNegativeSampleVariablesTests.hpp" 25 #include "gluShaderProgram.hpp" 26 27 namespace deqp 28 { 29 namespace gles31 30 { 31 namespace Functional 32 { 33 namespace NegativeTestShared 34 { 35 namespace 36 { 37 38 enum ExpectResult 39 { 40 EXPECT_RESULT_PASS = 0, 41 EXPECT_RESULT_FAIL, 42 EXPECT_RESULT_LAST 43 }; 44 45 void verifyShader (NegativeTestContext& ctx, glu::ShaderType shaderType, std::string shaderSource, ExpectResult expect) 46 { 47 DE_ASSERT(expect >= EXPECT_RESULT_PASS && expect < EXPECT_RESULT_LAST); 48 49 tcu::TestLog& log = ctx.getLog(); 50 bool testFailed = false; 51 const char* const source = shaderSource.c_str(); 52 const int length = (int) shaderSource.size(); 53 glu::Shader shader (ctx.getRenderContext(), shaderType); 54 std::string message; 55 56 shader.setSources(1, &source, &length); 57 shader.compile(); 58 59 log << shader; 60 61 if (expect == EXPECT_RESULT_PASS) 62 { 63 testFailed = !shader.getCompileStatus(); 64 message = "Shader did not compile."; 65 } 66 else 67 { 68 testFailed = shader.getCompileStatus(); 69 message = "Shader was not expected to compile."; 70 } 71 72 if (testFailed) 73 { 74 log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; 75 ctx.fail(message); 76 } 77 } 78 79 std::string getVersionAndExtension (NegativeTestContext& ctx) 80 { 81 const bool isES32 = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)); 82 const glu::GLSLVersion version = isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES; 83 84 std::string versionAndExtension = glu::getGLSLVersionDeclaration(version); 85 versionAndExtension += " \n"; 86 87 if (!isES32) 88 versionAndExtension += "#extension GL_OES_sample_variables : require \n"; 89 90 return versionAndExtension; 91 } 92 93 void checkSupported (NegativeTestContext& ctx) 94 { 95 const bool isES32 = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)); 96 97 if (!isES32 && !ctx.isExtensionSupported("GL_OES_sample_variables")) 98 TCU_THROW(NotSupportedError, "GL_OES_sample_variables is not supported."); 99 } 100 101 void write_to_read_only_types (NegativeTestContext& ctx) 102 { 103 checkSupported(ctx); 104 105 std::ostringstream shader; 106 107 struct testConfig 108 { 109 std::string builtInType; 110 std::string varyingCheck; 111 } testConfigs[] = 112 { 113 {"gl_SampleID", " lowp int writeValue = 1; \n gl_SampleID = writeValue; \n"}, 114 {"gl_SamplePosition", " mediump vec2 writeValue = vec2(1.0f, 1.0f); \n gl_SamplePosition = writeValue; \n"}, 115 {"gl_SampleMaskIn", " lowp int writeValue = 1; \n gl_SampleMaskIn[0] = writeValue; \n"} 116 }; 117 118 for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++) 119 { 120 shader.str(""); 121 shader 122 << getVersionAndExtension(ctx) 123 << "layout (location = 0) out mediump vec4 fs_color; \n" 124 << "void main() \n" 125 << "{ \n" 126 << testConfigs[idx].varyingCheck 127 << " fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n" 128 << "} \n"; 129 130 ctx.beginSection("OES_sample_variables: trying to write to built-in read-only variable" + testConfigs[idx].builtInType); 131 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL); 132 ctx.endSection(); 133 } 134 } 135 136 void access_built_in_types_inside_other_shaders (NegativeTestContext& ctx) 137 { 138 checkSupported(ctx); 139 140 if ((!ctx.isExtensionSupported("GL_EXT_tessellation_shader") && !ctx.isExtensionSupported("GL_OES_tessellation_shader")) || 141 (!ctx.isExtensionSupported("GL_EXT_geometry_shader") && !ctx.isExtensionSupported("GL_OES_geometry_shader"))) 142 { 143 TCU_THROW(NotSupportedError, "tessellation and geometry shader extensions not supported"); 144 } 145 146 std::ostringstream shader; 147 148 struct testConfig 149 { 150 std::string builtInType; 151 std::string varyingCheck; 152 } testConfigs[] = 153 { 154 {"gl_SampleID", " lowp int writeValue = 1; \n gl_SampleID = writeValue; \n"}, 155 {"gl_SamplePosition", " mediump vec2 writeValue = vec2(1.0f, 1.0f); \n gl_SamplePosition = writeValue; \n"}, 156 {"gl_SampleMaskIn", " lowp int writeValue = 1; \n gl_SampleMaskIn[0] = writeValue; \n"}, 157 {"gl_SampleMask", " highp int readValue = gl_SampleMask[0]; \n"}, 158 }; 159 160 for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++) 161 { 162 shader.str(""); 163 shader 164 << getVersionAndExtension(ctx) 165 << "void main () \n" 166 << "{ \n" 167 << testConfigs[idx].varyingCheck 168 << " gl_Position = vec4(1.0f, 0.0f, 0.0f , 1.0f); \n" 169 << "} \n"; 170 171 ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside vertex shader"); 172 verifyShader(ctx, glu::SHADERTYPE_VERTEX, shader.str(), EXPECT_RESULT_FAIL); 173 ctx.endSection(); 174 } 175 176 for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++) 177 { 178 shader.str(""); 179 shader 180 << getVersionAndExtension(ctx) 181 << "layout (vertices = 3) out; \n" 182 << "void main () \n" 183 << "{ \n" 184 << testConfigs[idx].varyingCheck 185 << "} \n"; 186 187 ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside tessellation control shader"); 188 verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, shader.str(), EXPECT_RESULT_FAIL); 189 ctx.endSection(); 190 } 191 192 for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++) 193 { 194 shader.str(""); 195 shader 196 << getVersionAndExtension(ctx) 197 << "layout (triangles, equal_spacing, ccw) in; \n" 198 << "void main () \n" 199 << "{ \n" 200 << testConfigs[idx].varyingCheck 201 << "} \n"; 202 203 ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside tessellation evaluation shader"); 204 verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_EVALUATION, shader.str(), EXPECT_RESULT_FAIL); 205 ctx.endSection(); 206 } 207 208 for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++) 209 { 210 shader.str(""); 211 shader 212 << getVersionAndExtension(ctx) 213 << "layout (triangles) in; \n" 214 << "layout (triangle_strip, max_vertices = 32) out; \n" 215 << "void main () \n" 216 << "{ \n" 217 << testConfigs[idx].varyingCheck 218 << "} \n"; 219 220 ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside geometry shader"); 221 verifyShader(ctx, glu::SHADERTYPE_GEOMETRY, shader.str(), EXPECT_RESULT_FAIL); 222 ctx.endSection(); 223 } 224 } 225 226 void index_outside_sample_mask_range (NegativeTestContext& ctx) 227 { 228 checkSupported(ctx); 229 230 std::ostringstream shader; 231 const int MAX_TYPES = 2; 232 const int MAX_INDEXES = 2; 233 234 struct testConfig 235 { 236 std::string builtInType[MAX_TYPES]; 237 std::string invalidIndex[MAX_INDEXES]; 238 } testConfigs = 239 { 240 { 241 "gl_SampleMask", 242 "gl_SampleMaskIn" 243 }, 244 { 245 " const highp int invalidIndex = (gl_MaxSamples + 31) / 32; \n", 246 " const highp int invalidIndex = -1; \n" 247 } 248 }; 249 250 for (int typeIdx = 0; typeIdx < MAX_TYPES; typeIdx++) 251 { 252 for (int invalidIdx = 0; invalidIdx < MAX_INDEXES; invalidIdx++) 253 { 254 shader.str(""); 255 shader 256 << getVersionAndExtension(ctx) 257 << "layout (location = 0) out mediump vec4 fs_color; \n" 258 << "void main() \n" 259 << "{ \n" 260 << testConfigs.invalidIndex[invalidIdx] 261 << " highp int invalidValue = " << testConfigs.builtInType[typeIdx] << "[invalidIndex]; \n" 262 << " fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n" 263 << "} \n"; 264 265 ctx.beginSection("OES_sample_variables: using constant integral expression outside of " + testConfigs.builtInType[typeIdx] + " bounds"); 266 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL); 267 ctx.endSection(); 268 } 269 } 270 } 271 272 void access_built_in_types_without_extension (NegativeTestContext& ctx) 273 { 274 checkSupported(ctx); 275 276 std::ostringstream shader; 277 278 struct testConfig 279 { 280 std::string builtInType; 281 std::string varyingCheck; 282 } testConfigs[] = 283 { 284 {"gl_SampleID", " lowp int writeValue = 1; \n gl_SampleID = writeValue; \n"}, 285 {"gl_SamplePosition", " mediump vec2 writeValue = vec2(1.0f, 1.0f); \n gl_SamplePosition = writeValue; \n"}, 286 {"gl_SampleMaskIn", " lowp int writeValue = 1; \n gl_SampleMaskIn[0] = writeValue; \n"}, 287 {"gl_SampleMask", " highp int readValue = gl_SampleMask[0]; \n"}, 288 }; 289 290 for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++) 291 { 292 shader.str(""); 293 shader 294 << "#version 310 es \n" 295 << "layout (location = 0) out mediump vec4 fs_color; \n" 296 << "void main() \n" 297 << "{ \n" 298 << testConfigs[idx].varyingCheck 299 << " fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n" 300 << "} \n"; 301 302 ctx.beginSection("OES_sample_variables: accessing built-in type " + testConfigs[idx].builtInType + " in shader version 310 ES without required extension"); 303 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL); 304 ctx.endSection(); 305 } 306 } 307 308 void redeclare_built_in_types (NegativeTestContext& ctx) 309 { 310 checkSupported(ctx); 311 312 std::ostringstream shader; 313 std::ostringstream testName; 314 315 const char* const testConfigs[] = 316 { 317 "gl_SampleID", 318 "gl_SamplePosition", 319 "gl_SampleMaskIn", 320 "gl_SampleMask", 321 }; 322 323 for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++) 324 { 325 shader.str(""); 326 shader 327 << getVersionAndExtension(ctx) 328 << "layout (location = 0) out mediump vec4 fs_color; \n" 329 << "uniform lowp int " << testConfigs[idx] << "; \n" 330 << "void main() \n" 331 << "{ \n" 332 << " if (" << testConfigs[idx] << " == 0) \n" 333 << " fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n" 334 << " else \n" 335 << " fs_color = vec4(0.0f, 1.0f, 0.0f, 1.0f); \n" 336 << "} \n"; 337 338 testName.str(""); 339 testName << "OES_sample_variables: redeclare built-in type " << testConfigs[idx]; 340 ctx.beginSection(testName.str()); 341 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL); 342 ctx.endSection(); 343 } 344 } 345 346 } // anonymous 347 348 std::vector<FunctionContainer> getNegativeSampleVariablesTestFunctions (void) 349 { 350 const FunctionContainer funcs[] = 351 { 352 {write_to_read_only_types, "write_to_read_only_types", "tests trying writing to read-only built-in sample variables"}, 353 {access_built_in_types_inside_other_shaders, "access_built_in_types_inside_other_shaders", "Tests try to access fragment shader sample variables in other shaders"}, 354 {index_outside_sample_mask_range, "index_outside_sample_mask_range", "tests try to index into built-in sample array types out of bounds"}, 355 {access_built_in_types_without_extension, "access_built_in_types_without_extension", "tests try to access built-in sample types without the correct extension using version 310 es"}, 356 {redeclare_built_in_types, "redeclare_built_in_types", "Tests try to redeclare built-in sample types"}, 357 }; 358 359 return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs)); 360 } 361 362 } // NegativeTestShared 363 } // Functional 364 } // gles31 365 } // deqp 366