I've attached a rough outline of a patch to add a bind_as_integer flag for vertex elements, sampler views and surfaces.
I wonder if the sampler view and surfaces are always going to be bind as integer for SCALED types, in which case maybe we can just state that somewhere and move on. I've also shown the clear color code in softpipe where it pick the correct clear color depending on the surface type. I've started hacking on u_blitter and r600g to no avail yet to try and get some of the -integer tests passing. Dave.
From 4a9f4129f8fecc37feda5de5431ee70b90c7337a Mon Sep 17 00:00:00 2001 From: Dave Airlie <airl...@redhat.com> Date: Tue, 13 Sep 2011 16:27:46 +0100 Subject: [PATCH] [RFC] gallium: initial integer binding + clear code. This is just a WIP so far. not really looked at vertex sampling yet. Signed-off-by: Dave Airlie <airl...@redhat.com> --- src/gallium/auxiliary/util/u_sampler.c | 8 ++- src/gallium/drivers/softpipe/sp_clear.c | 11 ++-- src/gallium/drivers/softpipe/sp_clear.h | 3 +- src/gallium/drivers/softpipe/sp_texture.c | 2 +- src/gallium/drivers/softpipe/sp_tile_cache.c | 66 +++++++++++++++++++------- src/gallium/drivers/softpipe/sp_tile_cache.h | 5 +- src/gallium/include/pipe/p_context.h | 6 +- src/gallium/include/pipe/p_defines.h | 6 ++ src/gallium/include/pipe/p_state.h | 4 +- src/mesa/state_tracker/st_atom_texture.c | 15 ++++-- src/mesa/state_tracker/st_cb_clear.c | 16 +++--- src/mesa/state_tracker/st_cb_fbo.c | 4 ++ src/mesa/state_tracker/st_format.c | 6 +- src/mesa/state_tracker/st_format.h | 4 +- 14 files changed, 106 insertions(+), 50 deletions(-) diff --git a/src/gallium/auxiliary/util/u_sampler.c b/src/gallium/auxiliary/util/u_sampler.c index bb26099..34e9bd1 100644 --- a/src/gallium/auxiliary/util/u_sampler.c +++ b/src/gallium/auxiliary/util/u_sampler.c @@ -34,12 +34,14 @@ static void default_template(struct pipe_sampler_view *view, const struct pipe_resource *texture, enum pipe_format format, - unsigned expand_green_blue) + unsigned expand_green_blue, + boolean is_integer) { /* XXX: Check if format is compatible with texture->format. */ view->format = format; + view->bind_as_integer = is_integer; view->u.tex.first_level = 0; view->u.tex.last_level = texture->last_level; view->u.tex.first_layer = 0; @@ -87,7 +89,7 @@ u_sampler_view_default_template(struct pipe_sampler_view *view, default_template(view, texture, format, - PIPE_SWIZZLE_ZERO); + PIPE_SWIZZLE_ZERO, FALSE); } void @@ -99,5 +101,5 @@ u_sampler_view_default_dx9_template(struct pipe_sampler_view *view, default_template(view, texture, format, - PIPE_SWIZZLE_ONE); + PIPE_SWIZZLE_ONE, FALSE); } diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c index 22e8a2e..9071282 100644 --- a/src/gallium/drivers/softpipe/sp_clear.c +++ b/src/gallium/drivers/softpipe/sp_clear.c @@ -45,7 +45,8 @@ * No masking, no scissor (clear entire buffer). */ void -softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, +softpipe_clear(struct pipe_context *pipe, unsigned buffers, + const union pipe_clear_color *color, double depth, unsigned stencil) { struct softpipe_context *softpipe = softpipe_context(pipe); @@ -67,17 +68,17 @@ softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { struct pipe_surface *ps = softpipe->framebuffer.cbufs[i]; - util_pack_color(rgba, ps->format, &uc); - sp_tile_cache_clear(softpipe->cbuf_cache[i], rgba, uc.ui); + util_pack_color(color->f, ps->format, &uc); + sp_tile_cache_clear(softpipe->cbuf_cache[i], color, uc.ui); } } if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { - static const float zero[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; + static const union pipe_clear_color zero; struct pipe_surface *ps = softpipe->framebuffer.zsbuf; cv = util_pack_z_stencil(ps->format, depth, stencil); - sp_tile_cache_clear(softpipe->zsbuf_cache, zero, cv); + sp_tile_cache_clear(softpipe->zsbuf_cache, &zero, cv); } softpipe->dirty_render_cache = TRUE; diff --git a/src/gallium/drivers/softpipe/sp_clear.h b/src/gallium/drivers/softpipe/sp_clear.h index 9be3b86..8915775 100644 --- a/src/gallium/drivers/softpipe/sp_clear.h +++ b/src/gallium/drivers/softpipe/sp_clear.h @@ -35,7 +35,8 @@ struct pipe_context; extern void -softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, +softpipe_clear(struct pipe_context *pipe, unsigned buffers, + const union pipe_clear_color *color, double depth, unsigned stencil); diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 95374c3..96d6f64 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -273,7 +273,7 @@ softpipe_create_surface(struct pipe_context *pipe, ps->width = u_minify(pt->width0, level); ps->height = u_minify(pt->height0, level); ps->usage = surf_tmpl->usage; - + ps->bind_as_integer = surf_tmpl->bind_as_integer; ps->u.tex.level = level; ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 60870b8..5543f3a 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -41,6 +41,9 @@ static struct softpipe_cached_tile * sp_alloc_tile(struct softpipe_tile_cache *tc); +#define SP_CLEAR_TYPE_FLOAT 0 +#define SP_CLEAR_TYPE_UNSIGNED 1 +#define SP_CLEAR_TYPE_SIGNED 2 /** * Return the position in the cache for the tile that contains win pos (x,y). @@ -224,23 +227,52 @@ sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc) */ static void clear_tile_rgba(struct softpipe_cached_tile *tile, - enum pipe_format format, - const float clear_value[4]) + enum pipe_format format, boolean bind_as_integer, + union pipe_clear_color *clear_value) { - if (clear_value[0] == 0.0 && - clear_value[1] == 0.0 && - clear_value[2] == 0.0 && - clear_value[3] == 0.0) { + int clear_type; + if (!bind_as_integer) + clear_type = SP_CLEAR_TYPE_FLOAT; + else { + struct util_format_description *desc = util_format_description(format); + if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) + clear_type = SP_CLEAR_TYPE_UNSIGNED; + else + clear_type = SP_CLEAR_TYPE_SIGNED; + } + + if (clear_value->f[0] == 0.0 && + clear_value->f[1] == 0.0 && + clear_value->f[2] == 0.0 && + clear_value->f[3] == 0.0) { memset(tile->data.color, 0, sizeof(tile->data.color)); } else { uint i, j; for (i = 0; i < TILE_SIZE; i++) { for (j = 0; j < TILE_SIZE; j++) { - tile->data.color[i][j][0] = clear_value[0]; - tile->data.color[i][j][1] = clear_value[1]; - tile->data.color[i][j][2] = clear_value[2]; - tile->data.color[i][j][3] = clear_value[3]; + switch (clear_type) { + case SP_CLEAR_TYPE_FLOAT: + default: + tile->data.color[i][j][0] = clear_value->f[0]; + tile->data.color[i][j][1] = clear_value->f[1]; + tile->data.color[i][j][2] = clear_value->f[2]; + tile->data.color[i][j][3] = clear_value->f[3]; + break; + case SP_CLEAR_TYPE_UNSIGNED: + tile->data.color[i][j][0] = clear_value->ui[0]; + tile->data.color[i][j][1] = clear_value->ui[1]; + tile->data.color[i][j][2] = clear_value->ui[2]; + tile->data.color[i][j][3] = clear_value->ui[3]; + break; + case SP_CLEAR_TYPE_SIGNED: + tile->data.color[i][j][0] = clear_value->i[0]; + tile->data.color[i][j][1] = clear_value->i[1]; + tile->data.color[i][j][2] = clear_value->i[2]; + tile->data.color[i][j][3] = clear_value->i[3]; + break; + + } } } } @@ -311,7 +343,9 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc) if (tc->depth_stencil) { clear_tile(tc->tile, pt->resource->format, tc->clear_val); } else { - clear_tile_rgba(tc->tile, pt->resource->format, tc->clear_color); + clear_tile_rgba(tc->tile, tc->surface->format, + tc->surface->bind_as_integer, + &tc->clear_color); } /* push the tile to all positions marked as clear */ @@ -486,7 +520,8 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc, clear_tile(tile, pt->resource->format, tc->clear_val); } else { - clear_tile_rgba(tile, pt->resource->format, tc->clear_color); + clear_tile_rgba(tile, tc->surface->format, + tc->surface->bind_as_integer, &tc->clear_color); } clear_clear_flag(tc->clear_flags, addr); } @@ -524,15 +559,12 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc, * Save the color and set a 'clearflag' for each tile of the screen. */ void -sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba, +sp_tile_cache_clear(struct softpipe_tile_cache *tc, const union pipe_clear_color *color, uint clearValue) { uint pos; - tc->clear_color[0] = rgba[0]; - tc->clear_color[1] = rgba[1]; - tc->clear_color[2] = rgba[2]; - tc->clear_color[3] = rgba[3]; + tc->clear_color = *color; tc->clear_val = clearValue; diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 68140b1..9547b96 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -85,7 +85,7 @@ struct softpipe_tile_cache union tile_address tile_addrs[NUM_ENTRIES]; struct softpipe_cached_tile *entries[NUM_ENTRIES]; uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; - float clear_color[4]; /**< for color bufs */ + union pipe_clear_color clear_color; /**< for color bufs */ uint clear_val; /**< for z+stencil */ boolean depth_stencil; /**< Is the surface a depth/stencil format? */ @@ -119,7 +119,8 @@ extern void sp_flush_tile_cache(struct softpipe_tile_cache *tc); extern void -sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba, +sp_tile_cache_clear(struct softpipe_tile_cache *tc, + const union pipe_clear_color *color, uint clearValue); extern struct softpipe_cached_tile * diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index da3ee87..d139a46 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -63,7 +63,7 @@ struct pipe_vertex_element; struct pipe_video_buffer; struct pipe_video_decoder; struct pipe_viewport_state; - +union pipe_clear_color; /** * Gallium rendering context. Basically: @@ -287,7 +287,7 @@ struct pipe_context { */ void (*clear)(struct pipe_context *pipe, unsigned buffers, - const float *rgba, + const union pipe_clear_color *color, double depth, unsigned stencil); @@ -297,7 +297,7 @@ struct pipe_context { */ void (*clear_render_target)(struct pipe_context *pipe, struct pipe_surface *dst, - const float *rgba, + const union pipe_clear_color *color, unsigned dstx, unsigned dsty, unsigned width, unsigned height); diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 777a177..032227d 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -515,6 +515,12 @@ struct pipe_query_data_timestamp_disjoint boolean disjoint; }; +union pipe_clear_color +{ + float f[4]; + int i[4]; + unsigned int ui[4]; +}; #ifdef __cplusplus } diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 840b3ee..b1ebd8b 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -286,7 +286,7 @@ struct pipe_surface struct pipe_resource *texture; /**< resource into which this is a view */ struct pipe_context *context; /**< context this view belongs to */ enum pipe_format format; - + boolean bind_as_integer; /**< certain resources can be interpreted as float or integer values */ /* XXX width/height should be removed */ unsigned width; /**< logical width in pixels */ unsigned height; /**< logical height in pixels */ @@ -314,6 +314,7 @@ struct pipe_sampler_view { struct pipe_reference reference; enum pipe_format format; /**< typed PIPE_FORMAT_x */ + boolean bind_as_integer; /**< certain resources can be interpreted as float or integer values */ struct pipe_resource *texture; /**< texture into which this is a view */ struct pipe_context *context; /**< context this view belongs to */ union { @@ -439,6 +440,7 @@ struct pipe_vertex_element unsigned vertex_buffer_index; enum pipe_format src_format; + boolean bind_as_integer; /**< certain resources can be interpreted as float or integer values */ }; diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 3115a25..8e923c1 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -35,6 +35,7 @@ #include "main/macros.h" #include "main/mtypes.h" #include "main/samplerobj.h" +#include "main/image.h" #include "program/prog_instruction.h" #include "st_context.h" @@ -141,7 +142,8 @@ static INLINE struct pipe_sampler_view * st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe, struct st_texture_object *stObj, const struct gl_sampler_object *samp, - enum pipe_format format) + enum pipe_format format, + bool is_integer) { struct pipe_sampler_view templ; GLuint swizzle = apply_depthmode(stObj->pt->format, @@ -151,6 +153,7 @@ st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe, u_sampler_view_default_template(&templ, stObj->pt, format); + templ.bind_as_integer = is_integer; templ.u.tex.first_level = stObj->base.BaseLevel; if (swizzle != SWIZZLE_NOOP) { @@ -168,7 +171,8 @@ static INLINE struct pipe_sampler_view * st_get_texture_sampler_view_from_stobj(struct st_texture_object *stObj, struct pipe_context *pipe, const struct gl_sampler_object *samp, - enum pipe_format format) + enum pipe_format format, + bool is_integer) { if (!stObj || !stObj->pt) { return NULL; @@ -176,7 +180,7 @@ st_get_texture_sampler_view_from_stobj(struct st_texture_object *stObj, if (!stObj->sampler_view) { stObj->sampler_view = - st_create_texture_sampler_view_from_stobj(pipe, stObj, samp, format); + st_create_texture_sampler_view_from_stobj(pipe, stObj, samp, format, is_integer); } return stObj->sampler_view; @@ -193,6 +197,7 @@ update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_ struct st_texture_object *stObj; enum pipe_format st_view_format; GLboolean retval; + bool is_integer = false; samp = _mesa_get_samplerobj(ctx, texUnit); @@ -229,6 +234,7 @@ update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_ firstImageFormat = st_mesa_format_to_pipe_format(linearFormat); } + is_integer = _mesa_is_integer_format(firstImage->base.InternalFormat); if (firstImageFormat != stObj->pt->format) st_view_format = firstImageFormat; } @@ -240,6 +246,7 @@ update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_ stObj->base._Swizzle, samp->DepthMode) || (st_view_format != stObj->sampler_view->format) || + (is_integer != stObj->sampler_view->bind_as_integer) || stObj->base.BaseLevel != stObj->sampler_view->u.tex.first_level) { pipe_sampler_view_reference(&stObj->sampler_view, NULL); } @@ -247,7 +254,7 @@ update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_ *sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe, samp, - st_view_format); + st_view_format, is_integer); return GL_TRUE; } diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index f32286c..499b682 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -227,7 +227,7 @@ clear_with_quad(struct gl_context *ctx, const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f; const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f; const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f; - float clearColor[4]; + union pipe_clear_color clearColor; /* printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, @@ -323,13 +323,13 @@ clear_with_quad(struct gl_context *ctx, set_vertex_shader(st); if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { - st_translate_clear_color(ctx->Color.ClearColorUnclamped, + st_translate_clear_color(&ctx->Color.ClearColorUnclamped, ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, - clearColor); + &clearColor); } /* draw quad matching scissor rect */ - draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, clearColor); + draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, clearColor.f); /* Restore pipe state */ cso_restore_blend(st->cso_context); @@ -572,7 +572,7 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) * required from the visual. Hence fix this up to avoid potential * read-modify-write in the driver. */ - float clearColor[4]; + union pipe_clear_color clearColor; if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) && ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) && @@ -582,12 +582,12 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { - st_translate_clear_color(ctx->Color.ClearColorUnclamped, + st_translate_clear_color(&ctx->Color.ClearColorUnclamped, ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, - clearColor); + &clearColor); } - st->pipe->clear(st->pipe, clear_buffers, clearColor, + st->pipe->clear(st->pipe, clear_buffers, &clearColor, ctx->Depth.Clear, ctx->Stencil.Clear); } if (mask & BUFFER_BIT_ACCUM) diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index d43f67a..4d5cb3a 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -38,6 +38,7 @@ #include "main/fbobject.h" #include "main/framebuffer.h" #include "main/macros.h" +#include "main/image.h" #include "main/mfeatures.h" #include "main/renderbuffer.h" @@ -344,6 +345,7 @@ st_render_texture(struct gl_context *ctx, struct st_texture_object *stObj; const struct gl_texture_image *texImage; struct pipe_surface surf_tmpl; + boolean is_integer; /* When would this fail? Perhaps assert? */ if (!pt) @@ -352,6 +354,7 @@ st_render_texture(struct gl_context *ctx, /* get pointer to texture image we're rendeing to */ texImage = _mesa_get_attachment_teximage(att); + is_integer = _mesa_is_integer_format(texImage->InternalFormat); /* create new renderbuffer which wraps the texture image */ rb = st_new_renderbuffer(ctx, 0); if (!rb) { @@ -392,6 +395,7 @@ st_render_texture(struct gl_context *ctx, memset(&surf_tmpl, 0, sizeof(surf_tmpl)); surf_tmpl.format = ctx->Color.sRGBEnabled ? strb->texture->format : util_format_linear(strb->texture->format); surf_tmpl.usage = PIPE_BIND_RENDER_TARGET; + surf_tmpl.bind_as_integer = is_integer; surf_tmpl.u.tex.level = strb->rtt_level; surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice; surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice; diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index b2c1d6c..711ce53 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -1488,10 +1488,10 @@ st_translate_color(const GLfloat colorIn[4], GLenum baseFormat, } void -st_translate_clear_color(const union gl_clear_color colorIn, +st_translate_clear_color(const union gl_clear_color *colorIn, GLenum baseFormat, - GLfloat colorOut[4]) + union pipe_clear_color *colorOut) { - st_translate_color(colorIn.f, baseFormat, colorOut); + st_translate_color(colorIn->f, baseFormat, colorOut->f); } diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index 6c04529..243dab8 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -84,7 +84,7 @@ st_translate_color(const GLfloat colorIn[4], GLenum baseFormat, GLfloat colorOut[4]); void -st_translate_clear_color(const union gl_clear_color colorIn, - GLenum baseFormat, GLfloat colorOut[4]); +st_translate_clear_color(const union gl_clear_color *colorIn, + GLenum baseFormat, union pipe_clear_color *colorOut); #endif /* ST_FORMAT_H */ -- 1.7.6
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev