xref: /aosp_15_r20/external/mesa3d/src/gallium/auxiliary/util/u_tile.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /**************************************************************************
2  *
3  * Copyright 2007 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 /**
29  * RGBA/float tile get/put functions.
30  * Usable both by drivers and gallium frontends.
31  */
32 
33 
34 #include "pipe/p_defines.h"
35 #include "util/u_inlines.h"
36 
37 #include "util/format/u_format.h"
38 #include "util/format/u_format_bptc.h"
39 #include "util/u_math.h"
40 #include "util/u_memory.h"
41 #include "util/u_surface.h"
42 #include "util/u_tile.h"
43 
44 
45 /**
46  * Move raw block of pixels from transfer object to user memory.
47  */
48 void
pipe_get_tile_raw(struct pipe_transfer * pt,const void * src,unsigned x,unsigned y,unsigned w,unsigned h,void * dst,int dst_stride)49 pipe_get_tile_raw(struct pipe_transfer *pt,
50                   const void *src,
51                   unsigned x, unsigned y,
52                   unsigned w, unsigned h,
53                   void *dst, int dst_stride)
54 {
55    if (dst_stride == 0)
56       dst_stride = util_format_get_stride(pt->resource->format, w);
57 
58    if (u_clip_tile(x, y, &w, &h, &pt->box))
59       return;
60 
61    util_copy_rect(dst, pt->resource->format, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
62 }
63 
64 
65 /**
66  * Move raw block of pixels from user memory to transfer object.
67  */
68 void
pipe_put_tile_raw(struct pipe_transfer * pt,void * dst,unsigned x,unsigned y,unsigned w,unsigned h,const void * src,int src_stride)69 pipe_put_tile_raw(struct pipe_transfer *pt,
70                   void *dst,
71                   unsigned x, unsigned y,
72                   unsigned w, unsigned h,
73                   const void *src, int src_stride)
74 {
75    enum pipe_format format = pt->resource->format;
76 
77    if (src_stride == 0)
78       src_stride = util_format_get_stride(format, w);
79 
80    if (u_clip_tile(x, y, &w, &h, &pt->box))
81       return;
82 
83    util_copy_rect(dst, format, pt->stride, x, y, w, h, src, src_stride, 0, 0);
84 }
85 
86 
87 
88 
89 /** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */
90 #define SHORT_TO_FLOAT(S)   ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
91 
92 #define UNCLAMPED_FLOAT_TO_SHORT(us, f)  \
93    us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
94 
95 
96 
97 /*** PIPE_FORMAT_Z16_UNORM ***/
98 
99 /**
100  * Return each Z value as four floats in [0,1].
101  */
102 static void
z16_get_tile_rgba(const uint16_t * src,unsigned w,unsigned h,float * p,unsigned dst_stride)103 z16_get_tile_rgba(const uint16_t *src,
104                   unsigned w, unsigned h,
105                   float *p,
106                   unsigned dst_stride)
107 {
108    const float scale = 1.0f / 65535.0f;
109    unsigned i, j;
110 
111    for (i = 0; i < h; i++) {
112       float *pRow = p;
113       for (j = 0; j < w; j++, pRow += 4) {
114          pRow[0] =
115          pRow[1] =
116          pRow[2] =
117          pRow[3] = *src++ * scale;
118       }
119       p += dst_stride;
120    }
121 }
122 
123 
124 
125 
126 /*** PIPE_FORMAT_Z32_UNORM ***/
127 
128 /**
129  * Return each Z value as four floats in [0,1].
130  */
131 static void
z32_get_tile_rgba(const uint32_t * src,unsigned w,unsigned h,float * p,unsigned dst_stride)132 z32_get_tile_rgba(const uint32_t *src,
133                   unsigned w, unsigned h,
134                   float *p,
135                   unsigned dst_stride)
136 {
137    const double scale = 1.0 / (double) 0xffffffff;
138    unsigned i, j;
139 
140    for (i = 0; i < h; i++) {
141       float *pRow = p;
142       for (j = 0; j < w; j++, pRow += 4) {
143          pRow[0] =
144          pRow[1] =
145          pRow[2] =
146          pRow[3] = (float) (*src++ * scale);
147       }
148       p += dst_stride;
149    }
150 }
151 
152 
153 /*** PIPE_FORMAT_Z24_UNORM_S8_UINT ***/
154 
155 /**
156  * Return Z component as four float in [0,1].  Stencil part ignored.
157  */
158 static void
s8z24_get_tile_rgba(const uint32_t * src,unsigned w,unsigned h,float * p,unsigned dst_stride)159 s8z24_get_tile_rgba(const uint32_t *src,
160                     unsigned w, unsigned h,
161                     float *p,
162                     unsigned dst_stride)
163 {
164    const double scale = 1.0 / ((1 << 24) - 1);
165    unsigned i, j;
166 
167    for (i = 0; i < h; i++) {
168       float *pRow = p;
169       for (j = 0; j < w; j++, pRow += 4) {
170          pRow[0] =
171          pRow[1] =
172          pRow[2] =
173          pRow[3] = (float) (scale * (*src++ & 0xffffff));
174       }
175       p += dst_stride;
176    }
177 }
178 
179 
180 /*** PIPE_FORMAT_S8_UINT_Z24_UNORM ***/
181 
182 /**
183  * Return Z component as four float in [0,1].  Stencil part ignored.
184  */
185 static void
z24s8_get_tile_rgba(const uint32_t * src,unsigned w,unsigned h,float * p,unsigned dst_stride)186 z24s8_get_tile_rgba(const uint32_t *src,
187                     unsigned w, unsigned h,
188                     float *p,
189                     unsigned dst_stride)
190 {
191    const double scale = 1.0 / ((1 << 24) - 1);
192    unsigned i, j;
193 
194    for (i = 0; i < h; i++) {
195       float *pRow = p;
196       for (j = 0; j < w; j++, pRow += 4) {
197          pRow[0] =
198          pRow[1] =
199          pRow[2] =
200          pRow[3] = (float) (scale * (*src++ >> 8));
201       }
202       p += dst_stride;
203    }
204 }
205 
206 /*** PIPE_FORMAT_S8X24_UINT ***/
207 
208 /**
209  * Return S component as four uint32_t in [0..255].  Z part ignored.
210  */
211 static void
s8x24_get_tile_rgba(const uint32_t * src,unsigned w,unsigned h,float * p,unsigned dst_stride)212 s8x24_get_tile_rgba(const uint32_t *src,
213                     unsigned w, unsigned h,
214                     float *p,
215                     unsigned dst_stride)
216 {
217    unsigned i, j;
218 
219    for (i = 0; i < h; i++) {
220       uint32_t *pRow = (uint32_t *)p;
221 
222       for (j = 0; j < w; j++, pRow += 4) {
223          pRow[0] =
224          pRow[1] =
225          pRow[2] =
226          pRow[3] = ((*src++ >> 24) & 0xff);
227       }
228 
229       p += dst_stride;
230    }
231 }
232 
233 /*** PIPE_FORMAT_X24S8_UINT ***/
234 
235 /**
236  * Return S component as four uint32_t in [0..255].  Z part ignored.
237  */
238 static void
x24s8_get_tile_rgba(const uint32_t * src,unsigned w,unsigned h,float * p,unsigned dst_stride)239 x24s8_get_tile_rgba(const uint32_t *src,
240                     unsigned w, unsigned h,
241                     float *p,
242                     unsigned dst_stride)
243 {
244    unsigned i, j;
245 
246    for (i = 0; i < h; i++) {
247       uint32_t *pRow = (uint32_t *)p;
248       for (j = 0; j < w; j++, pRow += 4) {
249          pRow[0] =
250          pRow[1] =
251          pRow[2] =
252          pRow[3] = (*src++ & 0xff);
253       }
254       p += dst_stride;
255    }
256 }
257 
258 
259 /**
260  * Return S component as four uint32_t in [0..255].  Z part ignored.
261  */
262 static void
s8_get_tile_rgba(const unsigned char * src,unsigned w,unsigned h,float * p,unsigned dst_stride)263 s8_get_tile_rgba(const unsigned char *src,
264 		 unsigned w, unsigned h,
265 		 float *p,
266 		 unsigned dst_stride)
267 {
268    unsigned i, j;
269 
270    for (i = 0; i < h; i++) {
271       uint32_t *pRow = (uint32_t *)p;
272       for (j = 0; j < w; j++, pRow += 4) {
273          pRow[0] =
274          pRow[1] =
275          pRow[2] =
276          pRow[3] = (*src++ & 0xff);
277       }
278       p += dst_stride;
279    }
280 }
281 
282 /*** PIPE_FORMAT_Z32_FLOAT ***/
283 
284 /**
285  * Return each Z value as four floats in [0,1].
286  */
287 static void
z32f_get_tile_rgba(const float * src,unsigned w,unsigned h,float * p,unsigned dst_stride)288 z32f_get_tile_rgba(const float *src,
289                    unsigned w, unsigned h,
290                    float *p,
291                    unsigned dst_stride)
292 {
293    unsigned i, j;
294 
295    for (i = 0; i < h; i++) {
296       float *pRow = p;
297       for (j = 0; j < w; j++, pRow += 4) {
298          pRow[0] =
299          pRow[1] =
300          pRow[2] =
301          pRow[3] = *src++;
302       }
303       p += dst_stride;
304    }
305 }
306 
307 /*** PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ***/
308 
309 /**
310  * Return each Z value as four floats in [0,1].
311  */
312 static void
z32f_x24s8_get_tile_rgba(const float * src,unsigned w,unsigned h,float * p,unsigned dst_stride)313 z32f_x24s8_get_tile_rgba(const float *src,
314                          unsigned w, unsigned h,
315                          float *p,
316                          unsigned dst_stride)
317 {
318    unsigned i, j;
319 
320    for (i = 0; i < h; i++) {
321       float *pRow = p;
322       for (j = 0; j < w; j++, pRow += 4) {
323          pRow[0] =
324          pRow[1] =
325          pRow[2] =
326          pRow[3] = *src;
327          src += 2;
328       }
329       p += dst_stride;
330    }
331 }
332 
333 /*** PIPE_FORMAT_X32_S8X24_UINT ***/
334 
335 /**
336  * Return S component as four uint32_t in [0..255].  Z part ignored.
337  */
338 static void
x32_s8_get_tile_rgba(const uint32_t * src,unsigned w,unsigned h,float * p,unsigned dst_stride)339 x32_s8_get_tile_rgba(const uint32_t *src,
340                      unsigned w, unsigned h,
341                      float *p,
342                      unsigned dst_stride)
343 {
344    unsigned i, j;
345 
346    for (i = 0; i < h; i++) {
347       uint32_t *pRow = (uint32_t *)p;
348       for (j = 0; j < w; j++, pRow += 4) {
349          src++;
350          pRow[0] =
351          pRow[1] =
352          pRow[2] =
353          pRow[3] = (*src++ & 0xff);
354       }
355       p += dst_stride;
356    }
357 }
358 
359 void
pipe_put_tile_rgba(struct pipe_transfer * pt,void * dst,unsigned x,unsigned y,unsigned w,unsigned h,enum pipe_format format,const void * p)360 pipe_put_tile_rgba(struct pipe_transfer *pt,
361                    void *dst,
362                    unsigned x, unsigned y, unsigned w, unsigned h,
363                    enum pipe_format format, const void *p)
364 {
365    unsigned src_stride = w * 4;
366 
367    if (u_clip_tile(x, y, &w, &h, &pt->box))
368       return;
369 
370    /* While we do generate RGBA tiles for z/s for softpipe's texture fetch
371     * path, we never have to store from "RGBA" to Z/S.
372     */
373    if (util_format_is_depth_or_stencil(format))
374       return;
375 
376    util_format_write_4(format,
377                        p, src_stride * sizeof(float),
378                        dst, pt->stride,
379                        x, y, w, h);
380 }
381 
382 void
pipe_get_tile_rgba(struct pipe_transfer * pt,const void * src,unsigned x,unsigned y,unsigned w,unsigned h,enum pipe_format format,void * dst)383 pipe_get_tile_rgba(struct pipe_transfer *pt,
384                    const void *src,
385                    unsigned x, unsigned y, unsigned w, unsigned h,
386                    enum pipe_format format,
387                    void *dst)
388 {
389    unsigned dst_stride = w * 4;
390    void *packed;
391 
392    if (u_clip_tile(x, y, &w, &h, &pt->box)) {
393       return;
394    }
395 
396    packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
397    if (!packed) {
398       return;
399    }
400 
401    if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
402       assert((x & 1) == 0);
403    }
404 
405    pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0);
406 
407    switch (format) {
408    case PIPE_FORMAT_Z16_UNORM:
409       z16_get_tile_rgba((uint16_t *) packed, w, h, dst, dst_stride);
410       break;
411    case PIPE_FORMAT_Z32_UNORM:
412       z32_get_tile_rgba((uint32_t *) packed, w, h, dst, dst_stride);
413       break;
414    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
415    case PIPE_FORMAT_Z24X8_UNORM:
416       s8z24_get_tile_rgba((uint32_t *) packed, w, h, dst, dst_stride);
417       break;
418    case PIPE_FORMAT_S8_UINT:
419       s8_get_tile_rgba((uint8_t *) packed, w, h, dst, dst_stride);
420       break;
421    case PIPE_FORMAT_X24S8_UINT:
422       s8x24_get_tile_rgba((uint32_t *) packed, w, h, dst, dst_stride);
423       break;
424    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
425    case PIPE_FORMAT_X8Z24_UNORM:
426       z24s8_get_tile_rgba((uint32_t *) packed, w, h, dst, dst_stride);
427       break;
428    case PIPE_FORMAT_S8X24_UINT:
429       x24s8_get_tile_rgba((uint32_t *) packed, w, h, dst, dst_stride);
430       break;
431    case PIPE_FORMAT_Z32_FLOAT:
432       z32f_get_tile_rgba((float *) packed, w, h, dst, dst_stride);
433       break;
434    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
435       z32f_x24s8_get_tile_rgba((float *) packed, w, h, dst, dst_stride);
436       break;
437    case PIPE_FORMAT_X32_S8X24_UINT:
438       x32_s8_get_tile_rgba((uint32_t *) packed, w, h, dst, dst_stride);
439       break;
440    default:
441       util_format_read_4(format,
442                          dst, dst_stride * sizeof(float),
443                          packed, util_format_get_stride(format, w),
444                          0, 0, w, h);
445    }
446 
447    FREE(packed);
448 }
449