diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2008-09-11 16:05:15 +0100 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2008-09-11 16:05:15 +0100 |
commit | 0397b2bb41b0f337af2949a15bcd7d0e7e8a7dc1 (patch) | |
tree | 732c93d74ed806942a13bf15575a61aa4f001253 /src/gallium/drivers/cell/spu/spu_texture.c | |
parent | 80af50b35b5a4e8890e15b28940576f8a1ac1476 (diff) | |
parent | e6887a5752774c18cf527477fdd3e57e4893ff3b (diff) |
Merge branch 'gallium-0.1' into gallium-0.2
A first attempt at moving gallium onto a branch directly off master...
It will be interesting to see how much work this takes to get running.
Have resolved the conflicts semi-arbitarily, not compiled or tested.
Conflicts:
.gitignore
Makefile
configs/config.mgw
configs/darwin
configs/darwin-x86ppc
configs/default
configs/freebsd-dri
configs/linux-dri
configs/linux-dri-xcb
configs/linux-fbdev
configs/linux-static
configs/linux-x86-64-static
configs/linux-x86-static
doxygen/Makefile
include/GL/gl.h
progs/demos/Makefile
progs/demos/descrip.mms
progs/demos/texenv.c
progs/egl/.gitignore
progs/egl/Makefile
progs/glsl/.gitignore
progs/glsl/Makefile
progs/glsl/convolutions.c
progs/samples/Makefile.mgw
progs/tests/.gitignore
progs/trivial/.gitignore
progs/trivial/point-param.c
progs/trivial/tri.c
progs/xdemos/.gitignore
progs/xdemos/glthreads.c
src/egl/drivers/demo/Makefile
src/egl/drivers/dri/Makefile
src/egl/main/Makefile
src/glu/Makefile
src/glu/sgi/Makefile
src/glu/sgi/Makefile.mgw
src/glut/glx/Makefile.mgw
src/glut/os2/WarpWin.cpp
src/glut/os2/glut_cindex.cpp
src/glut/os2/glut_gamemode.cpp
src/glut/os2/glut_win.cpp
src/glut/os2/glut_winmisc.cpp
src/glut/os2/os2_glx.cpp
src/glut/os2/os2_menu.cpp
src/glut/os2/os2_winproc.cpp
src/glw/Makefile
src/glx/x11/dri_glx.c
src/glx/x11/glxext.c
src/mesa/Makefile
src/mesa/Makefile.mgw
src/mesa/descrip.mms
src/mesa/drivers/beos/Makefile
src/mesa/drivers/common/descrip.mms
src/mesa/drivers/common/driverfuncs.c
src/mesa/drivers/directfb/Makefile
src/mesa/drivers/dri/Makefile.template
src/mesa/drivers/dri/common/dri_bufmgr.c
src/mesa/drivers/dri/common/dri_bufmgr.h
src/mesa/drivers/dri/common/dri_util.c
src/mesa/drivers/dri/common/extension_helper.h
src/mesa/drivers/dri/common/mmio.h
src/mesa/drivers/dri/common/utils.c
src/mesa/drivers/dri/common/utils.h
src/mesa/drivers/dri/glcore/Makefile
src/mesa/drivers/dri/i810/i810screen.c
src/mesa/drivers/dri/i915/intel_ioctl.c
src/mesa/drivers/dri/i915/intel_ioctl.h
src/mesa/drivers/dri/i915/intel_screen.c
src/mesa/drivers/dri/i915/server/i830_common.h
src/mesa/drivers/dri/i915/server/i830_dri.h
src/mesa/drivers/dri/i965/intel_screen.c
src/mesa/drivers/dri/i965/server/i830_common.h
src/mesa/drivers/dri/i965/server/i830_dri.h
src/mesa/drivers/dri/mach64/mach64_screen.c
src/mesa/drivers/dri/nouveau/nouveau_context.h
src/mesa/drivers/dri/nouveau/nouveau_fifo.c
src/mesa/drivers/dri/nouveau/nouveau_fifo.h
src/mesa/drivers/dri/nouveau/nouveau_screen.c
src/mesa/drivers/dri/nouveau/nouveau_screen.h
src/mesa/drivers/dri/r128/r128_tex.h
src/mesa/drivers/dri/savage/savageioctl.h
src/mesa/drivers/fbdev/Makefile
src/mesa/drivers/osmesa/Makefile
src/mesa/drivers/osmesa/descrip.mms
src/mesa/drivers/x11/Makefile
src/mesa/drivers/x11/descrip.mms
src/mesa/drivers/x11/xm_dd.c
src/mesa/glapi/glapi.c
src/mesa/glapi/glthread.c
src/mesa/main/api_validate.c
src/mesa/main/attrib.c
src/mesa/main/bufferobj.c
src/mesa/main/bufferobj.h
src/mesa/main/buffers.c
src/mesa/main/config.h
src/mesa/main/context.c
src/mesa/main/descrip.mms
src/mesa/main/drawpix.c
src/mesa/main/enums.c
src/mesa/main/fbobject.c
src/mesa/main/glheader.h
src/mesa/main/imports.c
src/mesa/main/mipmap.c
src/mesa/main/mm.c
src/mesa/main/mm.h
src/mesa/main/mtypes.h
src/mesa/main/points.c
src/mesa/main/sources
src/mesa/main/state.c
src/mesa/main/texcompress_fxt1.c
src/mesa/main/texenvprogram.c
src/mesa/main/texobj.c
src/mesa/main/texstate.c
src/mesa/main/texstore.c
src/mesa/math/descrip.mms
src/mesa/shader/arbprogram.c
src/mesa/shader/descrip.mms
src/mesa/shader/prog_execute.c
src/mesa/shader/prog_statevars.c
src/mesa/shader/prog_statevars.h
src/mesa/shader/prog_uniform.c
src/mesa/shader/program.c
src/mesa/shader/program.h
src/mesa/shader/shader_api.c
src/mesa/shader/slang/descrip.mms
src/mesa/shader/slang/library/slang_vertex_builtin_gc.h
src/mesa/sources
src/mesa/swrast/descrip.mms
src/mesa/swrast/s_drawpix.c
src/mesa/swrast/s_fragprog.c
src/mesa/swrast/s_readpix.c
src/mesa/swrast/s_span.c
src/mesa/swrast_setup/descrip.mms
src/mesa/tnl/descrip.mms
src/mesa/tnl/t_context.h
src/mesa/tnl/t_vp_build.c
src/mesa/tnl/tnl.h
src/mesa/vbo/descrip.mms
src/mesa/vbo/vbo_context.c
src/mesa/vbo/vbo_exec_array.c
src/mesa/x86-64/xform4.S
src/mesa/x86/rtasm/x86sse.c
src/mesa/x86/rtasm/x86sse.h
windows/VC6/progs/glut/glut.dsp
windows/VC7/mesa/gdi/gdi.vcproj
windows/VC7/mesa/glu/glu.vcproj
windows/VC7/mesa/mesa.sln
windows/VC7/mesa/mesa/mesa.vcproj
windows/VC7/mesa/osmesa/osmesa.vcproj
windows/VC7/progs/glut/glut.vcproj
windows/VC8/mesa/gdi/gdi.vcproj
windows/VC8/mesa/glu/glu.vcproj
windows/VC8/mesa/mesa.sln
windows/VC8/mesa/mesa/mesa.vcproj
windows/VC8/progs/glut/glut.vcproj
Diffstat (limited to 'src/gallium/drivers/cell/spu/spu_texture.c')
-rw-r--r-- | src/gallium/drivers/cell/spu/spu_texture.c | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c new file mode 100644 index 0000000000..5051774f00 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -0,0 +1,200 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + + +#include "pipe/p_compiler.h" +#include "spu_main.h" +#include "spu_texture.h" +#include "spu_tile.h" +#include "spu_colorpack.h" +#include "spu_dcache.h" + + +/** + * Mark all tex cache entries as invalid. + */ +void +invalidate_tex_cache(void) +{ + uint unit = 0; + uint bytes = 4 * spu.texture[unit].width + * spu.texture[unit].height; + + spu_dcache_mark_dirty((unsigned) spu.texture[unit].start, bytes); +} + + +/** + * XXX look into getting texels for all four pixels in a quad at once. + */ +static uint +get_texel(uint unit, vec_uint4 coordinate) +{ + /* + * XXX we could do the "/ TILE_SIZE" and "% TILE_SIZE" operations as + * SIMD since X and Y are already in a SIMD register. + */ + const unsigned texture_ea = (uintptr_t) spu.texture[unit].start; + ushort x = spu_extract(coordinate, 0); + ushort y = spu_extract(coordinate, 1); + unsigned tile_offset = sizeof(tile_t) + * ((y / TILE_SIZE * spu.texture[unit].tiles_per_row) + (x / TILE_SIZE)); + ushort texel_offset = (ushort) 4 + * (ushort) (((ushort) (y % TILE_SIZE) * (ushort) TILE_SIZE) + (x % TILE_SIZE)); + vec_uint4 tmp; + + spu_dcache_fetch_unaligned((qword *) & tmp, + texture_ea + tile_offset + texel_offset, + 4); + return spu_extract(tmp, 0); +} + + +/** + * Get four texels from locations (x[0], y[0]), (x[1], y[1]) ... + * + * NOTE: in the typical case of bilinear filtering, the four texels + * are in a 2x2 group so we could get by with just two dcache fetches + * (two side-by-side texels per fetch). But when bilinear filtering + * wraps around a texture edge, we'll probably need code like we have + * now. + * FURTHERMORE: since we're rasterizing a quad of 2x2 pixels at a time, + * it's quite likely that the four pixels in a quad will need some of the + * same texels. So look into doing texture fetches for four pixels at + * a time. + */ +static void +get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels) +{ + const unsigned texture_ea = (uintptr_t) spu.texture[unit].start; + vec_uint4 tile_x = spu_rlmask(x, -5); + vec_uint4 tile_y = spu_rlmask(y, -5); + const qword offset_x = si_andi((qword) x, 0x1f); + const qword offset_y = si_andi((qword) y, 0x1f); + + const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].tiles_per_row); + const qword tile_size = (qword) spu_splats(sizeof(tile_t)); + + qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x); + tile_offset = si_mpy((qword) tile_offset, tile_size); + + qword texel_offset = si_a(si_mpyui(offset_y, 32), offset_x); + texel_offset = si_mpyui(texel_offset, 4); + + vec_uint4 offset = (vec_uint4) si_a(tile_offset, texel_offset); + + spu_dcache_fetch_unaligned((qword *) & texels[0], + texture_ea + spu_extract(offset, 0), 4); + spu_dcache_fetch_unaligned((qword *) & texels[1], + texture_ea + spu_extract(offset, 1), 4); + spu_dcache_fetch_unaligned((qword *) & texels[2], + texture_ea + spu_extract(offset, 2), 4); + spu_dcache_fetch_unaligned((qword *) & texels[3], + texture_ea + spu_extract(offset, 3), 4); +} + + +/** + * Get texture sample at texcoord. + */ +vector float +sample_texture_nearest(uint unit, vector float texcoord) +{ + vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size); + vector unsigned int itc = spu_convtu(tc, 0); /* convert to int */ + itc = spu_and(itc, spu.texture[unit].tex_size_mask); /* mask (GL_REPEAT) */ + uint texel = get_texel(unit, itc); + return spu_unpack_A8R8G8B8(texel); +} + + +vector float +sample_texture_bilinear(uint unit, vector float texcoord) +{ + static const vec_uint4 offset_x = {0, 0, 1, 1}; + static const vec_uint4 offset_y = {0, 1, 0, 1}; + + vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size); + tc = spu_add(tc, spu_splats(-0.5f)); /* half texel bias */ + + /* integer texcoords S,T: */ + vec_uint4 itc = spu_convtu(tc, 0); /* convert to int */ + + vec_uint4 texels[4]; + + /* setup texcoords for quad: + * +-----+-----+ + * |x0,y0|x1,y1| + * +-----+-----+ + * |x2,y2|x3,y3| + * +-----+-----+ + */ + vec_uint4 x = spu_splats(spu_extract(itc, 0)); + vec_uint4 y = spu_splats(spu_extract(itc, 1)); + x = spu_add(x, offset_x); + y = spu_add(y, offset_y); + + /* GL_REPEAT wrap mode: */ + x = spu_and(x, spu.texture[unit].tex_size_x_mask); + y = spu_and(y, spu.texture[unit].tex_size_y_mask); + + get_four_texels(unit, x, y, texels); + + /* integer A8R8G8B8 to float texel conversion */ + vector float texel00 = spu_unpack_A8R8G8B8(spu_extract(texels[0], 0)); + vector float texel01 = spu_unpack_A8R8G8B8(spu_extract(texels[1], 0)); + vector float texel10 = spu_unpack_A8R8G8B8(spu_extract(texels[2], 0)); + vector float texel11 = spu_unpack_A8R8G8B8(spu_extract(texels[3], 0)); + + + /* Compute weighting factors in [0,1] + * Multiply texcoord by 1024, AND with 1023, convert back to float. + */ + vector float tc1024 = spu_mul(tc, spu_splats(1024.0f)); + vector signed int itc1024 = spu_convts(tc1024, 0); + itc1024 = spu_and(itc1024, spu_splats((1 << 10) - 1)); + vector float weight = spu_convtf(itc1024, 10); + + /* smeared frac and 1-frac */ + vector float sfrac = spu_splats(spu_extract(weight, 0)); + vector float tfrac = spu_splats(spu_extract(weight, 1)); + vector float sfrac1 = spu_sub(spu_splats(1.0f), sfrac); + vector float tfrac1 = spu_sub(spu_splats(1.0f), tfrac); + + /* multiply the samples (colors) by the S/T weights */ + texel00 = spu_mul(spu_mul(texel00, sfrac1), tfrac1); + texel10 = spu_mul(spu_mul(texel10, sfrac ), tfrac1); + texel01 = spu_mul(spu_mul(texel01, sfrac1), tfrac ); + texel11 = spu_mul(spu_mul(texel11, sfrac ), tfrac ); + + /* compute sum of weighted samples */ + vector float texel_sum = spu_add(texel00, texel01); + texel_sum = spu_add(texel_sum, texel10); + texel_sum = spu_add(texel_sum, texel11); + + return texel_sum; +} |