1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2007 VMware, Inc. 4848b8605Smrg * All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the 8848b8605Smrg * "Software"), to deal in the Software without restriction, including 9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 12848b8605Smrg * the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice (including the 15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 16848b8605Smrg * of the Software. 17848b8605Smrg * 18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25848b8605Smrg * 26848b8605Smrg **************************************************************************/ 27848b8605Smrg 28848b8605Smrg/** 29848b8605Smrg * RGBA/float tile get/put functions. 30848b8605Smrg * Usable both by drivers and state trackers. 31848b8605Smrg */ 32848b8605Smrg 33848b8605Smrg 34848b8605Smrg#include "pipe/p_defines.h" 35848b8605Smrg#include "util/u_inlines.h" 36848b8605Smrg 37848b8605Smrg#include "util/u_format.h" 38b8e80941Smrg#include "util/u_format_bptc.h" 39848b8605Smrg#include "util/u_math.h" 40848b8605Smrg#include "util/u_memory.h" 41848b8605Smrg#include "util/u_surface.h" 42848b8605Smrg#include "util/u_tile.h" 43848b8605Smrg 44848b8605Smrg 45848b8605Smrg/** 46848b8605Smrg * Move raw block of pixels from transfer object to user memory. 47848b8605Smrg */ 48848b8605Smrgvoid 49848b8605Smrgpipe_get_tile_raw(struct pipe_transfer *pt, 50848b8605Smrg const void *src, 51848b8605Smrg uint x, uint y, uint w, uint h, 52848b8605Smrg void *dst, int dst_stride) 53848b8605Smrg{ 54848b8605Smrg if (dst_stride == 0) 55848b8605Smrg dst_stride = util_format_get_stride(pt->resource->format, w); 56848b8605Smrg 57848b8605Smrg if (u_clip_tile(x, y, &w, &h, &pt->box)) 58848b8605Smrg return; 59848b8605Smrg 60848b8605Smrg util_copy_rect(dst, pt->resource->format, dst_stride, 0, 0, w, h, src, pt->stride, x, y); 61848b8605Smrg} 62848b8605Smrg 63848b8605Smrg 64848b8605Smrg/** 65848b8605Smrg * Move raw block of pixels from user memory to transfer object. 66848b8605Smrg */ 67848b8605Smrgvoid 68848b8605Smrgpipe_put_tile_raw(struct pipe_transfer *pt, 69848b8605Smrg void *dst, 70848b8605Smrg uint x, uint y, uint w, uint h, 71848b8605Smrg const void *src, int src_stride) 72848b8605Smrg{ 73848b8605Smrg enum pipe_format format = pt->resource->format; 74848b8605Smrg 75848b8605Smrg if (src_stride == 0) 76848b8605Smrg src_stride = util_format_get_stride(format, w); 77848b8605Smrg 78848b8605Smrg if (u_clip_tile(x, y, &w, &h, &pt->box)) 79848b8605Smrg return; 80848b8605Smrg 81848b8605Smrg util_copy_rect(dst, format, pt->stride, x, y, w, h, src, src_stride, 0, 0); 82848b8605Smrg} 83848b8605Smrg 84848b8605Smrg 85848b8605Smrg 86848b8605Smrg 87848b8605Smrg/** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */ 88848b8605Smrg#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) 89848b8605Smrg 90848b8605Smrg#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \ 91848b8605Smrg us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) ) 92848b8605Smrg 93848b8605Smrg 94848b8605Smrg 95848b8605Smrg/*** PIPE_FORMAT_Z16_UNORM ***/ 96848b8605Smrg 97848b8605Smrg/** 98848b8605Smrg * Return each Z value as four floats in [0,1]. 99848b8605Smrg */ 100848b8605Smrgstatic void 101848b8605Smrgz16_get_tile_rgba(const ushort *src, 102848b8605Smrg unsigned w, unsigned h, 103848b8605Smrg float *p, 104848b8605Smrg unsigned dst_stride) 105848b8605Smrg{ 106848b8605Smrg const float scale = 1.0f / 65535.0f; 107848b8605Smrg unsigned i, j; 108848b8605Smrg 109848b8605Smrg for (i = 0; i < h; i++) { 110848b8605Smrg float *pRow = p; 111848b8605Smrg for (j = 0; j < w; j++, pRow += 4) { 112848b8605Smrg pRow[0] = 113848b8605Smrg pRow[1] = 114848b8605Smrg pRow[2] = 115848b8605Smrg pRow[3] = *src++ * scale; 116848b8605Smrg } 117848b8605Smrg p += dst_stride; 118848b8605Smrg } 119848b8605Smrg} 120848b8605Smrg 121848b8605Smrg 122848b8605Smrg 123848b8605Smrg 124848b8605Smrg/*** PIPE_FORMAT_Z32_UNORM ***/ 125848b8605Smrg 126848b8605Smrg/** 127848b8605Smrg * Return each Z value as four floats in [0,1]. 128848b8605Smrg */ 129848b8605Smrgstatic void 130848b8605Smrgz32_get_tile_rgba(const unsigned *src, 131848b8605Smrg unsigned w, unsigned h, 132848b8605Smrg float *p, 133848b8605Smrg unsigned dst_stride) 134848b8605Smrg{ 135848b8605Smrg const double scale = 1.0 / (double) 0xffffffff; 136848b8605Smrg unsigned i, j; 137848b8605Smrg 138848b8605Smrg for (i = 0; i < h; i++) { 139848b8605Smrg float *pRow = p; 140848b8605Smrg for (j = 0; j < w; j++, pRow += 4) { 141848b8605Smrg pRow[0] = 142848b8605Smrg pRow[1] = 143848b8605Smrg pRow[2] = 144848b8605Smrg pRow[3] = (float) (*src++ * scale); 145848b8605Smrg } 146848b8605Smrg p += dst_stride; 147848b8605Smrg } 148848b8605Smrg} 149848b8605Smrg 150848b8605Smrg 151848b8605Smrg/*** PIPE_FORMAT_Z24_UNORM_S8_UINT ***/ 152848b8605Smrg 153848b8605Smrg/** 154848b8605Smrg * Return Z component as four float in [0,1]. Stencil part ignored. 155848b8605Smrg */ 156848b8605Smrgstatic void 157848b8605Smrgs8z24_get_tile_rgba(const unsigned *src, 158848b8605Smrg unsigned w, unsigned h, 159848b8605Smrg float *p, 160848b8605Smrg unsigned dst_stride) 161848b8605Smrg{ 162848b8605Smrg const double scale = 1.0 / ((1 << 24) - 1); 163848b8605Smrg unsigned i, j; 164848b8605Smrg 165848b8605Smrg for (i = 0; i < h; i++) { 166848b8605Smrg float *pRow = p; 167848b8605Smrg for (j = 0; j < w; j++, pRow += 4) { 168848b8605Smrg pRow[0] = 169848b8605Smrg pRow[1] = 170848b8605Smrg pRow[2] = 171848b8605Smrg pRow[3] = (float) (scale * (*src++ & 0xffffff)); 172848b8605Smrg } 173848b8605Smrg p += dst_stride; 174848b8605Smrg } 175848b8605Smrg} 176848b8605Smrg 177848b8605Smrg 178848b8605Smrg/*** PIPE_FORMAT_S8_UINT_Z24_UNORM ***/ 179848b8605Smrg 180848b8605Smrg/** 181848b8605Smrg * Return Z component as four float in [0,1]. Stencil part ignored. 182848b8605Smrg */ 183848b8605Smrgstatic void 184848b8605Smrgz24s8_get_tile_rgba(const unsigned *src, 185848b8605Smrg unsigned w, unsigned h, 186848b8605Smrg float *p, 187848b8605Smrg unsigned dst_stride) 188848b8605Smrg{ 189848b8605Smrg const double scale = 1.0 / ((1 << 24) - 1); 190848b8605Smrg unsigned i, j; 191848b8605Smrg 192848b8605Smrg for (i = 0; i < h; i++) { 193848b8605Smrg float *pRow = p; 194848b8605Smrg for (j = 0; j < w; j++, pRow += 4) { 195848b8605Smrg pRow[0] = 196848b8605Smrg pRow[1] = 197848b8605Smrg pRow[2] = 198848b8605Smrg pRow[3] = (float) (scale * (*src++ >> 8)); 199848b8605Smrg } 200848b8605Smrg p += dst_stride; 201848b8605Smrg } 202848b8605Smrg} 203848b8605Smrg 204848b8605Smrg/*** PIPE_FORMAT_S8X24_UINT ***/ 205848b8605Smrg 206848b8605Smrg/** 207848b8605Smrg * Return S component as four uint32_t in [0..255]. Z part ignored. 208848b8605Smrg */ 209848b8605Smrgstatic void 210848b8605Smrgs8x24_get_tile_rgba(const unsigned *src, 211848b8605Smrg unsigned w, unsigned h, 212848b8605Smrg float *p, 213848b8605Smrg unsigned dst_stride) 214848b8605Smrg{ 215848b8605Smrg unsigned i, j; 216848b8605Smrg 217848b8605Smrg for (i = 0; i < h; i++) { 218b8e80941Smrg uint32_t *pRow = (uint32_t *)p; 219848b8605Smrg 220848b8605Smrg for (j = 0; j < w; j++, pRow += 4) { 221848b8605Smrg pRow[0] = 222848b8605Smrg pRow[1] = 223848b8605Smrg pRow[2] = 224b8e80941Smrg pRow[3] = ((*src++ >> 24) & 0xff); 225848b8605Smrg } 226848b8605Smrg 227848b8605Smrg p += dst_stride; 228848b8605Smrg } 229848b8605Smrg} 230848b8605Smrg 231848b8605Smrg/*** PIPE_FORMAT_X24S8_UINT ***/ 232848b8605Smrg 233848b8605Smrg/** 234848b8605Smrg * Return S component as four uint32_t in [0..255]. Z part ignored. 235848b8605Smrg */ 236848b8605Smrgstatic void 237848b8605Smrgx24s8_get_tile_rgba(const unsigned *src, 238848b8605Smrg unsigned w, unsigned h, 239848b8605Smrg float *p, 240848b8605Smrg unsigned dst_stride) 241848b8605Smrg{ 242848b8605Smrg unsigned i, j; 243848b8605Smrg 244848b8605Smrg for (i = 0; i < h; i++) { 245b8e80941Smrg uint32_t *pRow = (uint32_t *)p; 246848b8605Smrg for (j = 0; j < w; j++, pRow += 4) { 247848b8605Smrg pRow[0] = 248848b8605Smrg pRow[1] = 249848b8605Smrg pRow[2] = 250b8e80941Smrg pRow[3] = (*src++ & 0xff); 251848b8605Smrg } 252848b8605Smrg p += dst_stride; 253848b8605Smrg } 254848b8605Smrg} 255848b8605Smrg 256848b8605Smrg 257848b8605Smrg/** 258848b8605Smrg * Return S component as four uint32_t in [0..255]. Z part ignored. 259848b8605Smrg */ 260848b8605Smrgstatic void 261848b8605Smrgs8_get_tile_rgba(const unsigned char *src, 262848b8605Smrg unsigned w, unsigned h, 263848b8605Smrg float *p, 264848b8605Smrg unsigned dst_stride) 265848b8605Smrg{ 266848b8605Smrg unsigned i, j; 267848b8605Smrg 268848b8605Smrg for (i = 0; i < h; i++) { 269b8e80941Smrg uint32_t *pRow = (uint32_t *)p; 270848b8605Smrg for (j = 0; j < w; j++, pRow += 4) { 271848b8605Smrg pRow[0] = 272848b8605Smrg pRow[1] = 273848b8605Smrg pRow[2] = 274b8e80941Smrg pRow[3] = (*src++ & 0xff); 275848b8605Smrg } 276848b8605Smrg p += dst_stride; 277848b8605Smrg } 278848b8605Smrg} 279848b8605Smrg 280848b8605Smrg/*** PIPE_FORMAT_Z32_FLOAT ***/ 281848b8605Smrg 282848b8605Smrg/** 283848b8605Smrg * Return each Z value as four floats in [0,1]. 284848b8605Smrg */ 285848b8605Smrgstatic void 286848b8605Smrgz32f_get_tile_rgba(const float *src, 287848b8605Smrg unsigned w, unsigned h, 288848b8605Smrg float *p, 289848b8605Smrg unsigned dst_stride) 290848b8605Smrg{ 291848b8605Smrg unsigned i, j; 292848b8605Smrg 293848b8605Smrg for (i = 0; i < h; i++) { 294848b8605Smrg float *pRow = p; 295848b8605Smrg for (j = 0; j < w; j++, pRow += 4) { 296848b8605Smrg pRow[0] = 297848b8605Smrg pRow[1] = 298848b8605Smrg pRow[2] = 299848b8605Smrg pRow[3] = *src++; 300848b8605Smrg } 301848b8605Smrg p += dst_stride; 302848b8605Smrg } 303848b8605Smrg} 304848b8605Smrg 305848b8605Smrg/*** PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ***/ 306848b8605Smrg 307848b8605Smrg/** 308848b8605Smrg * Return each Z value as four floats in [0,1]. 309848b8605Smrg */ 310848b8605Smrgstatic void 311848b8605Smrgz32f_x24s8_get_tile_rgba(const float *src, 312848b8605Smrg unsigned w, unsigned h, 313848b8605Smrg float *p, 314848b8605Smrg unsigned dst_stride) 315848b8605Smrg{ 316848b8605Smrg unsigned i, j; 317848b8605Smrg 318848b8605Smrg for (i = 0; i < h; i++) { 319848b8605Smrg float *pRow = p; 320848b8605Smrg for (j = 0; j < w; j++, pRow += 4) { 321848b8605Smrg pRow[0] = 322848b8605Smrg pRow[1] = 323848b8605Smrg pRow[2] = 324848b8605Smrg pRow[3] = *src; 325848b8605Smrg src += 2; 326848b8605Smrg } 327848b8605Smrg p += dst_stride; 328848b8605Smrg } 329848b8605Smrg} 330848b8605Smrg 331848b8605Smrg/*** PIPE_FORMAT_X32_S8X24_UINT ***/ 332848b8605Smrg 333848b8605Smrg/** 334848b8605Smrg * Return S component as four uint32_t in [0..255]. Z part ignored. 335848b8605Smrg */ 336848b8605Smrgstatic void 337848b8605Smrgx32_s8_get_tile_rgba(const unsigned *src, 338848b8605Smrg unsigned w, unsigned h, 339848b8605Smrg float *p, 340848b8605Smrg unsigned dst_stride) 341848b8605Smrg{ 342848b8605Smrg unsigned i, j; 343848b8605Smrg 344848b8605Smrg for (i = 0; i < h; i++) { 345b8e80941Smrg uint32_t *pRow = (uint32_t *)p; 346848b8605Smrg for (j = 0; j < w; j++, pRow += 4) { 347848b8605Smrg src++; 348848b8605Smrg pRow[0] = 349848b8605Smrg pRow[1] = 350848b8605Smrg pRow[2] = 351b8e80941Smrg pRow[3] = (*src++ & 0xff); 352848b8605Smrg } 353848b8605Smrg p += dst_stride; 354848b8605Smrg } 355848b8605Smrg} 356848b8605Smrg 357848b8605Smrgvoid 358848b8605Smrgpipe_tile_raw_to_rgba(enum pipe_format format, 359848b8605Smrg const void *src, 360848b8605Smrg uint w, uint h, 361848b8605Smrg float *dst, unsigned dst_stride) 362848b8605Smrg{ 363848b8605Smrg switch (format) { 364848b8605Smrg case PIPE_FORMAT_Z16_UNORM: 365848b8605Smrg z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); 366848b8605Smrg break; 367848b8605Smrg case PIPE_FORMAT_Z32_UNORM: 368848b8605Smrg z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 369848b8605Smrg break; 370848b8605Smrg case PIPE_FORMAT_Z24_UNORM_S8_UINT: 371848b8605Smrg case PIPE_FORMAT_Z24X8_UNORM: 372848b8605Smrg s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 373848b8605Smrg break; 374848b8605Smrg case PIPE_FORMAT_S8_UINT: 375848b8605Smrg s8_get_tile_rgba((unsigned char *) src, w, h, dst, dst_stride); 376848b8605Smrg break; 377848b8605Smrg case PIPE_FORMAT_X24S8_UINT: 378848b8605Smrg s8x24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 379848b8605Smrg break; 380848b8605Smrg case PIPE_FORMAT_S8_UINT_Z24_UNORM: 381848b8605Smrg case PIPE_FORMAT_X8Z24_UNORM: 382848b8605Smrg z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 383848b8605Smrg break; 384848b8605Smrg case PIPE_FORMAT_S8X24_UINT: 385848b8605Smrg x24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 386848b8605Smrg break; 387848b8605Smrg case PIPE_FORMAT_Z32_FLOAT: 388848b8605Smrg z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride); 389848b8605Smrg break; 390848b8605Smrg case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 391848b8605Smrg z32f_x24s8_get_tile_rgba((float *) src, w, h, dst, dst_stride); 392848b8605Smrg break; 393848b8605Smrg case PIPE_FORMAT_X32_S8X24_UINT: 394848b8605Smrg x32_s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 395848b8605Smrg break; 396848b8605Smrg default: 397848b8605Smrg util_format_read_4f(format, 398848b8605Smrg dst, dst_stride * sizeof(float), 399848b8605Smrg src, util_format_get_stride(format, w), 400848b8605Smrg 0, 0, w, h); 401848b8605Smrg } 402848b8605Smrg} 403848b8605Smrg 404848b8605Smrgvoid 405848b8605Smrgpipe_tile_raw_to_unsigned(enum pipe_format format, 406848b8605Smrg const void *src, 407848b8605Smrg uint w, uint h, 408848b8605Smrg unsigned *dst, unsigned dst_stride) 409848b8605Smrg{ 410848b8605Smrg util_format_read_4ui(format, 411848b8605Smrg dst, dst_stride * sizeof(float), 412848b8605Smrg src, util_format_get_stride(format, w), 413848b8605Smrg 0, 0, w, h); 414848b8605Smrg} 415848b8605Smrg 416848b8605Smrgvoid 417848b8605Smrgpipe_tile_raw_to_signed(enum pipe_format format, 418848b8605Smrg void *src, 419848b8605Smrg uint w, uint h, 420848b8605Smrg int *dst, unsigned dst_stride) 421848b8605Smrg{ 422848b8605Smrg util_format_read_4i(format, 423848b8605Smrg dst, dst_stride * sizeof(float), 424848b8605Smrg src, util_format_get_stride(format, w), 425848b8605Smrg 0, 0, w, h); 426848b8605Smrg} 427848b8605Smrg 428848b8605Smrgvoid 429848b8605Smrgpipe_get_tile_rgba(struct pipe_transfer *pt, 430848b8605Smrg const void *src, 431848b8605Smrg uint x, uint y, uint w, uint h, 432848b8605Smrg float *p) 433848b8605Smrg{ 434848b8605Smrg pipe_get_tile_rgba_format(pt, src, x, y, w, h, pt->resource->format, p); 435848b8605Smrg} 436848b8605Smrg 437848b8605Smrg 438848b8605Smrgvoid 439848b8605Smrgpipe_get_tile_rgba_format(struct pipe_transfer *pt, 440848b8605Smrg const void *src, 441848b8605Smrg uint x, uint y, uint w, uint h, 442848b8605Smrg enum pipe_format format, 443848b8605Smrg float *p) 444848b8605Smrg{ 445848b8605Smrg unsigned dst_stride = w * 4; 446848b8605Smrg void *packed; 447848b8605Smrg 448848b8605Smrg if (u_clip_tile(x, y, &w, &h, &pt->box)) { 449848b8605Smrg return; 450848b8605Smrg } 451848b8605Smrg 452848b8605Smrg packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); 453848b8605Smrg if (!packed) { 454848b8605Smrg return; 455848b8605Smrg } 456848b8605Smrg 457848b8605Smrg if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) { 458848b8605Smrg assert((x & 1) == 0); 459848b8605Smrg } 460848b8605Smrg 461848b8605Smrg pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0); 462848b8605Smrg 463848b8605Smrg pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride); 464848b8605Smrg 465848b8605Smrg FREE(packed); 466848b8605Smrg} 467848b8605Smrg 468848b8605Smrg 469848b8605Smrgvoid 470848b8605Smrgpipe_put_tile_rgba(struct pipe_transfer *pt, 471848b8605Smrg void *dst, 472848b8605Smrg uint x, uint y, uint w, uint h, 473848b8605Smrg const float *p) 474848b8605Smrg{ 475848b8605Smrg pipe_put_tile_rgba_format(pt, dst, x, y, w, h, pt->resource->format, p); 476848b8605Smrg} 477848b8605Smrg 478848b8605Smrg 479848b8605Smrgvoid 480848b8605Smrgpipe_put_tile_rgba_format(struct pipe_transfer *pt, 481848b8605Smrg void *dst, 482848b8605Smrg uint x, uint y, uint w, uint h, 483848b8605Smrg enum pipe_format format, 484848b8605Smrg const float *p) 485848b8605Smrg{ 486848b8605Smrg unsigned src_stride = w * 4; 487848b8605Smrg void *packed; 488848b8605Smrg 489848b8605Smrg if (u_clip_tile(x, y, &w, &h, &pt->box)) 490848b8605Smrg return; 491848b8605Smrg 492848b8605Smrg packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); 493848b8605Smrg 494848b8605Smrg if (!packed) 495848b8605Smrg return; 496848b8605Smrg 497848b8605Smrg switch (format) { 498848b8605Smrg case PIPE_FORMAT_Z16_UNORM: 499848b8605Smrg /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ 500848b8605Smrg break; 501848b8605Smrg case PIPE_FORMAT_Z32_UNORM: 502848b8605Smrg /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ 503848b8605Smrg break; 504848b8605Smrg case PIPE_FORMAT_Z24_UNORM_S8_UINT: 505848b8605Smrg case PIPE_FORMAT_Z24X8_UNORM: 506848b8605Smrg /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ 507848b8605Smrg break; 508848b8605Smrg case PIPE_FORMAT_S8_UINT_Z24_UNORM: 509848b8605Smrg case PIPE_FORMAT_X8Z24_UNORM: 510848b8605Smrg /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ 511848b8605Smrg break; 512848b8605Smrg case PIPE_FORMAT_Z32_FLOAT: 513848b8605Smrg /*z32f_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ 514848b8605Smrg break; 515848b8605Smrg case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 516848b8605Smrg /*z32f_s8x24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ 517848b8605Smrg break; 518848b8605Smrg default: 519848b8605Smrg util_format_write_4f(format, 520848b8605Smrg p, src_stride * sizeof(float), 521848b8605Smrg packed, util_format_get_stride(format, w), 522848b8605Smrg 0, 0, w, h); 523848b8605Smrg } 524848b8605Smrg 525848b8605Smrg pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0); 526848b8605Smrg 527848b8605Smrg FREE(packed); 528848b8605Smrg} 529848b8605Smrg 530848b8605Smrgvoid 531848b8605Smrgpipe_put_tile_i_format(struct pipe_transfer *pt, 532848b8605Smrg void *dst, 533848b8605Smrg uint x, uint y, uint w, uint h, 534848b8605Smrg enum pipe_format format, 535848b8605Smrg const int *p) 536848b8605Smrg{ 537848b8605Smrg unsigned src_stride = w * 4; 538848b8605Smrg void *packed; 539848b8605Smrg 540848b8605Smrg if (u_clip_tile(x, y, &w, &h, &pt->box)) 541848b8605Smrg return; 542848b8605Smrg 543848b8605Smrg packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); 544848b8605Smrg 545848b8605Smrg if (!packed) 546848b8605Smrg return; 547848b8605Smrg 548848b8605Smrg util_format_write_4i(format, 549848b8605Smrg p, src_stride * sizeof(float), 550848b8605Smrg packed, util_format_get_stride(format, w), 551848b8605Smrg 0, 0, w, h); 552848b8605Smrg 553848b8605Smrg pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0); 554848b8605Smrg 555848b8605Smrg FREE(packed); 556848b8605Smrg} 557848b8605Smrg 558848b8605Smrgvoid 559848b8605Smrgpipe_put_tile_ui_format(struct pipe_transfer *pt, 560848b8605Smrg void *dst, 561848b8605Smrg uint x, uint y, uint w, uint h, 562848b8605Smrg enum pipe_format format, 563848b8605Smrg const unsigned int *p) 564848b8605Smrg{ 565848b8605Smrg unsigned src_stride = w * 4; 566848b8605Smrg void *packed; 567848b8605Smrg 568848b8605Smrg if (u_clip_tile(x, y, &w, &h, &pt->box)) 569848b8605Smrg return; 570848b8605Smrg 571848b8605Smrg packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); 572848b8605Smrg 573848b8605Smrg if (!packed) 574848b8605Smrg return; 575848b8605Smrg 576848b8605Smrg util_format_write_4ui(format, 577848b8605Smrg p, src_stride * sizeof(float), 578848b8605Smrg packed, util_format_get_stride(format, w), 579848b8605Smrg 0, 0, w, h); 580848b8605Smrg 581848b8605Smrg pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0); 582848b8605Smrg 583848b8605Smrg FREE(packed); 584848b8605Smrg} 585848b8605Smrg 586848b8605Smrg/** 587848b8605Smrg * Get a block of Z values, converted to 32-bit range. 588848b8605Smrg */ 589848b8605Smrgvoid 590848b8605Smrgpipe_get_tile_z(struct pipe_transfer *pt, 591848b8605Smrg const void *src, 592848b8605Smrg uint x, uint y, uint w, uint h, 593848b8605Smrg uint *z) 594848b8605Smrg{ 595848b8605Smrg const uint dstStride = w; 596848b8605Smrg const ubyte *map = src; 597848b8605Smrg uint *pDest = z; 598848b8605Smrg uint i, j; 599848b8605Smrg enum pipe_format format = pt->resource->format; 600848b8605Smrg 601848b8605Smrg if (u_clip_tile(x, y, &w, &h, &pt->box)) 602848b8605Smrg return; 603848b8605Smrg 604848b8605Smrg switch (format) { 605848b8605Smrg case PIPE_FORMAT_Z32_UNORM: 606848b8605Smrg { 607848b8605Smrg const uint *ptrc 608848b8605Smrg = (const uint *)(map + y * pt->stride + x*4); 609848b8605Smrg for (i = 0; i < h; i++) { 610848b8605Smrg memcpy(pDest, ptrc, 4 * w); 611848b8605Smrg pDest += dstStride; 612848b8605Smrg ptrc += pt->stride/4; 613848b8605Smrg } 614848b8605Smrg } 615848b8605Smrg break; 616848b8605Smrg case PIPE_FORMAT_Z24_UNORM_S8_UINT: 617848b8605Smrg case PIPE_FORMAT_Z24X8_UNORM: 618848b8605Smrg { 619848b8605Smrg const uint *ptrc 620848b8605Smrg = (const uint *)(map + y * pt->stride + x*4); 621848b8605Smrg for (i = 0; i < h; i++) { 622848b8605Smrg for (j = 0; j < w; j++) { 623848b8605Smrg /* convert 24-bit Z to 32-bit Z */ 624848b8605Smrg pDest[j] = (ptrc[j] << 8) | ((ptrc[j] >> 16) & 0xff); 625848b8605Smrg } 626848b8605Smrg pDest += dstStride; 627848b8605Smrg ptrc += pt->stride/4; 628848b8605Smrg } 629848b8605Smrg } 630848b8605Smrg break; 631848b8605Smrg case PIPE_FORMAT_S8_UINT_Z24_UNORM: 632848b8605Smrg case PIPE_FORMAT_X8Z24_UNORM: 633848b8605Smrg { 634848b8605Smrg const uint *ptrc 635848b8605Smrg = (const uint *)(map + y * pt->stride + x*4); 636848b8605Smrg for (i = 0; i < h; i++) { 637848b8605Smrg for (j = 0; j < w; j++) { 638848b8605Smrg /* convert 24-bit Z to 32-bit Z */ 639848b8605Smrg pDest[j] = (ptrc[j] & 0xffffff00) | ((ptrc[j] >> 24) & 0xff); 640848b8605Smrg } 641848b8605Smrg pDest += dstStride; 642848b8605Smrg ptrc += pt->stride/4; 643848b8605Smrg } 644848b8605Smrg } 645848b8605Smrg break; 646848b8605Smrg case PIPE_FORMAT_Z16_UNORM: 647848b8605Smrg { 648848b8605Smrg const ushort *ptrc 649848b8605Smrg = (const ushort *)(map + y * pt->stride + x*2); 650848b8605Smrg for (i = 0; i < h; i++) { 651848b8605Smrg for (j = 0; j < w; j++) { 652848b8605Smrg /* convert 16-bit Z to 32-bit Z */ 653848b8605Smrg pDest[j] = (ptrc[j] << 16) | ptrc[j]; 654848b8605Smrg } 655848b8605Smrg pDest += dstStride; 656848b8605Smrg ptrc += pt->stride/2; 657848b8605Smrg } 658848b8605Smrg } 659848b8605Smrg break; 660848b8605Smrg case PIPE_FORMAT_Z32_FLOAT: 661848b8605Smrg { 662848b8605Smrg const float *ptrc = (const float *)(map + y * pt->stride + x*4); 663848b8605Smrg for (i = 0; i < h; i++) { 664848b8605Smrg for (j = 0; j < w; j++) { 665848b8605Smrg /* convert float Z to 32-bit Z */ 666848b8605Smrg if (ptrc[j] <= 0.0) { 667848b8605Smrg pDest[j] = 0; 668848b8605Smrg } 669848b8605Smrg else if (ptrc[j] >= 1.0) { 670848b8605Smrg pDest[j] = 0xffffffff; 671848b8605Smrg } 672848b8605Smrg else { 673848b8605Smrg double z = ptrc[j] * 0xffffffff; 674848b8605Smrg pDest[j] = (uint) z; 675848b8605Smrg } 676848b8605Smrg } 677848b8605Smrg pDest += dstStride; 678848b8605Smrg ptrc += pt->stride/4; 679848b8605Smrg } 680848b8605Smrg } 681848b8605Smrg break; 682848b8605Smrg case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 683848b8605Smrg { 684848b8605Smrg const float *ptrc = (const float *)(map + y * pt->stride + x*8); 685848b8605Smrg for (i = 0; i < h; i++) { 686848b8605Smrg for (j = 0; j < w; j++) { 687848b8605Smrg /* convert float Z to 32-bit Z */ 688848b8605Smrg if (ptrc[j] <= 0.0) { 689848b8605Smrg pDest[j*2] = 0; 690848b8605Smrg } 691848b8605Smrg else if (ptrc[j] >= 1.0) { 692848b8605Smrg pDest[j*2] = 0xffffffff; 693848b8605Smrg } 694848b8605Smrg else { 695848b8605Smrg double z = ptrc[j] * 0xffffffff; 696848b8605Smrg pDest[j*2] = (uint) z; 697848b8605Smrg } 698848b8605Smrg } 699848b8605Smrg pDest += dstStride; 700848b8605Smrg ptrc += pt->stride/4; 701848b8605Smrg } 702848b8605Smrg } 703848b8605Smrg break; 704848b8605Smrg default: 705848b8605Smrg assert(0); 706848b8605Smrg } 707848b8605Smrg} 708848b8605Smrg 709848b8605Smrg 710848b8605Smrgvoid 711848b8605Smrgpipe_put_tile_z(struct pipe_transfer *pt, 712848b8605Smrg void *dst, 713848b8605Smrg uint x, uint y, uint w, uint h, 714848b8605Smrg const uint *zSrc) 715848b8605Smrg{ 716848b8605Smrg const uint srcStride = w; 717848b8605Smrg const uint *ptrc = zSrc; 718848b8605Smrg ubyte *map = dst; 719848b8605Smrg uint i, j; 720848b8605Smrg enum pipe_format format = pt->resource->format; 721848b8605Smrg 722848b8605Smrg if (u_clip_tile(x, y, &w, &h, &pt->box)) 723848b8605Smrg return; 724848b8605Smrg 725848b8605Smrg switch (format) { 726848b8605Smrg case PIPE_FORMAT_Z32_UNORM: 727848b8605Smrg { 728848b8605Smrg uint *pDest = (uint *) (map + y * pt->stride + x*4); 729848b8605Smrg for (i = 0; i < h; i++) { 730848b8605Smrg memcpy(pDest, ptrc, 4 * w); 731848b8605Smrg pDest += pt->stride/4; 732848b8605Smrg ptrc += srcStride; 733848b8605Smrg } 734848b8605Smrg } 735848b8605Smrg break; 736848b8605Smrg case PIPE_FORMAT_Z24_UNORM_S8_UINT: 737848b8605Smrg { 738848b8605Smrg uint *pDest = (uint *) (map + y * pt->stride + x*4); 739848b8605Smrg /*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/ 740848b8605Smrg for (i = 0; i < h; i++) { 741848b8605Smrg for (j = 0; j < w; j++) { 742848b8605Smrg /* convert 32-bit Z to 24-bit Z, preserve stencil */ 743848b8605Smrg pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8; 744848b8605Smrg } 745848b8605Smrg pDest += pt->stride/4; 746848b8605Smrg ptrc += srcStride; 747848b8605Smrg } 748848b8605Smrg } 749848b8605Smrg break; 750848b8605Smrg case PIPE_FORMAT_Z24X8_UNORM: 751848b8605Smrg { 752848b8605Smrg uint *pDest = (uint *) (map + y * pt->stride + x*4); 753848b8605Smrg for (i = 0; i < h; i++) { 754848b8605Smrg for (j = 0; j < w; j++) { 755848b8605Smrg /* convert 32-bit Z to 24-bit Z (0 stencil) */ 756848b8605Smrg pDest[j] = ptrc[j] >> 8; 757848b8605Smrg } 758848b8605Smrg pDest += pt->stride/4; 759848b8605Smrg ptrc += srcStride; 760848b8605Smrg } 761848b8605Smrg } 762848b8605Smrg break; 763848b8605Smrg case PIPE_FORMAT_S8_UINT_Z24_UNORM: 764848b8605Smrg { 765848b8605Smrg uint *pDest = (uint *) (map + y * pt->stride + x*4); 766848b8605Smrg /*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/ 767848b8605Smrg for (i = 0; i < h; i++) { 768848b8605Smrg for (j = 0; j < w; j++) { 769848b8605Smrg /* convert 32-bit Z to 24-bit Z, preserve stencil */ 770848b8605Smrg pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00); 771848b8605Smrg } 772848b8605Smrg pDest += pt->stride/4; 773848b8605Smrg ptrc += srcStride; 774848b8605Smrg } 775848b8605Smrg } 776848b8605Smrg break; 777848b8605Smrg case PIPE_FORMAT_X8Z24_UNORM: 778848b8605Smrg { 779848b8605Smrg uint *pDest = (uint *) (map + y * pt->stride + x*4); 780848b8605Smrg for (i = 0; i < h; i++) { 781848b8605Smrg for (j = 0; j < w; j++) { 782848b8605Smrg /* convert 32-bit Z to 24-bit Z (0 stencil) */ 783848b8605Smrg pDest[j] = ptrc[j] & 0xffffff00; 784848b8605Smrg } 785848b8605Smrg pDest += pt->stride/4; 786848b8605Smrg ptrc += srcStride; 787848b8605Smrg } 788848b8605Smrg } 789848b8605Smrg break; 790848b8605Smrg case PIPE_FORMAT_Z16_UNORM: 791848b8605Smrg { 792848b8605Smrg ushort *pDest = (ushort *) (map + y * pt->stride + x*2); 793848b8605Smrg for (i = 0; i < h; i++) { 794848b8605Smrg for (j = 0; j < w; j++) { 795848b8605Smrg /* convert 32-bit Z to 16-bit Z */ 796848b8605Smrg pDest[j] = ptrc[j] >> 16; 797848b8605Smrg } 798848b8605Smrg pDest += pt->stride/2; 799848b8605Smrg ptrc += srcStride; 800848b8605Smrg } 801848b8605Smrg } 802848b8605Smrg break; 803848b8605Smrg case PIPE_FORMAT_Z32_FLOAT: 804848b8605Smrg { 805848b8605Smrg float *pDest = (float *) (map + y * pt->stride + x*4); 806848b8605Smrg for (i = 0; i < h; i++) { 807848b8605Smrg for (j = 0; j < w; j++) { 808848b8605Smrg /* convert 32-bit integer Z to float Z */ 809848b8605Smrg const double scale = 1.0 / 0xffffffffU; 810848b8605Smrg pDest[j] = (float) (ptrc[j] * scale); 811848b8605Smrg } 812848b8605Smrg pDest += pt->stride/4; 813848b8605Smrg ptrc += srcStride; 814848b8605Smrg } 815848b8605Smrg } 816848b8605Smrg break; 817848b8605Smrg case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 818848b8605Smrg { 819848b8605Smrg float *pDest = (float *) (map + y * pt->stride + x*8); 820848b8605Smrg for (i = 0; i < h; i++) { 821848b8605Smrg for (j = 0; j < w; j++) { 822848b8605Smrg /* convert 32-bit integer Z to float Z */ 823848b8605Smrg const double scale = 1.0 / 0xffffffffU; 824848b8605Smrg pDest[j*2] = (float) (ptrc[j] * scale); 825848b8605Smrg } 826848b8605Smrg pDest += pt->stride/4; 827848b8605Smrg ptrc += srcStride; 828848b8605Smrg } 829848b8605Smrg } 830848b8605Smrg break; 831848b8605Smrg default: 832848b8605Smrg assert(0); 833848b8605Smrg } 834848b8605Smrg} 835848b8605Smrg 836848b8605Smrg 837848b8605Smrgvoid 838848b8605Smrgpipe_get_tile_ui_format(struct pipe_transfer *pt, 839848b8605Smrg const void *src, 840848b8605Smrg uint x, uint y, uint w, uint h, 841848b8605Smrg enum pipe_format format, 842848b8605Smrg unsigned int *p) 843848b8605Smrg{ 844848b8605Smrg unsigned dst_stride = w * 4; 845848b8605Smrg void *packed; 846848b8605Smrg 847848b8605Smrg if (u_clip_tile(x, y, &w, &h, &pt->box)) { 848848b8605Smrg return; 849848b8605Smrg } 850848b8605Smrg 851848b8605Smrg packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); 852848b8605Smrg if (!packed) { 853848b8605Smrg return; 854848b8605Smrg } 855848b8605Smrg 856848b8605Smrg if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) { 857848b8605Smrg assert((x & 1) == 0); 858848b8605Smrg } 859848b8605Smrg 860848b8605Smrg pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0); 861848b8605Smrg 862848b8605Smrg pipe_tile_raw_to_unsigned(format, packed, w, h, p, dst_stride); 863848b8605Smrg 864848b8605Smrg FREE(packed); 865848b8605Smrg} 866848b8605Smrg 867848b8605Smrg 868848b8605Smrgvoid 869848b8605Smrgpipe_get_tile_i_format(struct pipe_transfer *pt, 870848b8605Smrg const void *src, 871848b8605Smrg uint x, uint y, uint w, uint h, 872848b8605Smrg enum pipe_format format, 873848b8605Smrg int *p) 874848b8605Smrg{ 875848b8605Smrg unsigned dst_stride = w * 4; 876848b8605Smrg void *packed; 877848b8605Smrg 878848b8605Smrg if (u_clip_tile(x, y, &w, &h, &pt->box)) { 879848b8605Smrg return; 880848b8605Smrg } 881848b8605Smrg 882848b8605Smrg packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format)); 883848b8605Smrg if (!packed) { 884848b8605Smrg return; 885848b8605Smrg } 886848b8605Smrg 887848b8605Smrg if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) { 888848b8605Smrg assert((x & 1) == 0); 889848b8605Smrg } 890848b8605Smrg 891848b8605Smrg pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0); 892848b8605Smrg 893848b8605Smrg pipe_tile_raw_to_signed(format, packed, w, h, p, dst_stride); 894848b8605Smrg 895848b8605Smrg FREE(packed); 896848b8605Smrg} 897