2 * Copyright 2016 Red Hat.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 #include "sp_context.h"
26 #include "sp_texture.h"
28 #include "util/format/u_format.h"
31 * Get the offset into the base image
32 * first element for a buffer or layer/level for texture.
35 get_image_offset(const struct softpipe_resource
*spr
,
36 const struct pipe_image_view
*iview
,
37 enum pipe_format format
, unsigned r_coord
)
41 if (spr
->base
.target
== PIPE_BUFFER
)
42 return iview
->u
.buf
.offset
;
44 if (spr
->base
.target
== PIPE_TEXTURE_1D_ARRAY
||
45 spr
->base
.target
== PIPE_TEXTURE_2D_ARRAY
||
46 spr
->base
.target
== PIPE_TEXTURE_CUBE_ARRAY
||
47 spr
->base
.target
== PIPE_TEXTURE_CUBE
||
48 spr
->base
.target
== PIPE_TEXTURE_3D
)
49 base_layer
= r_coord
+ iview
->u
.tex
.first_layer
;
50 return softpipe_get_tex_image_offset(spr
, iview
->u
.tex
.level
, base_layer
);
54 * Does this texture instruction have a layer or depth parameter.
57 has_layer_or_depth(unsigned tgsi_tex_instr
)
59 return (tgsi_tex_instr
== TGSI_TEXTURE_3D
||
60 tgsi_tex_instr
== TGSI_TEXTURE_CUBE
||
61 tgsi_tex_instr
== TGSI_TEXTURE_1D_ARRAY
||
62 tgsi_tex_instr
== TGSI_TEXTURE_2D_ARRAY
||
63 tgsi_tex_instr
== TGSI_TEXTURE_CUBE_ARRAY
||
64 tgsi_tex_instr
== TGSI_TEXTURE_2D_ARRAY_MSAA
);
68 * Is this texture instruction a single non-array coordinate.
71 has_1coord(unsigned tgsi_tex_instr
)
73 return (tgsi_tex_instr
== TGSI_TEXTURE_BUFFER
||
74 tgsi_tex_instr
== TGSI_TEXTURE_1D
||
75 tgsi_tex_instr
== TGSI_TEXTURE_1D_ARRAY
);
79 * check the bounds vs w/h/d
82 bounds_check(int width
, int height
, int depth
,
85 if (s
< 0 || s
>= width
)
87 if (t
< 0 || t
>= height
)
89 if (r
< 0 || r
>= depth
)
95 * Checks if the texture target compatible with the image resource
99 has_compat_target(unsigned pipe_target
, unsigned tgsi_target
)
101 switch (pipe_target
) {
102 case PIPE_TEXTURE_1D
:
103 if (tgsi_target
== TGSI_TEXTURE_1D
)
106 case PIPE_TEXTURE_2D
:
107 if (tgsi_target
== TGSI_TEXTURE_2D
)
110 case PIPE_TEXTURE_RECT
:
111 if (tgsi_target
== TGSI_TEXTURE_RECT
)
114 case PIPE_TEXTURE_3D
:
115 if (tgsi_target
== TGSI_TEXTURE_3D
||
116 tgsi_target
== TGSI_TEXTURE_2D
)
119 case PIPE_TEXTURE_CUBE
:
120 if (tgsi_target
== TGSI_TEXTURE_CUBE
||
121 tgsi_target
== TGSI_TEXTURE_2D
)
124 case PIPE_TEXTURE_1D_ARRAY
:
125 if (tgsi_target
== TGSI_TEXTURE_1D
||
126 tgsi_target
== TGSI_TEXTURE_1D_ARRAY
)
129 case PIPE_TEXTURE_2D_ARRAY
:
130 if (tgsi_target
== TGSI_TEXTURE_2D
||
131 tgsi_target
== TGSI_TEXTURE_2D_ARRAY
)
134 case PIPE_TEXTURE_CUBE_ARRAY
:
135 if (tgsi_target
== TGSI_TEXTURE_CUBE
||
136 tgsi_target
== TGSI_TEXTURE_CUBE_ARRAY
||
137 tgsi_target
== TGSI_TEXTURE_2D
)
141 return (tgsi_target
== TGSI_TEXTURE_BUFFER
);
147 get_dimensions(const struct pipe_image_view
*iview
,
148 const struct softpipe_resource
*spr
,
149 unsigned tgsi_tex_instr
,
150 enum pipe_format pformat
,
155 if (tgsi_tex_instr
== TGSI_TEXTURE_BUFFER
) {
156 *width
= iview
->u
.buf
.size
/ util_format_get_blocksize(pformat
);
160 * Bounds check the buffer size from the view
161 * and the buffer size from the underlying buffer.
163 if (util_format_get_stride(pformat
, *width
) >
164 util_format_get_stride(spr
->base
.format
, spr
->base
.width0
))
169 level
= spr
->base
.target
== PIPE_BUFFER
? 0 : iview
->u
.tex
.level
;
170 *width
= u_minify(spr
->base
.width0
, level
);
171 *height
= u_minify(spr
->base
.height0
, level
);
173 if (spr
->base
.target
== PIPE_TEXTURE_3D
)
174 *depth
= u_minify(spr
->base
.depth0
, level
);
176 *depth
= spr
->base
.array_size
;
178 /* Make sure the resource and view have compatiable formats */
179 if (util_format_get_blocksize(pformat
) >
180 util_format_get_blocksize(spr
->base
.format
))
187 fill_coords(const struct tgsi_image_params
*params
,
189 const int s
[TGSI_QUAD_SIZE
],
190 const int t
[TGSI_QUAD_SIZE
],
191 const int r
[TGSI_QUAD_SIZE
],
192 int *s_coord
, int *t_coord
, int *r_coord
)
195 *t_coord
= has_1coord(params
->tgsi_tex_instr
) ? 0 : t
[index
];
196 *r_coord
= has_layer_or_depth(params
->tgsi_tex_instr
) ?
197 (params
->tgsi_tex_instr
== TGSI_TEXTURE_1D_ARRAY
? t
[index
] : r
[index
]) : 0;
200 * Implement the image LOAD operation.
203 sp_tgsi_load(const struct tgsi_image
*image
,
204 const struct tgsi_image_params
*params
,
205 const int s
[TGSI_QUAD_SIZE
],
206 const int t
[TGSI_QUAD_SIZE
],
207 const int r
[TGSI_QUAD_SIZE
],
208 const int sample
[TGSI_QUAD_SIZE
],
209 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
211 struct sp_tgsi_image
*sp_img
= (struct sp_tgsi_image
*)image
;
212 struct pipe_image_view
*iview
;
213 struct softpipe_resource
*spr
;
214 unsigned width
, height
, depth
;
220 if (params
->unit
>= PIPE_MAX_SHADER_IMAGES
)
221 goto fail_write_all_zero
;
222 iview
= &sp_img
->sp_iview
[params
->unit
];
223 spr
= (struct softpipe_resource
*)iview
->resource
;
225 goto fail_write_all_zero
;
227 if (!has_compat_target(spr
->base
.target
, params
->tgsi_tex_instr
))
228 goto fail_write_all_zero
;
230 if (!get_dimensions(iview
, spr
, params
->tgsi_tex_instr
,
231 params
->format
, &width
, &height
, &depth
))
234 stride
= util_format_get_stride(params
->format
, width
);
236 for (j
= 0; j
< TGSI_QUAD_SIZE
; j
++) {
237 int s_coord
, t_coord
, r_coord
;
238 bool fill_zero
= false;
240 if (!(params
->execmask
& (1 << j
)))
243 fill_coords(params
, j
, s
, t
, r
, &s_coord
, &t_coord
, &r_coord
);
244 if (!bounds_check(width
, height
, depth
,
245 s_coord
, t_coord
, r_coord
))
249 int nc
= util_format_get_nr_components(params
->format
);
250 int ival
= util_format_is_pure_integer(params
->format
);
251 for (c
= 0; c
< 4; c
++) {
253 if (c
== 3 && nc
< 4) {
255 ((int32_t *)rgba
[c
])[j
] = 1;
262 offset
= get_image_offset(spr
, iview
, params
->format
, r_coord
);
263 data_ptr
= (char *)spr
->data
+ offset
;
265 if (util_format_is_pure_sint(params
->format
)) {
268 util_format_read_4i(params
->format
,
271 s_coord
, t_coord
, 1, 1);
272 for (c
= 0; c
< 4; c
++)
273 ((int32_t *)rgba
[c
])[j
] = sdata
[c
];
274 } else if (util_format_is_pure_uint(params
->format
)) {
276 util_format_read_4ui(params
->format
,
279 s_coord
, t_coord
, 1, 1);
280 for (c
= 0; c
< 4; c
++)
281 ((uint32_t *)rgba
[c
])[j
] = sdata
[c
];
284 util_format_read_4f(params
->format
,
287 s_coord
, t_coord
, 1, 1);
288 for (c
= 0; c
< 4; c
++)
289 rgba
[c
][j
] = sdata
[c
];
294 for (j
= 0; j
< TGSI_QUAD_SIZE
; j
++) {
295 for (c
= 0; c
< 4; c
++)
302 * Implement the image STORE operation.
305 sp_tgsi_store(const struct tgsi_image
*image
,
306 const struct tgsi_image_params
*params
,
307 const int s
[TGSI_QUAD_SIZE
],
308 const int t
[TGSI_QUAD_SIZE
],
309 const int r
[TGSI_QUAD_SIZE
],
310 const int sample
[TGSI_QUAD_SIZE
],
311 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
313 struct sp_tgsi_image
*sp_img
= (struct sp_tgsi_image
*)image
;
314 struct pipe_image_view
*iview
;
315 struct softpipe_resource
*spr
;
316 unsigned width
, height
, depth
;
321 unsigned pformat
= params
->format
;
323 if (params
->unit
>= PIPE_MAX_SHADER_IMAGES
)
325 iview
= &sp_img
->sp_iview
[params
->unit
];
326 spr
= (struct softpipe_resource
*)iview
->resource
;
329 if (!has_compat_target(spr
->base
.target
, params
->tgsi_tex_instr
))
332 if (params
->format
== PIPE_FORMAT_NONE
)
333 pformat
= spr
->base
.format
;
335 if (!get_dimensions(iview
, spr
, params
->tgsi_tex_instr
,
336 pformat
, &width
, &height
, &depth
))
339 stride
= util_format_get_stride(pformat
, width
);
341 for (j
= 0; j
< TGSI_QUAD_SIZE
; j
++) {
342 int s_coord
, t_coord
, r_coord
;
344 if (!(params
->execmask
& (1 << j
)))
347 fill_coords(params
, j
, s
, t
, r
, &s_coord
, &t_coord
, &r_coord
);
348 if (!bounds_check(width
, height
, depth
,
349 s_coord
, t_coord
, r_coord
))
352 offset
= get_image_offset(spr
, iview
, pformat
, r_coord
);
353 data_ptr
= (char *)spr
->data
+ offset
;
356 for (c
= 0; c
< 4; c
++)
357 sdata
[c
] = ((uint32_t *)rgba
[c
])[j
];
358 util_format_write_4(pformat
, sdata
, 0, data_ptr
, stride
,
359 s_coord
, t_coord
, 1, 1);
364 * Implement atomic operations on unsigned integers.
367 handle_op_uint(const struct pipe_image_view
*iview
,
368 const struct tgsi_image_params
*params
,
373 enum tgsi_opcode opcode
,
376 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
],
377 float rgba2
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
380 int nc
= util_format_get_nr_components(params
->format
);
383 util_format_read_4ui(params
->format
,
389 for (c
= 0; c
< nc
; c
++) {
390 ((uint32_t *)rgba
[c
])[qi
] = sdata
[c
];
395 case TGSI_OPCODE_ATOMUADD
:
396 for (c
= 0; c
< nc
; c
++) {
397 unsigned temp
= sdata
[c
];
398 sdata
[c
] += ((uint32_t *)rgba
[c
])[qi
];
399 ((uint32_t *)rgba
[c
])[qi
] = temp
;
402 case TGSI_OPCODE_ATOMXCHG
:
403 for (c
= 0; c
< nc
; c
++) {
404 unsigned temp
= sdata
[c
];
405 sdata
[c
] = ((uint32_t *)rgba
[c
])[qi
];
406 ((uint32_t *)rgba
[c
])[qi
] = temp
;
409 case TGSI_OPCODE_ATOMCAS
:
410 for (c
= 0; c
< nc
; c
++) {
411 unsigned dst_x
= sdata
[c
];
412 unsigned cmp_x
= ((uint32_t *)rgba
[c
])[qi
];
413 unsigned src_x
= ((uint32_t *)rgba2
[c
])[qi
];
414 unsigned temp
= sdata
[c
];
415 sdata
[c
] = (dst_x
== cmp_x
) ? src_x
: dst_x
;
416 ((uint32_t *)rgba
[c
])[qi
] = temp
;
419 case TGSI_OPCODE_ATOMAND
:
420 for (c
= 0; c
< nc
; c
++) {
421 unsigned temp
= sdata
[c
];
422 sdata
[c
] &= ((uint32_t *)rgba
[c
])[qi
];
423 ((uint32_t *)rgba
[c
])[qi
] = temp
;
426 case TGSI_OPCODE_ATOMOR
:
427 for (c
= 0; c
< nc
; c
++) {
428 unsigned temp
= sdata
[c
];
429 sdata
[c
] |= ((uint32_t *)rgba
[c
])[qi
];
430 ((uint32_t *)rgba
[c
])[qi
] = temp
;
433 case TGSI_OPCODE_ATOMXOR
:
434 for (c
= 0; c
< nc
; c
++) {
435 unsigned temp
= sdata
[c
];
436 sdata
[c
] ^= ((uint32_t *)rgba
[c
])[qi
];
437 ((uint32_t *)rgba
[c
])[qi
] = temp
;
440 case TGSI_OPCODE_ATOMUMIN
:
441 for (c
= 0; c
< nc
; c
++) {
442 unsigned dst_x
= sdata
[c
];
443 unsigned src_x
= ((uint32_t *)rgba
[c
])[qi
];
444 sdata
[c
] = MIN2(dst_x
, src_x
);
445 ((uint32_t *)rgba
[c
])[qi
] = dst_x
;
448 case TGSI_OPCODE_ATOMUMAX
:
449 for (c
= 0; c
< nc
; c
++) {
450 unsigned dst_x
= sdata
[c
];
451 unsigned src_x
= ((uint32_t *)rgba
[c
])[qi
];
452 sdata
[c
] = MAX2(dst_x
, src_x
);
453 ((uint32_t *)rgba
[c
])[qi
] = dst_x
;
456 case TGSI_OPCODE_ATOMIMIN
:
457 for (c
= 0; c
< nc
; c
++) {
458 int dst_x
= sdata
[c
];
459 int src_x
= ((uint32_t *)rgba
[c
])[qi
];
460 sdata
[c
] = MIN2(dst_x
, src_x
);
461 ((uint32_t *)rgba
[c
])[qi
] = dst_x
;
464 case TGSI_OPCODE_ATOMIMAX
:
465 for (c
= 0; c
< nc
; c
++) {
466 int dst_x
= sdata
[c
];
467 int src_x
= ((uint32_t *)rgba
[c
])[qi
];
468 sdata
[c
] = MAX2(dst_x
, src_x
);
469 ((uint32_t *)rgba
[c
])[qi
] = dst_x
;
473 assert(!"Unexpected TGSI opcode in sp_tgsi_op");
476 util_format_write_4(params
->format
, sdata
, 0, data_ptr
, stride
,
481 * Implement atomic operations on signed integers.
484 handle_op_int(const struct pipe_image_view
*iview
,
485 const struct tgsi_image_params
*params
,
490 enum tgsi_opcode opcode
,
493 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
],
494 float rgba2
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
497 int nc
= util_format_get_nr_components(params
->format
);
499 util_format_read_4i(params
->format
,
505 for (c
= 0; c
< nc
; c
++) {
506 ((int32_t *)rgba
[c
])[qi
] = sdata
[c
];
511 case TGSI_OPCODE_ATOMUADD
:
512 for (c
= 0; c
< nc
; c
++) {
514 sdata
[c
] += ((int32_t *)rgba
[c
])[qi
];
515 ((int32_t *)rgba
[c
])[qi
] = temp
;
518 case TGSI_OPCODE_ATOMXCHG
:
519 for (c
= 0; c
< nc
; c
++) {
521 sdata
[c
] = ((int32_t *)rgba
[c
])[qi
];
522 ((int32_t *)rgba
[c
])[qi
] = temp
;
525 case TGSI_OPCODE_ATOMCAS
:
526 for (c
= 0; c
< nc
; c
++) {
527 int dst_x
= sdata
[c
];
528 int cmp_x
= ((int32_t *)rgba
[c
])[qi
];
529 int src_x
= ((int32_t *)rgba2
[c
])[qi
];
531 sdata
[c
] = (dst_x
== cmp_x
) ? src_x
: dst_x
;
532 ((int32_t *)rgba
[c
])[qi
] = temp
;
535 case TGSI_OPCODE_ATOMAND
:
536 for (c
= 0; c
< nc
; c
++) {
538 sdata
[c
] &= ((int32_t *)rgba
[c
])[qi
];
539 ((int32_t *)rgba
[c
])[qi
] = temp
;
542 case TGSI_OPCODE_ATOMOR
:
543 for (c
= 0; c
< nc
; c
++) {
545 sdata
[c
] |= ((int32_t *)rgba
[c
])[qi
];
546 ((int32_t *)rgba
[c
])[qi
] = temp
;
549 case TGSI_OPCODE_ATOMXOR
:
550 for (c
= 0; c
< nc
; c
++) {
552 sdata
[c
] ^= ((int32_t *)rgba
[c
])[qi
];
553 ((int32_t *)rgba
[c
])[qi
] = temp
;
556 case TGSI_OPCODE_ATOMUMIN
:
557 for (c
= 0; c
< nc
; c
++) {
558 int dst_x
= sdata
[c
];
559 int src_x
= ((int32_t *)rgba
[c
])[qi
];
560 sdata
[c
] = MIN2(dst_x
, src_x
);
561 ((int32_t *)rgba
[c
])[qi
] = dst_x
;
564 case TGSI_OPCODE_ATOMUMAX
:
565 for (c
= 0; c
< nc
; c
++) {
566 int dst_x
= sdata
[c
];
567 int src_x
= ((int32_t *)rgba
[c
])[qi
];
568 sdata
[c
] = MAX2(dst_x
, src_x
);
569 ((int32_t *)rgba
[c
])[qi
] = dst_x
;
572 case TGSI_OPCODE_ATOMIMIN
:
573 for (c
= 0; c
< nc
; c
++) {
574 int dst_x
= sdata
[c
];
575 int src_x
= ((int32_t *)rgba
[c
])[qi
];
576 sdata
[c
] = MIN2(dst_x
, src_x
);
577 ((int32_t *)rgba
[c
])[qi
] = dst_x
;
580 case TGSI_OPCODE_ATOMIMAX
:
581 for (c
= 0; c
< nc
; c
++) {
582 int dst_x
= sdata
[c
];
583 int src_x
= ((int32_t *)rgba
[c
])[qi
];
584 sdata
[c
] = MAX2(dst_x
, src_x
);
585 ((int32_t *)rgba
[c
])[qi
] = dst_x
;
589 assert(!"Unexpected TGSI opcode in sp_tgsi_op");
592 util_format_write_4(params
->format
, sdata
, 0, data_ptr
, stride
,
596 /* GLES OES_shader_image_atomic.txt allows XCHG on R32F */
598 handle_op_r32f_xchg(const struct pipe_image_view
*iview
,
599 const struct tgsi_image_params
*params
,
604 enum tgsi_opcode opcode
,
607 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
612 util_format_read_4f(params
->format
,
617 for (c
= 0; c
< nc
; c
++) {
618 ((int32_t *)rgba
[c
])[qi
] = sdata
[c
];
623 for (c
= 0; c
< nc
; c
++) {
625 sdata
[c
] = ((float *)rgba
[c
])[qi
];
626 ((float *)rgba
[c
])[qi
] = temp
;
628 util_format_write_4(params
->format
, sdata
, 0, data_ptr
, stride
,
633 * Implement atomic image operations.
636 sp_tgsi_op(const struct tgsi_image
*image
,
637 const struct tgsi_image_params
*params
,
638 enum tgsi_opcode opcode
,
639 const int s
[TGSI_QUAD_SIZE
],
640 const int t
[TGSI_QUAD_SIZE
],
641 const int r
[TGSI_QUAD_SIZE
],
642 const int sample
[TGSI_QUAD_SIZE
],
643 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
],
644 float rgba2
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
646 struct sp_tgsi_image
*sp_img
= (struct sp_tgsi_image
*)image
;
647 struct pipe_image_view
*iview
;
648 struct softpipe_resource
*spr
;
649 unsigned width
, height
, depth
;
655 if (params
->unit
>= PIPE_MAX_SHADER_IMAGES
)
657 iview
= &sp_img
->sp_iview
[params
->unit
];
658 spr
= (struct softpipe_resource
*)iview
->resource
;
660 goto fail_write_all_zero
;
661 if (!has_compat_target(spr
->base
.target
, params
->tgsi_tex_instr
))
662 goto fail_write_all_zero
;
664 if (!get_dimensions(iview
, spr
, params
->tgsi_tex_instr
,
665 params
->format
, &width
, &height
, &depth
))
666 goto fail_write_all_zero
;
668 stride
= util_format_get_stride(spr
->base
.format
, width
);
670 for (j
= 0; j
< TGSI_QUAD_SIZE
; j
++) {
671 int s_coord
, t_coord
, r_coord
;
672 bool just_read
= false;
674 fill_coords(params
, j
, s
, t
, r
, &s_coord
, &t_coord
, &r_coord
);
675 if (!bounds_check(width
, height
, depth
,
676 s_coord
, t_coord
, r_coord
)) {
677 int nc
= util_format_get_nr_components(params
->format
);
678 int ival
= util_format_is_pure_integer(params
->format
);
680 for (c
= 0; c
< 4; c
++) {
682 if (c
== 3 && nc
< 4) {
684 ((int32_t *)rgba
[c
])[j
] = 1;
692 /* just readback the value for atomic if execmask isn't set */
693 if (!(params
->execmask
& (1 << j
))) {
697 offset
= get_image_offset(spr
, iview
, params
->format
, r_coord
);
698 data_ptr
= (char *)spr
->data
+ offset
;
700 /* we should see atomic operations on r32 formats */
701 if (util_format_is_pure_uint(params
->format
))
702 handle_op_uint(iview
, params
, just_read
, data_ptr
, j
, stride
,
703 opcode
, s_coord
, t_coord
, rgba
, rgba2
);
704 else if (util_format_is_pure_sint(params
->format
))
705 handle_op_int(iview
, params
, just_read
, data_ptr
, j
, stride
,
706 opcode
, s_coord
, t_coord
, rgba
, rgba2
);
707 else if (params
->format
== PIPE_FORMAT_R32_FLOAT
&&
708 opcode
== TGSI_OPCODE_ATOMXCHG
)
709 handle_op_r32f_xchg(iview
, params
, just_read
, data_ptr
, j
, stride
,
710 opcode
, s_coord
, t_coord
, rgba
);
716 for (j
= 0; j
< TGSI_QUAD_SIZE
; j
++) {
717 for (c
= 0; c
< 4; c
++)
724 sp_tgsi_get_dims(const struct tgsi_image
*image
,
725 const struct tgsi_image_params
*params
,
728 struct sp_tgsi_image
*sp_img
= (struct sp_tgsi_image
*)image
;
729 struct pipe_image_view
*iview
;
730 struct softpipe_resource
*spr
;
733 if (params
->unit
>= PIPE_MAX_SHADER_IMAGES
)
735 iview
= &sp_img
->sp_iview
[params
->unit
];
736 spr
= (struct softpipe_resource
*)iview
->resource
;
740 if (params
->tgsi_tex_instr
== TGSI_TEXTURE_BUFFER
) {
741 dims
[0] = iview
->u
.buf
.size
/ util_format_get_blocksize(iview
->format
);
742 dims
[1] = dims
[2] = dims
[3] = 0;
746 level
= iview
->u
.tex
.level
;
747 dims
[0] = u_minify(spr
->base
.width0
, level
);
748 switch (params
->tgsi_tex_instr
) {
749 case TGSI_TEXTURE_1D_ARRAY
:
750 dims
[1] = iview
->u
.tex
.last_layer
- iview
->u
.tex
.first_layer
+ 1;
752 case TGSI_TEXTURE_1D
:
754 case TGSI_TEXTURE_2D_ARRAY
:
755 dims
[2] = iview
->u
.tex
.last_layer
- iview
->u
.tex
.first_layer
+ 1;
757 case TGSI_TEXTURE_2D
:
758 case TGSI_TEXTURE_CUBE
:
759 case TGSI_TEXTURE_RECT
:
760 dims
[1] = u_minify(spr
->base
.height0
, level
);
762 case TGSI_TEXTURE_3D
:
763 dims
[1] = u_minify(spr
->base
.height0
, level
);
764 dims
[2] = u_minify(spr
->base
.depth0
, level
);
766 case TGSI_TEXTURE_CUBE_ARRAY
:
767 dims
[1] = u_minify(spr
->base
.height0
, level
);
768 dims
[2] = (iview
->u
.tex
.last_layer
- iview
->u
.tex
.first_layer
+ 1) / 6;
771 assert(!"unexpected texture target in sp_get_dims()");
776 struct sp_tgsi_image
*
777 sp_create_tgsi_image(void)
779 struct sp_tgsi_image
*img
= CALLOC_STRUCT(sp_tgsi_image
);
783 img
->base
.load
= sp_tgsi_load
;
784 img
->base
.store
= sp_tgsi_store
;
785 img
->base
.op
= sp_tgsi_op
;
786 img
->base
.get_dims
= sp_tgsi_get_dims
;