/** * Generate a vertex or fragment shader to test the given set of * varyings. */ static GLint get_shader(bool is_vs, unsigned glsl_version, int num_varyings, struct varying_desc *varyings, enum test_array_type array_type) { GLuint shader; char *full_text = malloc(1000 * 100 + num_varyings); char *text = full_text; unsigned i, j, k, l, m; const char *varying_keyword; unsigned offset = 0; GLenum shader_type = is_vs ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER; bool fp64 = false; if (glsl_version >= 130) { if (is_vs) varying_keyword = "out"; else varying_keyword = "in"; } else { varying_keyword = "varying"; } text += sprintf(text, "#version %u\n", glsl_version); if (array_type == ARRAYS_OF_ARRAYS) text += sprintf(text, "#extension GL_ARB_arrays_of_arrays: enable\n"); for (i = 0; i < num_varyings; ++i) { const char *opt_flat_keyword = ""; if (!fp64 && varyings[i].type->base == BASE_TYPE_DOUBLE) { text += sprintf(text, "#extension GL_ARB_gpu_shader_fp64: enable\n"); fp64 = true; } if (varyings[i].type->base != BASE_TYPE_FLOAT) opt_flat_keyword = "flat "; if (varyings[i].two_dim_array_elems != 0) { text += sprintf(text, "%s%s %s var%03u[%u][%u];\n", opt_flat_keyword, varying_keyword, varyings[i].type->name, i, outer_dim_size, varyings[i].two_dim_array_elems); } else if (varyings[i].one_dim_array_elems != 0) { text += sprintf(text, "%s%s %s var%03u[%u];\n", opt_flat_keyword, varying_keyword, varyings[i].type->name, i, varyings[i].one_dim_array_elems); } else { text += sprintf(text, "%s%s %s var%03u;\n", opt_flat_keyword, varying_keyword, varyings[i].type->name, i); } } if (glsl_version >= 150 && is_vs) { text += sprintf(text, "in vec4 piglit_vertex;\n"); text += sprintf(text, "#define gl_Vertex piglit_vertex\n"); } text += sprintf(text, "uniform int i;\n"); text += sprintf(text, "\n" "void main()\n" "{\n"); if (is_vs) text += sprintf(text, " gl_Position = gl_Vertex;\n"); else text += sprintf(text, " bool failed = false;\n"); for (i = 0; i < num_varyings; ++i) { unsigned array_loop_bound; unsigned outer_array_loop_bound = 1; const char *base_type_name = get_base_type_name(varyings[i].type->base); if (varyings[i].two_dim_array_elems != 0) { outer_array_loop_bound = outer_dim_size; array_loop_bound = varyings[i].two_dim_array_elems; } else { array_loop_bound = varyings[i].one_dim_array_elems; } if (array_loop_bound == 0) array_loop_bound = 1; for (j = 0; j < outer_array_loop_bound; ++j) { for (k = 0; k < array_loop_bound; ++k) { for (l = 0; l < varyings[i].type->num_cols; ++l) { for (m = 0; m < varyings[i].type->num_rows; ++m) { text += sprintf(text, " "); if (!is_vs) text += sprintf(text, "failed = failed || "); text += sprintf(text, "var%03u", i); if (varyings[i].two_dim_array_elems) text += sprintf(text, "[%u]", j); if (varyings[i].one_dim_array_elems || varyings[i].two_dim_array_elems) text += sprintf(text, "[%u]", k); if (varyings[i].type->num_cols > 1) text += sprintf(text, "[%u]", l); if (varyings[i].type->num_rows > 1) text += sprintf(text, "[%u]", m); if (is_vs) text += sprintf(text, " = "); else text += sprintf(text, " != "); text += sprintf(text, "%s(i + %u);\n", base_type_name, offset++); } } } } } if (!is_vs) { text += sprintf(text, " if (failed)\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" " else\n" " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"); } text += sprintf(text, "}\n"); shader = piglit_compile_shader_text(shader_type, full_text); free(full_text); return shader; }
/** * Generate a vertex or fragment shader to test the given set of * varyings. */ static GLint get_shader(bool is_vs, unsigned glsl_version, int num_varyings, struct varying_desc *varyings) { GLuint shader; char *full_text = malloc(1000 * 100 + num_varyings); char *text = full_text; unsigned i, j, k, l; const char *varying_keyword; unsigned offset = 0; GLenum shader_type = is_vs ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER; if (glsl_version >= 130) { if (is_vs) varying_keyword = "out"; else varying_keyword = "in"; } else { varying_keyword = "varying"; } text += sprintf(text, "#version %u\n", glsl_version); text += sprintf(text, "uniform int i;\n"); for (i = 0; i < num_varyings; ++i) { const char *opt_flat_keyword = ""; if (varyings[i].type->base != BASE_TYPE_FLOAT) opt_flat_keyword = "flat "; if (varyings[i].array_elems != 0) { text += sprintf(text, "%s%s %s var%u[%u];\n", opt_flat_keyword, varying_keyword, varyings[i].type->name, i, varyings[i].array_elems); } else { text += sprintf(text, "%s%s %s var%u;\n", opt_flat_keyword, varying_keyword, varyings[i].type->name, i); } } text += sprintf(text, "\n" "void main()\n" "{\n"); if (is_vs) text += sprintf(text, " gl_Position = gl_Vertex;\n"); else text += sprintf(text, " bool failed = false;\n"); for (i = 0; i < num_varyings; ++i) { unsigned array_loop_bound = varyings[i].array_elems; const char *base_type_name = get_base_type_name(varyings[i].type->base); if (array_loop_bound == 0) array_loop_bound = 1; for (j = 0; j < array_loop_bound; ++j) { for (k = 0; k < varyings[i].type->num_cols; ++k) { for (l = 0; l < varyings[i].type->num_rows; ++l) { text += sprintf(text, " "); if (!is_vs) text += sprintf(text, "if ("); text += sprintf(text, "var%u", i); if (varyings[i].array_elems) text += sprintf(text, "[%u]", j); if (varyings[i].type->num_cols > 1) text += sprintf(text, "[%u]", k); if (varyings[i].type->num_rows > 1) text += sprintf(text, "[%u]", l); if (is_vs) text += sprintf(text, " = "); else text += sprintf(text, " != "); text += sprintf(text, "%s(i + %u)", base_type_name, offset++); if (is_vs) { text += sprintf(text, ";\n"); } else { text += sprintf(text, ")\n" " failed = true;\n"); } } } } } if (!is_vs) { text += sprintf(text, " if (failed)\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" " else\n" " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"); } text += sprintf(text, "}\n"); shader = piglit_compile_shader_text(shader_type, full_text); free(full_text); return shader; }