mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-11 06:28:09 +02:00
[g3dvl] introduction of ycbcr buffers
Moves most of the buffer creation out of the idct code.
This commit is contained in:
parent
5a351e5129
commit
020328ca32
7 changed files with 433 additions and 152 deletions
|
|
@ -153,7 +153,8 @@ C_SOURCES = \
|
|||
vl/vl_compositor.c \
|
||||
vl/vl_csc.c \
|
||||
vl/vl_idct.c \
|
||||
vl/vl_vertex_buffers.c
|
||||
vl/vl_vertex_buffers.c \
|
||||
vl/vl_ycbcr_buffer.c
|
||||
|
||||
GALLIVM_SOURCES = \
|
||||
gallivm/lp_bld_arit.c \
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "vl_idct.h"
|
||||
#include "vl_vertex_buffers.h"
|
||||
#include "vl_ycbcr_buffer.h"
|
||||
#include "vl_defines.h"
|
||||
#include "util/u_draw.h"
|
||||
#include <assert.h>
|
||||
|
|
@ -457,89 +458,91 @@ cleanup_state(struct vl_idct *idct)
|
|||
}
|
||||
|
||||
static bool
|
||||
init_textures(struct vl_idct *idct, struct vl_idct_buffer *buffer)
|
||||
init_intermediate(struct vl_idct *idct, struct vl_idct_buffer *buffer)
|
||||
{
|
||||
struct pipe_resource template;
|
||||
struct pipe_sampler_view sampler_view;
|
||||
struct pipe_resource tex_templ, *tex;
|
||||
struct pipe_sampler_view sv_templ;
|
||||
struct pipe_surface surf_templ;
|
||||
unsigned i;
|
||||
|
||||
assert(idct && buffer);
|
||||
|
||||
/* create textures */
|
||||
memset(&template, 0, sizeof(struct pipe_resource));
|
||||
template.last_level = 0;
|
||||
template.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
template.flags = 0;
|
||||
memset(&tex_templ, 0, sizeof(tex_templ));
|
||||
tex_templ.target = PIPE_TEXTURE_3D;
|
||||
tex_templ.format = PIPE_FORMAT_R16G16B16A16_SNORM;
|
||||
tex_templ.width0 = idct->buffer_width / NR_RENDER_TARGETS;
|
||||
tex_templ.height0 = idct->buffer_height / 4;
|
||||
tex_templ.depth0 = NR_RENDER_TARGETS;
|
||||
tex_templ.array_size = 1;
|
||||
tex_templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
|
||||
tex_templ.usage = PIPE_USAGE_STATIC;
|
||||
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
template.format = PIPE_FORMAT_R16G16B16A16_SNORM;
|
||||
template.width0 = idct->buffer_width / 4;
|
||||
template.height0 = idct->buffer_height;
|
||||
template.depth0 = 1;
|
||||
template.array_size = 1;
|
||||
template.usage = PIPE_USAGE_STREAM;
|
||||
buffer->textures.individual.source = idct->pipe->screen->resource_create(idct->pipe->screen, &template);
|
||||
if (!buffer->textures.individual.source)
|
||||
goto error;
|
||||
tex = idct->pipe->screen->resource_create(idct->pipe->screen, &tex_templ);
|
||||
if (!tex)
|
||||
goto error_tex;
|
||||
|
||||
template.target = PIPE_TEXTURE_3D;
|
||||
template.format = PIPE_FORMAT_R16G16B16A16_SNORM;
|
||||
template.width0 = idct->buffer_width / NR_RENDER_TARGETS;
|
||||
template.height0 = idct->buffer_height / 4;
|
||||
template.depth0 = NR_RENDER_TARGETS;
|
||||
template.usage = PIPE_USAGE_STATIC;
|
||||
buffer->textures.individual.intermediate = idct->pipe->screen->resource_create(idct->pipe->screen, &template);
|
||||
if (!buffer->textures.individual.intermediate)
|
||||
goto error;
|
||||
memset(&sv_templ, 0, sizeof(sv_templ));
|
||||
u_sampler_view_default_template(&sv_templ, tex, tex->format);
|
||||
buffer->sampler_views.individual.intermediate =
|
||||
idct->pipe->create_sampler_view(idct->pipe, tex, &sv_templ);
|
||||
if (!buffer->sampler_views.individual.intermediate)
|
||||
goto error_sampler_view;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
memset(&sampler_view, 0, sizeof(sampler_view));
|
||||
u_sampler_view_default_template(&sampler_view, buffer->textures.all[i], buffer->textures.all[i]->format);
|
||||
buffer->sampler_views.all[i] = idct->pipe->create_sampler_view(idct->pipe, buffer->textures.all[i], &sampler_view);
|
||||
if (!buffer->sampler_views.all[i])
|
||||
goto error;
|
||||
buffer->fb_state[0].width = tex->width0;
|
||||
buffer->fb_state[0].height = tex->height0;
|
||||
buffer->fb_state[0].nr_cbufs = NR_RENDER_TARGETS;
|
||||
for(i = 0; i < NR_RENDER_TARGETS; ++i) {
|
||||
memset(&surf_templ, 0, sizeof(surf_templ));
|
||||
surf_templ.format = tex->format;
|
||||
surf_templ.u.tex.first_layer = i;
|
||||
surf_templ.u.tex.last_layer = i;
|
||||
surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
|
||||
buffer->fb_state[0].cbufs[i] = idct->pipe->create_surface(
|
||||
idct->pipe, tex, &surf_templ);
|
||||
|
||||
if (!buffer->fb_state[0].cbufs[i])
|
||||
goto error_surfaces;
|
||||
}
|
||||
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
/* TODO: Accomodate HW that can't do this and also for cases when this isn't precise enough */
|
||||
template.format = PIPE_FORMAT_R16_SNORM;
|
||||
template.width0 = idct->buffer_width;
|
||||
template.height0 = idct->buffer_height;
|
||||
template.depth0 = 1;
|
||||
|
||||
buffer->destination = idct->pipe->screen->resource_create(idct->pipe->screen, &template);
|
||||
if (!buffer->destination)
|
||||
goto error;
|
||||
buffer->viewport[0].scale[0] = tex->width0;
|
||||
buffer->viewport[0].scale[1] = tex->height0;
|
||||
|
||||
pipe_resource_reference(&tex, NULL);
|
||||
return true;
|
||||
|
||||
error:
|
||||
for (i = 0; i < 4; ++i) {
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.all[i], NULL);
|
||||
pipe_resource_reference(&buffer->textures.all[i], NULL);
|
||||
}
|
||||
error_surfaces:
|
||||
for(i = 0; i < NR_RENDER_TARGETS; ++i)
|
||||
pipe_surface_reference(&buffer->fb_state[0].cbufs[i], NULL);
|
||||
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.individual.intermediate, NULL);
|
||||
|
||||
error_sampler_view:
|
||||
pipe_resource_reference(&tex, NULL);
|
||||
|
||||
error_tex:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_textures(struct vl_idct *idct, struct vl_idct_buffer *buffer)
|
||||
cleanup_intermediate(struct vl_idct *idct, struct vl_idct_buffer *buffer)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
assert(idct && buffer);
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.all[i], NULL);
|
||||
pipe_resource_reference(&buffer->textures.all[i], NULL);
|
||||
}
|
||||
for(i = 0; i < NR_RENDER_TARGETS; ++i)
|
||||
pipe_surface_reference(&buffer->fb_state[0].cbufs[i], NULL);
|
||||
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.individual.intermediate, NULL);
|
||||
}
|
||||
|
||||
struct pipe_resource *
|
||||
struct pipe_sampler_view *
|
||||
vl_idct_upload_matrix(struct pipe_context *pipe)
|
||||
{
|
||||
const float scale = sqrtf(SCALE_FACTOR_16_TO_9);
|
||||
|
||||
struct pipe_resource template, *matrix;
|
||||
struct pipe_resource tex_templ, *matrix;
|
||||
struct pipe_sampler_view sv_templ, *sv;
|
||||
struct pipe_transfer *buf_transfer;
|
||||
unsigned i, j, pitch;
|
||||
float *f;
|
||||
|
|
@ -554,19 +557,19 @@ vl_idct_upload_matrix(struct pipe_context *pipe)
|
|||
|
||||
assert(pipe);
|
||||
|
||||
memset(&template, 0, sizeof(struct pipe_resource));
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
template.format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
template.last_level = 0;
|
||||
template.width0 = 2;
|
||||
template.height0 = 8;
|
||||
template.depth0 = 1;
|
||||
template.array_size = 1;
|
||||
template.usage = PIPE_USAGE_IMMUTABLE;
|
||||
template.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
template.flags = 0;
|
||||
memset(&tex_templ, 0, sizeof(tex_templ));
|
||||
tex_templ.target = PIPE_TEXTURE_2D;
|
||||
tex_templ.format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
tex_templ.last_level = 0;
|
||||
tex_templ.width0 = 2;
|
||||
tex_templ.height0 = 8;
|
||||
tex_templ.depth0 = 1;
|
||||
tex_templ.array_size = 1;
|
||||
tex_templ.usage = PIPE_USAGE_IMMUTABLE;
|
||||
tex_templ.bind = PIPE_BIND_SAMPLER_VIEW;
|
||||
tex_templ.flags = 0;
|
||||
|
||||
matrix = pipe->screen->resource_create(pipe->screen, &template);
|
||||
matrix = pipe->screen->resource_create(pipe->screen, &tex_templ);
|
||||
if (!matrix)
|
||||
goto error_matrix;
|
||||
|
||||
|
|
@ -593,7 +596,14 @@ vl_idct_upload_matrix(struct pipe_context *pipe)
|
|||
pipe->transfer_unmap(pipe, buf_transfer);
|
||||
pipe->transfer_destroy(pipe, buf_transfer);
|
||||
|
||||
return matrix;
|
||||
memset(&sv_templ, 0, sizeof(sv_templ));
|
||||
u_sampler_view_default_template(&sv_templ, matrix, matrix->format);
|
||||
sv = pipe->create_sampler_view(pipe, matrix, &sv_templ);
|
||||
pipe_resource_reference(&matrix, NULL);
|
||||
if (!sv)
|
||||
goto error_map;
|
||||
|
||||
return sv;
|
||||
|
||||
error_map:
|
||||
pipe->transfer_destroy(pipe, buf_transfer);
|
||||
|
|
@ -608,7 +618,7 @@ error_matrix:
|
|||
bool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe,
|
||||
unsigned buffer_width, unsigned buffer_height,
|
||||
unsigned blocks_x, unsigned blocks_y,
|
||||
int color_swizzle, struct pipe_resource *matrix)
|
||||
int color_swizzle, struct pipe_sampler_view *matrix)
|
||||
{
|
||||
assert(idct && pipe && matrix);
|
||||
|
||||
|
|
@ -617,7 +627,7 @@ bool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe,
|
|||
idct->buffer_height = buffer_height;
|
||||
idct->blocks_x = blocks_x;
|
||||
idct->blocks_y = blocks_y;
|
||||
pipe_resource_reference(&idct->matrix, matrix);
|
||||
pipe_sampler_view_reference(&idct->matrix, matrix);
|
||||
|
||||
if(!init_shaders(idct, color_swizzle))
|
||||
return false;
|
||||
|
|
@ -636,63 +646,35 @@ vl_idct_cleanup(struct vl_idct *idct)
|
|||
cleanup_shaders(idct);
|
||||
cleanup_state(idct);
|
||||
|
||||
pipe_resource_reference(&idct->matrix, NULL);
|
||||
pipe_sampler_view_reference(&idct->matrix, NULL);
|
||||
}
|
||||
|
||||
struct pipe_resource *
|
||||
vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer)
|
||||
bool
|
||||
vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer,
|
||||
struct pipe_sampler_view *source, struct pipe_surface *destination)
|
||||
{
|
||||
struct pipe_surface template;
|
||||
|
||||
unsigned i;
|
||||
|
||||
assert(buffer);
|
||||
assert(idct);
|
||||
assert(source);
|
||||
assert(destination);
|
||||
|
||||
pipe_resource_reference(&buffer->textures.individual.matrix, idct->matrix);
|
||||
pipe_resource_reference(&buffer->textures.individual.transpose, idct->matrix);
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.individual.matrix, idct->matrix);
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.individual.source, source);
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.individual.transpose, idct->matrix);
|
||||
|
||||
if (!init_textures(idct, buffer))
|
||||
goto error_textures;
|
||||
if (!init_intermediate(idct, buffer))
|
||||
return false;
|
||||
|
||||
/* init state */
|
||||
buffer->viewport[0].scale[0] = buffer->textures.individual.intermediate->width0;
|
||||
buffer->viewport[0].scale[1] = buffer->textures.individual.intermediate->height0;
|
||||
|
||||
buffer->viewport[1].scale[0] = buffer->destination->width0;
|
||||
buffer->viewport[1].scale[1] = buffer->destination->height0;
|
||||
|
||||
buffer->fb_state[0].width = buffer->textures.individual.intermediate->width0;
|
||||
buffer->fb_state[0].height = buffer->textures.individual.intermediate->height0;
|
||||
|
||||
buffer->fb_state[0].nr_cbufs = NR_RENDER_TARGETS;
|
||||
for(i = 0; i < NR_RENDER_TARGETS; ++i) {
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.format = buffer->textures.individual.intermediate->format;
|
||||
template.u.tex.first_layer = i;
|
||||
template.u.tex.last_layer = i;
|
||||
template.usage = PIPE_BIND_RENDER_TARGET;
|
||||
buffer->fb_state[0].cbufs[i] = idct->pipe->create_surface(
|
||||
idct->pipe, buffer->textures.individual.intermediate,
|
||||
&template);
|
||||
|
||||
if (!buffer->fb_state[0].cbufs[i])
|
||||
goto error_matrix_surfaces;
|
||||
}
|
||||
|
||||
buffer->fb_state[1].width = buffer->destination->width0;
|
||||
buffer->fb_state[1].height = buffer->destination->height0;
|
||||
|
||||
buffer->fb_state[1].width = destination->texture->width0;
|
||||
buffer->fb_state[1].height = destination->texture->height0;
|
||||
buffer->fb_state[1].nr_cbufs = 1;
|
||||
pipe_surface_reference(&buffer->fb_state[1].cbufs[0], destination);
|
||||
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.format = buffer->destination->format;
|
||||
template.usage = PIPE_BIND_RENDER_TARGET;
|
||||
buffer->fb_state[1].cbufs[0] = idct->pipe->create_surface(
|
||||
idct->pipe, buffer->destination, &template);
|
||||
|
||||
if (!buffer->fb_state[1].cbufs[0])
|
||||
goto error_transpose_surface;
|
||||
buffer->viewport[1].scale[0] = destination->texture->width0;
|
||||
buffer->viewport[1].scale[1] = destination->texture->height0;
|
||||
|
||||
for(i = 0; i < 2; ++i) {
|
||||
buffer->viewport[i].scale[2] = 1;
|
||||
|
|
@ -705,17 +687,7 @@ vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer)
|
|||
buffer->fb_state[i].zsbuf = NULL;
|
||||
}
|
||||
|
||||
return buffer->destination;
|
||||
|
||||
error_transpose_surface:
|
||||
pipe_surface_reference(&buffer->fb_state[1].cbufs[0], NULL);
|
||||
|
||||
error_matrix_surfaces:
|
||||
for(i = 0; i < NR_RENDER_TARGETS; ++i)
|
||||
pipe_surface_reference(&buffer->fb_state[0].cbufs[i], NULL);
|
||||
|
||||
error_textures:
|
||||
return NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -730,25 +702,29 @@ vl_idct_cleanup_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer)
|
|||
|
||||
pipe_surface_reference(&buffer->fb_state[1].cbufs[0], NULL);
|
||||
|
||||
cleanup_textures(idct, buffer);
|
||||
cleanup_intermediate(idct, buffer);
|
||||
}
|
||||
|
||||
void
|
||||
vl_idct_map_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
|
||||
{
|
||||
struct pipe_resource *tex;
|
||||
|
||||
assert(idct && buffer);
|
||||
|
||||
tex = buffer->sampler_views.individual.source->texture;
|
||||
|
||||
struct pipe_box rect =
|
||||
{
|
||||
0, 0, 0,
|
||||
buffer->textures.individual.source->width0,
|
||||
buffer->textures.individual.source->height0,
|
||||
tex->width0,
|
||||
tex->height0,
|
||||
1
|
||||
};
|
||||
|
||||
buffer->tex_transfer = idct->pipe->get_transfer
|
||||
(
|
||||
idct->pipe, buffer->textures.individual.source,
|
||||
idct->pipe, tex,
|
||||
0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
|
||||
&rect
|
||||
);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <pipe/p_state.h>
|
||||
#include "vl_vertex_buffers.h"
|
||||
#include "vl_ycbcr_buffer.h"
|
||||
|
||||
/* shader based inverse distinct cosinus transformation
|
||||
* expect usage of vl_vertex_buffers as a todo list
|
||||
|
|
@ -49,7 +50,7 @@ struct vl_idct
|
|||
void *matrix_vs, *transpose_vs;
|
||||
void *matrix_fs, *transpose_fs;
|
||||
|
||||
struct pipe_resource *matrix;
|
||||
struct pipe_sampler_view *matrix;
|
||||
};
|
||||
|
||||
/* a set of buffers to work with */
|
||||
|
|
@ -58,8 +59,6 @@ struct vl_idct_buffer
|
|||
struct pipe_viewport_state viewport[2];
|
||||
struct pipe_framebuffer_state fb_state[2];
|
||||
|
||||
struct pipe_resource *destination;
|
||||
|
||||
union
|
||||
{
|
||||
struct pipe_sampler_view *all[4];
|
||||
|
|
@ -70,34 +69,25 @@ struct vl_idct_buffer
|
|||
} individual;
|
||||
} sampler_views;
|
||||
|
||||
union
|
||||
{
|
||||
struct pipe_resource *all[4];
|
||||
struct pipe_resource *stage[2][2];
|
||||
struct {
|
||||
struct pipe_resource *matrix, *source;
|
||||
struct pipe_resource *transpose, *intermediate;
|
||||
} individual;
|
||||
} textures;
|
||||
|
||||
struct pipe_transfer *tex_transfer;
|
||||
short *texels;
|
||||
};
|
||||
|
||||
/* upload the idct matrix, which can be shared by all idct instances of a pipe */
|
||||
struct pipe_resource *vl_idct_upload_matrix(struct pipe_context *pipe);
|
||||
struct pipe_sampler_view *vl_idct_upload_matrix(struct pipe_context *pipe);
|
||||
|
||||
/* init an idct instance */
|
||||
bool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe,
|
||||
unsigned buffer_width, unsigned buffer_height,
|
||||
unsigned blocks_x, unsigned blocks_y,
|
||||
int color_swizzle, struct pipe_resource *matrix);
|
||||
int color_swizzle, struct pipe_sampler_view *matrix);
|
||||
|
||||
/* destroy an idct instance */
|
||||
void vl_idct_cleanup(struct vl_idct *idct);
|
||||
|
||||
/* init a buffer assosiated with agiven idct instance */
|
||||
struct pipe_resource *vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer);
|
||||
bool vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer,
|
||||
struct pipe_sampler_view *source, struct pipe_surface *destination);
|
||||
|
||||
/* cleanup a buffer of an idct instance */
|
||||
void vl_idct_cleanup_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer);
|
||||
|
|
|
|||
|
|
@ -268,12 +268,13 @@ static struct pipe_video_buffer *
|
|||
vl_mpeg12_create_buffer(struct pipe_video_context *vpipe)
|
||||
{
|
||||
struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
|
||||
struct pipe_resource *y, *cr, *cb;
|
||||
struct vl_mpeg12_buffer *buffer;
|
||||
|
||||
struct pipe_resource res_template, *resource;
|
||||
struct pipe_surface surf_template;
|
||||
struct pipe_sampler_view sv_template;
|
||||
struct vl_ycbcr_sampler_views *idct_views;
|
||||
struct vl_ycbcr_surfaces *idct_surfaces;
|
||||
|
||||
assert(ctx);
|
||||
|
||||
|
|
@ -329,22 +330,50 @@ vl_mpeg12_create_buffer(struct pipe_video_context *vpipe)
|
|||
|
||||
buffer->vertex_bufs.individual.stream = vl_vb_init(&buffer->vertex_stream, ctx->pipe,
|
||||
ctx->vertex_buffer_size);
|
||||
if (!(y = vl_idct_init_buffer(&ctx->idct_y, &buffer->idct_y))) {
|
||||
|
||||
if (!vl_ycbcr_buffer_init(&buffer->idct_source, ctx->pipe,
|
||||
ctx->buffer_width, ctx->buffer_height,
|
||||
ctx->base.chroma_format,
|
||||
PIPE_FORMAT_R16G16B16A16_SNORM,
|
||||
PIPE_USAGE_STREAM)) {
|
||||
FREE(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(cr = vl_idct_init_buffer(&ctx->idct_cr, &buffer->idct_cr))) {
|
||||
if (!vl_ycbcr_buffer_init(&buffer->idct_2_mc, ctx->pipe,
|
||||
ctx->buffer_width, ctx->buffer_height,
|
||||
ctx->base.chroma_format,
|
||||
PIPE_FORMAT_R16_SNORM,
|
||||
PIPE_USAGE_STATIC)) {
|
||||
FREE(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(cb = vl_idct_init_buffer(&ctx->idct_cb, &buffer->idct_cb))) {
|
||||
idct_views = vl_ycbcr_get_sampler_views(&buffer->idct_source);
|
||||
idct_surfaces = vl_ycbcr_get_surfaces(&buffer->idct_2_mc);
|
||||
|
||||
if (!vl_idct_init_buffer(&ctx->idct_y, &buffer->idct_y,
|
||||
idct_views->y, idct_surfaces->y)) {
|
||||
FREE(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!vl_mpeg12_mc_init_buffer(&ctx->mc_renderer, &buffer->mc, y, cr, cb)) {
|
||||
if (!vl_idct_init_buffer(&ctx->idct_cb, &buffer->idct_cb,
|
||||
idct_views->cb, idct_surfaces->cb)) {
|
||||
FREE(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!vl_idct_init_buffer(&ctx->idct_cr, &buffer->idct_cr,
|
||||
idct_views->cr, idct_surfaces->cr)) {
|
||||
FREE(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!vl_mpeg12_mc_init_buffer(&ctx->mc_renderer, &buffer->mc,
|
||||
buffer->idct_2_mc.resources.y,
|
||||
buffer->idct_2_mc.resources.cr,
|
||||
buffer->idct_2_mc.resources.cb)) {
|
||||
FREE(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -572,7 +601,7 @@ static bool
|
|||
init_idct(struct vl_mpeg12_context *ctx, unsigned buffer_width, unsigned buffer_height)
|
||||
{
|
||||
unsigned chroma_width, chroma_height, chroma_blocks_x, chroma_blocks_y;
|
||||
struct pipe_resource *idct_matrix;
|
||||
struct pipe_sampler_view *idct_matrix;
|
||||
|
||||
/* TODO: Implement 422, 444 */
|
||||
assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "vl_idct.h"
|
||||
#include "vl_mpeg12_mc_renderer.h"
|
||||
#include "vl_compositor.h"
|
||||
#include "vl_ycbcr_buffer.h"
|
||||
|
||||
struct pipe_screen;
|
||||
struct pipe_context;
|
||||
|
|
@ -62,6 +63,10 @@ struct vl_mpeg12_context
|
|||
struct vl_mpeg12_buffer
|
||||
{
|
||||
struct pipe_video_buffer base;
|
||||
|
||||
struct vl_ycbcr_buffer idct_source;
|
||||
struct vl_ycbcr_buffer idct_2_mc;
|
||||
|
||||
struct pipe_surface *surface;
|
||||
struct pipe_sampler_view *sampler_view;
|
||||
|
||||
|
|
|
|||
191
src/gallium/auxiliary/vl/vl_ycbcr_buffer.c
Normal file
191
src/gallium/auxiliary/vl/vl_ycbcr_buffer.c
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2011 Christian König.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "vl_ycbcr_buffer.h"
|
||||
#include <util/u_format.h>
|
||||
#include <util/u_inlines.h>
|
||||
#include <util/u_sampler.h>
|
||||
#include <pipe/p_screen.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <assert.h>
|
||||
|
||||
bool vl_ycbcr_buffer_init(struct vl_ycbcr_buffer *buffer,
|
||||
struct pipe_context *pipe,
|
||||
unsigned width, unsigned height,
|
||||
enum pipe_video_chroma_format chroma_format,
|
||||
enum pipe_format resource_format,
|
||||
unsigned usage)
|
||||
{
|
||||
struct pipe_resource templ;
|
||||
|
||||
assert(buffer && pipe);
|
||||
|
||||
memset(buffer, 0, sizeof(struct vl_ycbcr_buffer));
|
||||
buffer->pipe = pipe;
|
||||
|
||||
memset(&templ, 0, sizeof(templ));
|
||||
templ.target = PIPE_TEXTURE_2D;
|
||||
templ.format = resource_format;
|
||||
templ.width0 = width / util_format_get_nr_components(resource_format);
|
||||
templ.height0 = height;
|
||||
templ.depth0 = 1;
|
||||
templ.array_size = 1;
|
||||
templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
|
||||
templ.usage = usage;
|
||||
|
||||
buffer->resources.y = pipe->screen->resource_create(pipe->screen, &templ);
|
||||
if (!buffer->resources.y)
|
||||
goto error_resource_y;
|
||||
|
||||
if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
|
||||
templ.width0 /= 2;
|
||||
templ.height0 /= 2;
|
||||
} else if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
|
||||
templ.height0 /= 2;
|
||||
}
|
||||
|
||||
buffer->resources.cb = pipe->screen->resource_create(pipe->screen, &templ);
|
||||
if (!buffer->resources.cb)
|
||||
goto error_resource_cb;
|
||||
|
||||
buffer->resources.cr = pipe->screen->resource_create(pipe->screen, &templ);
|
||||
if (!buffer->resources.cr)
|
||||
goto error_resource_cr;
|
||||
|
||||
return true;
|
||||
|
||||
error_resource_cr:
|
||||
pipe_resource_reference(&buffer->resources.cb, NULL);
|
||||
|
||||
error_resource_cb:
|
||||
pipe_resource_reference(&buffer->resources.y, NULL);
|
||||
|
||||
error_resource_y:
|
||||
return false;
|
||||
}
|
||||
|
||||
struct vl_ycbcr_sampler_views *vl_ycbcr_get_sampler_views(struct vl_ycbcr_buffer *buffer)
|
||||
{
|
||||
struct pipe_sampler_view sv_templ;
|
||||
struct pipe_context *pipe;
|
||||
|
||||
assert(buffer);
|
||||
|
||||
pipe = buffer->pipe;
|
||||
|
||||
if (!buffer->sampler_views.y) {
|
||||
memset(&sv_templ, 0, sizeof(sv_templ));
|
||||
u_sampler_view_default_template(&sv_templ, buffer->resources.y, buffer->resources.y->format);
|
||||
buffer->sampler_views.y = pipe->create_sampler_view(pipe, buffer->resources.y, &sv_templ);
|
||||
if (!buffer->sampler_views.y)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!buffer->sampler_views.cb) {
|
||||
memset(&sv_templ, 0, sizeof(sv_templ));
|
||||
u_sampler_view_default_template(&sv_templ, buffer->resources.cb, buffer->resources.cb->format);
|
||||
buffer->sampler_views.cb = pipe->create_sampler_view(pipe, buffer->resources.cb, &sv_templ);
|
||||
if (!buffer->sampler_views.cb)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!buffer->sampler_views.cr) {
|
||||
memset(&sv_templ, 0, sizeof(sv_templ));
|
||||
u_sampler_view_default_template(&sv_templ, buffer->resources.cr, buffer->resources.cr->format);
|
||||
buffer->sampler_views.cr = pipe->create_sampler_view(pipe, buffer->resources.cr, &sv_templ);
|
||||
if (!buffer->sampler_views.cr)
|
||||
goto error;
|
||||
}
|
||||
|
||||
return &buffer->sampler_views;
|
||||
|
||||
error:
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.y, NULL);
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.cb, NULL);
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.cr, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct vl_ycbcr_surfaces *vl_ycbcr_get_surfaces(struct vl_ycbcr_buffer *buffer)
|
||||
{
|
||||
struct pipe_surface surf_templ;
|
||||
struct pipe_context *pipe;
|
||||
|
||||
assert(buffer);
|
||||
|
||||
pipe = buffer->pipe;
|
||||
|
||||
if (!buffer->surfaces.y) {
|
||||
memset(&surf_templ, 0, sizeof(surf_templ));
|
||||
surf_templ.format = buffer->resources.y->format;
|
||||
surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
|
||||
buffer->surfaces.y = pipe->create_surface(pipe, buffer->resources.y, &surf_templ);
|
||||
if (!buffer->surfaces.y)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!buffer->surfaces.cb) {
|
||||
memset(&surf_templ, 0, sizeof(surf_templ));
|
||||
surf_templ.format = buffer->resources.cb->format;
|
||||
surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
|
||||
buffer->surfaces.cb = pipe->create_surface(pipe, buffer->resources.cb, &surf_templ);
|
||||
if (!buffer->surfaces.cb)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!buffer->surfaces.cr) {
|
||||
memset(&surf_templ, 0, sizeof(surf_templ));
|
||||
surf_templ.format = buffer->resources.cr->format;
|
||||
surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
|
||||
buffer->surfaces.cr = pipe->create_surface(pipe, buffer->resources.cr, &surf_templ);
|
||||
if (!buffer->surfaces.cr)
|
||||
goto error;
|
||||
}
|
||||
|
||||
return &buffer->surfaces;
|
||||
|
||||
error:
|
||||
pipe_surface_reference(&buffer->surfaces.y, NULL);
|
||||
pipe_surface_reference(&buffer->surfaces.cb, NULL);
|
||||
pipe_surface_reference(&buffer->surfaces.cr, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vl_ycbcr_buffer_cleanup(struct vl_ycbcr_buffer *buffer)
|
||||
{
|
||||
pipe_surface_reference(&buffer->surfaces.y, NULL);
|
||||
pipe_surface_reference(&buffer->surfaces.cb, NULL);
|
||||
pipe_surface_reference(&buffer->surfaces.cr, NULL);
|
||||
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.y, NULL);
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.cb, NULL);
|
||||
pipe_sampler_view_reference(&buffer->sampler_views.cr, NULL);
|
||||
|
||||
pipe_resource_reference(&buffer->resources.y, NULL);
|
||||
pipe_resource_reference(&buffer->resources.cb, NULL);
|
||||
pipe_resource_reference(&buffer->resources.cr, NULL);
|
||||
}
|
||||
89
src/gallium/auxiliary/vl/vl_ycbcr_buffer.h
Normal file
89
src/gallium/auxiliary/vl/vl_ycbcr_buffer.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2011 Christian König.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef vl_ycbcr_buffer_h
|
||||
#define vl_ycbcr_buffer_h
|
||||
|
||||
#include <pipe/p_state.h>
|
||||
|
||||
/**
|
||||
* implementation of a planar ycbcr buffer
|
||||
*/
|
||||
|
||||
/* resources of a buffer */
|
||||
struct vl_ycbcr_resources
|
||||
{
|
||||
struct pipe_resource *y, *cb, *cr;
|
||||
};
|
||||
|
||||
/* sampler views of a buffer */
|
||||
struct vl_ycbcr_sampler_views
|
||||
{
|
||||
struct pipe_sampler_view *y, *cb, *cr;
|
||||
};
|
||||
|
||||
/* surfaces of a buffer */
|
||||
struct vl_ycbcr_surfaces
|
||||
{
|
||||
struct pipe_surface *y, *cb, *cr;
|
||||
};
|
||||
|
||||
/* planar buffer for vl data upload and manipulation */
|
||||
struct vl_ycbcr_buffer
|
||||
{
|
||||
struct pipe_context *pipe;
|
||||
struct vl_ycbcr_resources resources;
|
||||
struct vl_ycbcr_sampler_views sampler_views;
|
||||
struct vl_ycbcr_surfaces surfaces;
|
||||
};
|
||||
|
||||
/**
|
||||
* initialize a buffer, creating its resources
|
||||
*/
|
||||
bool vl_ycbcr_buffer_init(struct vl_ycbcr_buffer *buffer,
|
||||
struct pipe_context *pipe,
|
||||
unsigned width, unsigned height,
|
||||
enum pipe_video_chroma_format chroma_format,
|
||||
enum pipe_format resource_format,
|
||||
unsigned usage);
|
||||
|
||||
/**
|
||||
* create default sampler views for the buffer on demand
|
||||
*/
|
||||
struct vl_ycbcr_sampler_views *vl_ycbcr_get_sampler_views(struct vl_ycbcr_buffer *buffer);
|
||||
|
||||
/**
|
||||
* create default surfaces for the buffer on demand
|
||||
*/
|
||||
struct vl_ycbcr_surfaces *vl_ycbcr_get_surfaces(struct vl_ycbcr_buffer *buffer);
|
||||
|
||||
/**
|
||||
* cleanup the buffer destroying all its resources
|
||||
*/
|
||||
void vl_ycbcr_buffer_cleanup(struct vl_ycbcr_buffer *buffer);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue