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