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
;
266 util_format_read_4(params
->format
,
269 s_coord
, t_coord
, 1, 1);
270 for (c
= 0; c
< 4; c
++)
271 ((uint32_t *)rgba
[c
])[j
] = sdata
[c
];
275 for (j
= 0; j
< TGSI_QUAD_SIZE
; j
++) {
276 for (c
= 0; c
< 4; c
++)
283 * Implement the image STORE operation.
286 sp_tgsi_store(const struct tgsi_image
*image
,
287 const struct tgsi_image_params
*params
,
288 const int s
[TGSI_QUAD_SIZE
],
289 const int t
[TGSI_QUAD_SIZE
],
290 const int r
[TGSI_QUAD_SIZE
],
291 const int sample
[TGSI_QUAD_SIZE
],
292 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
294 struct sp_tgsi_image
*sp_img
= (struct sp_tgsi_image
*)image
;
295 struct pipe_image_view
*iview
;
296 struct softpipe_resource
*spr
;
297 unsigned width
, height
, depth
;
302 unsigned pformat
= params
->format
;
304 if (params
->unit
>= PIPE_MAX_SHADER_IMAGES
)
306 iview
= &sp_img
->sp_iview
[params
->unit
];
307 spr
= (struct softpipe_resource
*)iview
->resource
;
310 if (!has_compat_target(spr
->base
.target
, params
->tgsi_tex_instr
))
313 if (params
->format
== PIPE_FORMAT_NONE
)
314 pformat
= spr
->base
.format
;
316 if (!get_dimensions(iview
, spr
, params
->tgsi_tex_instr
,
317 pformat
, &width
, &height
, &depth
))
320 stride
= util_format_get_stride(pformat
, width
);
322 for (j
= 0; j
< TGSI_QUAD_SIZE
; j
++) {
323 int s_coord
, t_coord
, r_coord
;
325 if (!(params
->execmask
& (1 << j
)))
328 fill_coords(params
, j
, s
, t
, r
, &s_coord
, &t_coord
, &r_coord
);
329 if (!bounds_check(width
, height
, depth
,
330 s_coord
, t_coord
, r_coord
))
333 offset
= get_image_offset(spr
, iview
, pformat
, r_coord
);
334 data_ptr
= (char *)spr
->data
+ offset
;
337 for (c
= 0; c
< 4; c
++)
338 sdata
[c
] = ((uint32_t *)rgba
[c
])[j
];
339 util_format_write_4(pformat
, sdata
, 0, data_ptr
, stride
,
340 s_coord
, t_coord
, 1, 1);
345 * Implement atomic operations on unsigned integers.
348 handle_op_uint(const struct pipe_image_view
*iview
,
349 const struct tgsi_image_params
*params
,
354 enum tgsi_opcode opcode
,
357 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
],
358 float rgba2
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
361 int nc
= util_format_get_nr_components(params
->format
);
364 util_format_read_4(params
->format
,
370 for (c
= 0; c
< nc
; c
++) {
371 ((uint32_t *)rgba
[c
])[qi
] = sdata
[c
];
376 case TGSI_OPCODE_ATOMUADD
:
377 for (c
= 0; c
< nc
; c
++) {
378 unsigned temp
= sdata
[c
];
379 sdata
[c
] += ((uint32_t *)rgba
[c
])[qi
];
380 ((uint32_t *)rgba
[c
])[qi
] = temp
;
383 case TGSI_OPCODE_ATOMXCHG
:
384 for (c
= 0; c
< nc
; c
++) {
385 unsigned temp
= sdata
[c
];
386 sdata
[c
] = ((uint32_t *)rgba
[c
])[qi
];
387 ((uint32_t *)rgba
[c
])[qi
] = temp
;
390 case TGSI_OPCODE_ATOMCAS
:
391 for (c
= 0; c
< nc
; c
++) {
392 unsigned dst_x
= sdata
[c
];
393 unsigned cmp_x
= ((uint32_t *)rgba
[c
])[qi
];
394 unsigned src_x
= ((uint32_t *)rgba2
[c
])[qi
];
395 unsigned temp
= sdata
[c
];
396 sdata
[c
] = (dst_x
== cmp_x
) ? src_x
: dst_x
;
397 ((uint32_t *)rgba
[c
])[qi
] = temp
;
400 case TGSI_OPCODE_ATOMAND
:
401 for (c
= 0; c
< nc
; c
++) {
402 unsigned temp
= sdata
[c
];
403 sdata
[c
] &= ((uint32_t *)rgba
[c
])[qi
];
404 ((uint32_t *)rgba
[c
])[qi
] = temp
;
407 case TGSI_OPCODE_ATOMOR
:
408 for (c
= 0; c
< nc
; c
++) {
409 unsigned temp
= sdata
[c
];
410 sdata
[c
] |= ((uint32_t *)rgba
[c
])[qi
];
411 ((uint32_t *)rgba
[c
])[qi
] = temp
;
414 case TGSI_OPCODE_ATOMXOR
:
415 for (c
= 0; c
< nc
; c
++) {
416 unsigned temp
= sdata
[c
];
417 sdata
[c
] ^= ((uint32_t *)rgba
[c
])[qi
];
418 ((uint32_t *)rgba
[c
])[qi
] = temp
;
421 case TGSI_OPCODE_ATOMUMIN
:
422 for (c
= 0; c
< nc
; c
++) {
423 unsigned dst_x
= sdata
[c
];
424 unsigned src_x
= ((uint32_t *)rgba
[c
])[qi
];
425 sdata
[c
] = MIN2(dst_x
, src_x
);
426 ((uint32_t *)rgba
[c
])[qi
] = dst_x
;
429 case TGSI_OPCODE_ATOMUMAX
:
430 for (c
= 0; c
< nc
; c
++) {
431 unsigned dst_x
= sdata
[c
];
432 unsigned src_x
= ((uint32_t *)rgba
[c
])[qi
];
433 sdata
[c
] = MAX2(dst_x
, src_x
);
434 ((uint32_t *)rgba
[c
])[qi
] = dst_x
;
437 case TGSI_OPCODE_ATOMIMIN
:
438 for (c
= 0; c
< nc
; c
++) {
439 int dst_x
= sdata
[c
];
440 int src_x
= ((uint32_t *)rgba
[c
])[qi
];
441 sdata
[c
] = MIN2(dst_x
, src_x
);
442 ((uint32_t *)rgba
[c
])[qi
] = dst_x
;
445 case TGSI_OPCODE_ATOMIMAX
:
446 for (c
= 0; c
< nc
; c
++) {
447 int dst_x
= sdata
[c
];
448 int src_x
= ((uint32_t *)rgba
[c
])[qi
];
449 sdata
[c
] = MAX2(dst_x
, src_x
);
450 ((uint32_t *)rgba
[c
])[qi
] = dst_x
;
454 assert(!"Unexpected TGSI opcode in sp_tgsi_op");
457 util_format_write_4(params
->format
, sdata
, 0, data_ptr
, stride
,
462 * Implement atomic operations on signed integers.
465 handle_op_int(const struct pipe_image_view
*iview
,
466 const struct tgsi_image_params
*params
,
471 enum tgsi_opcode opcode
,
474 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
],
475 float rgba2
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
478 int nc
= util_format_get_nr_components(params
->format
);
480 util_format_read_4(params
->format
,
486 for (c
= 0; c
< nc
; c
++) {
487 ((int32_t *)rgba
[c
])[qi
] = sdata
[c
];
492 case TGSI_OPCODE_ATOMUADD
:
493 for (c
= 0; c
< nc
; c
++) {
495 sdata
[c
] += ((int32_t *)rgba
[c
])[qi
];
496 ((int32_t *)rgba
[c
])[qi
] = temp
;
499 case TGSI_OPCODE_ATOMXCHG
:
500 for (c
= 0; c
< nc
; c
++) {
502 sdata
[c
] = ((int32_t *)rgba
[c
])[qi
];
503 ((int32_t *)rgba
[c
])[qi
] = temp
;
506 case TGSI_OPCODE_ATOMCAS
:
507 for (c
= 0; c
< nc
; c
++) {
508 int dst_x
= sdata
[c
];
509 int cmp_x
= ((int32_t *)rgba
[c
])[qi
];
510 int src_x
= ((int32_t *)rgba2
[c
])[qi
];
512 sdata
[c
] = (dst_x
== cmp_x
) ? src_x
: dst_x
;
513 ((int32_t *)rgba
[c
])[qi
] = temp
;
516 case TGSI_OPCODE_ATOMAND
:
517 for (c
= 0; c
< nc
; c
++) {
519 sdata
[c
] &= ((int32_t *)rgba
[c
])[qi
];
520 ((int32_t *)rgba
[c
])[qi
] = temp
;
523 case TGSI_OPCODE_ATOMOR
:
524 for (c
= 0; c
< nc
; c
++) {
526 sdata
[c
] |= ((int32_t *)rgba
[c
])[qi
];
527 ((int32_t *)rgba
[c
])[qi
] = temp
;
530 case TGSI_OPCODE_ATOMXOR
:
531 for (c
= 0; c
< nc
; c
++) {
533 sdata
[c
] ^= ((int32_t *)rgba
[c
])[qi
];
534 ((int32_t *)rgba
[c
])[qi
] = temp
;
537 case TGSI_OPCODE_ATOMUMIN
:
538 for (c
= 0; c
< nc
; c
++) {
539 int dst_x
= sdata
[c
];
540 int src_x
= ((int32_t *)rgba
[c
])[qi
];
541 sdata
[c
] = MIN2(dst_x
, src_x
);
542 ((int32_t *)rgba
[c
])[qi
] = dst_x
;
545 case TGSI_OPCODE_ATOMUMAX
:
546 for (c
= 0; c
< nc
; c
++) {
547 int dst_x
= sdata
[c
];
548 int src_x
= ((int32_t *)rgba
[c
])[qi
];
549 sdata
[c
] = MAX2(dst_x
, src_x
);
550 ((int32_t *)rgba
[c
])[qi
] = dst_x
;
553 case TGSI_OPCODE_ATOMIMIN
:
554 for (c
= 0; c
< nc
; c
++) {
555 int dst_x
= sdata
[c
];
556 int src_x
= ((int32_t *)rgba
[c
])[qi
];
557 sdata
[c
] = MIN2(dst_x
, src_x
);
558 ((int32_t *)rgba
[c
])[qi
] = dst_x
;
561 case TGSI_OPCODE_ATOMIMAX
:
562 for (c
= 0; c
< nc
; c
++) {
563 int dst_x
= sdata
[c
];
564 int src_x
= ((int32_t *)rgba
[c
])[qi
];
565 sdata
[c
] = MAX2(dst_x
, src_x
);
566 ((int32_t *)rgba
[c
])[qi
] = dst_x
;
570 assert(!"Unexpected TGSI opcode in sp_tgsi_op");
573 util_format_write_4(params
->format
, sdata
, 0, data_ptr
, stride
,
577 /* GLES OES_shader_image_atomic.txt allows XCHG on R32F */
579 handle_op_r32f_xchg(const struct pipe_image_view
*iview
,
580 const struct tgsi_image_params
*params
,
585 enum tgsi_opcode opcode
,
588 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
593 util_format_read_4(params
->format
,
598 for (c
= 0; c
< nc
; c
++) {
599 ((int32_t *)rgba
[c
])[qi
] = sdata
[c
];
604 for (c
= 0; c
< nc
; c
++) {
606 sdata
[c
] = ((float *)rgba
[c
])[qi
];
607 ((float *)rgba
[c
])[qi
] = temp
;
609 util_format_write_4(params
->format
, sdata
, 0, data_ptr
, stride
,
614 * Implement atomic image operations.
617 sp_tgsi_op(const struct tgsi_image
*image
,
618 const struct tgsi_image_params
*params
,
619 enum tgsi_opcode opcode
,
620 const int s
[TGSI_QUAD_SIZE
],
621 const int t
[TGSI_QUAD_SIZE
],
622 const int r
[TGSI_QUAD_SIZE
],
623 const int sample
[TGSI_QUAD_SIZE
],
624 float rgba
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
],
625 float rgba2
[TGSI_NUM_CHANNELS
][TGSI_QUAD_SIZE
])
627 struct sp_tgsi_image
*sp_img
= (struct sp_tgsi_image
*)image
;
628 struct pipe_image_view
*iview
;
629 struct softpipe_resource
*spr
;
630 unsigned width
, height
, depth
;
636 if (params
->unit
>= PIPE_MAX_SHADER_IMAGES
)
638 iview
= &sp_img
->sp_iview
[params
->unit
];
639 spr
= (struct softpipe_resource
*)iview
->resource
;
641 goto fail_write_all_zero
;
642 if (!has_compat_target(spr
->base
.target
, params
->tgsi_tex_instr
))
643 goto fail_write_all_zero
;
645 if (!get_dimensions(iview
, spr
, params
->tgsi_tex_instr
,
646 params
->format
, &width
, &height
, &depth
))
647 goto fail_write_all_zero
;
649 stride
= util_format_get_stride(spr
->base
.format
, width
);
651 for (j
= 0; j
< TGSI_QUAD_SIZE
; j
++) {
652 int s_coord
, t_coord
, r_coord
;
653 bool just_read
= false;
655 fill_coords(params
, j
, s
, t
, r
, &s_coord
, &t_coord
, &r_coord
);
656 if (!bounds_check(width
, height
, depth
,
657 s_coord
, t_coord
, r_coord
)) {
658 int nc
= util_format_get_nr_components(params
->format
);
659 int ival
= util_format_is_pure_integer(params
->format
);
661 for (c
= 0; c
< 4; c
++) {
663 if (c
== 3 && nc
< 4) {
665 ((int32_t *)rgba
[c
])[j
] = 1;
673 /* just readback the value for atomic if execmask isn't set */
674 if (!(params
->execmask
& (1 << j
))) {
678 offset
= get_image_offset(spr
, iview
, params
->format
, r_coord
);
679 data_ptr
= (char *)spr
->data
+ offset
;
681 /* we should see atomic operations on r32 formats */
682 if (util_format_is_pure_uint(params
->format
))
683 handle_op_uint(iview
, params
, just_read
, data_ptr
, j
, stride
,
684 opcode
, s_coord
, t_coord
, rgba
, rgba2
);
685 else if (util_format_is_pure_sint(params
->format
))
686 handle_op_int(iview
, params
, just_read
, data_ptr
, j
, stride
,
687 opcode
, s_coord
, t_coord
, rgba
, rgba2
);
688 else if (params
->format
== PIPE_FORMAT_R32_FLOAT
&&
689 opcode
== TGSI_OPCODE_ATOMXCHG
)
690 handle_op_r32f_xchg(iview
, params
, just_read
, data_ptr
, j
, stride
,
691 opcode
, s_coord
, t_coord
, rgba
);
697 for (j
= 0; j
< TGSI_QUAD_SIZE
; j
++) {
698 for (c
= 0; c
< 4; c
++)
705 sp_tgsi_get_dims(const struct tgsi_image
*image
,
706 const struct tgsi_image_params
*params
,
709 struct sp_tgsi_image
*sp_img
= (struct sp_tgsi_image
*)image
;
710 struct pipe_image_view
*iview
;
711 struct softpipe_resource
*spr
;
714 if (params
->unit
>= PIPE_MAX_SHADER_IMAGES
)
716 iview
= &sp_img
->sp_iview
[params
->unit
];
717 spr
= (struct softpipe_resource
*)iview
->resource
;
721 if (params
->tgsi_tex_instr
== TGSI_TEXTURE_BUFFER
) {
722 dims
[0] = iview
->u
.buf
.size
/ util_format_get_blocksize(iview
->format
);
723 dims
[1] = dims
[2] = dims
[3] = 0;
727 level
= iview
->u
.tex
.level
;
728 dims
[0] = u_minify(spr
->base
.width0
, level
);
729 switch (params
->tgsi_tex_instr
) {
730 case TGSI_TEXTURE_1D_ARRAY
:
731 dims
[1] = iview
->u
.tex
.last_layer
- iview
->u
.tex
.first_layer
+ 1;
733 case TGSI_TEXTURE_1D
:
735 case TGSI_TEXTURE_2D_ARRAY
:
736 dims
[2] = iview
->u
.tex
.last_layer
- iview
->u
.tex
.first_layer
+ 1;
738 case TGSI_TEXTURE_2D
:
739 case TGSI_TEXTURE_CUBE
:
740 case TGSI_TEXTURE_RECT
:
741 dims
[1] = u_minify(spr
->base
.height0
, level
);
743 case TGSI_TEXTURE_3D
:
744 dims
[1] = u_minify(spr
->base
.height0
, level
);
745 dims
[2] = u_minify(spr
->base
.depth0
, level
);
747 case TGSI_TEXTURE_CUBE_ARRAY
:
748 dims
[1] = u_minify(spr
->base
.height0
, level
);
749 dims
[2] = (iview
->u
.tex
.last_layer
- iview
->u
.tex
.first_layer
+ 1) / 6;
752 assert(!"unexpected texture target in sp_get_dims()");
757 struct sp_tgsi_image
*
758 sp_create_tgsi_image(void)
760 struct sp_tgsi_image
*img
= CALLOC_STRUCT(sp_tgsi_image
);
764 img
->base
.load
= sp_tgsi_load
;
765 img
->base
.store
= sp_tgsi_store
;
766 img
->base
.op
= sp_tgsi_op
;
767 img
->base
.get_dims
= sp_tgsi_get_dims
;