mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-07 21:40:20 +01:00
u_blitter: Do blits in linear color space.
Blits between sRGB and linear formats should happen in linear color space. This fixes piglit fbo/fbo-srgb-blit.
This commit is contained in:
parent
6da4866ffd
commit
ab21147c89
3 changed files with 39 additions and 23 deletions
|
|
@ -304,8 +304,10 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
|||
{
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
enum pipe_format src_format, dst_format;
|
||||
struct pipe_sampler_view *sampler_view = NULL;
|
||||
struct pipe_sampler_view sv_templ;
|
||||
struct pipe_surface *dst_surface;
|
||||
struct pipe_framebuffer_state fb;
|
||||
const int srcW = abs(srcX1 - srcX0);
|
||||
const int srcH = abs(srcY1 - srcY0);
|
||||
|
|
@ -326,12 +328,15 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
|||
regions_overlap(srcX0, srcY0, srcX1, srcY1,
|
||||
dstX0, dstY0, dstX1, dstY1);
|
||||
|
||||
src_format = util_format_linear(src_tex->format);
|
||||
dst_format = util_format_linear(dst->format);
|
||||
|
||||
/*
|
||||
* Check for simple case: no format conversion, no flipping, no stretching,
|
||||
* no overlapping.
|
||||
* Filter mode should not matter since there's no stretching.
|
||||
*/
|
||||
if (dst->format == src_tex->format &&
|
||||
if (dst_format == src_format &&
|
||||
srcX0 < srcX1 &&
|
||||
dstX0 < dstX1 &&
|
||||
srcY0 < srcY1 &&
|
||||
|
|
@ -354,6 +359,14 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
|||
return;
|
||||
}
|
||||
|
||||
if (dst_format == dst->format) {
|
||||
dst_surface = dst;
|
||||
} else {
|
||||
struct pipe_surface templ = *dst;
|
||||
templ.format = dst_format;
|
||||
dst_surface = pipe->create_surface(pipe, dst->texture, &templ);
|
||||
}
|
||||
|
||||
/* Create a temporary texture when src and dest alias or when src
|
||||
* is anything other than a 2d texture.
|
||||
* XXX should just use appropriate shader to access 1d / 3d slice / cube face,
|
||||
|
|
@ -361,9 +374,9 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
|||
*
|
||||
* This can still be improved upon.
|
||||
*/
|
||||
if ((src_tex == dst->texture &&
|
||||
dst->u.tex.level == src_level &&
|
||||
dst->u.tex.first_layer == srcZ0) ||
|
||||
if ((src_tex == dst_surface->texture &&
|
||||
dst_surface->u.tex.level == src_level &&
|
||||
dst_surface->u.tex.first_layer == srcZ0) ||
|
||||
(src_tex->target != PIPE_TEXTURE_2D &&
|
||||
src_tex->target != PIPE_TEXTURE_2D &&
|
||||
src_tex->target != PIPE_TEXTURE_RECT))
|
||||
|
|
@ -392,7 +405,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
|||
/* create temp texture */
|
||||
memset(&texTemp, 0, sizeof(texTemp));
|
||||
texTemp.target = ctx->internal_target;
|
||||
texTemp.format = src_tex->format;
|
||||
texTemp.format = src_format;
|
||||
texTemp.last_level = 0;
|
||||
texTemp.width0 = srcW;
|
||||
texTemp.height0 = srcH;
|
||||
|
|
@ -439,7 +452,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
|||
pipe_resource_reference(&tex, NULL);
|
||||
}
|
||||
else {
|
||||
u_sampler_view_default_template(&sv_templ, src_tex, src_tex->format);
|
||||
u_sampler_view_default_template(&sv_templ, src_tex, src_format);
|
||||
sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ);
|
||||
|
||||
if (!sampler_view) {
|
||||
|
|
@ -460,13 +473,13 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
dst_is_depth = util_format_is_depth_or_stencil(dst->format);
|
||||
dst_is_depth = util_format_is_depth_or_stencil(dst_format);
|
||||
|
||||
assert(screen->is_format_supported(screen, sampler_view->format, ctx->internal_target,
|
||||
sampler_view->texture->nr_samples,
|
||||
PIPE_BIND_SAMPLER_VIEW));
|
||||
assert(screen->is_format_supported(screen, dst->format, ctx->internal_target,
|
||||
dst->texture->nr_samples,
|
||||
assert(screen->is_format_supported(screen, dst_format, ctx->internal_target,
|
||||
dst_surface->texture->nr_samples,
|
||||
dst_is_depth ? PIPE_BIND_DEPTH_STENCIL :
|
||||
PIPE_BIND_RENDER_TARGET));
|
||||
/* save state (restored below) */
|
||||
|
|
@ -502,12 +515,12 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
|||
cso_single_sampler_done(ctx->cso);
|
||||
|
||||
/* viewport */
|
||||
ctx->viewport.scale[0] = 0.5f * dst->width;
|
||||
ctx->viewport.scale[1] = 0.5f * dst->height;
|
||||
ctx->viewport.scale[0] = 0.5f * dst_surface->width;
|
||||
ctx->viewport.scale[1] = 0.5f * dst_surface->height;
|
||||
ctx->viewport.scale[2] = 0.5f;
|
||||
ctx->viewport.scale[3] = 1.0f;
|
||||
ctx->viewport.translate[0] = 0.5f * dst->width;
|
||||
ctx->viewport.translate[1] = 0.5f * dst->height;
|
||||
ctx->viewport.translate[0] = 0.5f * dst_surface->width;
|
||||
ctx->viewport.translate[1] = 0.5f * dst_surface->height;
|
||||
ctx->viewport.translate[2] = 0.5f;
|
||||
ctx->viewport.translate[3] = 0.0f;
|
||||
cso_set_viewport(ctx->cso, &ctx->viewport);
|
||||
|
|
@ -536,22 +549,22 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
|||
|
||||
/* drawing dest */
|
||||
memset(&fb, 0, sizeof(fb));
|
||||
fb.width = dst->width;
|
||||
fb.height = dst->height;
|
||||
fb.width = dst_surface->width;
|
||||
fb.height = dst_surface->height;
|
||||
if (dst_is_depth) {
|
||||
fb.zsbuf = dst;
|
||||
fb.zsbuf = dst_surface;
|
||||
} else {
|
||||
fb.nr_cbufs = 1;
|
||||
fb.cbufs[0] = dst;
|
||||
fb.cbufs[0] = dst_surface;
|
||||
}
|
||||
cso_set_framebuffer(ctx->cso, &fb);
|
||||
|
||||
/* draw quad */
|
||||
offset = setup_vertex_data_tex(ctx,
|
||||
(float) dstX0 / dst->width * 2.0f - 1.0f,
|
||||
(float) dstY0 / dst->height * 2.0f - 1.0f,
|
||||
(float) dstX1 / dst->width * 2.0f - 1.0f,
|
||||
(float) dstY1 / dst->height * 2.0f - 1.0f,
|
||||
(float) dstX0 / dst_surface->width * 2.0f - 1.0f,
|
||||
(float) dstY0 / dst_surface->height * 2.0f - 1.0f,
|
||||
(float) dstX1 / dst_surface->width * 2.0f - 1.0f,
|
||||
(float) dstY1 / dst_surface->height * 2.0f - 1.0f,
|
||||
s0, t0,
|
||||
s1, t1,
|
||||
z);
|
||||
|
|
@ -576,6 +589,8 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
|||
cso_restore_vertex_buffers(ctx->cso);
|
||||
|
||||
pipe_sampler_view_reference(&sampler_view, NULL);
|
||||
if (dst_surface != dst)
|
||||
pipe_surface_reference(&dst_surface, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -785,6 +785,7 @@ void util_blitter_copy_region(struct blitter_context *blitter,
|
|||
/* Get surface. */
|
||||
memset(&surf_templ, 0, sizeof(surf_templ));
|
||||
u_surface_default_template(&surf_templ, dst, bind);
|
||||
surf_templ.format = util_format_linear(dst->format);
|
||||
surf_templ.u.tex.level = dstlevel;
|
||||
surf_templ.u.tex.first_layer = dstz;
|
||||
surf_templ.u.tex.last_layer = dstz;
|
||||
|
|
@ -823,7 +824,7 @@ void util_blitter_copy_region(struct blitter_context *blitter,
|
|||
normalized = src->target != PIPE_TEXTURE_RECT;
|
||||
|
||||
/* Initialize sampler view. */
|
||||
u_sampler_view_default_template(&viewTempl, src, src->format);
|
||||
u_sampler_view_default_template(&viewTempl, src, util_format_linear(src->format));
|
||||
view = pipe->create_sampler_view(pipe, src, &viewTempl);
|
||||
|
||||
/* Set rasterizer state, shaders, and textures. */
|
||||
|
|
|
|||
|
|
@ -1530,7 +1530,7 @@ st_copy_texsubimage(struct gl_context *ctx,
|
|||
GLint srcY0, srcY1;
|
||||
struct pipe_surface surf_tmpl;
|
||||
memset(&surf_tmpl, 0, sizeof(surf_tmpl));
|
||||
surf_tmpl.format = stImage->pt->format;
|
||||
surf_tmpl.format = util_format_linear(stImage->pt->format);
|
||||
surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
|
||||
surf_tmpl.u.tex.level = stImage->level;
|
||||
surf_tmpl.u.tex.first_layer = stImage->face + destZ;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue