14a49301eSmrg/************************************************************************** 24a49301eSmrg * 3af69d88dSmrg * Copyright 2007 VMware, Inc. 44a49301eSmrg * All Rights Reserved. 54a49301eSmrg * 64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a 74a49301eSmrg * copy of this software and associated documentation files (the 84a49301eSmrg * "Software"), to deal in the Software without restriction, including 94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish, 104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to 114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to 124a49301eSmrg * the following conditions: 134a49301eSmrg * 144a49301eSmrg * The above copyright notice and this permission notice (including the 154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions 164a49301eSmrg * of the Software. 174a49301eSmrg * 184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 254a49301eSmrg * 264a49301eSmrg **************************************************************************/ 274a49301eSmrg 284a49301eSmrg/** 294a49301eSmrg * RGBA/float tile get/put functions. 307ec681f3Smrg * Usable both by drivers and gallium frontends. 314a49301eSmrg */ 324a49301eSmrg 334a49301eSmrg 344a49301eSmrg#include "pipe/p_defines.h" 35cdc920a0Smrg#include "util/u_inlines.h" 364a49301eSmrg 377ec681f3Smrg#include "util/format/u_format.h" 387ec681f3Smrg#include "util/format/u_format_bptc.h" 394a49301eSmrg#include "util/u_math.h" 404a49301eSmrg#include "util/u_memory.h" 41af69d88dSmrg#include "util/u_surface.h" 424a49301eSmrg#include "util/u_tile.h" 434a49301eSmrg 444a49301eSmrg 454a49301eSmrg/** 464a49301eSmrg * Move raw block of pixels from transfer object to user memory. 474a49301eSmrg */ 484a49301eSmrgvoid 49af69d88dSmrgpipe_get_tile_raw(struct pipe_transfer *pt, 50af69d88dSmrg const void *src, 514a49301eSmrg uint x, uint y, uint w, uint h, 524a49301eSmrg void *dst, int dst_stride) 534a49301eSmrg{ 544a49301eSmrg if (dst_stride == 0) 553464ebd5Sriastradh dst_stride = util_format_get_stride(pt->resource->format, w); 564a49301eSmrg 573464ebd5Sriastradh if (u_clip_tile(x, y, &w, &h, &pt->box)) 584a49301eSmrg return; 594a49301eSmrg 603464ebd5Sriastradh util_copy_rect(dst, pt->resource->format, dst_stride, 0, 0, w, h, src, pt->stride, x, y); 614a49301eSmrg} 624a49301eSmrg 634a49301eSmrg 644a49301eSmrg/** 654a49301eSmrg * Move raw block of pixels from user memory to transfer object. 664a49301eSmrg */ 674a49301eSmrgvoid 68af69d88dSmrgpipe_put_tile_raw(struct pipe_transfer *pt, 69af69d88dSmrg void *dst, 704a49301eSmrg uint x, uint y, uint w, uint h, 714a49301eSmrg const void *src, int src_stride) 724a49301eSmrg{ 733464ebd5Sriastradh enum pipe_format format = pt->resource->format; 744a49301eSmrg 754a49301eSmrg if (src_stride == 0) 76cdc920a0Smrg src_stride = util_format_get_stride(format, w); 774a49301eSmrg 783464ebd5Sriastradh if (u_clip_tile(x, y, &w, &h, &pt->box)) 794a49301eSmrg return; 804a49301eSmrg 81cdc920a0Smrg util_copy_rect(dst, format, pt->stride, x, y, w, h, src, src_stride, 0, 0); 824a49301eSmrg} 834a49301eSmrg 844a49301eSmrg 854a49301eSmrg 864a49301eSmrg 874a49301eSmrg/** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */ 884a49301eSmrg#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) 894a49301eSmrg 904a49301eSmrg#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \ 914a49301eSmrg us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) ) 924a49301eSmrg 934a49301eSmrg 944a49301eSmrg 953464ebd5Sriastradh/*** PIPE_FORMAT_Z16_UNORM ***/ 964a49301eSmrg 974a49301eSmrg/** 983464ebd5Sriastradh * Return each Z value as four floats in [0,1]. 994a49301eSmrg */ 1004a49301eSmrgstatic void 1013464ebd5Sriastradhz16_get_tile_rgba(const ushort *src, 1023464ebd5Sriastradh unsigned w, unsigned h, 1033464ebd5Sriastradh float *p, 1043464ebd5Sriastradh unsigned dst_stride) 1054a49301eSmrg{ 1063464ebd5Sriastradh const float scale = 1.0f / 65535.0f; 1074a49301eSmrg unsigned i, j; 1084a49301eSmrg 1094a49301eSmrg for (i = 0; i < h; i++) { 1104a49301eSmrg float *pRow = p; 1114a49301eSmrg for (j = 0; j < w; j++, pRow += 4) { 1124a49301eSmrg pRow[0] = 1134a49301eSmrg pRow[1] = 1143464ebd5Sriastradh pRow[2] = 1153464ebd5Sriastradh pRow[3] = *src++ * scale; 1164a49301eSmrg } 1174a49301eSmrg p += dst_stride; 1184a49301eSmrg } 1194a49301eSmrg} 1204a49301eSmrg 1214a49301eSmrg 1224a49301eSmrg 1234a49301eSmrg 1243464ebd5Sriastradh/*** PIPE_FORMAT_Z32_UNORM ***/ 1254a49301eSmrg 1263464ebd5Sriastradh/** 1273464ebd5Sriastradh * Return each Z value as four floats in [0,1]. 1283464ebd5Sriastradh */ 1294a49301eSmrgstatic void 1303464ebd5Sriastradhz32_get_tile_rgba(const unsigned *src, 1313464ebd5Sriastradh unsigned w, unsigned h, 1323464ebd5Sriastradh float *p, 1333464ebd5Sriastradh unsigned dst_stride) 1344a49301eSmrg{ 1353464ebd5Sriastradh const double scale = 1.0 / (double) 0xffffffff; 1364a49301eSmrg unsigned i, j; 1374a49301eSmrg 1384a49301eSmrg for (i = 0; i < h; i++) { 1394a49301eSmrg float *pRow = p; 1403464ebd5Sriastradh for (j = 0; j < w; j++, pRow += 4) { 1414a49301eSmrg pRow[0] = 1424a49301eSmrg pRow[1] = 1433464ebd5Sriastradh pRow[2] = 1443464ebd5Sriastradh pRow[3] = (float) (*src++ * scale); 1454a49301eSmrg } 1464a49301eSmrg p += dst_stride; 1474a49301eSmrg } 1484a49301eSmrg} 1494a49301eSmrg 1504a49301eSmrg 151af69d88dSmrg/*** PIPE_FORMAT_Z24_UNORM_S8_UINT ***/ 1524a49301eSmrg 1533464ebd5Sriastradh/** 1543464ebd5Sriastradh * Return Z component as four float in [0,1]. Stencil part ignored. 1553464ebd5Sriastradh */ 1564a49301eSmrgstatic void 1573464ebd5Sriastradhs8z24_get_tile_rgba(const unsigned *src, 1583464ebd5Sriastradh unsigned w, unsigned h, 1593464ebd5Sriastradh float *p, 1603464ebd5Sriastradh unsigned dst_stride) 1614a49301eSmrg{ 1623464ebd5Sriastradh const double scale = 1.0 / ((1 << 24) - 1); 1634a49301eSmrg unsigned i, j; 1644a49301eSmrg 1654a49301eSmrg for (i = 0; i < h; i++) { 1664a49301eSmrg float *pRow = p; 1673464ebd5Sriastradh for (j = 0; j < w; j++, pRow += 4) { 1684a49301eSmrg pRow[0] = 1694a49301eSmrg pRow[1] = 1704a49301eSmrg pRow[2] = 1713464ebd5Sriastradh pRow[3] = (float) (scale * (*src++ & 0xffffff)); 1724a49301eSmrg } 1734a49301eSmrg p += dst_stride; 1744a49301eSmrg } 1754a49301eSmrg} 1764a49301eSmrg 1774a49301eSmrg 178af69d88dSmrg/*** PIPE_FORMAT_S8_UINT_Z24_UNORM ***/ 1794a49301eSmrg 1803464ebd5Sriastradh/** 1813464ebd5Sriastradh * Return Z component as four float in [0,1]. Stencil part ignored. 1823464ebd5Sriastradh */ 1834a49301eSmrgstatic void 1843464ebd5Sriastradhz24s8_get_tile_rgba(const unsigned *src, 1853464ebd5Sriastradh unsigned w, unsigned h, 1863464ebd5Sriastradh float *p, 1873464ebd5Sriastradh unsigned dst_stride) 1884a49301eSmrg{ 1893464ebd5Sriastradh const double scale = 1.0 / ((1 << 24) - 1); 1904a49301eSmrg unsigned i, j; 1914a49301eSmrg 1924a49301eSmrg for (i = 0; i < h; i++) { 1934a49301eSmrg float *pRow = p; 1944a49301eSmrg for (j = 0; j < w; j++, pRow += 4) { 1954a49301eSmrg pRow[0] = 1964a49301eSmrg pRow[1] = 1973464ebd5Sriastradh pRow[2] = 1983464ebd5Sriastradh pRow[3] = (float) (scale * (*src++ >> 8)); 1994a49301eSmrg } 2004a49301eSmrg p += dst_stride; 2014a49301eSmrg } 2024a49301eSmrg} 2034a49301eSmrg 204af69d88dSmrg/*** PIPE_FORMAT_S8X24_UINT ***/ 2054a49301eSmrg 2064a49301eSmrg/** 2073464ebd5Sriastradh * Return S component as four uint32_t in [0..255]. Z part ignored. 2084a49301eSmrg */ 2094a49301eSmrgstatic void 2103464ebd5Sriastradhs8x24_get_tile_rgba(const unsigned *src, 2113464ebd5Sriastradh unsigned w, unsigned h, 2123464ebd5Sriastradh float *p, 2133464ebd5Sriastradh unsigned dst_stride) 2144a49301eSmrg{ 2154a49301eSmrg unsigned i, j; 2164a49301eSmrg 2174a49301eSmrg for (i = 0; i < h; i++) { 21801e04c3fSmrg uint32_t *pRow = (uint32_t *)p; 2193464ebd5Sriastradh 2204a49301eSmrg for (j = 0; j < w; j++, pRow += 4) { 2214a49301eSmrg pRow[0] = 2224a49301eSmrg pRow[1] = 2234a49301eSmrg pRow[2] = 22401e04c3fSmrg pRow[3] = ((*src++ >> 24) & 0xff); 2254a49301eSmrg } 2263464ebd5Sriastradh 2274a49301eSmrg p += dst_stride; 2284a49301eSmrg } 2294a49301eSmrg} 2304a49301eSmrg 231af69d88dSmrg/*** PIPE_FORMAT_X24S8_UINT ***/ 2324a49301eSmrg 2334a49301eSmrg/** 2343464ebd5Sriastradh * Return S component as four uint32_t in [0..255]. Z part ignored. 2354a49301eSmrg */ 2364a49301eSmrgstatic void 2373464ebd5Sriastradhx24s8_get_tile_rgba(const unsigned *src, 2384a49301eSmrg unsigned w, unsigned h, 2394a49301eSmrg float *p, 2404a49301eSmrg unsigned dst_stride) 2414a49301eSmrg{ 2424a49301eSmrg unsigned i, j; 2434a49301eSmrg 2444a49301eSmrg for (i = 0; i < h; i++) { 24501e04c3fSmrg uint32_t *pRow = (uint32_t *)p; 2464a49301eSmrg for (j = 0; j < w; j++, pRow += 4) { 2474a49301eSmrg pRow[0] = 2484a49301eSmrg pRow[1] = 2494a49301eSmrg pRow[2] = 25001e04c3fSmrg pRow[3] = (*src++ & 0xff); 2514a49301eSmrg } 2524a49301eSmrg p += dst_stride; 2534a49301eSmrg } 2544a49301eSmrg} 2554a49301eSmrg 2564a49301eSmrg 2574a49301eSmrg/** 2583464ebd5Sriastradh * Return S component as four uint32_t in [0..255]. Z part ignored. 2594a49301eSmrg */ 2604a49301eSmrgstatic void 2613464ebd5Sriastradhs8_get_tile_rgba(const unsigned char *src, 2623464ebd5Sriastradh unsigned w, unsigned h, 2633464ebd5Sriastradh float *p, 2643464ebd5Sriastradh unsigned dst_stride) 2654a49301eSmrg{ 2664a49301eSmrg unsigned i, j; 2674a49301eSmrg 2684a49301eSmrg for (i = 0; i < h; i++) { 26901e04c3fSmrg uint32_t *pRow = (uint32_t *)p; 2704a49301eSmrg for (j = 0; j < w; j++, pRow += 4) { 2714a49301eSmrg pRow[0] = 2724a49301eSmrg pRow[1] = 2734a49301eSmrg pRow[2] = 27401e04c3fSmrg pRow[3] = (*src++ & 0xff); 2754a49301eSmrg } 2764a49301eSmrg p += dst_stride; 2774a49301eSmrg } 2784a49301eSmrg} 2794a49301eSmrg 2804a49301eSmrg/*** PIPE_FORMAT_Z32_FLOAT ***/ 2814a49301eSmrg 2824a49301eSmrg/** 2834a49301eSmrg * Return each Z value as four floats in [0,1]. 2844a49301eSmrg */ 2854a49301eSmrgstatic void 2864a49301eSmrgz32f_get_tile_rgba(const float *src, 2874a49301eSmrg unsigned w, unsigned h, 2884a49301eSmrg float *p, 2894a49301eSmrg unsigned dst_stride) 2904a49301eSmrg{ 2914a49301eSmrg unsigned i, j; 2924a49301eSmrg 2934a49301eSmrg for (i = 0; i < h; i++) { 2944a49301eSmrg float *pRow = p; 2954a49301eSmrg for (j = 0; j < w; j++, pRow += 4) { 2964a49301eSmrg pRow[0] = 2974a49301eSmrg pRow[1] = 2984a49301eSmrg pRow[2] = 2994a49301eSmrg pRow[3] = *src++; 3004a49301eSmrg } 3014a49301eSmrg p += dst_stride; 3024a49301eSmrg } 3034a49301eSmrg} 3044a49301eSmrg 305af69d88dSmrg/*** PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ***/ 306af69d88dSmrg 307af69d88dSmrg/** 308af69d88dSmrg * Return each Z value as four floats in [0,1]. 309af69d88dSmrg */ 310af69d88dSmrgstatic void 311af69d88dSmrgz32f_x24s8_get_tile_rgba(const float *src, 312af69d88dSmrg unsigned w, unsigned h, 313af69d88dSmrg float *p, 314af69d88dSmrg unsigned dst_stride) 315af69d88dSmrg{ 316af69d88dSmrg unsigned i, j; 317af69d88dSmrg 318af69d88dSmrg for (i = 0; i < h; i++) { 319af69d88dSmrg float *pRow = p; 320af69d88dSmrg for (j = 0; j < w; j++, pRow += 4) { 321af69d88dSmrg pRow[0] = 322af69d88dSmrg pRow[1] = 323af69d88dSmrg pRow[2] = 324af69d88dSmrg pRow[3] = *src; 325af69d88dSmrg src += 2; 326af69d88dSmrg } 327af69d88dSmrg p += dst_stride; 328af69d88dSmrg } 329af69d88dSmrg} 330af69d88dSmrg 331af69d88dSmrg/*** PIPE_FORMAT_X32_S8X24_UINT ***/ 332af69d88dSmrg 333af69d88dSmrg/** 334af69d88dSmrg * Return S component as four uint32_t in [0..255]. Z part ignored. 335af69d88dSmrg */ 336af69d88dSmrgstatic void 337af69d88dSmrgx32_s8_get_tile_rgba(const unsigned *src, 338af69d88dSmrg unsigned w, unsigned h, 339af69d88dSmrg float *p, 340af69d88dSmrg unsigned dst_stride) 341af69d88dSmrg{ 342af69d88dSmrg unsigned i, j; 343af69d88dSmrg 344af69d88dSmrg for (i = 0; i < h; i++) { 34501e04c3fSmrg uint32_t *pRow = (uint32_t *)p; 346af69d88dSmrg for (j = 0; j < w; j++, pRow += 4) { 347af69d88dSmrg src++; 348af69d88dSmrg pRow[0] = 349af69d88dSmrg pRow[1] = 350af69d88dSmrg pRow[2] = 35101e04c3fSmrg pRow[3] = (*src++ & 0xff); 352af69d88dSmrg } 353af69d88dSmrg p += dst_stride; 354af69d88dSmrg } 355af69d88dSmrg} 3564a49301eSmrg 3574a49301eSmrgvoid 3587ec681f3Smrgpipe_put_tile_rgba(struct pipe_transfer *pt, 3597ec681f3Smrg void *dst, 3607ec681f3Smrg uint x, uint y, uint w, uint h, 3617ec681f3Smrg enum pipe_format format, const void *p) 3624a49301eSmrg{ 3637ec681f3Smrg unsigned src_stride = w * 4; 3644a49301eSmrg 3657ec681f3Smrg if (u_clip_tile(x, y, &w, &h, &pt->box)) 3667ec681f3Smrg return; 367af69d88dSmrg 3687ec681f3Smrg /* While we do generate RGBA tiles for z/s for softpipe's texture fetch 3697ec681f3Smrg * path, we never have to store from "RGBA" to Z/S. 3707ec681f3Smrg */ 3717ec681f3Smrg if (util_format_is_depth_or_stencil(format)) 3727ec681f3Smrg return; 3737ec681f3Smrg 3747ec681f3Smrg util_format_write_4(format, 3757ec681f3Smrg p, src_stride * sizeof(float), 3767ec681f3Smrg dst, pt->stride, 3777ec681f3Smrg x, y, w, h); 378af69d88dSmrg} 3794a49301eSmrg 3804a49301eSmrgvoid 381af69d88dSmrgpipe_get_tile_rgba(struct pipe_transfer *pt, 382af69d88dSmrg const void *src, 3834a49301eSmrg uint x, uint y, uint w, uint h, 3847ec681f3Smrg enum pipe_format format, 3857ec681f3Smrg void *dst) 3864a49301eSmrg{ 3874a49301eSmrg unsigned dst_stride = w * 4; 3884a49301eSmrg void *packed; 3894a49301eSmrg 3903464ebd5Sriastradh if (u_clip_tile(x, y, &w, &h, &pt->box)) { 3914a49301eSmrg return; 3923464ebd5Sriastradh } 3934a49301eSmrg 394cdc920a0Smrg packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); 3953464ebd5Sriastradh if (!packed) { 3964a49301eSmrg return; 3973464ebd5Sriastradh } 3984a49301eSmrg 3993464ebd5Sriastradh if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) { 4004a49301eSmrg assert((x & 1) == 0); 4013464ebd5Sriastradh } 4024a49301eSmrg 403af69d88dSmrg pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0); 4044a49301eSmrg 405cdc920a0Smrg switch (format) { 4064a49301eSmrg case PIPE_FORMAT_Z16_UNORM: 4077ec681f3Smrg z16_get_tile_rgba((ushort *) packed, w, h, dst, dst_stride); 4084a49301eSmrg break; 4094a49301eSmrg case PIPE_FORMAT_Z32_UNORM: 4107ec681f3Smrg z32_get_tile_rgba((unsigned *) packed, w, h, dst, dst_stride); 4114a49301eSmrg break; 412af69d88dSmrg case PIPE_FORMAT_Z24_UNORM_S8_UINT: 4134a49301eSmrg case PIPE_FORMAT_Z24X8_UNORM: 4147ec681f3Smrg s8z24_get_tile_rgba((unsigned *) packed, w, h, dst, dst_stride); 415cdc920a0Smrg break; 4167ec681f3Smrg case PIPE_FORMAT_S8_UINT: 4177ec681f3Smrg s8_get_tile_rgba((unsigned char *) packed, w, h, dst, dst_stride); 4184a49301eSmrg break; 4197ec681f3Smrg case PIPE_FORMAT_X24S8_UINT: 4207ec681f3Smrg s8x24_get_tile_rgba((unsigned *) packed, w, h, dst, dst_stride); 4214a49301eSmrg break; 422af69d88dSmrg case PIPE_FORMAT_S8_UINT_Z24_UNORM: 423cdc920a0Smrg case PIPE_FORMAT_X8Z24_UNORM: 4247ec681f3Smrg z24s8_get_tile_rgba((unsigned *) packed, w, h, dst, dst_stride); 4254a49301eSmrg break; 4267ec681f3Smrg case PIPE_FORMAT_S8X24_UINT: 4277ec681f3Smrg x24s8_get_tile_rgba((unsigned *) packed, w, h, dst, dst_stride); 4284a49301eSmrg break; 429af69d88dSmrg case PIPE_FORMAT_Z32_FLOAT: 4307ec681f3Smrg z32f_get_tile_rgba((float *) packed, w, h, dst, dst_stride); 431af69d88dSmrg break; 432af69d88dSmrg case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 4337ec681f3Smrg z32f_x24s8_get_tile_rgba((float *) packed, w, h, dst, dst_stride); 434af69d88dSmrg break; 4357ec681f3Smrg case PIPE_FORMAT_X32_S8X24_UINT: 4367ec681f3Smrg x32_s8_get_tile_rgba((unsigned *) packed, w, h, dst, dst_stride); 437af69d88dSmrg break; 4384a49301eSmrg default: 4397ec681f3Smrg util_format_read_4(format, 4407ec681f3Smrg dst, dst_stride * sizeof(float), 4417ec681f3Smrg packed, util_format_get_stride(format, w), 4427ec681f3Smrg 0, 0, w, h); 443af69d88dSmrg } 444af69d88dSmrg 445af69d88dSmrg FREE(packed); 446af69d88dSmrg} 447