From c1e6c7428a8d2c1b60ffac7df7a3f56c300fa983 Mon Sep 17 00:00:00 2001 From: marha Date: Thu, 22 Sep 2011 15:20:09 +0200 Subject: libxtrans libX11 libX11 libXext mesa xserver git update 22 sep 2011 --- mesalib/src/gallium/auxiliary/util/u_blit.c | 1584 ++++++++++---------- mesalib/src/gallium/auxiliary/util/u_format_latc.c | 654 ++++---- mesalib/src/gallium/auxiliary/util/u_format_rgtc.c | 928 ++++++------ 3 files changed, 1584 insertions(+), 1582 deletions(-) (limited to 'mesalib/src/gallium/auxiliary') diff --git a/mesalib/src/gallium/auxiliary/util/u_blit.c b/mesalib/src/gallium/auxiliary/util/u_blit.c index e892a4a77..87530e94a 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blit.c +++ b/mesalib/src/gallium/auxiliary/util/u_blit.c @@ -1,790 +1,794 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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. - * - **************************************************************************/ - -/** - * @file - * Copy/blit pixel rect between surfaces - * - * @author Brian Paul - */ - - -#include "pipe/p_context.h" -#include "util/u_debug.h" -#include "pipe/p_defines.h" -#include "util/u_inlines.h" -#include "pipe/p_shader_tokens.h" -#include "pipe/p_state.h" - -#include "util/u_blit.h" -#include "util/u_draw_quad.h" -#include "util/u_format.h" -#include "util/u_math.h" -#include "util/u_memory.h" -#include "util/u_sampler.h" -#include "util/u_simple_shaders.h" - -#include "cso_cache/cso_context.h" - - -struct blit_state -{ - struct pipe_context *pipe; - struct cso_context *cso; - - struct pipe_blend_state blend; - struct pipe_depth_stencil_alpha_state depthstencil_keep; - struct pipe_depth_stencil_alpha_state depthstencil_write; - struct pipe_rasterizer_state rasterizer; - struct pipe_sampler_state sampler; - struct pipe_viewport_state viewport; - struct pipe_clip_state clip; - struct pipe_vertex_element velem[2]; - enum pipe_texture_target internal_target; - - void *vs; - void *fs[TGSI_WRITEMASK_XYZW + 1]; - void *fs_depth; - - struct pipe_resource *vbuf; /**< quad vertices */ - unsigned vbuf_slot; - - float vertices[4][2][4]; /**< vertex/texcoords for quad */ -}; - - -/** - * Create state object for blit. - * Intended to be created once and re-used for many blit() calls. - */ -struct blit_state * -util_create_blit(struct pipe_context *pipe, struct cso_context *cso) -{ - struct blit_state *ctx; - uint i; - - ctx = CALLOC_STRUCT(blit_state); - if (!ctx) - return NULL; - - ctx->pipe = pipe; - ctx->cso = cso; - - /* disabled blending/masking */ - memset(&ctx->blend, 0, sizeof(ctx->blend)); - ctx->blend.rt[0].colormask = PIPE_MASK_RGBA; - - /* no-op depth/stencil/alpha */ - memset(&ctx->depthstencil_keep, 0, sizeof(ctx->depthstencil_keep)); - memset(&ctx->depthstencil_write, 0, sizeof(ctx->depthstencil_write)); - ctx->depthstencil_write.depth.enabled = 1; - ctx->depthstencil_write.depth.writemask = 1; - ctx->depthstencil_write.depth.func = PIPE_FUNC_ALWAYS; - - /* rasterizer */ - memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); - ctx->rasterizer.cull_face = PIPE_FACE_NONE; - ctx->rasterizer.gl_rasterization_rules = 1; - - /* samplers */ - memset(&ctx->sampler, 0, sizeof(ctx->sampler)); - ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; - ctx->sampler.min_img_filter = 0; /* set later */ - ctx->sampler.mag_img_filter = 0; /* set later */ - - /* vertex elements state */ - memset(&ctx->velem[0], 0, sizeof(ctx->velem[0]) * 2); - for (i = 0; i < 2; i++) { - ctx->velem[i].src_offset = i * 4 * sizeof(float); - ctx->velem[i].instance_divisor = 0; - ctx->velem[i].vertex_buffer_index = 0; - ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - } - - ctx->vbuf = NULL; - - /* init vertex data that doesn't change */ - for (i = 0; i < 4; i++) { - ctx->vertices[i][0][3] = 1.0f; /* w */ - ctx->vertices[i][1][2] = 0.0f; /* r */ - ctx->vertices[i][1][3] = 1.0f; /* q */ - } - - if(pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES)) - ctx->internal_target = PIPE_TEXTURE_2D; - else - ctx->internal_target = PIPE_TEXTURE_RECT; - - return ctx; -} - - -/** - * Destroy a blit context - */ -void -util_destroy_blit(struct blit_state *ctx) -{ - struct pipe_context *pipe = ctx->pipe; - unsigned i; - - if (ctx->vs) - pipe->delete_vs_state(pipe, ctx->vs); - - for (i = 0; i < Elements(ctx->fs); i++) - if (ctx->fs[i]) - pipe->delete_fs_state(pipe, ctx->fs[i]); - - if (ctx->fs_depth) - pipe->delete_fs_state(pipe, ctx->fs_depth); - - pipe_resource_reference(&ctx->vbuf, NULL); - - FREE(ctx); -} - - -/** - * Helper function to set the fragment shaders. - */ -static INLINE void -set_fragment_shader(struct blit_state *ctx, uint writemask) -{ - if (!ctx->fs[writemask]) - ctx->fs[writemask] = - util_make_fragment_tex_shader_writemask(ctx->pipe, TGSI_TEXTURE_2D, - TGSI_INTERPOLATE_LINEAR, - writemask); - - cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]); -} - - -/** - * Helper function to set the depthwrite shader. - */ -static INLINE void -set_depth_fragment_shader(struct blit_state *ctx) -{ - if (!ctx->fs_depth) - ctx->fs_depth = - util_make_fragment_tex_shader_writedepth(ctx->pipe, TGSI_TEXTURE_2D, - TGSI_INTERPOLATE_LINEAR); - - cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth); -} - - -/** - * Helper function to set the vertex shader. - */ -static INLINE void -set_vertex_shader(struct blit_state *ctx) -{ - /* vertex shader - still required to provide the linkage between - * fragment shader input semantics and vertex_element/buffers. - */ - if (!ctx->vs) { - const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC }; - const uint semantic_indexes[] = { 0, 0 }; - ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2, - semantic_names, - semantic_indexes); - } - - cso_set_vertex_shader_handle(ctx->cso, ctx->vs); -} - - -/** - * Get offset of next free slot in vertex buffer for quad vertices. - */ -static unsigned -get_next_slot( struct blit_state *ctx ) -{ - const unsigned max_slots = 4096 / sizeof ctx->vertices; - - if (ctx->vbuf_slot >= max_slots) - util_blit_flush( ctx ); - - if (!ctx->vbuf) { - ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, - PIPE_BIND_VERTEX_BUFFER, - PIPE_USAGE_STREAM, - max_slots * sizeof ctx->vertices); - } - - return ctx->vbuf_slot++ * sizeof ctx->vertices; -} - - - - -/** - * Setup vertex data for the textured quad we'll draw. - * Note: y=0=top - */ -static unsigned -setup_vertex_data_tex(struct blit_state *ctx, - float x0, float y0, float x1, float y1, - float s0, float t0, float s1, float t1, - float z) -{ - unsigned offset; - - ctx->vertices[0][0][0] = x0; - ctx->vertices[0][0][1] = y0; - ctx->vertices[0][0][2] = z; - ctx->vertices[0][1][0] = s0; /*s*/ - ctx->vertices[0][1][1] = t0; /*t*/ - - ctx->vertices[1][0][0] = x1; - ctx->vertices[1][0][1] = y0; - ctx->vertices[1][0][2] = z; - ctx->vertices[1][1][0] = s1; /*s*/ - ctx->vertices[1][1][1] = t0; /*t*/ - - ctx->vertices[2][0][0] = x1; - ctx->vertices[2][0][1] = y1; - ctx->vertices[2][0][2] = z; - ctx->vertices[2][1][0] = s1; - ctx->vertices[2][1][1] = t1; - - ctx->vertices[3][0][0] = x0; - ctx->vertices[3][0][1] = y1; - ctx->vertices[3][0][2] = z; - ctx->vertices[3][1][0] = s0; - ctx->vertices[3][1][1] = t1; - - offset = get_next_slot( ctx ); - - pipe_buffer_write_nooverlap(ctx->pipe, ctx->vbuf, - offset, sizeof(ctx->vertices), ctx->vertices); - - return offset; -} - - -/** - * \return TRUE if two regions overlap, FALSE otherwise - */ -static boolean -regions_overlap(int srcX0, int srcY0, - int srcX1, int srcY1, - int dstX0, int dstY0, - int dstX1, int dstY1) -{ - if (MAX2(srcX0, srcX1) < MIN2(dstX0, dstX1)) - return FALSE; /* src completely left of dst */ - - if (MAX2(dstX0, dstX1) < MIN2(srcX0, srcX1)) - return FALSE; /* dst completely left of src */ - - if (MAX2(srcY0, srcY1) < MIN2(dstY0, dstY1)) - return FALSE; /* src completely above dst */ - - if (MAX2(dstY0, dstY1) < MIN2(srcY0, srcY1)) - return FALSE; /* dst completely above src */ - - return TRUE; /* some overlap */ -} - - -/** - * Copy pixel block from src surface to dst surface. - * Overlapping regions are acceptable. - * Flipping and stretching are supported. - * \param filter one of PIPE_TEX_MIPFILTER_NEAREST/LINEAR - * \param writemask controls which channels in the dest surface are sourced - * from the src surface. Disabled channels are sourced - * from (0,0,0,1). - * XXX need some control over blitting stencil. - */ -void -util_blit_pixels_writemask(struct blit_state *ctx, - struct pipe_resource *src_tex, - unsigned src_level, - int srcX0, int srcY0, - int srcX1, int srcY1, - int srcZ0, - struct pipe_surface *dst, - int dstX0, int dstY0, - int dstX1, int dstY1, - float z, uint filter, - uint writemask) -{ - 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); - unsigned offset; - boolean overlap, dst_is_depth; - float s0, t0, s1, t1; - boolean normalized; - - assert(filter == PIPE_TEX_MIPFILTER_NEAREST || - filter == PIPE_TEX_MIPFILTER_LINEAR); - - assert(src_level <= src_tex->last_level); - - /* do the regions overlap? */ - overlap = src_tex == dst->texture && - dst->u.tex.level == src_level && - dst->u.tex.first_layer == srcZ0 && - 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_format && - srcX0 < srcX1 && - dstX0 < dstX1 && - srcY0 < srcY1 && - dstY0 < dstY1 && - (dstX1 - dstX0) == (srcX1 - srcX0) && - (dstY1 - dstY0) == (srcY1 - srcY0) && - !overlap) { - struct pipe_box src_box; - src_box.x = srcX0; - src_box.y = srcY0; - src_box.z = srcZ0; - src_box.width = srcW; - src_box.height = srcH; - src_box.depth = 1; - pipe->resource_copy_region(pipe, - dst->texture, dst->u.tex.level, - dstX0, dstY0, dst->u.tex.first_layer,/* dest */ - src_tex, src_level, - &src_box); - 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, - * much like the u_blitter code does (should be pretty trivial). - * - * This can still be improved upon. - */ - 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)) - { - struct pipe_resource texTemp; - struct pipe_resource *tex; - struct pipe_sampler_view sv_templ; - struct pipe_box src_box; - const int srcLeft = MIN2(srcX0, srcX1); - const int srcTop = MIN2(srcY0, srcY1); - - if (srcLeft != srcX0) { - /* left-right flip */ - int tmp = dstX0; - dstX0 = dstX1; - dstX1 = tmp; - } - - if (srcTop != srcY0) { - /* up-down flip */ - int tmp = dstY0; - dstY0 = dstY1; - dstY1 = tmp; - } - - /* create temp texture */ - memset(&texTemp, 0, sizeof(texTemp)); - texTemp.target = ctx->internal_target; - texTemp.format = src_format; - texTemp.last_level = 0; - texTemp.width0 = srcW; - texTemp.height0 = srcH; - texTemp.depth0 = 1; - texTemp.array_size = 1; - texTemp.bind = PIPE_BIND_SAMPLER_VIEW; - - tex = screen->resource_create(screen, &texTemp); - if (!tex) - return; - - src_box.x = srcLeft; - src_box.y = srcTop; - src_box.z = srcZ0; - src_box.width = srcW; - src_box.height = srcH; - src_box.depth = 1; - /* load temp texture */ - pipe->resource_copy_region(pipe, - tex, 0, 0, 0, 0, /* dest */ - src_tex, src_level, &src_box); - - normalized = tex->target != PIPE_TEXTURE_RECT; - if(normalized) { - s0 = 0.0f; - s1 = 1.0f; - t0 = 0.0f; - t1 = 1.0f; - } - else { - s0 = 0; - s1 = srcW; - t0 = 0; - t1 = srcH; - } - - 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 { - 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) { - return; - } - - s0 = srcX0; - s1 = srcX1; - t0 = srcY0; - t1 = srcY1; - normalized = sampler_view->texture->target != PIPE_TEXTURE_RECT; - if(normalized) - { - s0 /= (float)(u_minify(sampler_view->texture->width0, src_level)); - s1 /= (float)(u_minify(sampler_view->texture->width0, src_level)); - t0 /= (float)(u_minify(sampler_view->texture->height0, src_level)); - t1 /= (float)(u_minify(sampler_view->texture->height0, src_level)); - } - } - - 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_surface->texture->nr_samples, - dst_is_depth ? PIPE_BIND_DEPTH_STENCIL : - PIPE_BIND_RENDER_TARGET)); - /* save state (restored below) */ - cso_save_blend(ctx->cso); - cso_save_depth_stencil_alpha(ctx->cso); - cso_save_rasterizer(ctx->cso); - cso_save_samplers(ctx->cso); - cso_save_fragment_sampler_views(ctx->cso); - cso_save_viewport(ctx->cso); - cso_save_framebuffer(ctx->cso); - cso_save_fragment_shader(ctx->cso); - cso_save_vertex_shader(ctx->cso); - cso_save_clip(ctx->cso); - cso_save_vertex_elements(ctx->cso); - cso_save_vertex_buffers(ctx->cso); - - /* set misc state we care about */ - cso_set_blend(ctx->cso, &ctx->blend); - cso_set_depth_stencil_alpha(ctx->cso, - dst_is_depth ? &ctx->depthstencil_write : - &ctx->depthstencil_keep); - cso_set_rasterizer(ctx->cso, &ctx->rasterizer); - cso_set_clip(ctx->cso, &ctx->clip); - cso_set_vertex_elements(ctx->cso, 2, ctx->velem); - - /* sampler */ - ctx->sampler.normalized_coords = normalized; - ctx->sampler.min_img_filter = filter; - ctx->sampler.mag_img_filter = filter; - ctx->sampler.min_lod = src_level; - ctx->sampler.max_lod = src_level; - cso_single_sampler(ctx->cso, 0, &ctx->sampler); - cso_single_sampler_done(ctx->cso); - - /* viewport */ - 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_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); - - /* texture */ - cso_set_fragment_sampler_views(ctx->cso, 1, &sampler_view); - - /* shaders */ - if (dst_is_depth) { - set_depth_fragment_shader(ctx); - } else { - set_fragment_shader(ctx, writemask); - } - set_vertex_shader(ctx); - - /* drawing dest */ - memset(&fb, 0, sizeof(fb)); - fb.width = dst_surface->width; - fb.height = dst_surface->height; - if (dst_is_depth) { - fb.zsbuf = dst_surface; - } else { - fb.nr_cbufs = 1; - fb.cbufs[0] = dst_surface; - } - cso_set_framebuffer(ctx->cso, &fb); - - /* draw quad */ - offset = setup_vertex_data_tex(ctx, - (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); - - util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf, offset, - PIPE_PRIM_TRIANGLE_FAN, - 4, /* verts */ - 2); /* attribs/vert */ - - /* restore state we changed */ - cso_restore_blend(ctx->cso); - cso_restore_depth_stencil_alpha(ctx->cso); - cso_restore_rasterizer(ctx->cso); - cso_restore_samplers(ctx->cso); - cso_restore_fragment_sampler_views(ctx->cso); - cso_restore_viewport(ctx->cso); - cso_restore_framebuffer(ctx->cso); - cso_restore_fragment_shader(ctx->cso); - cso_restore_vertex_shader(ctx->cso); - cso_restore_clip(ctx->cso); - cso_restore_vertex_elements(ctx->cso); - cso_restore_vertex_buffers(ctx->cso); - - pipe_sampler_view_reference(&sampler_view, NULL); - if (dst_surface != dst) - pipe_surface_reference(&dst_surface, NULL); -} - - -void -util_blit_pixels(struct blit_state *ctx, - struct pipe_resource *src_tex, - unsigned src_level, - 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_tex, - src_level, - srcX0, srcY0, - srcX1, srcY1, - srcZ, - dst, - dstX0, dstY0, - dstX1, dstY1, - z, filter, - TGSI_WRITEMASK_XYZW ); -} - - -/* Release vertex buffer at end of frame to avoid synchronous - * rendering. - */ -void util_blit_flush( struct blit_state *ctx ) -{ - pipe_resource_reference(&ctx->vbuf, NULL); - ctx->vbuf_slot = 0; -} - - - -/** - * Copy pixel block from src texture to dst surface. - * - * XXX Should support selection of level. - * XXX need some control over blitting Z and/or stencil. - */ -void -util_blit_pixels_tex(struct blit_state *ctx, - struct pipe_sampler_view *src_sampler_view, - int srcX0, int srcY0, - int srcX1, int srcY1, - struct pipe_surface *dst, - int dstX0, int dstY0, - int dstX1, int dstY1, - float z, uint filter) -{ - boolean normalized = src_sampler_view->texture->target != PIPE_TEXTURE_RECT; - struct pipe_framebuffer_state fb; - float s0, t0, s1, t1; - unsigned offset; - struct pipe_resource *tex = src_sampler_view->texture; - - assert(filter == PIPE_TEX_MIPFILTER_NEAREST || - filter == PIPE_TEX_MIPFILTER_LINEAR); - - assert(tex); - assert(tex->width0 != 0); - assert(tex->height0 != 0); - - s0 = srcX0; - s1 = srcX1; - t0 = srcY0; - t1 = srcY1; - - if(normalized) - { - s0 /= (float)tex->width0; - s1 /= (float)tex->width0; - t0 /= (float)tex->height0; - t1 /= (float)tex->height0; - } - - assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format, - PIPE_TEXTURE_2D, - dst->texture->nr_samples, - PIPE_BIND_RENDER_TARGET)); - - /* save state (restored below) */ - cso_save_blend(ctx->cso); - cso_save_depth_stencil_alpha(ctx->cso); - cso_save_rasterizer(ctx->cso); - cso_save_samplers(ctx->cso); - cso_save_fragment_sampler_views(ctx->cso); - cso_save_viewport(ctx->cso); - cso_save_framebuffer(ctx->cso); - cso_save_fragment_shader(ctx->cso); - cso_save_vertex_shader(ctx->cso); - cso_save_clip(ctx->cso); - cso_save_vertex_elements(ctx->cso); - cso_save_vertex_buffers(ctx->cso); - - /* set misc state we care about */ - cso_set_blend(ctx->cso, &ctx->blend); - cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil_keep); - cso_set_rasterizer(ctx->cso, &ctx->rasterizer); - cso_set_clip(ctx->cso, &ctx->clip); - cso_set_vertex_elements(ctx->cso, 2, ctx->velem); - - /* sampler */ - ctx->sampler.normalized_coords = normalized; - ctx->sampler.min_img_filter = filter; - ctx->sampler.mag_img_filter = filter; - cso_single_sampler(ctx->cso, 0, &ctx->sampler); - 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[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[2] = 0.5f; - ctx->viewport.translate[3] = 0.0f; - cso_set_viewport(ctx->cso, &ctx->viewport); - - /* texture */ - cso_set_fragment_sampler_views(ctx->cso, 1, &src_sampler_view); - - /* shaders */ - set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW); - set_vertex_shader(ctx); - - /* drawing dest */ - memset(&fb, 0, sizeof(fb)); - fb.width = dst->width; - fb.height = dst->height; - fb.nr_cbufs = 1; - fb.cbufs[0] = dst; - 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, - s0, t0, s1, t1, - z); - - util_draw_vertex_buffer(ctx->pipe, ctx->cso, - ctx->vbuf, offset, - PIPE_PRIM_TRIANGLE_FAN, - 4, /* verts */ - 2); /* attribs/vert */ - - /* restore state we changed */ - cso_restore_blend(ctx->cso); - cso_restore_depth_stencil_alpha(ctx->cso); - cso_restore_rasterizer(ctx->cso); - cso_restore_samplers(ctx->cso); - cso_restore_fragment_sampler_views(ctx->cso); - cso_restore_viewport(ctx->cso); - cso_restore_framebuffer(ctx->cso); - cso_restore_fragment_shader(ctx->cso); - cso_restore_vertex_shader(ctx->cso); - cso_restore_clip(ctx->cso); - cso_restore_vertex_elements(ctx->cso); - cso_restore_vertex_buffers(ctx->cso); -} +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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. + * + **************************************************************************/ + +/** + * @file + * Copy/blit pixel rect between surfaces + * + * @author Brian Paul + */ + + +#include "pipe/p_context.h" +#include "util/u_debug.h" +#include "pipe/p_defines.h" +#include "util/u_inlines.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_state.h" + +#include "util/u_blit.h" +#include "util/u_draw_quad.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "util/u_sampler.h" +#include "util/u_simple_shaders.h" + +#include "cso_cache/cso_context.h" + + +struct blit_state +{ + struct pipe_context *pipe; + struct cso_context *cso; + + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state depthstencil_keep; + struct pipe_depth_stencil_alpha_state depthstencil_write; + struct pipe_rasterizer_state rasterizer; + struct pipe_sampler_state sampler; + struct pipe_viewport_state viewport; + struct pipe_clip_state clip; + struct pipe_vertex_element velem[2]; + enum pipe_texture_target internal_target; + + void *vs; + void *fs[TGSI_WRITEMASK_XYZW + 1]; + void *fs_depth; + + struct pipe_resource *vbuf; /**< quad vertices */ + unsigned vbuf_slot; + + float vertices[4][2][4]; /**< vertex/texcoords for quad */ +}; + + +/** + * Create state object for blit. + * Intended to be created once and re-used for many blit() calls. + */ +struct blit_state * +util_create_blit(struct pipe_context *pipe, struct cso_context *cso) +{ + struct blit_state *ctx; + uint i; + + ctx = CALLOC_STRUCT(blit_state); + if (!ctx) + return NULL; + + ctx->pipe = pipe; + ctx->cso = cso; + + /* disabled blending/masking */ + memset(&ctx->blend, 0, sizeof(ctx->blend)); + ctx->blend.rt[0].colormask = PIPE_MASK_RGBA; + + /* no-op depth/stencil/alpha */ + memset(&ctx->depthstencil_keep, 0, sizeof(ctx->depthstencil_keep)); + memset(&ctx->depthstencil_write, 0, sizeof(ctx->depthstencil_write)); + ctx->depthstencil_write.depth.enabled = 1; + ctx->depthstencil_write.depth.writemask = 1; + ctx->depthstencil_write.depth.func = PIPE_FUNC_ALWAYS; + + /* rasterizer */ + memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); + ctx->rasterizer.cull_face = PIPE_FACE_NONE; + ctx->rasterizer.gl_rasterization_rules = 1; + + /* samplers */ + memset(&ctx->sampler, 0, sizeof(ctx->sampler)); + ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + ctx->sampler.min_img_filter = 0; /* set later */ + ctx->sampler.mag_img_filter = 0; /* set later */ + + /* vertex elements state */ + memset(&ctx->velem[0], 0, sizeof(ctx->velem[0]) * 2); + for (i = 0; i < 2; i++) { + ctx->velem[i].src_offset = i * 4 * sizeof(float); + ctx->velem[i].instance_divisor = 0; + ctx->velem[i].vertex_buffer_index = 0; + ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + } + + ctx->vbuf = NULL; + + /* init vertex data that doesn't change */ + for (i = 0; i < 4; i++) { + ctx->vertices[i][0][3] = 1.0f; /* w */ + ctx->vertices[i][1][2] = 0.0f; /* r */ + ctx->vertices[i][1][3] = 1.0f; /* q */ + } + + if(pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES)) + ctx->internal_target = PIPE_TEXTURE_2D; + else + ctx->internal_target = PIPE_TEXTURE_RECT; + + return ctx; +} + + +/** + * Destroy a blit context + */ +void +util_destroy_blit(struct blit_state *ctx) +{ + struct pipe_context *pipe = ctx->pipe; + unsigned i; + + if (ctx->vs) + pipe->delete_vs_state(pipe, ctx->vs); + + for (i = 0; i < Elements(ctx->fs); i++) + if (ctx->fs[i]) + pipe->delete_fs_state(pipe, ctx->fs[i]); + + if (ctx->fs_depth) + pipe->delete_fs_state(pipe, ctx->fs_depth); + + pipe_resource_reference(&ctx->vbuf, NULL); + + FREE(ctx); +} + + +/** + * Helper function to set the fragment shaders. + */ +static INLINE void +set_fragment_shader(struct blit_state *ctx, uint writemask) +{ + if (!ctx->fs[writemask]) + ctx->fs[writemask] = + util_make_fragment_tex_shader_writemask(ctx->pipe, TGSI_TEXTURE_2D, + TGSI_INTERPOLATE_LINEAR, + writemask); + + cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]); +} + + +/** + * Helper function to set the depthwrite shader. + */ +static INLINE void +set_depth_fragment_shader(struct blit_state *ctx) +{ + if (!ctx->fs_depth) + ctx->fs_depth = + util_make_fragment_tex_shader_writedepth(ctx->pipe, TGSI_TEXTURE_2D, + TGSI_INTERPOLATE_LINEAR); + + cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth); +} + + +/** + * Helper function to set the vertex shader. + */ +static INLINE void +set_vertex_shader(struct blit_state *ctx) +{ + /* vertex shader - still required to provide the linkage between + * fragment shader input semantics and vertex_element/buffers. + */ + if (!ctx->vs) { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2, + semantic_names, + semantic_indexes); + } + + cso_set_vertex_shader_handle(ctx->cso, ctx->vs); +} + + +/** + * Get offset of next free slot in vertex buffer for quad vertices. + */ +static unsigned +get_next_slot( struct blit_state *ctx ) +{ + const unsigned max_slots = 4096 / sizeof ctx->vertices; + + if (ctx->vbuf_slot >= max_slots) + util_blit_flush( ctx ); + + if (!ctx->vbuf) { + ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, + PIPE_BIND_VERTEX_BUFFER, + PIPE_USAGE_STREAM, + max_slots * sizeof ctx->vertices); + } + + return ctx->vbuf_slot++ * sizeof ctx->vertices; +} + + + + +/** + * Setup vertex data for the textured quad we'll draw. + * Note: y=0=top + */ +static unsigned +setup_vertex_data_tex(struct blit_state *ctx, + float x0, float y0, float x1, float y1, + float s0, float t0, float s1, float t1, + float z) +{ + unsigned offset; + + ctx->vertices[0][0][0] = x0; + ctx->vertices[0][0][1] = y0; + ctx->vertices[0][0][2] = z; + ctx->vertices[0][1][0] = s0; /*s*/ + ctx->vertices[0][1][1] = t0; /*t*/ + + ctx->vertices[1][0][0] = x1; + ctx->vertices[1][0][1] = y0; + ctx->vertices[1][0][2] = z; + ctx->vertices[1][1][0] = s1; /*s*/ + ctx->vertices[1][1][1] = t0; /*t*/ + + ctx->vertices[2][0][0] = x1; + ctx->vertices[2][0][1] = y1; + ctx->vertices[2][0][2] = z; + ctx->vertices[2][1][0] = s1; + ctx->vertices[2][1][1] = t1; + + ctx->vertices[3][0][0] = x0; + ctx->vertices[3][0][1] = y1; + ctx->vertices[3][0][2] = z; + ctx->vertices[3][1][0] = s0; + ctx->vertices[3][1][1] = t1; + + offset = get_next_slot( ctx ); + + pipe_buffer_write_nooverlap(ctx->pipe, ctx->vbuf, + offset, sizeof(ctx->vertices), ctx->vertices); + + return offset; +} + + +/** + * \return TRUE if two regions overlap, FALSE otherwise + */ +static boolean +regions_overlap(int srcX0, int srcY0, + int srcX1, int srcY1, + int dstX0, int dstY0, + int dstX1, int dstY1) +{ + if (MAX2(srcX0, srcX1) < MIN2(dstX0, dstX1)) + return FALSE; /* src completely left of dst */ + + if (MAX2(dstX0, dstX1) < MIN2(srcX0, srcX1)) + return FALSE; /* dst completely left of src */ + + if (MAX2(srcY0, srcY1) < MIN2(dstY0, dstY1)) + return FALSE; /* src completely above dst */ + + if (MAX2(dstY0, dstY1) < MIN2(srcY0, srcY1)) + return FALSE; /* dst completely above src */ + + return TRUE; /* some overlap */ +} + + +/** + * Copy pixel block from src surface to dst surface. + * Overlapping regions are acceptable. + * Flipping and stretching are supported. + * \param filter one of PIPE_TEX_MIPFILTER_NEAREST/LINEAR + * \param writemask controls which channels in the dest surface are sourced + * from the src surface. Disabled channels are sourced + * from (0,0,0,1). + * XXX need some control over blitting stencil. + */ +void +util_blit_pixels_writemask(struct blit_state *ctx, + struct pipe_resource *src_tex, + unsigned src_level, + int srcX0, int srcY0, + int srcX1, int srcY1, + int srcZ0, + struct pipe_surface *dst, + int dstX0, int dstY0, + int dstX1, int dstY1, + float z, uint filter, + uint writemask) +{ + 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); + unsigned offset; + boolean overlap, dst_is_depth; + float s0, t0, s1, t1; + boolean normalized; + + assert(filter == PIPE_TEX_MIPFILTER_NEAREST || + filter == PIPE_TEX_MIPFILTER_LINEAR); + + assert(src_level <= src_tex->last_level); + + /* do the regions overlap? */ + overlap = src_tex == dst->texture && + dst->u.tex.level == src_level && + dst->u.tex.first_layer == srcZ0 && + 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_format && + srcX0 < srcX1 && + dstX0 < dstX1 && + srcY0 < srcY1 && + dstY0 < dstY1 && + (dstX1 - dstX0) == (srcX1 - srcX0) && + (dstY1 - dstY0) == (srcY1 - srcY0) && + !overlap) { + struct pipe_box src_box; + src_box.x = srcX0; + src_box.y = srcY0; + src_box.z = srcZ0; + src_box.width = srcW; + src_box.height = srcH; + src_box.depth = 1; + pipe->resource_copy_region(pipe, + dst->texture, dst->u.tex.level, + dstX0, dstY0, dst->u.tex.first_layer,/* dest */ + src_tex, src_level, + &src_box); + 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, + * much like the u_blitter code does (should be pretty trivial). + * + * This can still be improved upon. + */ + 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)) + { + struct pipe_resource texTemp; + struct pipe_resource *tex; + struct pipe_sampler_view sv_templ; + struct pipe_box src_box; + const int srcLeft = MIN2(srcX0, srcX1); + const int srcTop = MIN2(srcY0, srcY1); + + if (srcLeft != srcX0) { + /* left-right flip */ + int tmp = dstX0; + dstX0 = dstX1; + dstX1 = tmp; + } + + if (srcTop != srcY0) { + /* up-down flip */ + int tmp = dstY0; + dstY0 = dstY1; + dstY1 = tmp; + } + + /* create temp texture */ + memset(&texTemp, 0, sizeof(texTemp)); + texTemp.target = ctx->internal_target; + texTemp.format = src_format; + texTemp.last_level = 0; + texTemp.width0 = srcW; + texTemp.height0 = srcH; + texTemp.depth0 = 1; + texTemp.array_size = 1; + texTemp.bind = PIPE_BIND_SAMPLER_VIEW; + + tex = screen->resource_create(screen, &texTemp); + if (!tex) + return; + + src_box.x = srcLeft; + src_box.y = srcTop; + src_box.z = srcZ0; + src_box.width = srcW; + src_box.height = srcH; + src_box.depth = 1; + /* load temp texture */ + pipe->resource_copy_region(pipe, + tex, 0, 0, 0, 0, /* dest */ + src_tex, src_level, &src_box); + + normalized = tex->target != PIPE_TEXTURE_RECT; + if(normalized) { + s0 = 0.0f; + s1 = 1.0f; + t0 = 0.0f; + t1 = 1.0f; + } + else { + s0 = 0; + s1 = srcW; + t0 = 0; + t1 = srcH; + } + + 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 { + 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) { + return; + } + + s0 = srcX0; + s1 = srcX1; + t0 = srcY0; + t1 = srcY1; + normalized = sampler_view->texture->target != PIPE_TEXTURE_RECT; + if(normalized) + { + s0 /= (float)(u_minify(sampler_view->texture->width0, src_level)); + s1 /= (float)(u_minify(sampler_view->texture->width0, src_level)); + t0 /= (float)(u_minify(sampler_view->texture->height0, src_level)); + t1 /= (float)(u_minify(sampler_view->texture->height0, src_level)); + } + } + + 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_surface->texture->nr_samples, + dst_is_depth ? PIPE_BIND_DEPTH_STENCIL : + PIPE_BIND_RENDER_TARGET)); + /* save state (restored below) */ + cso_save_blend(ctx->cso); + cso_save_depth_stencil_alpha(ctx->cso); + cso_save_rasterizer(ctx->cso); + cso_save_samplers(ctx->cso); + cso_save_fragment_sampler_views(ctx->cso); + cso_save_viewport(ctx->cso); + cso_save_framebuffer(ctx->cso); + cso_save_fragment_shader(ctx->cso); + cso_save_vertex_shader(ctx->cso); + cso_save_clip(ctx->cso); + cso_save_vertex_elements(ctx->cso); + cso_save_vertex_buffers(ctx->cso); + + /* set misc state we care about */ + cso_set_blend(ctx->cso, &ctx->blend); + cso_set_depth_stencil_alpha(ctx->cso, + dst_is_depth ? &ctx->depthstencil_write : + &ctx->depthstencil_keep); + cso_set_rasterizer(ctx->cso, &ctx->rasterizer); + cso_set_clip(ctx->cso, &ctx->clip); + cso_set_vertex_elements(ctx->cso, 2, ctx->velem); + + /* sampler */ + ctx->sampler.normalized_coords = normalized; + ctx->sampler.min_img_filter = filter; + ctx->sampler.mag_img_filter = filter; + ctx->sampler.min_lod = src_level; + ctx->sampler.max_lod = src_level; + cso_single_sampler(ctx->cso, 0, &ctx->sampler); + cso_single_sampler_done(ctx->cso); + + /* viewport */ + 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_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); + + /* texture */ + cso_set_fragment_sampler_views(ctx->cso, 1, &sampler_view); + + /* shaders */ + if (dst_is_depth) { + set_depth_fragment_shader(ctx); + } else { + set_fragment_shader(ctx, writemask); + } + set_vertex_shader(ctx); + + /* drawing dest */ + memset(&fb, 0, sizeof(fb)); + fb.width = dst_surface->width; + fb.height = dst_surface->height; + if (dst_is_depth) { + fb.zsbuf = dst_surface; + } else { + fb.nr_cbufs = 1; + fb.cbufs[0] = dst_surface; + } + cso_set_framebuffer(ctx->cso, &fb); + + /* draw quad */ + offset = setup_vertex_data_tex(ctx, + (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); + + util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf, offset, + PIPE_PRIM_TRIANGLE_FAN, + 4, /* verts */ + 2); /* attribs/vert */ + + /* restore state we changed */ + cso_restore_blend(ctx->cso); + cso_restore_depth_stencil_alpha(ctx->cso); + cso_restore_rasterizer(ctx->cso); + cso_restore_samplers(ctx->cso); + cso_restore_fragment_sampler_views(ctx->cso); + cso_restore_viewport(ctx->cso); + cso_restore_framebuffer(ctx->cso); + cso_restore_fragment_shader(ctx->cso); + cso_restore_vertex_shader(ctx->cso); + cso_restore_clip(ctx->cso); + cso_restore_vertex_elements(ctx->cso); + cso_restore_vertex_buffers(ctx->cso); + + pipe_sampler_view_reference(&sampler_view, NULL); + if (dst_surface != dst) + pipe_surface_reference(&dst_surface, NULL); +} + + +void +util_blit_pixels(struct blit_state *ctx, + struct pipe_resource *src_tex, + unsigned src_level, + 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_tex, + src_level, + srcX0, srcY0, + srcX1, srcY1, + srcZ, + dst, + dstX0, dstY0, + dstX1, dstY1, + z, filter, + TGSI_WRITEMASK_XYZW ); +} + + +/* Release vertex buffer at end of frame to avoid synchronous + * rendering. + */ +void util_blit_flush( struct blit_state *ctx ) +{ + pipe_resource_reference(&ctx->vbuf, NULL); + ctx->vbuf_slot = 0; +} + + + +/** + * Copy pixel block from src texture to dst surface. + * The sampler view's first_level field indicates the source + * mipmap level to use. + * XXX need some control over blitting Z and/or stencil. + */ +void +util_blit_pixels_tex(struct blit_state *ctx, + struct pipe_sampler_view *src_sampler_view, + int srcX0, int srcY0, + int srcX1, int srcY1, + struct pipe_surface *dst, + int dstX0, int dstY0, + int dstX1, int dstY1, + float z, uint filter) +{ + boolean normalized = src_sampler_view->texture->target != PIPE_TEXTURE_RECT; + struct pipe_framebuffer_state fb; + float s0, t0, s1, t1; + unsigned offset; + struct pipe_resource *tex = src_sampler_view->texture; + + assert(filter == PIPE_TEX_MIPFILTER_NEAREST || + filter == PIPE_TEX_MIPFILTER_LINEAR); + + assert(tex); + assert(tex->width0 != 0); + assert(tex->height0 != 0); + + s0 = srcX0; + s1 = srcX1; + t0 = srcY0; + t1 = srcY1; + + if(normalized) + { + /* normalize according to the mipmap level's size */ + int level = src_sampler_view->u.tex.first_level; + float w = (float) u_minify(tex->width0, level); + float h = (float) u_minify(tex->height0, level); + s0 /= w; + s1 /= w; + t0 /= h; + t1 /= h; + } + + assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format, + PIPE_TEXTURE_2D, + dst->texture->nr_samples, + PIPE_BIND_RENDER_TARGET)); + + /* save state (restored below) */ + cso_save_blend(ctx->cso); + cso_save_depth_stencil_alpha(ctx->cso); + cso_save_rasterizer(ctx->cso); + cso_save_samplers(ctx->cso); + cso_save_fragment_sampler_views(ctx->cso); + cso_save_viewport(ctx->cso); + cso_save_framebuffer(ctx->cso); + cso_save_fragment_shader(ctx->cso); + cso_save_vertex_shader(ctx->cso); + cso_save_clip(ctx->cso); + cso_save_vertex_elements(ctx->cso); + cso_save_vertex_buffers(ctx->cso); + + /* set misc state we care about */ + cso_set_blend(ctx->cso, &ctx->blend); + cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil_keep); + cso_set_rasterizer(ctx->cso, &ctx->rasterizer); + cso_set_clip(ctx->cso, &ctx->clip); + cso_set_vertex_elements(ctx->cso, 2, ctx->velem); + + /* sampler */ + ctx->sampler.normalized_coords = normalized; + ctx->sampler.min_img_filter = filter; + ctx->sampler.mag_img_filter = filter; + cso_single_sampler(ctx->cso, 0, &ctx->sampler); + 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[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[2] = 0.5f; + ctx->viewport.translate[3] = 0.0f; + cso_set_viewport(ctx->cso, &ctx->viewport); + + /* texture */ + cso_set_fragment_sampler_views(ctx->cso, 1, &src_sampler_view); + + /* shaders */ + set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW); + set_vertex_shader(ctx); + + /* drawing dest */ + memset(&fb, 0, sizeof(fb)); + fb.width = dst->width; + fb.height = dst->height; + fb.nr_cbufs = 1; + fb.cbufs[0] = dst; + 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, + s0, t0, s1, t1, + z); + + util_draw_vertex_buffer(ctx->pipe, ctx->cso, + ctx->vbuf, offset, + PIPE_PRIM_TRIANGLE_FAN, + 4, /* verts */ + 2); /* attribs/vert */ + + /* restore state we changed */ + cso_restore_blend(ctx->cso); + cso_restore_depth_stencil_alpha(ctx->cso); + cso_restore_rasterizer(ctx->cso); + cso_restore_samplers(ctx->cso); + cso_restore_fragment_sampler_views(ctx->cso); + cso_restore_viewport(ctx->cso); + cso_restore_framebuffer(ctx->cso); + cso_restore_fragment_shader(ctx->cso); + cso_restore_vertex_shader(ctx->cso); + cso_restore_clip(ctx->cso); + cso_restore_vertex_elements(ctx->cso); + cso_restore_vertex_buffers(ctx->cso); +} diff --git a/mesalib/src/gallium/auxiliary/util/u_format_latc.c b/mesalib/src/gallium/auxiliary/util/u_format_latc.c index a25faf5d9..113a793e2 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format_latc.c +++ b/mesalib/src/gallium/auxiliary/util/u_format_latc.c @@ -1,328 +1,326 @@ -/************************************************************************** - * - * Copyright (C) 2011 Red Hat Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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 -#include "u_math.h" -#include "u_format.h" -#include "u_format_rgtc.h" -#include "u_format_latc.h" - -static void u_format_unsigned_encode_rgtc_chan(uint8_t *blkaddr, uint8_t srccolors[4][4], - int numxpixels, int numypixels); - -static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata, - unsigned i, unsigned j, uint8_t *value, unsigned comps); - -static void u_format_signed_encode_rgtc_chan(int8_t *blkaddr, int8_t srccolors[4][4], - int numxpixels, int numypixels); - -static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata, - unsigned i, unsigned j, int8_t *value, unsigned comps); - -void -util_format_latc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) -{ - /* Fix warnings here: */ - (void) u_format_unsigned_encode_rgtc_chan; - (void) u_format_signed_encode_rgtc_chan; - - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1); -} - -void -util_format_latc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - util_format_rgtc1_unorm_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); -} - -void -util_format_latc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, - unsigned src_stride, unsigned width, unsigned height) -{ - util_format_rgtc1_unorm_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); -} - -void -util_format_latc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - unsigned x, y, i, j; - int block_size = 8; - - for(y = 0; y < height; y += 4) { - const uint8_t *src = src_row; - for(x = 0; x < width; x += 4) { - for(j = 0; j < 4; ++j) { - for(i = 0; i < 4; ++i) { - float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; - uint8_t tmp_r; - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); - dst[0] = - dst[1] = - dst[2] = ubyte_to_float(tmp_r); - dst[3] = 1.0; - } - } - src += block_size; - } - src_row += src_stride; - } -} - -void -util_format_latc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - util_format_rgtc1_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); -} - -void -util_format_latc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) -{ - uint8_t tmp_r; - - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); - dst[0] = - dst[1] = - dst[2] = ubyte_to_float(tmp_r); - dst[3] = 1.0; -} - -void -util_format_latc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) -{ - fprintf(stderr,"%s\n", __func__); -} - -void -util_format_latc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - fprintf(stderr,"%s\n", __func__); -} - -void -util_format_latc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - fprintf(stderr,"%s\n", __func__); -} - -void -util_format_latc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - util_format_rgtc1_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); -} - -void -util_format_latc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - unsigned x, y, i, j; - int block_size = 8; - - for(y = 0; y < height; y += 4) { - const int8_t *src = (int8_t *)src_row; - for(x = 0; x < width; x += 4) { - for(j = 0; j < 4; ++j) { - for(i = 0; i < 4; ++i) { - float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; - int8_t tmp_r; - u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); - dst[0] = - dst[1] = - dst[2] = byte_to_float_tex(tmp_r); - dst[3] = 1.0; - } - } - src += block_size; - } - src_row += src_stride; - } -} - -void -util_format_latc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) -{ - int8_t tmp_r; - - u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1); - dst[0] = - dst[1] = - dst[2] = byte_to_float_tex(tmp_r); - dst[3] = 1.0; -} - - -void -util_format_latc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) -{ - puts(__func__); - - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2); - u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2); -} - -void -util_format_latc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - util_format_rgtc2_unorm_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); -} - -void -util_format_latc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - util_format_rgtc2_unorm_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); -} - -void -util_format_latc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 3); -} - -void -util_format_latc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - unsigned x, y, i, j; - int block_size = 16; - - for(y = 0; y < height; y += 4) { - const uint8_t *src = src_row; - for(x = 0; x < width; x += 4) { - for(j = 0; j < 4; ++j) { - for(i = 0; i < 4; ++i) { - float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; - uint8_t tmp_r, tmp_g; - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); - u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); - dst[0] = - dst[1] = - dst[2] = ubyte_to_float(tmp_r); - dst[3] = ubyte_to_float(tmp_g); - } - } - src += block_size; - } - src_row += src_stride; - } -} - -void -util_format_latc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) -{ - uint8_t tmp_r, tmp_g; - - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); - u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); - dst[0] = - dst[1] = - dst[2] = ubyte_to_float(tmp_r); - dst[3] = ubyte_to_float(tmp_g); -} - - -void -util_format_latc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) -{ - fprintf(stderr,"%s\n", __func__); -} - -void -util_format_latc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - fprintf(stderr,"%s\n", __func__); -} - -void -util_format_latc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - fprintf(stderr,"%s\n", __func__); -} - -void -util_format_latc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - unsigned x, y, i, j; - int block_size = 16; - - for(y = 0; y < height; y += 4) { - const int8_t *src = (int8_t *)src_row; - for(x = 0; x < width; x += 4) { - for(j = 0; j < 4; ++j) { - for(i = 0; i < 4; ++i) { - float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; - int8_t tmp_r, tmp_g; - u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); - u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); - dst[0] = - dst[1] = - dst[2] = byte_to_float_tex(tmp_r); - dst[3] = byte_to_float_tex(tmp_g); - } - } - src += block_size; - } - src_row += src_stride; - } -} - -void -util_format_latc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 3); -} - -void -util_format_latc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) -{ - int8_t tmp_r, tmp_g; - - u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2); - u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2); - dst[0] = - dst[1] = - dst[2] = byte_to_float_tex(tmp_r); - dst[3] = byte_to_float_tex(tmp_g); -} - - -#define TAG(x) u_format_unsigned_##x -#define TYPE uint8_t -#define T_MIN 0 -#define T_MAX 255 - -#include "../../../mesa/main/texcompress_rgtc_tmp.h" - -#undef TYPE -#undef TAG -#undef T_MIN -#undef T_MAX - - -#define TAG(x) u_format_signed_##x -#define TYPE int8_t -#define T_MIN (int8_t)-128 -#define T_MAX (int8_t)127 - -#include "../../../mesa/main/texcompress_rgtc_tmp.h" - -#undef TYPE -#undef TAG -#undef T_MIN -#undef T_MAX +/************************************************************************** + * + * Copyright (C) 2011 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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 +#include "u_math.h" +#include "u_format.h" +#include "u_format_rgtc.h" +#include "u_format_latc.h" + +static void u_format_unsigned_encode_rgtc_ubyte(uint8_t *blkaddr, uint8_t srccolors[4][4], + int numxpixels, int numypixels); + +static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata, + unsigned i, unsigned j, uint8_t *value, unsigned comps); + +static void u_format_signed_encode_rgtc_ubyte(int8_t *blkaddr, int8_t srccolors[4][4], + int numxpixels, int numypixels); + +static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata, + unsigned i, unsigned j, int8_t *value, unsigned comps); + +void +util_format_latc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) +{ + /* Fix warnings here: */ + (void) u_format_unsigned_encode_rgtc_ubyte; + (void) u_format_signed_encode_rgtc_ubyte; + + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1); +} + +void +util_format_latc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rgtc1_unorm_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); +} + +void +util_format_latc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, + unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rgtc1_unorm_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); +} + +void +util_format_latc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + unsigned x, y, i, j; + int block_size = 8; + + for(y = 0; y < height; y += 4) { + const uint8_t *src = src_row; + for(x = 0; x < width; x += 4) { + for(j = 0; j < 4; ++j) { + for(i = 0; i < 4; ++i) { + float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; + uint8_t tmp_r; + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); + dst[0] = + dst[1] = + dst[2] = ubyte_to_float(tmp_r); + dst[3] = 1.0; + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_latc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rgtc1_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); +} + +void +util_format_latc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ + uint8_t tmp_r; + + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); + dst[0] = + dst[1] = + dst[2] = ubyte_to_float(tmp_r); + dst[3] = 1.0; +} + +void +util_format_latc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_latc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_latc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_latc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rgtc1_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); +} + +void +util_format_latc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + unsigned x, y, i, j; + int block_size = 8; + + for(y = 0; y < height; y += 4) { + const int8_t *src = (int8_t *)src_row; + for(x = 0; x < width; x += 4) { + for(j = 0; j < 4; ++j) { + for(i = 0; i < 4; ++i) { + float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; + int8_t tmp_r; + u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); + dst[0] = + dst[1] = + dst[2] = byte_to_float_tex(tmp_r); + dst[3] = 1.0; + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_latc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ + int8_t tmp_r; + + u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1); + dst[0] = + dst[1] = + dst[2] = byte_to_float_tex(tmp_r); + dst[3] = 1.0; +} + + +void +util_format_latc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) +{ + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2); + u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2); +} + +void +util_format_latc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rgtc2_unorm_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); +} + +void +util_format_latc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rgtc2_unorm_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); +} + +void +util_format_latc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 3); +} + +void +util_format_latc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + unsigned x, y, i, j; + int block_size = 16; + + for(y = 0; y < height; y += 4) { + const uint8_t *src = src_row; + for(x = 0; x < width; x += 4) { + for(j = 0; j < 4; ++j) { + for(i = 0; i < 4; ++i) { + float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; + uint8_t tmp_r, tmp_g; + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); + u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); + dst[0] = + dst[1] = + dst[2] = ubyte_to_float(tmp_r); + dst[3] = ubyte_to_float(tmp_g); + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_latc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ + uint8_t tmp_r, tmp_g; + + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); + u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); + dst[0] = + dst[1] = + dst[2] = ubyte_to_float(tmp_r); + dst[3] = ubyte_to_float(tmp_g); +} + + +void +util_format_latc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_latc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_latc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_latc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + unsigned x, y, i, j; + int block_size = 16; + + for(y = 0; y < height; y += 4) { + const int8_t *src = (int8_t *)src_row; + for(x = 0; x < width; x += 4) { + for(j = 0; j < 4; ++j) { + for(i = 0; i < 4; ++i) { + float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; + int8_t tmp_r, tmp_g; + u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); + u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); + dst[0] = + dst[1] = + dst[2] = byte_to_float_tex(tmp_r); + dst[3] = byte_to_float_tex(tmp_g); + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_latc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 3); +} + +void +util_format_latc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ + int8_t tmp_r, tmp_g; + + u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2); + u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2); + dst[0] = + dst[1] = + dst[2] = byte_to_float_tex(tmp_r); + dst[3] = byte_to_float_tex(tmp_g); +} + + +#define TAG(x) u_format_unsigned_##x +#define TYPE uint8_t +#define T_MIN 0 +#define T_MAX 255 + +#include "../../../mesa/main/texcompress_rgtc_tmp.h" + +#undef TYPE +#undef TAG +#undef T_MIN +#undef T_MAX + + +#define TAG(x) u_format_signed_##x +#define TYPE int8_t +#define T_MIN (int8_t)-128 +#define T_MAX (int8_t)127 + +#include "../../../mesa/main/texcompress_rgtc_tmp.h" + +#undef TYPE +#undef TAG +#undef T_MIN +#undef T_MAX diff --git a/mesalib/src/gallium/auxiliary/util/u_format_rgtc.c b/mesalib/src/gallium/auxiliary/util/u_format_rgtc.c index c3fa54c74..2371bab1e 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format_rgtc.c +++ b/mesalib/src/gallium/auxiliary/util/u_format_rgtc.c @@ -1,464 +1,464 @@ -/************************************************************************** - * - * Copyright (C) 2011 Red Hat Inc. - * - * 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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 -#include "u_math.h" -#include "u_format.h" -#include "u_format_rgtc.h" - -static void u_format_unsigned_encode_rgtc_chan(uint8_t *blkaddr, uint8_t srccolors[4][4], - int numxpixels, int numypixels); - -static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata, - unsigned i, unsigned j, uint8_t *value, unsigned comps); - -static void u_format_signed_encode_rgtc_chan(int8_t *blkaddr, int8_t srccolors[4][4], - int numxpixels, int numypixels); - -static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata, - unsigned i, unsigned j, int8_t *value, unsigned comps); - -void -util_format_rgtc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) -{ - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1); -} - -void -util_format_rgtc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - const unsigned bw = 4, bh = 4, comps = 4; - unsigned x, y, i, j; - unsigned block_size = 8; - - for(y = 0; y < height; y += bh) { - const uint8_t *src = src_row; - for(x = 0; x < width; x += bw) { - for(j = 0; j < bh; ++j) { - for(i = 0; i < bw; ++i) { - uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps; - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1); - } - } - src += block_size; - } - src_row += src_stride; - } -} - -void -util_format_rgtc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, - unsigned src_stride, unsigned width, unsigned height) -{ - const unsigned bw = 4, bh = 4, bytes_per_block = 8; - unsigned x, y, i, j; - - for(y = 0; y < height; y += bh) { - uint8_t *dst = dst_row; - for(x = 0; x < width; x += bw) { - uint8_t tmp[4][4]; /* [bh][bw][comps] */ - for(j = 0; j < bh; ++j) { - for(i = 0; i < bw; ++i) { - tmp[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]; - } - } - u_format_unsigned_encode_rgtc_chan(dst, tmp, 4, 4); - dst += bytes_per_block; - } - dst_row += dst_stride / sizeof(*dst_row); - } -} - -void -util_format_rgtc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - unsigned x, y, i, j; - int block_size = 8; - for(y = 0; y < height; y += 4) { - const uint8_t *src = src_row; - for(x = 0; x < width; x += 4) { - for(j = 0; j < 4; ++j) { - for(i = 0; i < 4; ++i) { - float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; - uint8_t tmp_r; - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); - dst[0] = ubyte_to_float(tmp_r); - dst[1] = 0.0; - dst[2] = 0.0; - dst[3] = 1.0; - } - } - src += block_size; - } - src_row += src_stride; - } -} - -void -util_format_rgtc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - const unsigned bw = 4, bh = 4, bytes_per_block = 8; - unsigned x, y, i, j; - - for(y = 0; y < height; y += bh) { - uint8_t *dst = dst_row; - for(x = 0; x < width; x += bw) { - uint8_t tmp[4][4]; /* [bh][bw][comps] */ - for(j = 0; j < bh; ++j) { - for(i = 0; i < bw; ++i) { - tmp[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); - } - } - u_format_unsigned_encode_rgtc_chan(dst, tmp, 4, 4); - dst += bytes_per_block; - } - dst_row += dst_stride / sizeof(*dst_row); - } -} - -void -util_format_rgtc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) -{ - uint8_t tmp_r; - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); - dst[0] = ubyte_to_float(tmp_r); - dst[1] = 0.0; - dst[2] = 0.0; - dst[3] = 1.0; -} - -void -util_format_rgtc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) -{ - fprintf(stderr,"%s\n", __func__); -} - -void -util_format_rgtc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - fprintf(stderr,"%s\n", __func__); -} - -void -util_format_rgtc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - fprintf(stderr,"%s\n", __func__); -} - -void -util_format_rgtc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - const unsigned bw = 4, bh = 4, bytes_per_block = 8; - unsigned x, y, i, j; - - for(y = 0; y < height; y += bh) { - int8_t *dst = (int8_t *)dst_row; - for(x = 0; x < width; x += bw) { - int8_t tmp[4][4]; /* [bh][bw][comps] */ - for(j = 0; j < bh; ++j) { - for(i = 0; i < bw; ++i) { - tmp[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); - } - } - u_format_signed_encode_rgtc_chan(dst, tmp, 4, 4); - dst += bytes_per_block; - } - dst_row += dst_stride / sizeof(*dst_row); - } -} - -void -util_format_rgtc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - unsigned x, y, i, j; - int block_size = 8; - for(y = 0; y < height; y += 4) { - const int8_t *src = (int8_t *)src_row; - for(x = 0; x < width; x += 4) { - for(j = 0; j < 4; ++j) { - for(i = 0; i < 4; ++i) { - float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; - int8_t tmp_r; - u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); - dst[0] = byte_to_float_tex(tmp_r); - dst[1] = 0.0; - dst[2] = 0.0; - dst[3] = 1.0; - } - } - src += block_size; - } - src_row += src_stride; - } -} - -void -util_format_rgtc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) -{ - int8_t tmp_r; - u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1); - dst[0] = byte_to_float_tex(tmp_r); - dst[1] = 0.0; - dst[2] = 0.0; - dst[3] = 1.0; -} - - -void -util_format_rgtc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) -{ - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2); - u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2); -} - -void -util_format_rgtc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - const unsigned bw = 4, bh = 4, comps = 4; - unsigned x, y, i, j; - unsigned block_size = 16; - - for(y = 0; y < height; y += bh) { - const uint8_t *src = src_row; - for(x = 0; x < width; x += bw) { - for(j = 0; j < bh; ++j) { - for(i = 0; i < bw; ++i) { - uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps; - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2); - u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2); - - } - } - src += block_size; - } - src_row += src_stride; - } -} - -void -util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - const unsigned bw = 4, bh = 4, bytes_per_block = 16; - unsigned x, y, i, j; - - for(y = 0; y < height; y += bh) { - uint8_t *dst = dst_row; - for(x = 0; x < width; x += bw) { - uint8_t tmp_r[4][4]; /* [bh][bw] */ - uint8_t tmp_g[4][4]; /* [bh][bw] */ - for(j = 0; j < bh; ++j) { - for(i = 0; i < bw; ++i) { - tmp_r[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]; - tmp_g[j][i] = src_row[((y + j)*src_stride/sizeof(*src_row) + (x + i)*4) + 1]; - } - } - u_format_unsigned_encode_rgtc_chan(dst, tmp_r, 4, 4); - u_format_unsigned_encode_rgtc_chan(dst + 8, tmp_g, 4, 4); - dst += bytes_per_block; - } - dst_row += dst_stride / sizeof(*dst_row); - } -} - -void -util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off) -{ - const unsigned bw = 4, bh = 4, bytes_per_block = 16; - unsigned x, y, i, j; - - for(y = 0; y < height; y += bh) { - uint8_t *dst = dst_row; - for(x = 0; x < width; x += bw) { - uint8_t tmp_r[4][4]; /* [bh][bw][comps] */ - uint8_t tmp_g[4][4]; /* [bh][bw][comps] */ - for(j = 0; j < bh; ++j) { - for(i = 0; i < bw; ++i) { - tmp_r[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); - tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]); - } - } - u_format_unsigned_encode_rgtc_chan(dst, tmp_r, 4, 4); - u_format_unsigned_encode_rgtc_chan(dst + 8, tmp_g, 4, 4); - dst += bytes_per_block; - } - dst_row += dst_stride / sizeof(*dst_row); - } -} - -void -util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1); -} - -void -util_format_rgtc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - unsigned x, y, i, j; - int block_size = 16; - for(y = 0; y < height; y += 4) { - const uint8_t *src = src_row; - for(x = 0; x < width; x += 4) { - for(j = 0; j < 4; ++j) { - for(i = 0; i < 4; ++i) { - float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; - uint8_t tmp_r, tmp_g; - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); - u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); - dst[0] = ubyte_to_float(tmp_r); - dst[1] = ubyte_to_float(tmp_g); - dst[2] = 0.0; - dst[3] = 1.0; - } - } - src += block_size; - } - src_row += src_stride; - } -} - -void -util_format_rgtc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) -{ - uint8_t tmp_r, tmp_g; - u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); - u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); - dst[0] = ubyte_to_float(tmp_r); - dst[1] = ubyte_to_float(tmp_g); - dst[2] = 0.0; - dst[3] = 1.0; -} - - -void -util_format_rgtc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) -{ - fprintf(stderr,"%s\n", __func__); -} - -void -util_format_rgtc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - fprintf(stderr,"%s\n", __func__); -} - -void -util_format_rgtc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - fprintf(stderr,"%s\n", __func__); -} - -void -util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - unsigned x, y, i, j; - int block_size = 16; - for(y = 0; y < height; y += 4) { - const int8_t *src = (int8_t *)src_row; - for(x = 0; x < width; x += 4) { - for(j = 0; j < 4; ++j) { - for(i = 0; i < 4; ++i) { - float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; - int8_t tmp_r, tmp_g; - u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); - u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); - dst[0] = byte_to_float_tex(tmp_r); - dst[1] = byte_to_float_tex(tmp_g); - dst[2] = 0.0; - dst[3] = 1.0; - } - } - src += block_size; - } - src_row += src_stride; - } -} - -void -util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off) -{ - const unsigned bw = 4, bh = 4, bytes_per_block = 16; - unsigned x, y, i, j; - - for(y = 0; y < height; y += bh) { - int8_t *dst = (int8_t *)dst_row; - for(x = 0; x < width; x += bw) { - int8_t tmp_r[4][4]; /* [bh][bw][comps] */ - int8_t tmp_g[4][4]; /* [bh][bw][comps] */ - for(j = 0; j < bh; ++j) { - for(i = 0; i < bw; ++i) { - tmp_r[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); - tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]); - } - } - u_format_signed_encode_rgtc_chan(dst, tmp_r, 4, 4); - u_format_signed_encode_rgtc_chan(dst + 8, tmp_g, 4, 4); - dst += bytes_per_block; - } - dst_row += dst_stride / sizeof(*dst_row); - } -} - -void -util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) -{ - util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1); -} - -void -util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) -{ - int8_t tmp_r, tmp_g; - u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2); - u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2); - dst[0] = byte_to_float_tex(tmp_r); - dst[1] = byte_to_float_tex(tmp_g); - dst[2] = 0.0; - dst[3] = 1.0; -} - - -#define TAG(x) u_format_unsigned_##x -#define TYPE uint8_t -#define T_MIN 0 -#define T_MAX 255 - -#include "../../../mesa/main/texcompress_rgtc_tmp.h" - -#undef TYPE -#undef TAG -#undef T_MIN -#undef T_MAX - - -#define TAG(x) u_format_signed_##x -#define TYPE int8_t -#define T_MIN (int8_t)-128 -#define T_MAX (int8_t)127 - -#include "../../../mesa/main/texcompress_rgtc_tmp.h" - -#undef TYPE -#undef TAG -#undef T_MIN -#undef T_MAX +/************************************************************************** + * + * Copyright (C) 2011 Red Hat Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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 +#include "u_math.h" +#include "u_format.h" +#include "u_format_rgtc.h" + +static void u_format_unsigned_encode_rgtc_ubyte(uint8_t *blkaddr, uint8_t srccolors[4][4], + int numxpixels, int numypixels); + +static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata, + unsigned i, unsigned j, uint8_t *value, unsigned comps); + +static void u_format_signed_encode_rgtc_ubyte(int8_t *blkaddr, int8_t srccolors[4][4], + int numxpixels, int numypixels); + +static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata, + unsigned i, unsigned j, int8_t *value, unsigned comps); + +void +util_format_rgtc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) +{ + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1); +} + +void +util_format_rgtc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + const unsigned bw = 4, bh = 4, comps = 4; + unsigned x, y, i, j; + unsigned block_size = 8; + + for(y = 0; y < height; y += bh) { + const uint8_t *src = src_row; + for(x = 0; x < width; x += bw) { + for(j = 0; j < bh; ++j) { + for(i = 0; i < bw; ++i) { + uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps; + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1); + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_rgtc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, + unsigned src_stride, unsigned width, unsigned height) +{ + const unsigned bw = 4, bh = 4, bytes_per_block = 8; + unsigned x, y, i, j; + + for(y = 0; y < height; y += bh) { + uint8_t *dst = dst_row; + for(x = 0; x < width; x += bw) { + uint8_t tmp[4][4]; /* [bh][bw][comps] */ + for(j = 0; j < bh; ++j) { + for(i = 0; i < bw; ++i) { + tmp[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]; + } + } + u_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4); + dst += bytes_per_block; + } + dst_row += dst_stride / sizeof(*dst_row); + } +} + +void +util_format_rgtc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + unsigned x, y, i, j; + int block_size = 8; + for(y = 0; y < height; y += 4) { + const uint8_t *src = src_row; + for(x = 0; x < width; x += 4) { + for(j = 0; j < 4; ++j) { + for(i = 0; i < 4; ++i) { + float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; + uint8_t tmp_r; + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); + dst[0] = ubyte_to_float(tmp_r); + dst[1] = 0.0; + dst[2] = 0.0; + dst[3] = 1.0; + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_rgtc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + const unsigned bw = 4, bh = 4, bytes_per_block = 8; + unsigned x, y, i, j; + + for(y = 0; y < height; y += bh) { + uint8_t *dst = dst_row; + for(x = 0; x < width; x += bw) { + uint8_t tmp[4][4]; /* [bh][bw][comps] */ + for(j = 0; j < bh; ++j) { + for(i = 0; i < bw; ++i) { + tmp[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); + } + } + u_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4); + dst += bytes_per_block; + } + dst_row += dst_stride / sizeof(*dst_row); + } +} + +void +util_format_rgtc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ + uint8_t tmp_r; + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); + dst[0] = ubyte_to_float(tmp_r); + dst[1] = 0.0; + dst[2] = 0.0; + dst[3] = 1.0; +} + +void +util_format_rgtc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_rgtc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_rgtc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_rgtc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + const unsigned bw = 4, bh = 4, bytes_per_block = 8; + unsigned x, y, i, j; + + for(y = 0; y < height; y += bh) { + int8_t *dst = (int8_t *)dst_row; + for(x = 0; x < width; x += bw) { + int8_t tmp[4][4]; /* [bh][bw][comps] */ + for(j = 0; j < bh; ++j) { + for(i = 0; i < bw; ++i) { + tmp[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); + } + } + u_format_signed_encode_rgtc_ubyte(dst, tmp, 4, 4); + dst += bytes_per_block; + } + dst_row += dst_stride / sizeof(*dst_row); + } +} + +void +util_format_rgtc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + unsigned x, y, i, j; + int block_size = 8; + for(y = 0; y < height; y += 4) { + const int8_t *src = (int8_t *)src_row; + for(x = 0; x < width; x += 4) { + for(j = 0; j < 4; ++j) { + for(i = 0; i < 4; ++i) { + float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; + int8_t tmp_r; + u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); + dst[0] = byte_to_float_tex(tmp_r); + dst[1] = 0.0; + dst[2] = 0.0; + dst[3] = 1.0; + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_rgtc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ + int8_t tmp_r; + u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1); + dst[0] = byte_to_float_tex(tmp_r); + dst[1] = 0.0; + dst[2] = 0.0; + dst[3] = 1.0; +} + + +void +util_format_rgtc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) +{ + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2); + u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2); +} + +void +util_format_rgtc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + const unsigned bw = 4, bh = 4, comps = 4; + unsigned x, y, i, j; + unsigned block_size = 16; + + for(y = 0; y < height; y += bh) { + const uint8_t *src = src_row; + for(x = 0; x < width; x += bw) { + for(j = 0; j < bh; ++j) { + for(i = 0; i < bw; ++i) { + uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps; + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2); + u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2); + + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + const unsigned bw = 4, bh = 4, bytes_per_block = 16; + unsigned x, y, i, j; + + for(y = 0; y < height; y += bh) { + uint8_t *dst = dst_row; + for(x = 0; x < width; x += bw) { + uint8_t tmp_r[4][4]; /* [bh][bw] */ + uint8_t tmp_g[4][4]; /* [bh][bw] */ + for(j = 0; j < bh; ++j) { + for(i = 0; i < bw; ++i) { + tmp_r[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]; + tmp_g[j][i] = src_row[((y + j)*src_stride/sizeof(*src_row) + (x + i)*4) + 1]; + } + } + u_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4); + u_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4); + dst += bytes_per_block; + } + dst_row += dst_stride / sizeof(*dst_row); + } +} + +void +util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off) +{ + const unsigned bw = 4, bh = 4, bytes_per_block = 16; + unsigned x, y, i, j; + + for(y = 0; y < height; y += bh) { + uint8_t *dst = dst_row; + for(x = 0; x < width; x += bw) { + uint8_t tmp_r[4][4]; /* [bh][bw][comps] */ + uint8_t tmp_g[4][4]; /* [bh][bw][comps] */ + for(j = 0; j < bh; ++j) { + for(i = 0; i < bw; ++i) { + tmp_r[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); + tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]); + } + } + u_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4); + u_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4); + dst += bytes_per_block; + } + dst_row += dst_stride / sizeof(*dst_row); + } +} + +void +util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1); +} + +void +util_format_rgtc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + unsigned x, y, i, j; + int block_size = 16; + for(y = 0; y < height; y += 4) { + const uint8_t *src = src_row; + for(x = 0; x < width; x += 4) { + for(j = 0; j < 4; ++j) { + for(i = 0; i < 4; ++i) { + float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; + uint8_t tmp_r, tmp_g; + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); + u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); + dst[0] = ubyte_to_float(tmp_r); + dst[1] = ubyte_to_float(tmp_g); + dst[2] = 0.0; + dst[3] = 1.0; + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_rgtc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ + uint8_t tmp_r, tmp_g; + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); + u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); + dst[0] = ubyte_to_float(tmp_r); + dst[1] = ubyte_to_float(tmp_g); + dst[2] = 0.0; + dst[3] = 1.0; +} + + +void +util_format_rgtc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_rgtc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_rgtc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + unsigned x, y, i, j; + int block_size = 16; + for(y = 0; y < height; y += 4) { + const int8_t *src = (int8_t *)src_row; + for(x = 0; x < width; x += 4) { + for(j = 0; j < 4; ++j) { + for(i = 0; i < 4; ++i) { + float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; + int8_t tmp_r, tmp_g; + u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); + u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); + dst[0] = byte_to_float_tex(tmp_r); + dst[1] = byte_to_float_tex(tmp_g); + dst[2] = 0.0; + dst[3] = 1.0; + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off) +{ + const unsigned bw = 4, bh = 4, bytes_per_block = 16; + unsigned x, y, i, j; + + for(y = 0; y < height; y += bh) { + int8_t *dst = (int8_t *)dst_row; + for(x = 0; x < width; x += bw) { + int8_t tmp_r[4][4]; /* [bh][bw][comps] */ + int8_t tmp_g[4][4]; /* [bh][bw][comps] */ + for(j = 0; j < bh; ++j) { + for(i = 0; i < bw; ++i) { + tmp_r[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); + tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]); + } + } + u_format_signed_encode_rgtc_ubyte(dst, tmp_r, 4, 4); + u_format_signed_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4); + dst += bytes_per_block; + } + dst_row += dst_stride / sizeof(*dst_row); + } +} + +void +util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1); +} + +void +util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ + int8_t tmp_r, tmp_g; + u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2); + u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2); + dst[0] = byte_to_float_tex(tmp_r); + dst[1] = byte_to_float_tex(tmp_g); + dst[2] = 0.0; + dst[3] = 1.0; +} + + +#define TAG(x) u_format_unsigned_##x +#define TYPE uint8_t +#define T_MIN 0 +#define T_MAX 255 + +#include "../../../mesa/main/texcompress_rgtc_tmp.h" + +#undef TYPE +#undef TAG +#undef T_MIN +#undef T_MAX + + +#define TAG(x) u_format_signed_##x +#define TYPE int8_t +#define T_MIN (int8_t)-128 +#define T_MAX (int8_t)127 + +#include "../../../mesa/main/texcompress_rgtc_tmp.h" + +#undef TYPE +#undef TAG +#undef T_MIN +#undef T_MAX -- cgit v1.2.3