Ejemplo n.º 1
0
static bool
check(const struct grid_info grid, const struct image_info img)
{
        const int n = num_images_for_stages(grid, ~0);
        const int m = max_image_units();
        uint32_t pixels[N], expect[N];
        int i;

        for (i = 0; i < N; ++i) {
                if (i < m) {
                        /*
                         * The sum at this location is just the number
                         * of times that the image with index i was
                         * bound to the pipeline.
                         */
                        expect[i] = (n - i + m - 1) / m;
                } else {
                        /*
                         * No image has a non-zero value at this
                         * location, so the sum is zero.
                         */
                        expect[i] = 0;
                }
        }

        return download_result(grid, pixels) &&
                check_pixels_v(img, pixels, expect);
}
Ejemplo n.º 2
0
bool
init_fb(const struct grid_info grid)
{
        bool ret = true;

        if (grid.stages & GL_COMPUTE_SHADER_BIT) {
                const struct image_info img = image_info_for_grid(grid);
                const unsigned n = product(grid.size) *
                        image_num_components(grid.format);
                uint32_t *pixels = malloc(n * sizeof(*pixels));

                ret = init_pixels(img, pixels, 0.5, 0.5, 0.5, 0.5) &&
                        upload_image(img, max_image_units(), pixels);

                free(pixels);
        } else {
                ret = generate_fb(grid, 0);

                glClearColor(0.5, 0.5, 0.5, 0.5);
                glClear(GL_COLOR_BUFFER_BIT);

                glClearDepth(0.5);
                glClear(GL_DEPTH_BUFFER_BIT);
        }

        return ret;
}
Ejemplo n.º 3
0
/**
 * Bind all image uniforms present in the program to the available
 * image units, re-using the same unit several times if necessary in
 * cyclical order.
 */
static bool
bind_images(const struct grid_info grid, GLuint prog)
{
        const unsigned m = max_image_units();
        const struct image_stage_info *stage;

        for (stage = image_stages(); stage->name; ++stage) {
                if (grid.stages & stage->bit) {
                        const unsigned first =
                                num_images_for_stages(grid, stage->bit - 1);
                        const unsigned n = num_images_for_stage(grid, stage);
                        const unsigned stage_idx = stage - image_stages();
                        int i;

                        for (i = 0; i < n; ++i) {
                                char *name = NULL;

                                asprintf(&name, "imgs_%d[%d]", stage_idx, i);

                                if (!set_uniform_int(prog, name,
                                                     (first + i) % m))
                                        return false;

                                free(name);
                        }
                }
        }

        return true;
}
Ejemplo n.º 4
0
/**
 * Bind a number of texture objects to different image units and check
 * that the image unit state was updated correctly.
 */
static bool
run_test_binding(void)
{
        const struct image_unit_action *action;
        bool ret = true;
        int i;

        for (action = actions; action->action; ++action)
                ret &= exec_action(*action);

        for (i = 0; i < max_image_units(); ++i)
                ret &= check_action(get_last_unit_action(i));

        return ret;
}
Ejemplo n.º 5
0
static bool
init_images(const struct image_info img)
{
        uint32_t pixels[N];
        int unit, i;

        for (unit = 0; unit < max_image_units(); ++unit) {
                for (i = 0; i < N; ++i)
                        pixels[i] = (i == unit ? 1 : 0);

                if (!upload_image(img, unit, pixels))
                        return false;
        }

        return true;
}
Ejemplo n.º 6
0
bool
download_result(const struct grid_info grid, uint32_t *r_pixels)
{
        if (grid.stages & GL_COMPUTE_SHADER_BIT) {
                /* No actual framebuffer.  Results are returned into
                 * an image. */
                return download_image(image_info_for_grid(grid),
                                      max_image_units(), r_pixels);

        } else {
                glReadPixels(0, 0, grid.size.x, grid.size.y,
                             grid.format->pixel_format,
                             image_base_type(grid.format),
                             r_pixels);
                return piglit_check_gl_error(GL_NO_ERROR);
        }
}
Ejemplo n.º 7
0
/**
 * Execute the given action.
 */
static bool
exec_action(const struct image_unit_action a)
{
        if (a.action == BIND_NEW) {
                const GLenum format = (get_image_format(a.format) ?
                                       a.format : GL_RGBA32F);
                const struct image_info img = image_info(a.obj, format, W, H);
                const unsigned num_levels = image_num_levels(img);
                uint32_t pixels[4 * N * M] = { 0 };

                if (!upload_image_levels(img, num_levels, 0, a.idx, pixels))
                        return false;

                glBindImageTexture(a.idx, get_texture(a.idx),
                                   a.level, a.layered, a.layer,
                                   a.access, a.format);

        } else if (a.action == BIND_IDX) {
                const unsigned idx = MIN2(a.idx, max_image_units());

                glBindImageTexture(idx, get_texture(a.obj),
                                   a.level, a.layered, a.layer,
                                   a.access, a.format);

        } else if (a.action == BIND_OBJ) {
                glBindImageTexture(a.idx, a.obj,
                                   a.level, a.layered, a.layer,
                                   a.access, a.format);

        } else if (a.action == DELETE_IDX) {
                GLuint tex = get_texture(a.idx);

                glDeleteTextures(1, &tex);

        } else {
                abort();
        }

        return piglit_check_gl_error(a.expect_status);
}
Ejemplo n.º 8
0
/**
 * Test binding image uniforms to image units for a simple shader
 * program.
 */
static bool
run_test_uniform(void)
{
        const struct grid_info grid =
                grid_info(GL_FRAGMENT_SHADER, GL_RGBA32F, W, H);
        GLuint prog = generate_program(
                grid, GL_FRAGMENT_SHADER,
                concat(image_hunk(image_info_for_grid(grid), ""),
                       hunk("uniform IMAGE_T imgs[2];\n"
                            "\n"
                            "GRID_T op(ivec2 idx, GRID_T x) {\n"
                            "        imageStore(imgs[0], IMAGE_ADDR(idx), x);\n"
                            "        imageStore(imgs[1], IMAGE_ADDR(idx), x);\n"
                            "        return x;\n"
                            "}\n"), NULL));
        const int loc = glGetUniformLocation(prog, "imgs");
        bool ret = prog && check_uniform_int(prog, loc, 0) &&
                check_uniform_int(prog, loc + 1, 0);
        int v[2];

        glUseProgram(prog);

        /*
         * Image uniforms are bound to image units using
         * glUniform1i{v}.
         */
        glUniform1i(loc, 3);
        ret &= check_uniform_int(prog, loc, 3) &&
                check_uniform_int(prog, loc + 1, 0);

        glUniform1i(loc + 1, 3);
        ret &= check_uniform_int(prog, loc, 3) &&
                check_uniform_int(prog, loc + 1, 3);

        v[0] = 4;
        v[1] = 5;
        glUniform1iv(loc, 2, v);
        ret &= check_uniform_int(prog, loc, 4) &&
                check_uniform_int(prog, loc + 1, 5);

        /*
         * GL_INVALID_VALUE is generated if the value specified is
         * greater than or equal to the value of GL_MAX_IMAGE_UNITS.
         */
        glUniform1i(loc, max_image_units());
        ret &= piglit_check_gl_error(GL_INVALID_VALUE);

        v[0] = 3;
        v[1] = max_image_units() + 1;
        glUniform1iv(loc, 2, v);
        ret &= piglit_check_gl_error(GL_INVALID_VALUE);

        /*
         * GL_INVALID_VALUE is generated if the value specified is
         * less than zero.
         */
        glUniform1i(loc, -1);
        ret &= piglit_check_gl_error(GL_INVALID_VALUE);

        v[0] = 3;
        v[1] = -4;
        glUniform1iv(loc, 2, v);
        ret &= piglit_check_gl_error(GL_INVALID_VALUE);

        /*
         * GL_INVALID_OPERATION is generated by Uniform* functions
         * other than Uniform1i{v}.
         */
        CHECK_INVAL_2(glUniform, 1f, 1ui, (loc, 0), ret);
        CHECK_INVAL_3(glUniform, 2i, 2f, 2ui, (loc, 0, 0), ret);
        CHECK_INVAL_3(glUniform, 3i, 3f, 3ui, (loc, 0, 0, 0), ret);
        CHECK_INVAL_3(glUniform, 4i, 4f, 4ui, (loc, 0, 0, 0, 0), ret);

        CHECK_INVAL_2(glUniform, 1fv, 1uiv, (loc, 1, (void *)v), ret);
        CHECK_INVAL_3(glUniform, 2iv, 2fv, 2uiv, (loc, 1, (void *)v), ret);
        CHECK_INVAL_3(glUniform, 3iv, 3fv, 3uiv, (loc, 1, (void *)v), ret);
        CHECK_INVAL_3(glUniform, 4iv, 4fv, 4uiv, (loc, 1, (void *)v), ret);

        CHECK_INVAL_3(glUniformMatrix, 2fv, 3fv, 4fv,
                (loc, 1, GL_FALSE, (float *)v), ret);
        CHECK_INVAL_3(glUniformMatrix, 2x3fv, 3x2fv, 2x4fv,
                (loc, 1, GL_FALSE, (float *)v), ret);
        CHECK_INVAL_3(glUniformMatrix, 4x2fv, 3x4fv, 4x3fv,
                (loc, 1, GL_FALSE, (float *)v), ret);

        if (piglit_is_extension_supported("GL_ARB_gpu_shader_fp64")) {
                CHECK_INVAL_1(glUniform, 1d, (loc, 0), ret);
                CHECK_INVAL_1(glUniform, 2d, (loc, 0, 0), ret);
                CHECK_INVAL_1(glUniform, 3d, (loc, 0, 0, 0), ret);
                CHECK_INVAL_1(glUniform, 4d, (loc, 0, 0, 0, 0), ret);

                CHECK_INVAL_2(glUniform, 1dv, 2dv, (loc, 1, (double *)v), ret);
                CHECK_INVAL_2(glUniform, 3dv, 4dv, (loc, 1, (double *)v), ret);

                CHECK_INVAL_3(glUniformMatrix, 2dv, 3dv, 4dv,
                        (loc, 1, GL_FALSE, (double *)v), ret);
                CHECK_INVAL_3(glUniformMatrix, 2x3dv, 3x2dv, 2x4dv,
                        (loc, 1, GL_FALSE, (double *)v), ret);
                CHECK_INVAL_3(glUniformMatrix, 4x2dv, 3x4dv, 4x3dv,
                        (loc, 1, GL_FALSE, (double *)v), ret);
        }

        glDeleteProgram(prog);
        return ret;
}
Ejemplo n.º 9
0
bool
draw_grid(const struct grid_info grid, GLuint prog)
{
        static GLuint lprog;

        if (lprog != prog) {
                glUseProgram(prog);
                lprog = prog;
        }

        if (grid.stages & GL_COMPUTE_SHADER_BIT) {
                set_uniform_int(prog, "ret_img", max_image_units());
                glDispatchCompute(1, grid.size.y, 1);

        } else if (grid.stages & (GL_TESS_CONTROL_SHADER_BIT |
                                  GL_TESS_EVALUATION_SHADER_BIT)) {
                static struct image_extent size;
                static GLuint vao, vbo;

                if (size.x != grid.size.x || size.y != grid.size.y) {
                        size = grid.size;

                        if (!generate_grid_arrays(
                                    &vao, &vbo,
                                    1.0 / size.x - 1.0, 1.0 / size.y - 1.0,
                                    2.0 / size.x, 2.0 / size.y,
                                    size.x, size.y))
                                return false;
                }

                glBindVertexArray(vao);
                glPatchParameteri(GL_PATCH_VERTICES, 4);
                glDrawArrays(GL_PATCHES, 0, product(size));

        } else if (grid.stages & (GL_VERTEX_SHADER_BIT |
                                  GL_GEOMETRY_SHADER_BIT)) {
                static struct image_extent size;
                static GLuint vao, vbo;

                if (size.x != grid.size.x || size.y != grid.size.y) {
                        size = grid.size;

                        if (!generate_grid_arrays(
                                    &vao, &vbo,
                                    1.0 / size.x - 1.0, 1.0 / size.y - 1.0,
                                    2.0 / size.x, 2.0 / size.y,
                                    size.x, size.y))
                                return false;
                }

                glBindVertexArray(vao);
                glDrawArrays(GL_POINTS, 0, product(size));

        } else {
                static struct image_extent size;
                static GLuint vao, vbo;

                if (size.x != grid.size.x || size.y != grid.size.y) {
                        float vp[4];

                        glGetFloati_v(GL_VIEWPORT, 0, vp);
                        size = grid.size;

                        if (!generate_grid_arrays(
                                    &vao, &vbo, -1.0, -1.0,
                                    2.0 * size.x / vp[2], 2.0 * size.y / vp[3],
                                    2, 2))
                                return false;
                }


                glBindVertexArray(vao);
                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        }

        return piglit_check_gl_error(GL_NO_ERROR);
}