This looks good to me.<br><br>Marek<br><br><div class="gmail_quote">On Wed, Mar 9, 2011 at 9:31 PM, Henri Verbeet <span dir="ltr"><<a href="mailto:hverbeet@gmail.com">hverbeet@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Blits between sRGB and linear formats should happen in linear color space.<br>
This fixes piglit fbo/fbo-srgb-blit.<br>
---<br>
src/gallium/auxiliary/util/u_blit.c | 57 ++++++++++++++++++++------------<br>
src/gallium/auxiliary/util/u_blitter.c | 3 +-<br>
src/mesa/state_tracker/st_cb_texture.c | 2 +-<br>
3 files changed, 39 insertions(+), 23 deletions(-)<br>
<br>
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c<br>
index 76bd7ac..3618353 100644<br>
--- a/src/gallium/auxiliary/util/u_blit.c<br>
+++ b/src/gallium/auxiliary/util/u_blit.c<br>
@@ -304,8 +304,10 @@ util_blit_pixels_writemask(struct blit_state *ctx,<br>
{<br>
struct pipe_context *pipe = ctx->pipe;<br>
struct pipe_screen *screen = pipe->screen;<br>
+ enum pipe_format src_format, dst_format;<br>
struct pipe_sampler_view *sampler_view = NULL;<br>
struct pipe_sampler_view sv_templ;<br>
+ struct pipe_surface *dst_surface;<br>
struct pipe_framebuffer_state fb;<br>
const int srcW = abs(srcX1 - srcX0);<br>
const int srcH = abs(srcY1 - srcY0);<br>
@@ -326,12 +328,15 @@ util_blit_pixels_writemask(struct blit_state *ctx,<br>
regions_overlap(srcX0, srcY0, srcX1, srcY1,<br>
dstX0, dstY0, dstX1, dstY1);<br>
<br>
+ src_format = util_format_linear(src_tex->format);<br>
+ dst_format = util_format_linear(dst->format);<br>
+<br>
/*<br>
* Check for simple case: no format conversion, no flipping, no stretching,<br>
* no overlapping.<br>
* Filter mode should not matter since there's no stretching.<br>
*/<br>
- if (dst->format == src_tex->format &&<br>
+ if (dst_format == src_format &&<br>
srcX0 < srcX1 &&<br>
dstX0 < dstX1 &&<br>
srcY0 < srcY1 &&<br>
@@ -354,6 +359,14 @@ util_blit_pixels_writemask(struct blit_state *ctx,<br>
return;<br>
}<br>
<br>
+ if (dst_format == dst->format) {<br>
+ dst_surface = dst;<br>
+ } else {<br>
+ struct pipe_surface templ = *dst;<br>
+ templ.format = dst_format;<br>
+ dst_surface = pipe->create_surface(pipe, dst->texture, &templ);<br>
+ }<br>
+<br>
/* Create a temporary texture when src and dest alias or when src<br>
* is anything other than a 2d texture.<br>
* XXX should just use appropriate shader to access 1d / 3d slice / cube face,<br>
@@ -361,9 +374,9 @@ util_blit_pixels_writemask(struct blit_state *ctx,<br>
*<br>
* This can still be improved upon.<br>
*/<br>
- if ((src_tex == dst->texture &&<br>
- dst->u.tex.level == src_level &&<br>
- dst->u.tex.first_layer == srcZ0) ||<br>
+ if ((src_tex == dst_surface->texture &&<br>
+ dst_surface->u.tex.level == src_level &&<br>
+ dst_surface->u.tex.first_layer == srcZ0) ||<br>
(src_tex->target != PIPE_TEXTURE_2D &&<br>
src_tex->target != PIPE_TEXTURE_2D &&<br>
src_tex->target != PIPE_TEXTURE_RECT))<br>
@@ -392,7 +405,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,<br>
/* create temp texture */<br>
memset(&texTemp, 0, sizeof(texTemp));<br>
texTemp.target = ctx->internal_target;<br>
- texTemp.format = src_tex->format;<br>
+ texTemp.format = src_format;<br>
texTemp.last_level = 0;<br>
texTemp.width0 = srcW;<br>
texTemp.height0 = srcH;<br>
@@ -439,7 +452,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,<br>
pipe_resource_reference(&tex, NULL);<br>
}<br>
else {<br>
- u_sampler_view_default_template(&sv_templ, src_tex, src_tex->format);<br>
+ u_sampler_view_default_template(&sv_templ, src_tex, src_format);<br>
sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ);<br>
<br>
if (!sampler_view) {<br>
@@ -460,13 +473,13 @@ util_blit_pixels_writemask(struct blit_state *ctx,<br>
}<br>
}<br>
<br>
- dst_is_depth = util_format_is_depth_or_stencil(dst->format);<br>
+ dst_is_depth = util_format_is_depth_or_stencil(dst_format);<br>
<br>
assert(screen->is_format_supported(screen, sampler_view->format, ctx->internal_target,<br>
sampler_view->texture->nr_samples,<br>
PIPE_BIND_SAMPLER_VIEW, 0));<br>
- assert(screen->is_format_supported(screen, dst->format, ctx->internal_target,<br>
- dst->texture->nr_samples,<br>
+ assert(screen->is_format_supported(screen, dst_format, ctx->internal_target,<br>
+ dst_surface->texture->nr_samples,<br>
dst_is_depth ? PIPE_BIND_DEPTH_STENCIL :<br>
PIPE_BIND_RENDER_TARGET, 0));<br>
/* save state (restored below) */<br>
@@ -502,12 +515,12 @@ util_blit_pixels_writemask(struct blit_state *ctx,<br>
cso_single_sampler_done(ctx->cso);<br>
<br>
/* viewport */<br>
- ctx->viewport.scale[0] = 0.5f * dst->width;<br>
- ctx->viewport.scale[1] = 0.5f * dst->height;<br>
+ ctx->viewport.scale[0] = 0.5f * dst_surface->width;<br>
+ ctx->viewport.scale[1] = 0.5f * dst_surface->height;<br>
ctx->viewport.scale[2] = 0.5f;<br>
ctx->viewport.scale[3] = 1.0f;<br>
- ctx->viewport.translate[0] = 0.5f * dst->width;<br>
- ctx->viewport.translate[1] = 0.5f * dst->height;<br>
+ ctx->viewport.translate[0] = 0.5f * dst_surface->width;<br>
+ ctx->viewport.translate[1] = 0.5f * dst_surface->height;<br>
ctx->viewport.translate[2] = 0.5f;<br>
ctx->viewport.translate[3] = 0.0f;<br>
cso_set_viewport(ctx->cso, &ctx->viewport);<br>
@@ -536,22 +549,22 @@ util_blit_pixels_writemask(struct blit_state *ctx,<br>
<br>
/* drawing dest */<br>
memset(&fb, 0, sizeof(fb));<br>
- fb.width = dst->width;<br>
- fb.height = dst->height;<br>
+ fb.width = dst_surface->width;<br>
+ fb.height = dst_surface->height;<br>
if (dst_is_depth) {<br>
- fb.zsbuf = dst;<br>
+ fb.zsbuf = dst_surface;<br>
} else {<br>
fb.nr_cbufs = 1;<br>
- fb.cbufs[0] = dst;<br>
+ fb.cbufs[0] = dst_surface;<br>
}<br>
cso_set_framebuffer(ctx->cso, &fb);<br>
<br>
/* draw quad */<br>
offset = setup_vertex_data_tex(ctx,<br>
- (float) dstX0 / dst->width * 2.0f - 1.0f,<br>
- (float) dstY0 / dst->height * 2.0f - 1.0f,<br>
- (float) dstX1 / dst->width * 2.0f - 1.0f,<br>
- (float) dstY1 / dst->height * 2.0f - 1.0f,<br>
+ (float) dstX0 / dst_surface->width * 2.0f - 1.0f,<br>
+ (float) dstY0 / dst_surface->height * 2.0f - 1.0f,<br>
+ (float) dstX1 / dst_surface->width * 2.0f - 1.0f,<br>
+ (float) dstY1 / dst_surface->height * 2.0f - 1.0f,<br>
s0, t0,<br>
s1, t1,<br>
z);<br>
@@ -576,6 +589,8 @@ util_blit_pixels_writemask(struct blit_state *ctx,<br>
cso_restore_vertex_buffers(ctx->cso);<br>
<br>
pipe_sampler_view_reference(&sampler_view, NULL);<br>
+ if (dst_surface != dst)<br>
+ pipe_surface_reference(&dst_surface, NULL);<br>
}<br>
<br>
<br>
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c<br>
index fd1c2b7..287f5da 100644<br>
--- a/src/gallium/auxiliary/util/u_blitter.c<br>
+++ b/src/gallium/auxiliary/util/u_blitter.c<br>
@@ -785,6 +785,7 @@ void util_blitter_copy_region(struct blitter_context *blitter,<br>
/* Get surface. */<br>
memset(&surf_templ, 0, sizeof(surf_templ));<br>
u_surface_default_template(&surf_templ, dst, bind);<br>
+ surf_templ.format = util_format_linear(dst->format);<br>
surf_templ.u.tex.level = dstlevel;<br>
surf_templ.u.tex.first_layer = dstz;<br>
surf_templ.u.tex.last_layer = dstz;<br>
@@ -823,7 +824,7 @@ void util_blitter_copy_region(struct blitter_context *blitter,<br>
normalized = src->target != PIPE_TEXTURE_RECT;<br>
<br>
/* Initialize sampler view. */<br>
- u_sampler_view_default_template(&viewTempl, src, src->format);<br>
+ u_sampler_view_default_template(&viewTempl, src, util_format_linear(src->format));<br>
view = pipe->create_sampler_view(pipe, src, &viewTempl);<br>
<br>
/* Set rasterizer state, shaders, and textures. */<br>
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c<br>
index 3f98ffd..ab2d645 100644<br>
--- a/src/mesa/state_tracker/st_cb_texture.c<br>
+++ b/src/mesa/state_tracker/st_cb_texture.c<br>
@@ -1533,7 +1533,7 @@ st_copy_texsubimage(struct gl_context *ctx,<br>
GLint srcY0, srcY1;<br>
struct pipe_surface surf_tmpl;<br>
memset(&surf_tmpl, 0, sizeof(surf_tmpl));<br>
- surf_tmpl.format = stImage->pt->format;<br>
+ surf_tmpl.format = util_format_linear(stImage->pt->format);<br>
surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;<br>
surf_tmpl.u.tex.level = stImage->level;<br>
surf_tmpl.u.tex.first_layer = stImage->face + destZ;<br>
<font color="#888888">--<br>
1.7.2.3<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></blockquote></div><br>