[Piglit] [PATCH 1/2] Add a new textureLod test case, similar to texelFetch. GLSL textureLod and textureLodOffset functions available in VS, GS, FS
Steve Miller
dervishx at gmail.com
Mon Sep 16 10:26:29 PDT 2013
From: Kenneth Graunke <kenneth at whitecape.org>
>From GLSL Spec 1.50 Section 8.7 (Texture Lookup Functions):
"Texture lookup functions are available to vertex, geometry, and fragment
shaders."
Test sampler types avaiable for texture lookup functions in vertex, geometry, and fragment shading stages of the pipeline:
For each pixel we want to display, generate a single texel and color it
according to a texture lookup during the chose stage of the pipeline.
The color is unique to its eventual position on screen.
Sampler types tested: sampler1D/2D/3D, sampler1D/2DArray
not tested: samplerCube, sampler1D/2DShadow, sampler1DArrayShadow
Credit for this test goes to Kenneth Graunke <kenneth at whitecape.org>
Fixed up by Steve Miller <dervishx at gmail.com>
---
tests/all.tests | 8 +
tests/texturing/shaders/CMakeLists.gl.txt | 1 +
tests/texturing/shaders/texelFetch.c | 2 +-
tests/texturing/shaders/textureLod.c | 715 ++++++++++++++++++++++++++++++
4 files changed, 725 insertions(+), 1 deletion(-)
create mode 100644 tests/texturing/shaders/textureLod.c
diff --git a/tests/all.tests b/tests/all.tests
index dc36841..d06ec00 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -876,6 +876,14 @@ for stage in ['vs', 'gs', 'fs']:
'texelFetch {0} {1}sampler2DArray b0r1'.format(
stage, type))
+ # textureLod():
+ # XXX: samplerCube
+ for sampler in ['sampler1D', 'sampler2D', 'sampler3D', 'sampler1DArray', 'sampler2DArray', 'isampler1D', 'isampler2D', 'isampler3D', 'isampler1DArray', 'isampler2DArray', 'usampler1D', 'usampler2D', 'usampler3D', 'usampler1DArray', 'usampler2DArray']:
+ profile.test_list['glsl-1.30/execution/textureLod/' + stage + '-textureLod-' + sampler] = PlainExecTest(['textureLod', stage, sampler, '-auto', '-fbo'])
+ # textureLod() with EXT_texture_swizzle mode "b0r1":
+ for type in ['i', 'u', '']:
+ profile.test_list['glsl-1.30/execution/textureLod/' + stage + '-textureLod-' + type + 'sampler2DArray-swizzle'] = PlainExecTest(['textureLod', stage, type + 'sampler2DArray', 'b0r1', '-auto', '-fbo'])
+
add_plain_test(spec['glsl-1.30']['execution'], 'fs-texelFetch-2D')
add_plain_test(spec['glsl-1.30']['execution'], 'fs-texelFetchOffset-2D')
add_shader_test_dir(spec['glsl-1.30']['execution'],
diff --git a/tests/texturing/shaders/CMakeLists.gl.txt b/tests/texturing/shaders/CMakeLists.gl.txt
index 7210c1c..272bbf6 100644
--- a/tests/texturing/shaders/CMakeLists.gl.txt
+++ b/tests/texturing/shaders/CMakeLists.gl.txt
@@ -12,3 +12,4 @@ link_libraries (
piglit_add_executable (textureSize textureSize.c common.c)
piglit_add_executable (texelFetch texelFetch.c common.c)
+piglit_add_executable (textureLod textureLod.c common.c)
diff --git a/tests/texturing/shaders/texelFetch.c b/tests/texturing/shaders/texelFetch.c
index badaac7..d10a5d6 100644
--- a/tests/texturing/shaders/texelFetch.c
+++ b/tests/texturing/shaders/texelFetch.c
@@ -759,7 +759,7 @@ generate_GLSL(enum shader_target test_stage)
void
set_base_size()
{
- base_size[0] = 65;
+ base_size[0] = 65;
base_size[1] = has_height() ? 32 : 1;
base_size[2] = has_slices() ? 5 : 1;
}
diff --git a/tests/texturing/shaders/textureLod.c b/tests/texturing/shaders/textureLod.c
new file mode 100644
index 0000000..1cd4ad9
--- /dev/null
+++ b/tests/texturing/shaders/textureLod.c
@@ -0,0 +1,715 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file textureLod.c
+ *
+ * Tests the GLSL 1.30+ textureLod() built-in function.
+ *
+ * The "textureLod" binary takes two arguments: shader stage and sampler type.
+ *
+ * For example:
+ * ./bin/textureLod fs sampler1DArray
+ * ./bin/textureLod usampler3D vs
+ *
+ * The test covers:
+ * - All pipeline stages (VS, GS, FS)
+ * - Integer and floating point texture formats
+ * - Sampler dimensionality (1D, 2D, 3D, 1DArray, 2DArray)
+ * - Mipmapping
+ * - Non-power-of-two textures
+ *
+ * Draws a series of "rectangles" which display each miplevel and array slice,
+ * at full size. They are layed out as follows:
+ *
+ * miplevel 3 + + + + +
+ *
+ * miplevel 2 +-+ +-+ +-+ +-+ +-+
+ * +-+ +-+ +-+ +-+ +-+
+ *
+ * miplevel 1 +---+ +---+ +---+ +---+ +---+
+ * | | | | | | | | | |
+ * +---+ +---+ +---+ +---+ +---+
+ *
+ * +------+ +------+ +------+ +------+ +------+
+ * miplevel 0 | | | | | | | | | |
+ * | | | | | | | | | |
+ * +------+ +------+ +------+ +------+ +------+
+ * slice #0 slice #1 slice #2 slice #3 slice #4
+ *
+ * Normally, we could draw each rectangle as a single quad (or two triangles),
+ * interpolate the texture coordinates across the primitive, and let the
+ * fragment shader look up the color values from the texture.
+ *
+ * However, this fails miserably for vertex shader texturing: a quad only has
+ * four vertices, which means we could only fetch/display at most 4 texels.
+ * If we used a simple RGBW checkerboard, as in other Piglit tests, this would
+ * only tell us that we sampled somewhere in the right 1/4 of the texture.
+ *
+ * Instead, we take a clever approach: draw each "rectangle" via a series of
+ * 1-pixel wide GL_POINT primitives. This gives us one vertex per pixel; by
+ * drawing the texture at full size, each pixel and vertex also correspond to
+ * exactly one texel. So every texel is sampled and verified for correctness.
+ *
+ * In other words: "One pixel, one texel, one vertex."
+ *
+ * For convenience, we take the same approach for fragment shader testing
+ * as well, since it allows us to reuse the same VBO setup and drawing code.
+ */
+#include "common.h"
+
+void
+parse_args(int argc, char **argv);
+
+static enum shader_target test_stage = UNKNOWN;
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ parse_args(argc, argv);
+ if (test_stage == GS) {
+ config.supports_gl_compat_version = 32;
+ config.supports_gl_core_version = 32;
+ } else {
+ config.supports_gl_compat_version = 10;
+ config.supports_gl_core_version = 31;
+ }
+
+ config.window_width = 355;
+ config.window_height = 350;
+ config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+/** Vertex shader attribute locations */
+const int pos_loc = 0;
+const int texcoord_loc = 1;
+
+/** Whether we're testing textureLodOffset() instead of textureLod(). */
+static bool test_offset = false;
+const int fetch_x_offset = 7;
+const int fetch_y_offset = -8;
+const int fetch_z_offset = 4;
+const char *fetch_1d_arg = ", int(7)";
+const char *fetch_2d_arg = ", ivec2(7, -8)";
+const char *fetch_3d_arg = ", ivec3(7, -8, 4)";
+
+/** Uniform locations */
+int divisor_loc;
+
+/**
+ * Expected color data for each rectangle drawn, indexed by miplevel and slice.
+ * For example, expected_colors[1][3] contains the data for miplevel 1 slice 3.
+ */
+float ***expected_colors;
+
+/**
+ * Return the divisors necessary to scale the unnormalized texture data to
+ * a floating point color value in the range [0, 1].
+ */
+static void
+compute_divisors(int lod, float *divisors)
+{
+ divisors[0] = max2(level_size[lod][0] - 1, 1);
+ divisors[1] = max2(level_size[lod][1] - 1, 1);
+ divisors[2] = max2(level_size[lod][2] - 1, 1);
+ divisors[3] = 1.0;
+
+ if (sampler.data_type != GL_UNSIGNED_INT)
+ divisors[0] = -divisors[0];
+}
+
+enum piglit_result
+piglit_display()
+{
+ int i, l, z;
+ bool pass = true;
+
+ glViewport(0, 0, piglit_width, piglit_height);
+
+ glClearColor(0.1, 0.1, 0.1, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glPointSize(1.0);
+
+ i = 0;
+ for (l = 0; l < miplevels; ++l) {
+ for (z = 0; z < level_size[l][2]; z++) {
+ /* Draw the "rectangle" for this miplevel/slice. */
+ int points = level_size[l][0] * level_size[l][1];
+ float divisors[4];
+
+ compute_divisors(l, divisors);
+ swizzle(divisors);
+ glUniform4fv(divisor_loc, 1, divisors);
+
+ glDrawArrays(GL_POINTS, i, points);
+
+ i += points;
+
+ /* Compare results against reference image. */
+ pass &= piglit_probe_image_rgba(5+(5+base_size[0]) * z,
+ 5+(5+base_size[1]) * l,
+ level_size[l][0],
+ level_size[l][1],
+ expected_colors[l][z]);
+ }
+ }
+
+ piglit_present_results();
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+/**
+ * Generate two VBOs for our vertex attributes:
+ * 1. Pixel position (in window coordinates).
+ * 2. Texture coordinates.
+ *
+ * The VBOs contain the data for every rectangle being drawn (as opposed to
+ * creating and binding a separate VBO per miplevel/slice.)
+ */
+void
+generate_VBOs()
+{
+ int x, y, z, l;
+ GLuint pos_vbo, tc_vbo;
+ float *pos, *pos_data;
+ float *tc, *tc_data;
+ bool array_1D = sampler.target == GL_TEXTURE_1D_ARRAY;
+ int num_texels = 0;
+
+ /* Calculate the # of texels a.k.a. size of the VBOs */
+ for (l = 0; l < miplevels; l++) {
+ num_texels += level_size[l][0] * level_size[l][1] * level_size[l][2];
+ }
+
+ pos = pos_data = malloc(num_texels * 4 * sizeof(float));
+ tc = tc_data = malloc(num_texels * 4 * sizeof(int));
+
+ for (l = 0; l < miplevels; l++) {
+ for (z = 0; z < level_size[l][2]; z++) {
+ for (y = 0; y < level_size[l][1]; y++) {
+ for (x = 0; x < level_size[l][0]; x++) {
+ /* Assign pixel positions: */
+ pos[0] = 5.5 + (5 + base_size[0])*z + x;
+ pos[1] = 5.5 + (5 + base_size[1])*l + y;
+ pos[2] = 0.0;
+ pos[3] = 1.0;
+
+ pos[0] = -1.0 + 2.0 * (pos[0] /
+ piglit_width);
+ pos[1] = -1.0 + 2.0 * (pos[1] /
+ piglit_height);
+
+ pos += 4;
+
+ /* Assign texture coordinates:
+ * 1D: x _ _ l
+ * 2D: x y _ l
+ * 3D: x y z l
+ * 1DArray: x z _ l
+ * 2DArray: x y z l
+ */
+ if (sampler.target == GL_TEXTURE_RECTANGLE) {
+ tc[0] = x;
+ tc[1] = y;
+ tc[2] = z;
+ } else {
+ tc[0] = (float) x / ((float) level_size[l][0] - 1);
+ tc[1] = array_1D ? z : (float) y / ((float) level_size[l][1] -1);
+ if (sampler.target == GL_TEXTURE_3D)
+ tc[2] = (float) z / ((float) level_size[l][2] - 1);
+ else
+ tc[2] = z;
+
+ if (test_offset) {
+ tc[0] -= (float) fetch_x_offset / ((float) level_size[l][0]);
+ if (sampler.target != GL_TEXTURE_1D_ARRAY)
+ tc[1] -= (float) fetch_y_offset / ((float) level_size[l][1]);
+ if (sampler.target != GL_TEXTURE_2D_ARRAY)
+ tc[2] -= (float) fetch_z_offset / ((float) level_size[l][2]);
+ }
+ }
+
+
+ tc[3] = l;
+ tc += 4;
+ }
+ }
+ }
+ }
+
+ if (piglit_get_gl_version() >= 31) {
+ GLuint vao;
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+ }
+
+ /* Create VBO for pixel positions in NDC: */
+ glGenBuffers(1, &pos_vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, pos_vbo);
+ glBufferData(GL_ARRAY_BUFFER,
+ num_texels * 4 * sizeof(float),
+ pos_data, GL_STATIC_DRAW);
+ glVertexAttribPointer(pos_loc, 4, GL_FLOAT, false, 0, 0);
+ glEnableVertexAttribArray(pos_loc);
+
+ /* Create VBO for texture coordinates: */
+ glGenBuffers(1, &tc_vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, tc_vbo);
+ glBufferData(GL_ARRAY_BUFFER,
+ num_texels * 4 * sizeof(float),
+ tc_data, GL_STATIC_DRAW);
+ glVertexAttribPointer(texcoord_loc, 4, GL_FLOAT, false, 0, 0);
+ glEnableVertexAttribArray(texcoord_loc);
+}
+
+/**
+ * Create texel data.
+ */
+void
+generate_texture()
+{
+ int l, x, y, z;
+ unsigned *u_level, *u_ptr;
+ int *i_level, *i_ptr;
+ float *f_level, *f_ptr;
+ float *expected_ptr;
+ void *level_image;
+ float divisors[4];
+ GLuint tex;
+ GLenum target = sampler.target;
+
+ glActiveTexture(GL_TEXTURE0);
+
+ glGenTextures(1, &tex);
+ glBindTexture(target, tex);
+
+ if (sampler.target == GL_TEXTURE_RECTANGLE) {
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ } else {
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ if (swizzling)
+ glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA,
+ (GLint *) sampler.swizzle);
+
+ expected_colors = calloc(miplevels, sizeof(float **));
+
+ for (l = 0; l < miplevels; l++) {
+ expected_colors[l] = calloc(level_size[l][2], sizeof(float **));
+
+ i_ptr = i_level =
+ malloc(level_size[l][0] * level_size[l][1] *
+ level_size[l][2] * 4 * sizeof(int));
+
+ u_ptr = u_level =
+ malloc(level_size[l][0] * level_size[l][1] *
+ level_size[l][2] * 4 * sizeof(unsigned));
+
+ f_ptr = f_level =
+ malloc(level_size[l][0] * level_size[l][1] *
+ level_size[l][2] * 4 * sizeof(float));
+
+ for (z = 0; z < level_size[l][2]; z++) {
+ expected_ptr = expected_colors[l][z] =
+ malloc(level_size[l][0] * level_size[l][1] *
+ level_size[l][2] * 4 * sizeof(float));
+ for (y = 0; y < level_size[l][1]; y++) {
+ for (x = 0; x < level_size[l][0]; x++) {
+ int nx = sampler.data_type == GL_UNSIGNED_INT ? x : -x;
+ f_ptr[0] = nx;
+ f_ptr[1] = y;
+ f_ptr[2] = z;
+ f_ptr[3] = 1.0;
+
+ i_ptr[0] = nx;
+ i_ptr[1] = y;
+ i_ptr[2] = z;
+ i_ptr[3] = 1;
+
+ u_ptr[0] = nx;
+ u_ptr[1] = y;
+ u_ptr[2] = z;
+ u_ptr[3] = 1;
+
+ compute_divisors(l, divisors);
+
+ expected_ptr[0] = f_ptr[0]/divisors[0];
+ expected_ptr[1] = f_ptr[1]/divisors[1];
+ expected_ptr[2] = f_ptr[2]/divisors[2];
+ expected_ptr[3] = 1.0;
+ swizzle(expected_ptr);
+
+ f_ptr += 4;
+ i_ptr += 4;
+ u_ptr += 4;
+ expected_ptr += 4;
+ }
+ }
+ }
+
+ switch (sampler.data_type) {
+ case GL_FLOAT:
+ level_image = f_level;
+ break;
+ case GL_UNSIGNED_INT:
+ level_image = u_level;
+ break;
+ case GL_INT:
+ level_image = i_level;
+ break;
+ default:
+ assert(!"Unexpected data type");
+ level_image = NULL;
+ break;
+ }
+
+ upload_miplevel_data(target, l, level_image);
+ }
+
+}
+
+/**
+ * How many components are in the coordinate?
+ */
+static int
+coordinate_size()
+{
+ switch (sampler.target) {
+ case GL_TEXTURE_1D:
+ return 1;
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_1D_ARRAY:
+ case GL_TEXTURE_RECTANGLE:
+ return 2;
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_2D_ARRAY:
+ return 3;
+ default:
+ assert(!"Should not get here.");
+ return 0;
+ }
+}
+
+/**
+ * Generate, compile, and link the GLSL shaders.
+ */
+int
+generate_GLSL(enum shader_target test_stage)
+{
+ int vs, gs, fs, prog;
+
+ static char *vs_code;
+ static char *gs_code = NULL;
+ static char *fs_code;
+
+ const char *offset_func, *offset_arg;
+
+ if (test_offset) {
+ offset_func = "Offset";
+ switch (sampler.target) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_1D_ARRAY:
+ offset_arg = fetch_1d_arg;
+ break;
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_RECTANGLE:
+ offset_arg = fetch_2d_arg;
+ break;
+ case GL_TEXTURE_3D:
+ offset_arg = fetch_3d_arg;
+ break;
+ default:
+ assert(!"Unexpected target texture");
+ offset_arg = "";
+ break;
+ }
+ } else {
+ offset_func = "";
+ offset_arg = "";
+ }
+
+ switch (test_stage) {
+ case VS:
+ asprintf(&vs_code,
+ "#version %d\n"
+ "#define vec1 float\n"
+ "flat out %s color;\n"
+ "in vec4 pos;\n"
+ "in vec4 texcoord;\n"
+ "uniform %s tex;\n"
+ "void main()\n"
+ "{\n"
+ " color = textureLod%s(tex, vec%d(texcoord),\n"
+ " texcoord.w%s);\n"
+ " gl_Position = pos;\n"
+ "}\n",
+ shader_version,
+ sampler.return_type, sampler.name, offset_func,
+ coordinate_size(), offset_arg);
+ asprintf(&fs_code,
+ "#version %d\n"
+ "flat in %s color;\n"
+ "uniform vec4 divisor;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = vec4(color)/divisor;\n"
+ "}\n",
+ shader_version,
+ sampler.return_type);
+ break;
+ case GS:
+ asprintf(&vs_code,
+ "#version %d\n"
+ "in vec4 pos;\n"
+ "in vec4 texcoord;\n"
+ "flat out vec4 texcoord_to_gs;\n"
+ "out vec4 pos_to_gs;\n"
+ "void main()\n"
+ "{\n"
+ " texcoord_to_gs = texcoord;\n"
+ " pos_to_gs = pos;\n"
+ "}\n",
+ shader_version);
+ asprintf(&gs_code,
+ "#version %d\n"
+ "%s\n"
+ "#define vec1 float\n"
+ "layout(points) in;\n"
+ "layout(points, max_vertices = 1) out;\n"
+ "flat out %s color;\n"
+ "flat in vec4 texcoord_to_gs[1];\n"
+ "in vec4 pos_to_gs[1];\n"
+ "uniform %s tex;\n"
+ "void main()\n"
+ "{\n"
+ " vec4 texcoord = texcoord_to_gs[0];\n"
+ " color = textureLod%s(tex, vec%d(texcoord)%s%s);\n"
+ " gl_Position = pos_to_gs[0];\n"
+ " EmitVertex();\n"
+ "}\n",
+ shader_version,
+ has_samples() ? "#extension GL_ARB_texture_multisample: require" : "",
+ sampler.return_type, sampler.name,
+ offset_func,
+ coordinate_size(),
+ ((sampler.target == GL_TEXTURE_RECTANGLE) ?
+ "" : ", texcoord.w"),
+ offset_arg);
+ asprintf(&fs_code,
+ "#version %d\n"
+ "flat in %s color;\n"
+ "uniform vec4 divisor;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = vec4(color)/divisor;\n"
+ "}\n",
+ shader_version,
+ sampler.return_type);
+ break;
+ case FS:
+ asprintf(&vs_code,
+ "#version %d\n"
+ "in vec4 pos;\n"
+ "in vec4 texcoord;\n"
+ "flat out vec4 tc;\n"
+ "void main()\n"
+ "{\n"
+ " tc = texcoord;\n"
+ " gl_Position = pos;\n"
+ "}\n",
+ shader_version);
+ asprintf(&fs_code,
+ "#version %d\n"
+ "#define vec1 float\n"
+ "flat in vec4 tc;\n"
+ "uniform vec4 divisor;\n"
+ "uniform %s tex;\n"
+ "void main()\n"
+ "{\n"
+ " vec4 color = textureLod%s(tex, vec%d(tc), tc.w%s);\n"
+ " gl_FragColor = color/divisor;\n"
+ "}\n",
+ shader_version,
+ sampler.name, offset_func, coordinate_size(), offset_arg);
+ break;
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_code);
+ if (!vs) {
+ printf("VS code:\n%s", vs_code);
+ piglit_report_result(PIGLIT_FAIL);
+ }
+ if (gs_code) {
+ gs = piglit_compile_shader_text(GL_GEOMETRY_SHADER, gs_code);
+ if (!gs) {
+ printf("GS code:\n%s", gs_code);
+ piglit_report_result(PIGLIT_FAIL);
+ }
+ }
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code);
+ if (!fs) {
+ printf("FS code:\n%s", fs_code);
+ piglit_report_result(PIGLIT_FAIL);
+ }
+ prog = glCreateProgram();
+ glAttachShader(prog, vs);
+ if (gs_code)
+ glAttachShader(prog, gs);
+ glAttachShader(prog, fs);
+
+ glBindAttribLocation(prog, pos_loc, "pos");
+ glBindAttribLocation(prog, texcoord_loc, "texcoord");
+
+ glLinkProgram(prog);
+ if (!piglit_link_check_status(prog))
+ piglit_report_result(PIGLIT_FAIL);
+
+ return prog;
+}
+
+/**
+ * Set the size of the texture's base level.
+ */
+void
+set_base_size()
+{
+ base_size[0] = 65;
+ base_size[1] = has_height() ? 32 : 1;
+ base_size[2] = has_slices() ? 5 : 1;
+}
+
+/**
+ * Is this sampler supported by textureLod?
+ */
+static bool
+supported_sampler()
+{
+ switch (sampler.target) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_1D_ARRAY:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_RECTANGLE:
+ return true;
+ }
+ return false;
+}
+
+void
+fail_and_show_usage()
+{
+ printf("Usage: textureLod [140] <vs|gs|fs> <sampler type> "
+ "[swizzle] [piglit args...]\n");
+ piglit_report_result(PIGLIT_FAIL);
+}
+
+void
+parse_args(int argc, char **argv)
+{
+ int i;
+ bool sampler_found = false;
+
+ for (i = 1; i < argc; i++) {
+ if (test_stage == UNKNOWN) {
+ /* Maybe it's the shader stage? */
+ if (strcmp(argv[i], "vs") == 0) {
+ test_stage = VS;
+ continue;
+ } else if (strcmp(argv[i], "gs") == 0) {
+ test_stage = GS;
+ continue;
+ } else if (strcmp(argv[i], "fs") == 0) {
+ test_stage = FS;
+ continue;
+ }
+ }
+
+ if (strcmp(argv[i], "140") == 0) {
+ shader_version = 140;
+ continue;
+ }
+
+ if (strcmp(argv[i], "offset") == 0) {
+ test_offset = true;
+ continue;
+ }
+
+ /* Maybe it's the sampler type? */
+ if (!sampler_found && (sampler_found = select_sampler(argv[i])))
+ continue;
+
+ if (!swizzling && (swizzling = parse_swizzle(argv[i])))
+ continue;
+
+ fail_and_show_usage();
+ }
+
+ if (test_stage == UNKNOWN || !sampler_found)
+ fail_and_show_usage();
+
+ if (test_stage == GS && shader_version < 150)
+ shader_version = 150;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+ int prog;
+ int tex_location;
+
+ if (!supported_sampler()) {
+ printf("%s unsupported\n", sampler.name);
+ piglit_report_result(PIGLIT_FAIL);
+ }
+
+ require_GL_features(test_stage);
+
+ prog = generate_GLSL(test_stage);
+
+ tex_location = glGetUniformLocation(prog, "tex");
+ divisor_loc = glGetUniformLocation(prog, "divisor");
+
+ /* Create textures and set miplevel info */
+ set_base_size();
+ compute_miplevel_info();
+ generate_texture();
+
+ generate_VBOs();
+
+ glUseProgram(prog);
+
+ glUniform1i(tex_location, 0);
+}
--
1.8.3.1
More information about the Piglit
mailing list