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/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
.first_element
* util_format_get_blocksize(format
);
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
.last_element
- iview
->u
.buf
.first_element
+ 1;
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
== TGSI_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
;
355 if (util_format_is_pure_sint(pformat
)) {
357 for (c
= 0; c
< 4; c
++)
358 sdata
[c
] = ((int32_t *)rgba
[c
])[j
];
359 util_format_write_4i(pformat
, sdata
, 0, data_ptr
, stride
,
360 s_coord
, t_coord
, 1, 1);
361 } else if (util_format_is_pure_uint(pformat
)) {
363 for (c
= 0; c
< 4; c
++)
364 sdata
[c
] = ((uint32_t *)rgba
[c
])[j
];
365 util_format_write_4ui(pformat
, sdata
, 0, data_ptr
, stride
,
366 s_coord
, t_coord
, 1, 1);
369 for (c
= 0; c
< 4; c
++)
370 sdata
[c
] = rgba
[c
][j
];
371 util_format_write_4f(pformat
, sdata
, 0, data_ptr
, stride
,
372 s_coord
, t_coord
, 1, 1);
378 * Implement atomic operations on unsigned integers.
381 handle_op_uint(const struct pipe_image_view
*iview
,
382 const struct tgsi_image_params
*params
,
390 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
],
391 float rgba2
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
394 int nc
= util_format_get_nr_components(params
->format
);
397 util_format_read_4ui(params
->format
,
403 for (c
= 0; c
< nc
; c
++) {
404 ((uint32_t *)rgba
[c
])[qi
] = sdata
[c
];
409 case TGSI_OPCODE_ATOMUADD
:
410 for (c
= 0; c
< nc
; c
++) {
411 unsigned temp
= sdata
[c
];
412 sdata
[c
] += ((uint32_t *)rgba
[c
])[qi
];
413 ((uint32_t *)rgba
[c
])[qi
] = temp
;
416 case TGSI_OPCODE_ATOMXCHG
:
417 for (c
= 0; c
< nc
; c
++) {
418 unsigned temp
= sdata
[c
];
419 sdata
[c
] = ((uint32_t *)rgba
[c
])[qi
];
420 ((uint32_t *)rgba
[c
])[qi
] = temp
;
423 case TGSI_OPCODE_ATOMCAS
:
424 for (c
= 0; c
< nc
; c
++) {
425 unsigned dst_x
= sdata
[c
];
426 unsigned cmp_x
= ((uint32_t *)rgba
[c
])[qi
];
427 unsigned src_x
= ((uint32_t *)rgba2
[c
])[qi
];
428 unsigned temp
= sdata
[c
];
429 sdata
[c
] = (dst_x
== cmp_x
) ? src_x
: dst_x
;
430 ((uint32_t *)rgba
[c
])[qi
] = temp
;
433 case TGSI_OPCODE_ATOMAND
:
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_ATOMOR
:
441 for (c
= 0; c
< nc
; c
++) {
442 unsigned temp
= sdata
[c
];
443 sdata
[c
] |= ((uint32_t *)rgba
[c
])[qi
];
444 ((uint32_t *)rgba
[c
])[qi
] = temp
;
447 case TGSI_OPCODE_ATOMXOR
:
448 for (c
= 0; c
< nc
; c
++) {
449 unsigned temp
= sdata
[c
];
450 sdata
[c
] ^= ((uint32_t *)rgba
[c
])[qi
];
451 ((uint32_t *)rgba
[c
])[qi
] = temp
;
454 case TGSI_OPCODE_ATOMUMIN
:
455 for (c
= 0; c
< nc
; c
++) {
456 unsigned dst_x
= sdata
[c
];
457 unsigned src_x
= ((uint32_t *)rgba
[c
])[qi
];
458 sdata
[c
] = MIN2(dst_x
, src_x
);
459 ((uint32_t *)rgba
[c
])[qi
] = dst_x
;
462 case TGSI_OPCODE_ATOMUMAX
:
463 for (c
= 0; c
< nc
; c
++) {
464 unsigned dst_x
= sdata
[c
];
465 unsigned src_x
= ((uint32_t *)rgba
[c
])[qi
];
466 sdata
[c
] = MAX2(dst_x
, src_x
);
467 ((uint32_t *)rgba
[c
])[qi
] = dst_x
;
470 case TGSI_OPCODE_ATOMIMIN
:
471 for (c
= 0; c
< nc
; c
++) {
472 int dst_x
= sdata
[c
];
473 int src_x
= ((uint32_t *)rgba
[c
])[qi
];
474 sdata
[c
] = MIN2(dst_x
, src_x
);
475 ((uint32_t *)rgba
[c
])[qi
] = dst_x
;
478 case TGSI_OPCODE_ATOMIMAX
:
479 for (c
= 0; c
< nc
; c
++) {
480 int dst_x
= sdata
[c
];
481 int src_x
= ((uint32_t *)rgba
[c
])[qi
];
482 sdata
[c
] = MAX2(dst_x
, src_x
);
483 ((uint32_t *)rgba
[c
])[qi
] = dst_x
;
487 assert(!"Unexpected TGSI opcode in sp_tgsi_op");
490 util_format_write_4ui(params
->format
, sdata
, 0, data_ptr
, stride
,
495 * Implement atomic operations on signed integers.
498 handle_op_int(const struct pipe_image_view
*iview
,
499 const struct tgsi_image_params
*params
,
507 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
],
508 float rgba2
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
511 int nc
= util_format_get_nr_components(params
->format
);
513 util_format_read_4i(params
->format
,
519 for (c
= 0; c
< nc
; c
++) {
520 ((int32_t *)rgba
[c
])[qi
] = sdata
[c
];
525 case TGSI_OPCODE_ATOMUADD
:
526 for (c
= 0; c
< nc
; c
++) {
528 sdata
[c
] += ((int32_t *)rgba
[c
])[qi
];
529 ((int32_t *)rgba
[c
])[qi
] = temp
;
532 case TGSI_OPCODE_ATOMXCHG
:
533 for (c
= 0; c
< nc
; c
++) {
535 sdata
[c
] = ((int32_t *)rgba
[c
])[qi
];
536 ((int32_t *)rgba
[c
])[qi
] = temp
;
539 case TGSI_OPCODE_ATOMCAS
:
540 for (c
= 0; c
< nc
; c
++) {
541 int dst_x
= sdata
[c
];
542 int cmp_x
= ((int32_t *)rgba
[c
])[qi
];
543 int src_x
= ((int32_t *)rgba2
[c
])[qi
];
545 sdata
[c
] = (dst_x
== cmp_x
) ? src_x
: dst_x
;
546 ((int32_t *)rgba
[c
])[qi
] = temp
;
549 case TGSI_OPCODE_ATOMAND
:
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_ATOMOR
:
557 for (c
= 0; c
< nc
; c
++) {
559 sdata
[c
] |= ((int32_t *)rgba
[c
])[qi
];
560 ((int32_t *)rgba
[c
])[qi
] = temp
;
563 case TGSI_OPCODE_ATOMXOR
:
564 for (c
= 0; c
< nc
; c
++) {
566 sdata
[c
] ^= ((int32_t *)rgba
[c
])[qi
];
567 ((int32_t *)rgba
[c
])[qi
] = temp
;
570 case TGSI_OPCODE_ATOMUMIN
:
571 for (c
= 0; c
< nc
; c
++) {
572 int dst_x
= sdata
[c
];
573 int src_x
= ((int32_t *)rgba
[c
])[qi
];
574 sdata
[c
] = MIN2(dst_x
, src_x
);
575 ((int32_t *)rgba
[c
])[qi
] = dst_x
;
578 case TGSI_OPCODE_ATOMUMAX
:
579 for (c
= 0; c
< nc
; c
++) {
580 int dst_x
= sdata
[c
];
581 int src_x
= ((int32_t *)rgba
[c
])[qi
];
582 sdata
[c
] = MAX2(dst_x
, src_x
);
583 ((int32_t *)rgba
[c
])[qi
] = dst_x
;
586 case TGSI_OPCODE_ATOMIMIN
:
587 for (c
= 0; c
< nc
; c
++) {
588 int dst_x
= sdata
[c
];
589 int src_x
= ((int32_t *)rgba
[c
])[qi
];
590 sdata
[c
] = MIN2(dst_x
, src_x
);
591 ((int32_t *)rgba
[c
])[qi
] = dst_x
;
594 case TGSI_OPCODE_ATOMIMAX
:
595 for (c
= 0; c
< nc
; c
++) {
596 int dst_x
= sdata
[c
];
597 int src_x
= ((int32_t *)rgba
[c
])[qi
];
598 sdata
[c
] = MAX2(dst_x
, src_x
);
599 ((int32_t *)rgba
[c
])[qi
] = dst_x
;
603 assert(!"Unexpected TGSI opcode in sp_tgsi_op");
606 util_format_write_4i(params
->format
, sdata
, 0, data_ptr
, stride
,
611 * Implement atomic image operations.
614 sp_tgsi_op(const struct tgsi_image
*image
,
615 const struct tgsi_image_params
*params
,
617 const int s
[TGSI_QUAD_SIZE
],
618 const int t
[TGSI_QUAD_SIZE
],
619 const int r
[TGSI_QUAD_SIZE
],
620 const int sample
[TGSI_QUAD_SIZE
],
621 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
],
622 float rgba2
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
624 struct sp_tgsi_image
*sp_img
= (struct sp_tgsi_image
*)image
;
625 struct pipe_image_view
*iview
;
626 struct softpipe_resource
*spr
;
627 unsigned width
, height
, depth
;
633 if (params
->unit
> PIPE_MAX_SHADER_IMAGES
)
635 iview
= &sp_img
->sp_iview
[params
->unit
];
636 spr
= (struct softpipe_resource
*)iview
->resource
;
638 goto fail_write_all_zero
;
639 if (!has_compat_target(spr
->base
.target
, params
->tgsi_tex_instr
))
640 goto fail_write_all_zero
;
642 if (!get_dimensions(iview
, spr
, params
->tgsi_tex_instr
,
643 params
->format
, &width
, &height
, &depth
))
644 goto fail_write_all_zero
;
646 stride
= util_format_get_stride(spr
->base
.format
, width
);
648 for (j
= 0; j
< TGSI_QUAD_SIZE
; j
++) {
649 int s_coord
, t_coord
, r_coord
;
650 bool just_read
= false;
652 fill_coords(params
, j
, s
, t
, r
, &s_coord
, &t_coord
, &r_coord
);
653 if (!bounds_check(width
, height
, depth
,
654 s_coord
, t_coord
, r_coord
)) {
655 int nc
= util_format_get_nr_components(params
->format
);
656 int ival
= util_format_is_pure_integer(params
->format
);
658 for (c
= 0; c
< 4; c
++) {
660 if (c
== 3 && nc
< 4) {
662 ((int32_t *)rgba
[c
])[j
] = 1;
670 /* just readback the value for atomic if execmask isn't set */
671 if (!(params
->execmask
& (1 << j
))) {
675 offset
= get_image_offset(spr
, iview
, params
->format
, r_coord
);
676 data_ptr
= (char *)spr
->data
+ offset
;
678 /* we should see atomic operations on r32 formats */
679 if (util_format_is_pure_uint(params
->format
))
680 handle_op_uint(iview
, params
, just_read
, data_ptr
, j
, stride
,
681 opcode
, s_coord
, t_coord
, rgba
, rgba2
);
682 else if (util_format_is_pure_sint(params
->format
))
683 handle_op_int(iview
, params
, just_read
, data_ptr
, j
, stride
,
684 opcode
, s_coord
, t_coord
, rgba
, rgba2
);
690 for (j
= 0; j
< TGSI_QUAD_SIZE
; j
++) {
691 for (c
= 0; c
< 4; c
++)
698 sp_tgsi_get_dims(const struct tgsi_image
*image
,
699 const struct tgsi_image_params
*params
,
702 struct sp_tgsi_image
*sp_img
= (struct sp_tgsi_image
*)image
;
703 struct pipe_image_view
*iview
;
704 struct softpipe_resource
*spr
;
707 if (params
->unit
> PIPE_MAX_SHADER_IMAGES
)
709 iview
= &sp_img
->sp_iview
[params
->unit
];
710 spr
= (struct softpipe_resource
*)iview
->resource
;
714 if (params
->tgsi_tex_instr
== TGSI_TEXTURE_BUFFER
) {
715 dims
[0] = iview
->u
.buf
.last_element
- iview
->u
.buf
.first_element
+ 1;
716 dims
[1] = dims
[2] = dims
[3] = 0;
720 level
= iview
->u
.tex
.level
;
721 dims
[0] = u_minify(spr
->base
.width0
, level
);
722 switch (params
->tgsi_tex_instr
) {
723 case TGSI_TEXTURE_1D_ARRAY
:
724 dims
[1] = iview
->u
.tex
.last_layer
- iview
->u
.tex
.first_layer
+ 1;
726 case TGSI_TEXTURE_1D
:
728 case TGSI_TEXTURE_2D_ARRAY
:
729 dims
[2] = iview
->u
.tex
.last_layer
- iview
->u
.tex
.first_layer
+ 1;
731 case TGSI_TEXTURE_2D
:
732 case TGSI_TEXTURE_CUBE
:
733 case TGSI_TEXTURE_RECT
:
734 dims
[1] = u_minify(spr
->base
.height0
, level
);
736 case TGSI_TEXTURE_3D
:
737 dims
[1] = u_minify(spr
->base
.height0
, level
);
738 dims
[2] = u_minify(spr
->base
.depth0
, level
);
740 case TGSI_TEXTURE_CUBE_ARRAY
:
741 dims
[1] = u_minify(spr
->base
.height0
, level
);
742 dims
[2] = (iview
->u
.tex
.last_layer
- iview
->u
.tex
.first_layer
+ 1) / 6;
745 assert(!"unexpected texture target in sp_get_dims()");
750 struct sp_tgsi_image
*
751 sp_create_tgsi_image(void)
753 struct sp_tgsi_image
*img
= CALLOC_STRUCT(sp_tgsi_image
);
757 img
->base
.load
= sp_tgsi_load
;
758 img
->base
.store
= sp_tgsi_store
;
759 img
->base
.op
= sp_tgsi_op
;
760 img
->base
.get_dims
= sp_tgsi_get_dims
;