Example #1
0
void process(const YV12Image &in_data, const YV12Image &out_data)
{
	// (1) Fill the format descriptors for the top and bottom fields. The same
	// context can not be used for both fields, as they are located at opposite
	// offsets from the image center. If the fields were to be scaled as
	// progressive-scan images of half height, spatial misalignment of the
	// output would occur.
	zimgxx::zimage_format in_format_t = get_image_format(in_data, true);
	zimgxx::zimage_format in_format_b = get_image_format(in_data, false);
	zimgxx::zimage_format out_format_t = get_image_format(out_data, true);
	zimgxx::zimage_format out_format_b = get_image_format(out_data, false);

	// (2) Build the processing contexts.
	zimgxx::FilterGraph graph_t{ zimgxx::FilterGraph::build(in_format_t, out_format_t) };
	zimgxx::FilterGraph graph_b{ zimgxx::FilterGraph::build(in_format_b, out_format_b) };

	// (3) Allocate scanline and temporary buffers for input and output data. In
	// this case, the same buffers can be used for both fields.
	unsigned input_buffering_t = graph_t.get_input_buffering();
	unsigned input_buffering_b = graph_b.get_input_buffering();
	unsigned output_buffering_t = graph_t.get_input_buffering();
	unsigned output_buffering_b = graph_b.get_input_buffering();
	size_t tmp_size_t = graph_t.get_tmp_size();
	size_t tmp_size_b = graph_b.get_tmp_size();

	std::cout << "input buffering:  " << std::max(input_buffering_t, input_buffering_b) << '\n';
	std::cout << "output buffering: " << std::max(output_buffering_t, output_buffering_b) << '\n';
	std::cout << "heap usage: " << std::max(tmp_size_t, tmp_size_b) << '\n';

	auto in_buf = allocate_buffer(in_format_t, std::max(input_buffering_t, input_buffering_b));
	auto out_buf = allocate_buffer(out_format_t, std::max(output_buffering_t, output_buffering_b));
	auto tmp_buf = allocate_buffer(std::max(tmp_size_t, tmp_size_b));

	// (4) Store context information required by the I/O callbacks. The
	// callbacks convert between the on-disk and z.lib alignment requirements.
	Callback unpack_data = { &in_buf.first, &in_data, false, true };
	Callback pack_data = { &out_buf.first, &out_data, true, true };

	// (5) Process the top field.
	graph_t.process(in_buf.first.as_const(), out_buf.first, tmp_buf.get(),
	                yv12_bitblt_callback, &unpack_data, yv12_bitblt_callback, &pack_data);

	// (6) Process the bottom field.
	unpack_data.top_field = false;
	pack_data.top_field = false;

	graph_b.process(in_buf.first.as_const(), out_buf.first, tmp_buf.get(),
	                yv12_bitblt_callback, &unpack_data, yv12_bitblt_callback, &pack_data);
}
Example #2
0
static bool
run_test(GLbitfield shaders)
{
        const struct grid_info grid = {
                shaders,
                get_image_format(GL_R32UI),
                { W, H, 1, 1 }
        };
        const struct image_info img = image_info_for_grid(grid);
        GLuint prog = generate_program(
                grid,
                GL_VERTEX_SHADER,
                generate_source(grid, img, GL_VERTEX_SHADER),
                GL_TESS_CONTROL_SHADER,
                generate_source(grid, img, GL_TESS_CONTROL_SHADER),
                GL_TESS_EVALUATION_SHADER,
                generate_source(grid, img, GL_TESS_EVALUATION_SHADER),
                GL_GEOMETRY_SHADER,
                generate_source(grid, img, GL_GEOMETRY_SHADER),
                GL_FRAGMENT_SHADER,
                generate_source(grid, img, GL_FRAGMENT_SHADER),
                GL_COMPUTE_SHADER,
                generate_source(grid, img, GL_COMPUTE_SHADER));
        bool ret = prog && init_fb(grid) &&
                init_images(img) &&
                bind_images(grid, prog) &&
                draw_grid(grid, prog) &&
                check(grid, img);

        glDeleteProgram(prog);
        return ret;
}
Example #3
0
static bool
run_test(const struct image_target_info *target,
         const struct image_extent size)
{
        const struct grid_info grid = {
                GL_FRAGMENT_SHADER_BIT,
                get_image_format(GL_RGBA32F),
                image_optimal_extent(size)
        };
        const struct image_info img = {
                target, grid.format, size,
                image_format_epsilon(grid.format)
        };
        GLuint prog = generate_program(
                grid, GL_FRAGMENT_SHADER,
                concat(image_hunk(img, ""),
                       hunk("readonly uniform IMAGE_T src_img;\n"
                            "writeonly uniform IMAGE_T dst_img;\n"
                            "\n"
                            "GRID_T op(ivec2 idx, GRID_T x) {\n"
                            "        imageStore(dst_img, IMAGE_ADDR(idx),"
                            "                imageLoad(src_img, IMAGE_ADDR(idx)));\n"
                            "        return x;\n"
                            "}\n"), NULL));
        bool ret = prog && init_fb(grid) &&
                init_image(img, 0) &&
                init_image(img, 1) &&
                set_uniform_int(prog, "src_img", 0) &&
                set_uniform_int(prog, "dst_img", 1)  &&
                draw_grid(grid, prog) &&
                check(img);

        glDeleteProgram(prog);
        return ret;
}
Example #4
0
static bool
run_test(const struct image_qualifier_info *qual,
         const struct image_stage_info *stage_w,
         const struct image_stage_info *stage_r,
         unsigned l)
{
        const struct grid_info grid = {
                stage_w->bit | stage_r->bit,
                get_image_format(GL_RGBA32UI),
                { l, l, 1, 1 }
        };
        const struct image_info img = image_info_for_grid(grid);
        GLuint prog = generate_program(
                grid,
                /*
                 * Write (11, 22, 33, 44) to some location on the
                 * image from the write stage.
                 */
                stage_w->stage,
                concat(qualifier_hunk(qual),
                       image_hunk(img, ""),
                       hunk("IMAGE_Q uniform IMAGE_T img;\n"
                            "\n"
                            "GRID_T op(ivec2 idx, GRID_T x) {\n"
                            "       imageStore(img, idx, DATA_T(11, 22, 33, 44));"
                            "       return x;"
                            "}\n"), NULL),
                /*
                 * The same location will read back the expected value
                 * if image access is coherent, as the shader inputs
                 * of the read stage are dependent on the outputs of
                 * the write stage and consequently they are
                 * guaranteed to be executed sequentially.
                 */
                stage_r->stage,
                concat(qualifier_hunk(qual),
                       image_hunk(img, ""),
                       hunk("IMAGE_Q uniform IMAGE_T img;\n"
                            "\n"
                            "GRID_T op(ivec2 idx, GRID_T x) {\n"
                            "       DATA_T v = imageLoad(img, idx);"
                            "       if (v == DATA_T(11, 22, 33, 44))"
                            "             return GRID_T(33, 33, 33, 33);"
                            "       else"
                            "             return GRID_T(77, 77, 77, 77);"
                            "}\n"), NULL));
        bool ret = prog &&
                init_fb(grid) &&
                init_image(img) &&
                set_uniform_int(prog, "img", 0) &&
                draw_grid(grid, prog) &&
                (check(grid, img) || qual->control_test);

        glDeleteProgram(prog);
        return ret;
}
Example #5
0
void GLAPIENTRY
_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level,
                       GLboolean layered, GLint layer, GLenum access,
                       GLenum format)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_texture_object *t = NULL;
   struct gl_image_unit *u;

   if (!validate_bind_image_texture(ctx, unit, texture, level,
                                    layered, layer, access, format))
      return;

   u = &ctx->ImageUnits[unit];

   FLUSH_VERTICES(ctx, 0);
   ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;

   if (texture) {
      t = _mesa_lookup_texture(ctx, texture);
      if (!t) {
         _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(texture)");
         return;
      }

      _mesa_reference_texobj(&u->TexObj, t);
      u->Level = level;
      u->Access = access;
      u->Format = format;
      u->_ActualFormat = get_image_format(format);

      if (_mesa_tex_target_is_layered(t->Target)) {
         u->Layered = layered;
         u->Layer = (layered ? 0 : layer);
      } else {
         u->Layered = GL_FALSE;
         u->Layer = 0;
      }

   } else {
      _mesa_reference_texobj(&u->TexObj, NULL);
   }

   u->_Valid = validate_image_unit(ctx, u);

   if (ctx->Driver.BindImageTexture)
      ctx->Driver.BindImageTexture(ctx, u, t, level, layered,
                                   layer, access, format);
}
int load_image_f(char * fname,FILE * f,mgfx_image_t ** the_img)
{
 struct mgfx_image_format * fmt;
 mgfx_image_t * img;
 int __ret;
 if(!(img=(mgfx_image_t *)malloc(sizeof(mgfx_image_t))))
  return _PICERR_NOMEM;
 if(!(fmt=get_image_format(fname)))
  return _PICERR_UNSUPPORTED;
 img->fmt=fmt;
 __ret=fmt->load_fn(f,img);
 if(__ret==_PIC_OK)
 {
  *the_img=img;
 } else {
  *the_img=NULL;
  free(img);
 }
 fclose(f);
 return __ret;
}
Example #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);
}
Example #8
0
static bool
check_derivative(const struct grid_info grid, const struct image_info img,
                 unsigned w, unsigned h)
{
        uint32_t pixels_fb[H][W], expect_fb[H][W];
        uint32_t pixels_img[H][W], expect_img[H][W];
        int i, j;

        for (i = 0; i < W; ++i) {
                for (j = 0; j < H; ++j) {
                        expect_fb[j][i] = (j < h && i < w ? 1000 :
                                           encode(get_image_format(GL_R32F), 0.5));
                        expect_img[j][i] = (j < h && i < w ? 1 : 0) + j;
                }
        }

        if (!download_result(grid, pixels_fb[0]) ||
            !download_image(img, 0, pixels_img[0]))
                return false;

        if (!check_pixels_v(img, pixels_fb[0], expect_fb[0])) {
                printf("  Source: framebuffer\n");
                /*
                 * Purely informational check, we don't care what the
                 * result is as long as derivatives are being
                 * calculated, don't fail if the result doesn't equal
                 * the expected value as it's most likely an accuracy
                 * issue.
                 */
        }

        if (!check_pixels_v(img, pixels_img[0], expect_img[0])) {
                printf("  Source: image\n");
                return false;
        }

        return true;
}
Example #9
0
static GLboolean
validate_bind_image_texture(struct gl_context *ctx, GLuint unit,
                            GLuint texture, GLint level, GLboolean layered,
                            GLint layer, GLenum access, GLenum format)
{
   assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS);

   if (unit >= ctx->Const.MaxImageUnits) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(unit)");
      return GL_FALSE;
   }

   if (level < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(level)");
      return GL_FALSE;
   }

   if (layer < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(layer)");
      return GL_FALSE;
   }

   if (access != GL_READ_ONLY &&
       access != GL_WRITE_ONLY &&
       access != GL_READ_WRITE) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(access)");
      return GL_FALSE;
   }

   if (!get_image_format(format)) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(format)");
      return GL_FALSE;
   }

   return GL_TRUE;
}
Example #10
0
int get_image(VASurfaceID surface, Image *dst_img)
{
    VAAPIContext * const vaapi = vaapi_get_context();
    VAImage image;
    VAImageFormat *image_format = NULL;
    VAStatus status;
    Image bound_image;
    int i, is_bound_image = 0, is_derived_image = 0, error = -1;

    image.image_id = VA_INVALID_ID;
    image.buf      = VA_INVALID_ID;

    if (!image_format) {
        status = vaDeriveImage(vaapi->display, surface, &image);
        if (vaapi_check_status(status, "vaDeriveImage()")) {
            if (image.image_id != VA_INVALID_ID && image.buf != VA_INVALID_ID) {
                D(bug("using vaDeriveImage()\n"));
                is_derived_image = 1;
                image_format = &image.format;
            }
            else {
                D(bug("vaDeriveImage() returned success but VA image is invalid. Trying vaGetImage()\n"));
            }
        }
    }

    if (!image_format) {
        for (i = 0; image_formats[i] != 0; i++) {
            if (get_image_format(vaapi, image_formats[i], &image_format))
                break;
        }
    }

    if (!image_format)
        goto end;
    D(bug("selected %s image format for getimage\n",
          string_of_VAImageFormat(image_format)));

    if (!is_derived_image) {
        status = vaCreateImage(vaapi->display, image_format,
                               vaapi->picture_width, vaapi->picture_height,
                               &image);
        if (!vaapi_check_status(status, "vaCreateImage()"))
            goto end;
        D(bug("created image with id 0x%08x and buffer id 0x%08x\n",
              image.image_id, image.buf));

        VARectangle src_rect;

        src_rect.x      = 0;
        src_rect.y      = 0;
        src_rect.width  = vaapi->picture_width;
        src_rect.height = vaapi->picture_height;

        D(bug("src rect (%d,%d):%ux%u\n",
              src_rect.x, src_rect.y, src_rect.width, src_rect.height));

        status = vaGetImage(
            vaapi->display, vaapi->surface_id,
            src_rect.x, src_rect.y, src_rect.width, src_rect.height,
            image.image_id
        );
        if (!vaapi_check_status(status, "vaGetImage()")) {
            vaDestroyImage(vaapi->display, image.image_id);
            goto end;
        }
    }

    if (bind_image(&image, &bound_image) < 0)
        goto end;
    is_bound_image = 1;

    if (image_convert(dst_img, &bound_image) < 0)
        goto end;

    error = 0;
end:
    if (is_bound_image) {
        if (release_image(&image) < 0)
            error = -1;
    }

    if (image.image_id != VA_INVALID_ID) {
        status = vaDestroyImage(vaapi->display, image.image_id);
        if (!vaapi_check_status(status, "vaDestroyImage()"))
            error = -1;
    }
    return error;
}