gallium/util: adapt util code to interface changes

The util blit functions change their interface (apart from some rename) too
(in particular util_blit_pixels now also takes a pipe_resource as the src blit
argument instead of a surface, as it might just call resource_copy_region).
Maybe the blit util code might need a bit more cleanup, it still doesn't feel
very clean. In particular it seems that util_blit_pixels_tex should probably
disappear, and I think it would be great if the code called by drivers for
blitting (u_blitter.c, which isn't really touched by this change) could somehow
be merged with the u_blit code.
This commit is contained in:
Roland Scheidegger 2010-05-17 21:15:20 +02:00
parent 379db6a36b
commit 815b75705f
8 changed files with 145 additions and 143 deletions

View file

@ -192,7 +192,6 @@ get_next_slot( struct blit_state *ctx )
return ctx->vbuf_slot++ * sizeof ctx->vertices;
}
@ -279,10 +278,11 @@ regions_overlap(int srcX0, int srcY0,
*/
void
util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_surface *src,
struct pipe_sampler_view *src_sampler_view,
struct pipe_resource *src_tex,
struct pipe_subresource srcsub,
int srcX0, int srcY0,
int srcX1, int srcY1,
int srcZ0,
struct pipe_surface *dst,
int dstX0, int dstY0,
int dstX1, int dstY1,
@ -292,6 +292,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_sampler_view *sampler_view = NULL;
struct pipe_sampler_view sv_templ;
struct pipe_framebuffer_state fb;
const int srcW = abs(srcX1 - srcX0);
const int srcH = abs(srcY1 - srcY0);
@ -302,13 +303,13 @@ util_blit_pixels_writemask(struct blit_state *ctx,
assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
filter == PIPE_TEX_MIPFILTER_LINEAR);
assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
PIPE_BIND_SAMPLER_VIEW, 0));
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
PIPE_BIND_RENDER_TARGET, 0));
assert(srcsub.level <= src_tex->last_level);
/* do the regions overlap? */
overlap = util_same_surface(src, dst) &&
overlap = src_tex == dst->texture &&
dst->face == srcsub.face &&
dst->level == srcsub.level &&
dst->zslice == srcZ0 &&
regions_overlap(srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1);
@ -317,8 +318,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
* no overlapping.
* Filter mode should not matter since there's no stretching.
*/
if (pipe->surface_copy &&
dst->format == src->format &&
if (dst->format == src_tex->format &&
srcX0 < srcX1 &&
dstX0 < dstX1 &&
srcY0 < srcY1 &&
@ -326,29 +326,36 @@ util_blit_pixels_writemask(struct blit_state *ctx,
(dstX1 - dstX0) == (srcX1 - srcX0) &&
(dstY1 - dstY0) == (srcY1 - srcY0) &&
!overlap) {
pipe->surface_copy(pipe,
dst, dstX0, dstY0, /* dest */
src, srcX0, srcY0, /* src */
srcW, srcH); /* size */
struct pipe_subresource subdst;
subdst.face = dst->face;
subdst.level = dst->level;
pipe->resource_copy_region(pipe,
dst->texture, subdst,
dstX0, dstY0, dst->zslice,/* dest */
src_tex, srcsub,
srcX0, srcY0, srcZ0,/* src */
srcW, srcH); /* size */
return;
}
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
PIPE_BIND_RENDER_TARGET, 0));
/* Create a temporary texture when src and dest alias or when src
* is anything other than a single-level 2d texture.
* is anything other than a 2d texture.
* XXX should just use appropriate shader to access 1d / 3d slice / cube face,
* much like the u_blitter code does (should be pretty trivial).
*
* This can still be improved upon.
*/
if (util_same_surface(src, dst) ||
src->texture->target != PIPE_TEXTURE_2D ||
src->texture->last_level != 0)
if ((src_tex == dst->texture &&
dst->face == srcsub.face &&
dst->level == srcsub.level &&
dst->zslice == srcZ0) ||
src_tex->target != PIPE_TEXTURE_2D)
{
struct pipe_resource texTemp;
struct pipe_resource *tex;
struct pipe_sampler_view sv_templ;
struct pipe_surface *texSurf;
struct pipe_subresource texsub;
const int srcLeft = MIN2(srcX0, srcX1);
const int srcTop = MIN2(srcY0, srcY1);
@ -369,7 +376,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
/* create temp texture */
memset(&texTemp, 0, sizeof(texTemp));
texTemp.target = PIPE_TEXTURE_2D;
texTemp.format = src->format;
texTemp.format = src_tex->format;
texTemp.last_level = 0;
texTemp.width0 = srcW;
texTemp.height0 = srcH;
@ -380,49 +387,50 @@ util_blit_pixels_writemask(struct blit_state *ctx,
if (!tex)
return;
u_sampler_view_default_template(&sv_templ, tex, tex->format);
sampler_view = ctx->pipe->create_sampler_view(ctx->pipe, tex, &sv_templ);
if (!sampler_view) {
pipe_resource_reference(&tex, NULL);
return;
}
texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0,
PIPE_BIND_BLIT_DESTINATION);
texsub.face = 0;
texsub.level = 0;
/* load temp texture */
if (pipe->surface_copy) {
pipe->surface_copy(pipe,
texSurf, 0, 0, /* dest */
src, srcLeft, srcTop, /* src */
srcW, srcH); /* size */
} else {
util_surface_copy(pipe, FALSE,
texSurf, 0, 0, /* dest */
src, srcLeft, srcTop, /* src */
srcW, srcH); /* size */
}
pipe->resource_copy_region(pipe,
tex, texsub, 0, 0, 0, /* dest */
src_tex, srcsub, srcLeft, srcTop, srcZ0, /* src */
srcW, srcH); /* size */
/* free the surface, update the texture if necessary.
*/
pipe_surface_reference(&texSurf, NULL);
s0 = 0.0f;
s1 = 1.0f;
t0 = 0.0f;
t1 = 1.0f;
u_sampler_view_default_template(&sv_templ, tex, tex->format);
sampler_view = pipe->create_sampler_view(pipe, tex, &sv_templ);
if (!sampler_view) {
pipe_resource_reference(&tex, NULL);
return;
}
pipe_resource_reference(&tex, NULL);
}
else {
pipe_sampler_view_reference(&sampler_view, src_sampler_view);
s0 = srcX0 / (float)src->texture->width0;
s1 = srcX1 / (float)src->texture->width0;
t0 = srcY0 / (float)src->texture->height0;
t1 = srcY1 / (float)src->texture->height0;
u_sampler_view_default_template(&sv_templ, src_tex, src_tex->format);
sv_templ.first_level = sv_templ.last_level = srcsub.level;
sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ);
if (!sampler_view) {
return;
}
s0 = srcX0 / (float)(u_minify(sampler_view->texture->width0, srcsub.level));
s1 = srcX1 / (float)(u_minify(sampler_view->texture->width0, srcsub.level));
t0 = srcY0 / (float)(u_minify(sampler_view->texture->height0, srcsub.level));
t1 = srcY1 / (float)(u_minify(sampler_view->texture->height0, srcsub.level));
}
assert(screen->is_format_supported(screen, sampler_view->format, PIPE_TEXTURE_2D,
sampler_view->texture->nr_samples,
PIPE_BIND_SAMPLER_VIEW, 0));
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
dst->texture->nr_samples,
PIPE_BIND_RENDER_TARGET, 0));
/* save state (restored below) */
cso_save_blend(ctx->cso);
@ -447,6 +455,9 @@ util_blit_pixels_writemask(struct blit_state *ctx,
/* sampler */
ctx->sampler.min_img_filter = filter;
ctx->sampler.mag_img_filter = filter;
/* we've limited this already with the sampler view but you never know... */
ctx->sampler.min_lod = srcsub.level;
ctx->sampler.max_lod = srcsub.level;
cso_single_sampler(ctx->cso, 0, &ctx->sampler);
cso_single_sampler_done(ctx->cso);
@ -515,18 +526,21 @@ util_blit_pixels_writemask(struct blit_state *ctx,
void
util_blit_pixels(struct blit_state *ctx,
struct pipe_surface *src,
struct pipe_sampler_view *src_sampler_view,
struct pipe_resource *src_tex,
struct pipe_subresource srcsub,
int srcX0, int srcY0,
int srcX1, int srcY1,
int srcZ,
struct pipe_surface *dst,
int dstX0, int dstY0,
int dstX1, int dstY1,
float z, uint filter )
{
util_blit_pixels_writemask( ctx, src, src_sampler_view,
util_blit_pixels_writemask( ctx, src_tex,
srcsub,
srcX0, srcY0,
srcX1, srcY1,
srcZ,
dst,
dstX0, dstY0,
dstX1, dstY1,
@ -548,7 +562,6 @@ void util_blit_flush( struct blit_state *ctx )
/**
* Copy pixel block from src texture to dst surface.
* Overlapping regions are acceptable.
*
* XXX Should support selection of level.
* XXX need some control over blitting Z and/or stencil.
@ -582,6 +595,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format,
PIPE_TEXTURE_2D,
dst->texture->nr_samples,
PIPE_BIND_RENDER_TARGET,
0));

View file

@ -52,10 +52,11 @@ util_destroy_blit(struct blit_state *ctx);
extern void
util_blit_pixels(struct blit_state *ctx,
struct pipe_surface *src,
struct pipe_sampler_view *src_sampler_view,
struct pipe_resource *src_tex,
struct pipe_subresource srcsub,
int srcX0, int srcY0,
int srcX1, int srcY1,
int srcZ0,
struct pipe_surface *dst,
int dstX0, int dstY0,
int dstX1, int dstY1,
@ -63,10 +64,11 @@ util_blit_pixels(struct blit_state *ctx,
void
util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_surface *src,
struct pipe_sampler_view *src_sampler_view,
struct pipe_resource *src_tex,
struct pipe_subresource srcsub,
int srcX0, int srcY0,
int srcX1, int srcY1,
int srcZ0,
struct pipe_surface *dst,
int dstX0, int dstY0,
int dstX1, int dstY1,

View file

@ -743,8 +743,8 @@ static void util_blitter_overlap_copy(struct blitter_context *blitter,
return;
tex_surf = screen->get_tex_surface(screen, texture, 0, 0, 0,
PIPE_BIND_BLIT_SOURCE |
PIPE_BIND_BLIT_DESTINATION);
PIPE_BIND_SAMPLER_VIEW |
PIPE_BIND_RENDER_TARGET);
/* blit from the src to the temp */
util_blitter_do_copy(blitter, tex_surf, 0, 0,
@ -797,9 +797,9 @@ void util_blitter_copy(struct blitter_context *blitter,
/* (assuming copying a stencil buffer is not possible) */
if ((!ignore_stencil && is_stencil) ||
!screen->is_format_supported(screen, dst->format, dst->texture->target,
dst_tex_usage, 0) ||
dst->texture->nr_samples, dst_tex_usage, 0) ||
!screen->is_format_supported(screen, src->format, src->texture->target,
PIPE_BIND_SAMPLER_VIEW, 0)) {
src->texture->nr_samples, PIPE_BIND_SAMPLER_VIEW, 0)) {
util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy,
width, height);
return;
@ -836,6 +836,7 @@ void util_blitter_fill(struct blitter_context *blitter,
/* check if we can render to the surface */
if (util_format_is_depth_or_stencil(dst->format) || /* unlikely, but you never know */
!screen->is_format_supported(screen, dst->format, dst->texture->target,
dst->texture->nr_samples,
PIPE_BIND_RENDER_TARGET, 0)) {
util_surface_fill(pipe, dst, dstx, dsty, width, height, value);
return;

View file

@ -68,6 +68,7 @@ util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out)
if (!screen->is_format_supported(screen,
list[i++],
PIPE_TEXTURE_2D,
0,
PIPE_BIND_SAMPLER_VIEW,
0)) {
*out = i - 2;

View file

@ -47,25 +47,24 @@ util_clear(struct pipe_context *pipe,
{
if (buffers & PIPE_CLEAR_COLOR) {
struct pipe_surface *ps = framebuffer->cbufs[0];
struct pipe_subresource subdst;
union util_color uc;
subdst.face = ps->face;
subdst.level = ps->level;
util_pack_color(rgba, ps->format, &uc);
if (pipe->surface_fill) {
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui);
} else {
util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui);
}
pipe->resource_fill_region(pipe, ps->texture, subdst, 0, 0, ps->zslice,
ps->width, ps->height, uc.ui);
}
if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
struct pipe_surface *ps = framebuffer->zsbuf;
struct pipe_subresource subdst;
if (pipe->surface_fill) {
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height,
util_pack_z_stencil(ps->format, depth, stencil));
} else {
util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height,
util_pack_z_stencil(ps->format, depth, stencil));
}
subdst.face = ps->face;
subdst.level = ps->level;
pipe->resource_fill_region(pipe, ps->texture, subdst, 0, 0, ps->zslice,
ps->width, ps->height,
util_pack_z_stencil(ps->format, depth, stencil));
}
}

View file

@ -1494,7 +1494,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
/* check if we can render in the texture's format */
if (!screen->is_format_supported(screen, psv->format, PIPE_TEXTURE_2D,
PIPE_BIND_RENDER_TARGET, 0)) {
pt->nr_samples, PIPE_BIND_RENDER_TARGET, 0)) {
fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
return;
}

View file

@ -70,7 +70,7 @@ util_create_rgba_surface(struct pipe_screen *screen,
/* Choose surface format */
for (i = 0; rgbaFormats[i]; i++) {
if (screen->is_format_supported(screen, rgbaFormats[i],
target, bind, 0)) {
target, 0, bind, 0)) {
format = rgbaFormats[i];
break;
}
@ -122,42 +122,42 @@ util_destroy_rgba_surface(struct pipe_resource *texture,
/**
* Fallback function for pipe->surface_copy().
* Note: (X,Y)=(0,0) is always the upper-left corner.
* if do_flip, flip the image vertically on its way from src rect to dst rect.
*/
void
util_surface_copy(struct pipe_context *pipe,
boolean do_flip,
struct pipe_surface *dst,
unsigned dst_x, unsigned dst_y,
struct pipe_surface *src,
unsigned src_x, unsigned src_y,
unsigned w, unsigned h)
util_resource_copy_region(struct pipe_context *pipe,
struct pipe_resource *dst,
struct pipe_subresource subdst,
unsigned dst_x, unsigned dst_y, unsigned dst_z,
struct pipe_resource *src,
struct pipe_subresource subsrc,
unsigned src_x, unsigned src_y, unsigned src_z,
unsigned w, unsigned h)
{
struct pipe_transfer *src_trans, *dst_trans;
void *dst_map;
const void *src_map;
enum pipe_format src_format, dst_format;
assert(src->texture && dst->texture);
if (!src->texture || !dst->texture)
assert(src && dst);
if (!src || !dst)
return;
src_format = src->texture->format;
dst_format = dst->texture->format;
src_format = src->format;
dst_format = dst->format;
src_trans = pipe_get_transfer(pipe,
src->texture,
src->face,
src->level,
src->zslice,
src,
subsrc.face,
subsrc.level,
src_z,
PIPE_TRANSFER_READ,
src_x, src_y, w, h);
dst_trans = pipe_get_transfer(pipe,
dst->texture,
dst->face,
dst->level,
dst->zslice,
dst,
subdst.face,
subdst.level,
src_z,
PIPE_TRANSFER_WRITE,
dst_x, dst_y, w, h);
@ -172,16 +172,15 @@ util_surface_copy(struct pipe_context *pipe,
assert(dst_map);
if (src_map && dst_map) {
/* If do_flip, invert src_y position and pass negative src stride */
util_copy_rect(dst_map,
dst_format,
dst_trans->stride,
0, 0,
w, h,
src_map,
do_flip ? -(int) src_trans->stride : src_trans->stride,
src_trans->stride,
0,
do_flip ? h - 1 : 0);
0);
}
pipe->transfer_unmap(pipe, src_trans);
@ -200,22 +199,23 @@ util_surface_copy(struct pipe_context *pipe,
* Fallback for pipe->surface_fill() function.
*/
void
util_surface_fill(struct pipe_context *pipe,
struct pipe_surface *dst,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height, unsigned value)
util_resource_fill_region(struct pipe_context *pipe,
struct pipe_resource *dst,
struct pipe_subresource subdst,
unsigned dstx, unsigned dsty, unsigned dstz,
unsigned width, unsigned height, unsigned value)
{
struct pipe_transfer *dst_trans;
void *dst_map;
assert(dst->texture);
if (!dst->texture)
assert(dst);
if (!dst)
return;
dst_trans = pipe_get_transfer(pipe,
dst->texture,
dst->face,
dst->level,
dst->zslice,
dst,
subdst.face,
subdst.level,
dstz,
PIPE_TRANSFER_WRITE,
dstx, dsty, width, height);
@ -226,11 +226,11 @@ util_surface_fill(struct pipe_context *pipe,
if (dst_map) {
assert(dst_trans->stride > 0);
switch (util_format_get_blocksize(dst->texture->format)) {
switch (util_format_get_blocksize(dst->format)) {
case 1:
case 2:
case 4:
util_fill_rect(dst_map, dst->texture->format,
util_fill_rect(dst_map, dst->format,
dst_trans->stride,
0, 0, width, height, value);
break;

View file

@ -33,23 +33,6 @@
#include "pipe/p_state.h"
/**
* Are s1 and s2 the same surface?
* Surfaces are basically views into textures so check if the two surfaces
* name the same part of the same texture.
*/
static INLINE boolean
util_same_surface(const struct pipe_surface *s1, const struct pipe_surface *s2)
{
return (s1->texture == s2->texture &&
s1->face == s2->face &&
s1->level == s2->level &&
s1->zslice == s2->zslice);
}
extern boolean
util_create_rgba_surface(struct pipe_screen *screen,
uint width, uint height, uint bind,
@ -64,19 +47,21 @@ util_destroy_rgba_surface(struct pipe_resource *texture,
extern void
util_surface_copy(struct pipe_context *pipe,
boolean do_flip,
struct pipe_surface *dst,
unsigned dst_x, unsigned dst_y,
struct pipe_surface *src,
unsigned src_x, unsigned src_y,
unsigned w, unsigned h);
util_resource_copy_region(struct pipe_context *pipe,
struct pipe_resource *dst,
struct pipe_subresource subdst,
unsigned dst_x, unsigned dst_y, unsigned dst_z,
struct pipe_resource *src,
struct pipe_subresource subsrc,
unsigned src_x, unsigned src_y, unsigned src_z,
unsigned w, unsigned h);
extern void
util_surface_fill(struct pipe_context *pipe,
struct pipe_surface *dst,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height, unsigned value);
util_resource_fill_region(struct pipe_context *pipe,
struct pipe_resource *dst,
struct pipe_subresource subdst,
unsigned dstx, unsigned dsty, unsigned dstz,
unsigned width, unsigned height, unsigned value);