From e2a669aed4bc6f9c94b6b664bf667777078e02c0 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 17 Dec 2007 20:41:20 -0700 Subject: obsolete --- src/mesa/pipe/softpipe/sp_rgba_tile.c | 758 ---------------------------------- src/mesa/pipe/softpipe/sp_rgba_tile.h | 48 --- 2 files changed, 806 deletions(-) delete mode 100644 src/mesa/pipe/softpipe/sp_rgba_tile.c delete mode 100644 src/mesa/pipe/softpipe/sp_rgba_tile.h (limited to 'src') diff --git a/src/mesa/pipe/softpipe/sp_rgba_tile.c b/src/mesa/pipe/softpipe/sp_rgba_tile.c deleted file mode 100644 index c42635a1ad..0000000000 --- a/src/mesa/pipe/softpipe/sp_rgba_tile.c +++ /dev/null @@ -1,758 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - -/** - * RGBA/float tile get/put functions. - * XXX eventually this should go into a utility library usable by - * the state tracker too. - * Then, remove pipe->get/put_tile_rgba() - */ - - -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" - -#include "sp_rgba_tile.h" - - -/** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */ -#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) - -#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \ - us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) ) - - - -#define CLIP_TILE \ - do { \ - if (x >= ps->width) \ - return; \ - if (y >= ps->height) \ - return; \ - if (x + w > ps->width) \ - w = ps->width - x; \ - if (y + h > ps->height) \ - h = ps->height - y; \ - } while(0) - - -/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ - -static void -a8r8g8b8_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const unsigned *src - = ((const unsigned *) (ps->map)) - + y * ps->pitch + x; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_A8R8G8B8_UNORM); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++) { - const unsigned pixel = src[j]; - pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); - pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); - pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); - pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); - pRow += 4; - } - src += ps->pitch; - p += w0 * 4; - } -} - - -static void -a8r8g8b8_put_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - const float *p) -{ - unsigned *dst - = ((unsigned *) (ps->map)) - + y * ps->pitch + x; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_A8R8G8B8_UNORM); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++) { - unsigned r, g, b, a; - UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); - UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); - UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); - UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); - dst[j] = (a << 24) | (r << 16) | (g << 8) | b; - pRow += 4; - } - dst += ps->pitch; - p += w0 * 4; - } -} - - -/*** PIPE_FORMAT_B8G8R8A8_UNORM ***/ - -static void -b8g8r8a8_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const unsigned *src - = ((const unsigned *) (ps->map)) - + y * ps->pitch + x; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_B8G8R8A8_UNORM); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++) { - const unsigned pixel = src[j]; - pRow[0] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); - pRow[1] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); - pRow[2] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); - pRow[3] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); - pRow += 4; - } - src += ps->pitch; - p += w0 * 4; - } -} - - -static void -b8g8r8a8_put_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - const float *p) -{ - unsigned *dst - = ((unsigned *) (ps->map)) - + y * ps->pitch + x; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_B8G8R8A8_UNORM); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++) { - unsigned r, g, b, a; - UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); - UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); - UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); - UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); - dst[j] = (b << 24) | (g << 16) | (r << 8) | a; - pRow += 4; - } - dst += ps->pitch; - p += w0 * 4; - } -} - - -/*** PIPE_FORMAT_A1R5G5B5_UNORM ***/ - -static void -a1r5g5b5_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const ushort *src - = ((const ushort *) (ps->map)) - + y * ps->pitch + x; - unsigned i, j; - - assert(ps->format == PIPE_FORMAT_A1R5G5B5_UNORM); - - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - const ushort pixel = src[j]; - p[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f); - p[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f); - p[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); - p[3] = ((pixel >> 15) ) * 1.0f; - p += 4; - } - src += ps->pitch; - } -} - - -/*** PIPE_FORMAT_A4R4G4B4_UNORM ***/ - -static void -a4r4g4b4_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const ushort *src - = ((const ushort *) (ps->map)) - + y * ps->pitch + x; - unsigned i, j; - - assert(ps->format == PIPE_FORMAT_A4R4G4B4_UNORM); - - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - const ushort pixel = src[j]; - p[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f); - p[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f); - p[2] = ((pixel ) & 0xf) * (1.0f / 15.0f); - p[3] = ((pixel >> 12) ) * (1.0f / 15.0f); - p += 4; - } - src += ps->pitch; - } -} - - -/*** PIPE_FORMAT_R5G6B5_UNORM ***/ - -static void -r5g6b5_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const ushort *src - = ((const ushort *) (ps->map)) - + y * ps->pitch + x; - unsigned i, j; - - assert(ps->format == PIPE_FORMAT_R5G6B5_UNORM); - - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - const ushort pixel = src[j]; - p[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f); - p[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f); - p[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); - p[3] = 1.0f; - p += 4; - } - src += ps->pitch; - } -} - - -static void -r5g5b5_put_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - const float *p) -{ - ushort *dst - = ((ushort *) (ps->map)) - + y * ps->pitch + x; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_R5G6B5_UNORM); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++) { - uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0); - uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0); - uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0); - dst[j] = (r << 11) | (g << 5) | (b); - pRow += 4; - } - dst += ps->pitch; - p += w0 * 4; - } -} - - - -/*** PIPE_FORMAT_Z16_UNORM ***/ - -/** - * Return each Z value as four floats in [0,1]. - */ -static void -z16_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const ushort *src - = ((const ushort *) (ps->map)) - + y * ps->pitch + x; - const float scale = 1.0f / 65535.0f; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_Z16_UNORM); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++) { - pRow[j * 4 + 0] = - pRow[j * 4 + 1] = - pRow[j * 4 + 2] = - pRow[j * 4 + 3] = src[j] * scale; - } - src += ps->pitch; - p += 4 * w0; - } -} - - - - -/*** PIPE_FORMAT_U_L8 ***/ - -static void -l8_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const ubyte *src - = ((const ubyte *) (ps->map)) - + y * ps->pitch + x; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_U_L8); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++) { - pRow[0] = - pRow[1] = - pRow[2] = UBYTE_TO_FLOAT(src[j]); - pRow[3] = 1.0; - pRow += 4; - } - src += ps->pitch; - p += w0 * 4; - } -} - - -/*** PIPE_FORMAT_U_A8 ***/ - -static void -a8_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const ubyte *src - = ((const ubyte *) (ps->map)) - + y * ps->pitch + x; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_U_A8); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++) { - pRow[0] = - pRow[1] = - pRow[2] = 0.0; - pRow[3] = UBYTE_TO_FLOAT(src[j]); - pRow += 4; - } - src += ps->pitch; - p += w0 * 4; - } -} - - -/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/ - -static void -r16g16b16a16_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const short *src - = ((const short *) (ps->map)) - + (y * ps->pitch + x) * 4; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_R16G16B16A16_SNORM); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - float *pRow = p; - const short *pixel = src; - for (j = 0; j < w; j++) { - pRow[0] = SHORT_TO_FLOAT(pixel[0]); - pRow[1] = SHORT_TO_FLOAT(pixel[1]); - pRow[2] = SHORT_TO_FLOAT(pixel[2]); - pRow[3] = SHORT_TO_FLOAT(pixel[3]); - pRow += 4; - pixel += 4; - } - src += ps->pitch * 4; - p += w0 * 4; - } -} - - -static void -r16g16b16a16_put_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - const float *p) -{ - short *dst - = ((short *) (ps->map)) - + (y * ps->pitch + x) * 4; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_R16G16B16A16_SNORM); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++) { - short r, g, b, a; - UNCLAMPED_FLOAT_TO_SHORT(r, pRow[0]); - UNCLAMPED_FLOAT_TO_SHORT(g, pRow[1]); - UNCLAMPED_FLOAT_TO_SHORT(b, pRow[2]); - UNCLAMPED_FLOAT_TO_SHORT(a, pRow[3]); - dst[j*4+0] = r; - dst[j*4+1] = g; - dst[j*4+2] = b; - dst[j*4+3] = a; - pRow += 4; - } - dst += ps->pitch * 4; - p += w0 * 4; - } -} - - - -/*** PIPE_FORMAT_U_I8 ***/ - -static void -i8_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const ubyte *src - = ((const ubyte *) (ps->map)) - + y * ps->pitch + x; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_U_I8); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++) { - pRow[0] = - pRow[1] = - pRow[2] = - pRow[3] = UBYTE_TO_FLOAT(src[j]); - pRow += 4; - } - src += ps->pitch; - p += w0 * 4; - } -} - - -/*** PIPE_FORMAT_U_A8_L8 ***/ - -static void -a8_l8_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const ushort *src - = ((const ushort *) (ps->map)) - + y * ps->pitch + x; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_U_A8_L8); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++) { - const ushort p = src[j]; - pRow[0] = - pRow[1] = - pRow[2] = UBYTE_TO_FLOAT(p & 0xff); - pRow[3] = UBYTE_TO_FLOAT(p >> 8); - pRow += 4; - } - src += ps->pitch; - p += w0 * 4; - } -} - - - - -/*** PIPE_FORMAT_Z32_UNORM ***/ - -/** - * Return each Z value as four floats in [0,1]. - */ -static void -z32_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const uint *src - = ((const uint *) (ps->map)) - + y * ps->pitch + x; - const double scale = 1.0 / (double) 0xffffffff; - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_Z16_UNORM); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++) { - pRow[j * 4 + 0] = - pRow[j * 4 + 1] = - pRow[j * 4 + 2] = - pRow[j * 4 + 3] = (float) (scale * src[j]); - } - src += ps->pitch; - p += 4 * w0; - } -} - - -/*** PIPE_FORMAT_S8Z24_UNORM ***/ - -/** - * Return Z component as four float in [0,1]. Stencil part ignored. - */ -static void -s8z24_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const uint *src - = ((const uint *) (ps->map)) - + y * ps->pitch + x; - const double scale = 1.0 / ((1 << 24) - 1); - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_S8Z24_UNORM); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++) { - pRow[j * 4 + 0] = - pRow[j * 4 + 1] = - pRow[j * 4 + 2] = - pRow[j * 4 + 3] = (float) (scale * (src[j] & 0xffffff)); - } - src += ps->pitch; - p += 4 * w0; - } -} - - -/*** PIPE_FORMAT_Z24S8_UNORM ***/ - -/** - * Return Z component as four float in [0,1]. Stencil part ignored. - */ -static void -z24s8_get_tile_rgba(struct pipe_surface *ps, - unsigned x, unsigned y, unsigned w, unsigned h, - float *p) -{ - const uint *src - = ((const uint *) (ps->map)) - + y * ps->pitch + x; - const double scale = 1.0 / ((1 << 24) - 1); - unsigned i, j; - unsigned w0 = w; - - assert(ps->format == PIPE_FORMAT_Z24S8_UNORM); - - CLIP_TILE; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++) { - pRow[j * 4 + 0] = - pRow[j * 4 + 1] = - pRow[j * 4 + 2] = - pRow[j * 4 + 3] = (float) (scale * (src[j] >> 8)); - } - src += ps->pitch; - p += 4 * w0; - } -} - - -void -softpipe_get_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - float *p) -{ - switch (ps->format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - a8r8g8b8_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_B8G8R8A8_UNORM: - b8g8r8a8_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_A1R5G5B5_UNORM: - a1r5g5b5_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_A4R4G4B4_UNORM: - a4r4g4b4_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_R5G6B5_UNORM: - r5g6b5_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_U_L8: - l8_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_U_A8: - a8_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_U_I8: - i8_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_U_A8_L8: - a8_l8_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_R16G16B16A16_SNORM: - r16g16b16a16_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_Z16_UNORM: - z16_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_Z32_UNORM: - z32_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_S8Z24_UNORM: - s8z24_get_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_Z24S8_UNORM: - z24s8_get_tile_rgba(ps, x, y, w, h, p); - break; - default: - assert(0); - } -} - - -void -softpipe_put_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const float *p) -{ - switch (ps->format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - a8r8g8b8_put_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_B8G8R8A8_UNORM: - b8g8r8a8_put_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_A1R5G5B5_UNORM: - /*a1r5g5b5_put_tile_rgba(ps, x, y, w, h, p);*/ - break; - case PIPE_FORMAT_R5G6B5_UNORM: - r5g5b5_put_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_R8G8B8A8_UNORM: - break; - case PIPE_FORMAT_U_L8: - /*l8_put_tile_rgba(ps, x, y, w, h, p);*/ - break; - case PIPE_FORMAT_U_A8: - /*a8_put_tile_rgba(ps, x, y, w, h, p);*/ - break; - case PIPE_FORMAT_U_I8: - /*i8_put_tile_rgba(ps, x, y, w, h, p);*/ - break; - case PIPE_FORMAT_U_A8_L8: - /*a8_l8_put_tile_rgba(ps, x, y, w, h, p);*/ - break; - case PIPE_FORMAT_R16G16B16A16_SNORM: - r16g16b16a16_put_tile_rgba(ps, x, y, w, h, p); - break; - case PIPE_FORMAT_Z16_UNORM: - /*z16_put_tile_rgba(ps, x, y, w, h, p);*/ - break; - case PIPE_FORMAT_Z32_UNORM: - /*z32_put_tile_rgba(ps, x, y, w, h, p);*/ - break; - case PIPE_FORMAT_S8Z24_UNORM: - /*s8z24_put_tile_rgba(ps, x, y, w, h, p);*/ - break; - case PIPE_FORMAT_Z24S8_UNORM: - /*z24s8_put_tile_rgba(ps, x, y, w, h, p);*/ - break; - default: - assert(0); - } -} diff --git a/src/mesa/pipe/softpipe/sp_rgba_tile.h b/src/mesa/pipe/softpipe/sp_rgba_tile.h deleted file mode 100644 index ffa1b65de1..0000000000 --- a/src/mesa/pipe/softpipe/sp_rgba_tile.h +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - -#ifndef SP_RGBA_TILE_H -#define SP_RGBA_TILE_H - -#include "pipe/p_compiler.h" - -struct pipe_context; -struct pipe_surface; - -extern void -softpipe_get_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - float *p); - -extern void -softpipe_put_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const float *p); - -#endif -- cgit v1.2.3 From 7cef9237ae663f107dce82a688e8e0a9ce8193bc Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 18 Dec 2007 09:59:54 -0500 Subject: i965: don't treat swz differently and upload vertex buffers --- src/mesa/pipe/i965simple/brw_draw.c | 5 ++++- src/mesa/pipe/i965simple/brw_draw_upload.c | 2 +- src/mesa/pipe/i965simple/brw_vs_emit.c | 31 ++++++++++++++++++------------ 3 files changed, 24 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/mesa/pipe/i965simple/brw_draw.c b/src/mesa/pipe/i965simple/brw_draw.c index 25861a4373..acfb524a30 100644 --- a/src/mesa/pipe/i965simple/brw_draw.c +++ b/src/mesa/pipe/i965simple/brw_draw.c @@ -158,10 +158,13 @@ static boolean brw_try_draw_elements( struct pipe_context *pipe, /* Upload index, vertex data: */ - if (index_buffer && + if (index_buffer && !brw_upload_indices( brw, index_buffer, index_size, start, count )) return FALSE; + if (!brw_upload_vertex_buffers(brw)) + return FALSE; + if (!brw_upload_vertex_elements( brw )) return FALSE; diff --git a/src/mesa/pipe/i965simple/brw_draw_upload.c b/src/mesa/pipe/i965simple/brw_draw_upload.c index 79144837e8..19626ca633 100644 --- a/src/mesa/pipe/i965simple/brw_draw_upload.c +++ b/src/mesa/pipe/i965simple/brw_draw_upload.c @@ -217,7 +217,7 @@ boolean brw_upload_vertex_buffers( struct brw_context *brw ) for (i = 0; i < BRW_VEP_MAX; i++) { - if (brw->vb.vbo_array[i]->buffer == NULL) { + if (brw->vb.vbo_array[i] == NULL) { nr_enabled = i; break; } diff --git a/src/mesa/pipe/i965simple/brw_vs_emit.c b/src/mesa/pipe/i965simple/brw_vs_emit.c index 530e17a736..f4d61eade0 100644 --- a/src/mesa/pipe/i965simple/brw_vs_emit.c +++ b/src/mesa/pipe/i965simple/brw_vs_emit.c @@ -995,7 +995,7 @@ static void process_declaration(const struct tgsi_full_declaration *decl, printf("DECLARATION MASK = %d\n", decl->u.DeclarationMask.Mask); assert(0); - } else { //range + } else { /*range*/ idx = decl->u.DeclarationRange.First; } switch (decl->Semantic.SemanticName) { @@ -1057,17 +1057,15 @@ static void process_instruction(struct brw_vs_compile *c, unsigned insn, if_insn = 0; */ - /* Get argument regs. SWZ is special and does this itself. */ - if (inst->Instruction.Opcode != TGSI_OPCODE_SWZ) - for (i = 0; i < 3; i++) { - struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - index = src->SrcRegister.Index; - file = src->SrcRegister.File; - if (file == TGSI_FILE_OUTPUT&&c->output_regs[index].used_in_src) - args[i] = c->output_regs[index].reg; - else - args[i] = get_arg(c, &src->SrcRegister); - } + for (i = 0; i < 3; i++) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + index = src->SrcRegister.Index; + file = src->SrcRegister.File; + if (file == TGSI_FILE_OUTPUT&&c->output_regs[index].used_in_src) + args[i] = c->output_regs[index].reg; + else + args[i] = get_arg(c, &src->SrcRegister); + } /* Get dest regs. Note that it is possible for a reg to be both * dst and arg, given the static allocation of registers. So @@ -1208,11 +1206,16 @@ static void process_instruction(struct brw_vs_compile *c, break; #endif case TGSI_OPCODE_RET: +#if 0 brw_ADD(p, get_addr_reg(stack_index), get_addr_reg(stack_index), brw_imm_d(-4)); brw_set_access_mode(p, BRW_ALIGN_1); brw_MOV(p, brw_ip_reg(), deref_1uw(stack_index, 0)); brw_set_access_mode(p, BRW_ALIGN_16); +#else + /*brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));*/ +#endif + break; case TGSI_OPCODE_END: brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); break; @@ -1295,7 +1298,11 @@ void brw_vs_emit(struct brw_vs_compile *c) * now that we know what vars are being used allocate * registers for them.*/ brw_vs_alloc_regs(c, &prog_info); + + brw_set_access_mode(p, BRW_ALIGN_1); brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack)); + brw_set_access_mode(p, BRW_ALIGN_16); + allocated_registers = 1; } process_instruction(c, inst, &prog_info); -- cgit v1.2.3 From 9d4ab42f4be3a26f702729cc79ef67f8afc2eca5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 18 Dec 2007 16:56:22 +0000 Subject: vbo: unmap and remap immediate vbo before/after each draw. Also use BufferData(NULL) to get fresh storage and avoid synchronous operation where we would have to flush and wait for the fence after each draw because of the map. This will chew through a whole load of buffer space on small draws, so it isn't a proper solution. Need to support a no-fence or append mapping mode to do this right, or use user buffers. --- src/mesa/vbo/vbo_exec_draw.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index 68aba1df66..23a3658386 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -221,8 +221,18 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec ) if (exec->vtx.copied.nr != exec->vtx.vert_count) { GLcontext *ctx = exec->ctx; + GLenum target = GL_ARRAY_BUFFER_ARB; + GLenum access = GL_READ_WRITE_ARB; + GLenum usage = GL_STREAM_DRAW_ARB; + GLsizei size = VBO_VERT_BUFFER_SIZE * sizeof(GLfloat); + + /* Before the unmap (why?) + */ vbo_exec_bind_arrays( ctx ); + ctx->Driver.UnmapBuffer(ctx, target, exec->vtx.bufferobj); + exec->vtx.buffer_map = NULL; + vbo_context(ctx)->draw_prims( ctx, exec->vtx.inputs, exec->vtx.prim, @@ -230,6 +240,12 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec ) NULL, 0, exec->vtx.vert_count - 1); + + /* Get new data: + */ + ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj); + exec->vtx.buffer_map + = ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj); } } -- cgit v1.2.3 From 208b2ad8ab51c472886388fdd872e3a86e2c1c5c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 18 Dec 2007 16:57:17 +0000 Subject: gallium: give userbuffers some storage in the aub buffer pool --- src/mesa/pipe/xlib/xm_winsys_aub.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/pipe/xlib/xm_winsys_aub.c b/src/mesa/pipe/xlib/xm_winsys_aub.c index 0348c2ad40..ef3d975afb 100644 --- a/src/mesa/pipe/xlib/xm_winsys_aub.c +++ b/src/mesa/pipe/xlib/xm_winsys_aub.c @@ -51,7 +51,6 @@ struct aub_buffer { unsigned refcount; unsigned map_count; boolean dump_on_unmap; - boolean userbuffer; }; @@ -276,9 +275,15 @@ static struct pipe_buffer_handle * aub_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) { struct aub_buffer *sbo = CALLOC_STRUCT(aub_buffer); - sbo->size = bytes; - sbo->userbuffer = 1; - sbo->data = ptr; + + /* Lets hope this is meant for upload, not as a result! + */ + aub_buffer_data( winsys, + pipe_bo(sbo), + bytes, + ptr, + 0 ); + return pipe_bo(sbo); } -- cgit v1.2.3 From c31416971e4eac148f8e82d6c4392bd6f9cbc05d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 18 Dec 2007 17:25:33 +0000 Subject: gallium: rationalize vertex_element state packet Remove dst_offset (not used) Add nr_components, which could be calculated from format, but would be too much effort. Update i965 driver to cope. --- src/mesa/pipe/i965simple/brw_context.h | 10 +------ src/mesa/pipe/i965simple/brw_draw_upload.c | 14 ++------- src/mesa/pipe/i965simple/brw_state.c | 46 ++++++++++++++---------------- src/mesa/pipe/p_state.h | 4 +-- src/mesa/state_tracker/st_draw.c | 6 ++-- 5 files changed, 29 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/mesa/pipe/i965simple/brw_context.h b/src/mesa/pipe/i965simple/brw_context.h index 11146570be..fc2cb055e9 100644 --- a/src/mesa/pipe/i965simple/brw_context.h +++ b/src/mesa/pipe/i965simple/brw_context.h @@ -443,14 +443,6 @@ struct brw_cached_batch_item { */ #define ATTRIB_BIT_DWORDS ((PIPE_ATTRIB_MAX+31)/32) -struct brw_vertex_element { - struct brw_vertex_element_state vep; - - unsigned index; - unsigned element_size; - unsigned count; - unsigned vbo_rebase_offset; -}; @@ -508,7 +500,7 @@ struct brw_context */ struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX]; - struct brw_vertex_element inputs[PIPE_ATTRIB_MAX]; + struct brw_vertex_element_state inputs[PIPE_ATTRIB_MAX]; #define BRW_NR_UPLOAD_BUFS 17 #define BRW_UPLOAD_INIT_SIZE (128*1024) diff --git a/src/mesa/pipe/i965simple/brw_draw_upload.c b/src/mesa/pipe/i965simple/brw_draw_upload.c index 19626ca633..88d6c9d111 100644 --- a/src/mesa/pipe/i965simple/brw_draw_upload.c +++ b/src/mesa/pipe/i965simple/brw_draw_upload.c @@ -260,18 +260,8 @@ boolean brw_upload_vertex_elements( struct brw_context *brw ) memset(&vep, 0, sizeof(vep)); - for (i = 0; i < nr_enabled; i++) { - struct brw_vertex_element *input = &brw->vb.inputs[i]; - - switch (brw->vb.vbo_array[input->vep.ve0.vertex_buffer_index]->pitch) { - case 0: input->vep.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_0; - case 1: input->vep.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; - case 2: input->vep.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; - case 3: input->vep.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; - break; - } - vep.ve[i] = input->vep; - } + for (i = 0; i < nr_enabled; i++) + vep.ve[i] = brw->vb.inputs[i]; vep.header.length = (1 + nr_enabled * sizeof(vep.ve[0])/4) - 2; diff --git a/src/mesa/pipe/i965simple/brw_state.c b/src/mesa/pipe/i965simple/brw_state.c index 2008853654..daf14ff4ff 100644 --- a/src/mesa/pipe/i965simple/brw_state.c +++ b/src/mesa/pipe/i965simple/brw_state.c @@ -272,31 +272,27 @@ static void brw_set_vertex_element(struct pipe_context *pipe, struct brw_context *brw = brw_context(pipe); assert(index < PIPE_ATTRIB_MAX); - struct brw_vertex_element el; - memset(&el, 0, sizeof(struct brw_vertex_element)); - - /* do we need those anymore?*/ - el.index = index; -#if 0 - /*FIXME*/ - el.element_size = 0; - el.count = 0; - el.vbo_rebase_offset = 0; -#endif - - el.vep.ve0.src_offset = element->src_offset; - el.vep.ve0.src_format = brw_translate_surface_format(element->src_format); - el.vep.ve0.valid = 1; - el.vep.ve0.vertex_buffer_index = element->vertex_buffer_index; - - el.vep.ve1.dst_offset = index * 4; - el.vep.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; - el.vep.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; - el.vep.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; - el.vep.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; - /*can we count of brw->vb.vbo_array[element->vertex_buffer_index] - * being initialized ok to actually compute vbcomponent's - * correctly? */ + struct brw_vertex_element_state el; + memset(&el, 0, sizeof(el)); + + el.ve0.src_offset = element->src_offset; + el.ve0.src_format = brw_translate_surface_format(element->src_format); + el.ve0.valid = 1; + el.ve0.vertex_buffer_index = element->vertex_buffer_index; + + el.ve1.dst_offset = index * 4; + + el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; + + switch (element->nr_components) { + case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; + case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; + case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; + break; + } brw->vb.inputs[index] = el; } diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h index b7793c6d31..16d50fdb82 100644 --- a/src/mesa/pipe/p_state.h +++ b/src/mesa/pipe/p_state.h @@ -307,8 +307,8 @@ struct pipe_vertex_element * this attribute live in? */ unsigned vertex_buffer_index:5; - - unsigned dst_offset:8; + unsigned nr_components:3; + enum pipe_format src_format; /**< PIPE_FORMAT_* */ }; diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 274ae86a3e..a3e061d604 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -289,7 +289,7 @@ st_draw_vbo(GLcontext *ctx, vbuffer[attr].pitch = arrays[mesaAttr]->StrideB; /* in bytes */ vbuffer[attr].max_index = 0; /* need this? */ velement.vertex_buffer_index = attr; - velement.dst_offset = 0; /* need this? */ + velement.nr_components = arrays[mesaAttr]->Size; velement.src_format = pipe_vertex_format(arrays[mesaAttr]->Type, arrays[mesaAttr]->Size, arrays[mesaAttr]->Normalized); @@ -415,7 +415,7 @@ st_draw_vertices(GLcontext *ctx, unsigned prim, velement.src_offset = i * 4 * sizeof(GLfloat); velement.vertex_buffer_index = 0; velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - velement.dst_offset = 0; + velement.nr_components = 4; pipe->set_vertex_element(pipe, i, &velement); } @@ -547,7 +547,7 @@ st_feedback_draw_vbo(GLcontext *ctx, vbuffer[attr].pitch = arrays[mesaAttr]->StrideB; /* in bytes */ vbuffer[attr].max_index = 0; /* need this? */ velement.vertex_buffer_index = attr; - velement.dst_offset = 0; /* need this? */ + velement.nr_components = arrays[mesaAttr]->Size; velement.src_format = pipe_vertex_format(arrays[mesaAttr]->Type, arrays[mesaAttr]->Size, arrays[mesaAttr]->Normalized); -- cgit v1.2.3 From fb4eb8c91b7e76bf66d92da91c1e6d994b6e7e3e Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Dec 2007 15:59:54 -0700 Subject: fix some semantic info mix-ups in calculate_vertex_layout() --- src/mesa/pipe/softpipe/sp_state_derived.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c index 94072a2d30..a5e766781f 100644 --- a/src/mesa/pipe/softpipe/sp_state_derived.c +++ b/src/mesa/pipe/softpipe/sp_state_derived.c @@ -81,21 +81,21 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) break; case TGSI_SEMANTIC_COLOR: - if (fs->input_semantic_index[i] == 0) { + if (vs->output_semantic_index[i] == 0) { front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp); } else { - assert(fs->input_semantic_index[i] == 1); + assert(vs->output_semantic_index[i] == 1); front1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp); } break; case TGSI_SEMANTIC_BCOLOR: - if (fs->input_semantic_index[i] == 0) { + if (vs->output_semantic_index[i] == 0) { emitBack0 = TRUE; } else { - assert(fs->input_semantic_index[i] == 1); + assert(vs->output_semantic_index[i] == 1); emitBack1 = TRUE; } break; @@ -121,11 +121,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) } } -#if 00 - softpipe->nr_frag_attrs = vinfo->num_attribs; -#else softpipe->nr_frag_attrs = fs->num_inputs; -#endif /* We want these after all other attribs since they won't get passed * to the fragment shader. All prior vertex output attribs should match -- cgit v1.2.3 From 8c20747834c2ea7006f127e974560534ab279da2 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Dec 2007 16:00:31 -0700 Subject: setup the frontface register (fog.y, ATM) --- src/mesa/pipe/softpipe/sp_prim_setup.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c index 2ccf5e2624..de45529bf9 100644 --- a/src/mesa/pipe/softpipe/sp_prim_setup.c +++ b/src/mesa/pipe/softpipe/sp_prim_setup.c @@ -516,7 +516,7 @@ setup_fragcoord_coeff(struct setup_stage *setup) static void setup_tri_coefficients( struct setup_stage *setup ) { const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode; -#define USE_INPUT_MAP 0 +#define USE_INPUT_MAP 01 #if USE_INPUT_MAP const struct pipe_shader_state *fs = &setup->softpipe->fs->shader; #endif @@ -554,6 +554,12 @@ static void setup_tri_coefficients( struct setup_stage *setup ) */ setup_fragcoord_coeff(setup); } + else if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + /* FOG.y = front/back facing XXX fix this */ + setup->coef[fragSlot].a0[1] = 1 - setup->quad.facing; + setup->coef[fragSlot].dadx[1] = 0.0; + setup->coef[fragSlot].dady[1] = 0.0; + } else { #endif uint j; -- cgit v1.2.3 From 52da6b559a47eca2c1a8ec1b713e188f38e1d16a Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Dec 2007 16:00:58 -0700 Subject: fix bug on GL_VERTEX_PROGRAM_TWO_SIDE path --- src/mesa/state_tracker/st_atom_rasterizer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index 5c6b89d78c..35fd506458 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -109,7 +109,7 @@ static void update_raster_state( struct st_context *st ) * GL_LIGHT_MODEL_TWO_SIDE is set) or from vertex programs (when * GL_VERTEX_PROGRAM_TWO_SIDE is set). Note the logic here. */ - if (ctx->VertexProgram._Enabled) { + if (ctx->VertexProgram._Current) { raster.light_twoside = ctx->VertexProgram.TwoSideEnabled; } else if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) { -- cgit v1.2.3 From d0a63de37888966591735a190d69b0333d31bef5 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Dec 2007 16:01:25 -0700 Subject: turn off TGSI_DEBUG --- src/mesa/state_tracker/st_program.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index fe22233c93..6802bb3b06 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -47,7 +47,7 @@ #include "st_mesa_to_tgsi.h" -#define TGSI_DEBUG 01 +#define TGSI_DEBUG 0 /** -- cgit v1.2.3