1eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/*
2eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Copyright 2016 Red Hat.
3eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie *
4eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Permission is hereby granted, free of charge, to any person obtaining a
5eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * copy of this software and associated documentation files (the "Software"),
6eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * to deal in the Software without restriction, including without limitation
7eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * on the rights to use, copy, modify, merge, publish, distribute, sub
8eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * license, and/or sell copies of the Software, and to permit persons to whom
9eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * the Software is furnished to do so, subject to the following conditions:
10eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie *
11eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * The above copyright notice and this permission notice (including the next
12eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * paragraph) shall be included in all copies or substantial portions of the
13eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Software.
14eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie *
15eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * USE OR OTHER DEALINGS IN THE SOFTWARE.
22eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */
23eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
24eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie#include "sp_context.h"
25eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie#include "sp_image.h"
26eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie#include "sp_texture.h"
27eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
28eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie#include "util/u_format.h"
29eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
30eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/*
31eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Get the offset into the base image
32eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * first element for a buffer or layer/level for texture.
33eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */
34eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic uint32_t
35eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlieget_image_offset(const struct softpipe_resource *spr,
36eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                 const struct pipe_image_view *iview,
37eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                 enum pipe_format format, unsigned r_coord)
38eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
39eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   int base_layer = 0;
40eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
41eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (spr->base.target == PIPE_BUFFER)
42325379096f54dde39171d1b8804e29a8003bb3c7Marek Olšák      return iview->u.buf.offset;
43eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
44eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (spr->base.target == PIPE_TEXTURE_1D_ARRAY ||
45eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie       spr->base.target == PIPE_TEXTURE_2D_ARRAY ||
46eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie       spr->base.target == PIPE_TEXTURE_CUBE_ARRAY ||
47eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie       spr->base.target == PIPE_TEXTURE_CUBE ||
48eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie       spr->base.target == PIPE_TEXTURE_3D)
49eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      base_layer = r_coord + iview->u.tex.first_layer;
50eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   return softpipe_get_tex_image_offset(spr, iview->u.tex.level, base_layer);
51eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
52eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
53eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/*
54eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Does this texture instruction have a layer or depth parameter.
55eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */
56eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic inline bool
57eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliehas_layer_or_depth(unsigned tgsi_tex_instr)
58eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
59eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   return (tgsi_tex_instr == TGSI_TEXTURE_3D ||
60eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           tgsi_tex_instr == TGSI_TEXTURE_CUBE ||
61eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           tgsi_tex_instr == TGSI_TEXTURE_1D_ARRAY ||
62eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           tgsi_tex_instr == TGSI_TEXTURE_2D_ARRAY ||
63eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           tgsi_tex_instr == TGSI_TEXTURE_CUBE_ARRAY ||
64eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           tgsi_tex_instr == TGSI_TEXTURE_2D_ARRAY_MSAA);
65eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
66eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
67eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/*
68eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Is this texture instruction a single non-array coordinate.
69eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */
70eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic inline bool
71eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliehas_1coord(unsigned tgsi_tex_instr)
72eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
73eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   return (tgsi_tex_instr == TGSI_TEXTURE_BUFFER ||
74eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           tgsi_tex_instr == TGSI_TEXTURE_1D ||
75eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           tgsi_tex_instr == TGSI_TEXTURE_1D_ARRAY);
76eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
77eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
78eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/*
79eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * check the bounds vs w/h/d
80eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */
81eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic inline bool
82eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliebounds_check(int width, int height, int depth,
83eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie             int s, int t, int r)
84eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
85eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (s < 0 || s >= width)
86eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return false;
87eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (t < 0 || t >= height)
88eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return false;
89eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (r < 0 || r >= depth)
90eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return false;
91eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   return true;
92eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
93eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
94eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/*
95eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Checks if the texture target compatible with the image resource
96eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * pipe target.
97eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */
98eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic inline bool
99eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliehas_compat_target(unsigned pipe_target, unsigned tgsi_target)
100eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
101eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   switch (pipe_target) {
102eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case PIPE_TEXTURE_1D:
103eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (tgsi_target == TGSI_TEXTURE_1D)
104eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         return true;
105eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
106eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case PIPE_TEXTURE_2D:
107eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (tgsi_target == TGSI_TEXTURE_2D)
108eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         return true;
109eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
110eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case PIPE_TEXTURE_RECT:
111eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (tgsi_target == TGSI_TEXTURE_RECT)
112eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         return true;
113eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
114eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case PIPE_TEXTURE_3D:
115eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (tgsi_target == TGSI_TEXTURE_3D ||
116eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie          tgsi_target == TGSI_TEXTURE_2D)
117eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         return true;
118eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
119eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case PIPE_TEXTURE_CUBE:
120eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (tgsi_target == TGSI_TEXTURE_CUBE ||
121eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie          tgsi_target == TGSI_TEXTURE_2D)
122eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         return true;
123eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
124eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case PIPE_TEXTURE_1D_ARRAY:
125eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (tgsi_target == TGSI_TEXTURE_1D ||
126eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie          tgsi_target == TGSI_TEXTURE_1D_ARRAY)
127eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         return true;
128eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
129eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case PIPE_TEXTURE_2D_ARRAY:
130eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (tgsi_target == TGSI_TEXTURE_2D ||
131eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie          tgsi_target == TGSI_TEXTURE_2D_ARRAY)
132eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         return true;
133eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
134eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case PIPE_TEXTURE_CUBE_ARRAY:
135eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (tgsi_target == TGSI_TEXTURE_CUBE ||
136eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie          tgsi_target == TGSI_TEXTURE_CUBE_ARRAY ||
137eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie          tgsi_target == TGSI_TEXTURE_2D)
138eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         return true;
139eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
140eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case PIPE_BUFFER:
141eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return (tgsi_target == TGSI_TEXTURE_BUFFER);
142eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
143eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   return false;
144eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
145eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
146eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic bool
147eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlieget_dimensions(const struct pipe_image_view *iview,
148eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               const struct softpipe_resource *spr,
149eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               unsigned tgsi_tex_instr,
150eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               enum pipe_format pformat,
151eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               unsigned *width,
152eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               unsigned *height,
153eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               unsigned *depth)
154eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
155eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (tgsi_tex_instr == TGSI_TEXTURE_BUFFER) {
156325379096f54dde39171d1b8804e29a8003bb3c7Marek Olšák      *width = iview->u.buf.size / util_format_get_blocksize(pformat);
157eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      *height = 1;
158eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      *depth = 1;
159eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      /*
160eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie       * Bounds check the buffer size from the view
161eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie       * and the buffer size from the underlying buffer.
162eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie       */
163eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (util_format_get_stride(pformat, *width) >
164eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie          util_format_get_stride(spr->base.format, spr->base.width0))
165eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         return false;
166eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   } else {
167eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      unsigned level;
168eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
169eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      level = spr->base.target == PIPE_BUFFER ? 0 : iview->u.tex.level;
170eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      *width = u_minify(spr->base.width0, level);
171eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      *height = u_minify(spr->base.height0, level);
172eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
173c3b88cc2c15f19e748c9c406e9ab053975adab7eMarek Olšák      if (spr->base.target == PIPE_TEXTURE_3D)
174eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         *depth = u_minify(spr->base.depth0, level);
175eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      else
176eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         *depth = spr->base.array_size;
177eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
178eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      /* Make sure the resource and view have compatiable formats */
179eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (util_format_get_blocksize(pformat) >
180eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie          util_format_get_blocksize(spr->base.format))
181eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         return false;
182eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
183eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   return true;
184eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
185eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
186eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void
187eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliefill_coords(const struct tgsi_image_params *params,
188eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            unsigned index,
189eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            const int s[TGSI_QUAD_SIZE],
190eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            const int t[TGSI_QUAD_SIZE],
191eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            const int r[TGSI_QUAD_SIZE],
192eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            int *s_coord, int *t_coord, int *r_coord)
193eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
194eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   *s_coord = s[index];
195eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   *t_coord = has_1coord(params->tgsi_tex_instr) ? 0 : t[index];
196eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   *r_coord = has_layer_or_depth(params->tgsi_tex_instr) ?
197eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      (params->tgsi_tex_instr == TGSI_TEXTURE_1D_ARRAY ? t[index] : r[index]) : 0;
198eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
199eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/*
200eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Implement the image LOAD operation.
201eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */
202eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void
203eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliesp_tgsi_load(const struct tgsi_image *image,
204eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie             const struct tgsi_image_params *params,
205eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie             const int s[TGSI_QUAD_SIZE],
206eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie             const int t[TGSI_QUAD_SIZE],
207eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie             const int r[TGSI_QUAD_SIZE],
208eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie             const int sample[TGSI_QUAD_SIZE],
209eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie             float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
210eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
211eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct sp_tgsi_image *sp_img = (struct sp_tgsi_image *)image;
212eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct pipe_image_view *iview;
213eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct softpipe_resource *spr;
214eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   unsigned width, height, depth;
215eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   unsigned stride;
216eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   int c, j;
217eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   char *data_ptr;
218eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   unsigned offset = 0;
219eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
2206d6525a377250865cc6baa2c9cd5c6c0b6cd3f9cThomas Hindoe Paaboel Andersen   if (params->unit >= PIPE_MAX_SHADER_IMAGES)
221eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      goto fail_write_all_zero;
222eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   iview = &sp_img->sp_iview[params->unit];
223eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   spr = (struct softpipe_resource *)iview->resource;
224eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (!spr)
225eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      goto fail_write_all_zero;
226eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
227eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (!has_compat_target(spr->base.target, params->tgsi_tex_instr))
228eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      goto fail_write_all_zero;
229eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
230eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (!get_dimensions(iview, spr, params->tgsi_tex_instr,
231eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                       params->format, &width, &height, &depth))
232eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
233eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
234eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   stride = util_format_get_stride(params->format, width);
235eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
236eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
237eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      int s_coord, t_coord, r_coord;
238eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      bool fill_zero = false;
239eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
240eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (!(params->execmask & (1 << j)))
241eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         fill_zero = true;
242eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
243eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      fill_coords(params, j, s, t, r, &s_coord, &t_coord, &r_coord);
244eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (!bounds_check(width, height, depth,
245eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                        s_coord, t_coord, r_coord))
246eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         fill_zero = true;
247eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
248eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (fill_zero) {
249eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int nc = util_format_get_nr_components(params->format);
250eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int ival = util_format_is_pure_integer(params->format);
251eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         for (c = 0; c < 4; c++) {
252eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            rgba[c][j] = 0;
253eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            if (c == 3 && nc < 4) {
254eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               if (ival)
255eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                  ((int32_t *)rgba[c])[j] = 1;
256eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               else
257eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                  rgba[c][j] = 1.0;
258eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            }
259eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         }
260eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         continue;
261eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
262eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      offset = get_image_offset(spr, iview, params->format, r_coord);
263eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      data_ptr = (char *)spr->data + offset;
264eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
265eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (util_format_is_pure_sint(params->format)) {
266eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int32_t sdata[4];
267eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
268eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         util_format_read_4i(params->format,
269eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                             sdata, 0,
270eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                             data_ptr, stride,
271eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                             s_coord, t_coord, 1, 1);
272eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         for (c = 0; c < 4; c++)
273eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            ((int32_t *)rgba[c])[j] = sdata[c];
274eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      } else if (util_format_is_pure_uint(params->format)) {
275eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         uint32_t sdata[4];
276eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         util_format_read_4ui(params->format,
277eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                             sdata, 0,
278eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                             data_ptr, stride,
279eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                             s_coord, t_coord, 1, 1);
280eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         for (c = 0; c < 4; c++)
281eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            ((uint32_t *)rgba[c])[j] = sdata[c];
282eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      } else {
283eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         float sdata[4];
284eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         util_format_read_4f(params->format,
285eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                             sdata, 0,
286eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                             data_ptr, stride,
287eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                             s_coord, t_coord, 1, 1);
288eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         for (c = 0; c < 4; c++)
289eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            rgba[c][j] = sdata[c];
290eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
291eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
292eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   return;
293eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliefail_write_all_zero:
294eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
295eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < 4; c++)
296eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         rgba[c][j] = 0;
297eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
298eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   return;
299eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
300eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
301eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/*
302eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Implement the image STORE operation.
303eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */
304eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void
305eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliesp_tgsi_store(const struct tgsi_image *image,
306eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              const struct tgsi_image_params *params,
307eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              const int s[TGSI_QUAD_SIZE],
308eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              const int t[TGSI_QUAD_SIZE],
309eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              const int r[TGSI_QUAD_SIZE],
310eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              const int sample[TGSI_QUAD_SIZE],
311eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
312eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
313eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct sp_tgsi_image *sp_img = (struct sp_tgsi_image *)image;
314eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct pipe_image_view *iview;
315eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct softpipe_resource *spr;
316eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   unsigned width, height, depth;
317eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   unsigned stride;
318eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   char *data_ptr;
319eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   int j, c;
320eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   unsigned offset = 0;
321eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   unsigned pformat = params->format;
322eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
3236d6525a377250865cc6baa2c9cd5c6c0b6cd3f9cThomas Hindoe Paaboel Andersen   if (params->unit >= PIPE_MAX_SHADER_IMAGES)
324eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
325eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   iview = &sp_img->sp_iview[params->unit];
326eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   spr = (struct softpipe_resource *)iview->resource;
327eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (!spr)
328eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
329eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (!has_compat_target(spr->base.target, params->tgsi_tex_instr))
330eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
331eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
332eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (params->format == PIPE_FORMAT_NONE)
333eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      pformat = spr->base.format;
334eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
335eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (!get_dimensions(iview, spr, params->tgsi_tex_instr,
336eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                       pformat, &width, &height, &depth))
337eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
338eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
339eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   stride = util_format_get_stride(pformat, width);
340eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
341eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
342eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      int s_coord, t_coord, r_coord;
343eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
344eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (!(params->execmask & (1 << j)))
345eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         continue;
346eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
347eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      fill_coords(params, j, s, t, r, &s_coord, &t_coord, &r_coord);
348eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (!bounds_check(width, height, depth,
349eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                        s_coord, t_coord, r_coord))
350eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         continue;
351eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
352eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      offset = get_image_offset(spr, iview, pformat, r_coord);
353eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      data_ptr = (char *)spr->data + offset;
354eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
355eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (util_format_is_pure_sint(pformat)) {
356eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int32_t sdata[4];
357eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         for (c = 0; c < 4; c++)
358eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            sdata[c] = ((int32_t *)rgba[c])[j];
359eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         util_format_write_4i(pformat, sdata, 0, data_ptr, stride,
360eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                              s_coord, t_coord, 1, 1);
361eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      } else if (util_format_is_pure_uint(pformat)) {
362eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         uint32_t sdata[4];
363eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         for (c = 0; c < 4; c++)
364eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            sdata[c] = ((uint32_t *)rgba[c])[j];
365eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         util_format_write_4ui(pformat, sdata, 0, data_ptr, stride,
366eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                               s_coord, t_coord, 1, 1);
367eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      } else {
368eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         float sdata[4];
369eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         for (c = 0; c < 4; c++)
370eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            sdata[c] = rgba[c][j];
371eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         util_format_write_4f(pformat, sdata, 0, data_ptr, stride,
372eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                              s_coord, t_coord, 1, 1);
373eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
374eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
375eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
376eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
377eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/*
378eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Implement atomic operations on unsigned integers.
379eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */
380eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void
381eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliehandle_op_uint(const struct pipe_image_view *iview,
382eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               const struct tgsi_image_params *params,
383eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               bool just_read,
384eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               char *data_ptr,
385eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               uint qi,
386eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               unsigned stride,
387eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               unsigned opcode,
388eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               int s,
389eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               int t,
390eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
391eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
392eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
393eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   uint c;
394eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   int nc = util_format_get_nr_components(params->format);
395eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   unsigned sdata[4];
396eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
397eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   util_format_read_4ui(params->format,
398eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                        sdata, 0,
399eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                        data_ptr, stride,
400eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                        s, t, 1, 1);
401eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
402eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (just_read) {
403eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
404eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((uint32_t *)rgba[c])[qi] = sdata[c];
405eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
406eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
407eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
408eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   switch (opcode) {
409eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMUADD:
410eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
411eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned temp = sdata[c];
412eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] += ((uint32_t *)rgba[c])[qi];
413eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((uint32_t *)rgba[c])[qi] = temp;
414eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
415eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
416eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMXCHG:
417eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
418eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned temp = sdata[c];
419eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] = ((uint32_t *)rgba[c])[qi];
420eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((uint32_t *)rgba[c])[qi] = temp;
421eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
422eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
423eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMCAS:
424eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
425eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned dst_x = sdata[c];
426eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned cmp_x = ((uint32_t *)rgba[c])[qi];
427eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned src_x = ((uint32_t *)rgba2[c])[qi];
428eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned temp = sdata[c];
429eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] = (dst_x == cmp_x) ? src_x : dst_x;
430eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((uint32_t *)rgba[c])[qi] = temp;
431eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
432eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
433eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMAND:
434eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
435eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned temp = sdata[c];
436eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] &= ((uint32_t *)rgba[c])[qi];
437eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((uint32_t *)rgba[c])[qi] = temp;
438eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
439eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
440eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMOR:
441eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
442eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned temp = sdata[c];
443eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] |= ((uint32_t *)rgba[c])[qi];
444eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((uint32_t *)rgba[c])[qi] = temp;
445eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
446eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
447eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMXOR:
448eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
449eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned temp = sdata[c];
450eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] ^= ((uint32_t *)rgba[c])[qi];
451eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((uint32_t *)rgba[c])[qi] = temp;
452eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
453eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
454eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMUMIN:
455eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
456eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned dst_x = sdata[c];
457eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned src_x = ((uint32_t *)rgba[c])[qi];
458eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] = MIN2(dst_x, src_x);
459eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((uint32_t *)rgba[c])[qi] = dst_x;
460eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
461eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
462eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMUMAX:
463eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
464eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned dst_x = sdata[c];
465eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         unsigned src_x = ((uint32_t *)rgba[c])[qi];
466eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] = MAX2(dst_x, src_x);
467eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((uint32_t *)rgba[c])[qi] = dst_x;
468eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
469eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
470eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMIMIN:
471eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
472eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int dst_x = sdata[c];
473eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int src_x = ((uint32_t *)rgba[c])[qi];
474eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] = MIN2(dst_x, src_x);
475eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((uint32_t *)rgba[c])[qi] = dst_x;
476eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
477eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
478eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMIMAX:
479eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
480eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int dst_x = sdata[c];
481eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int src_x = ((uint32_t *)rgba[c])[qi];
482eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] = MAX2(dst_x, src_x);
483eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((uint32_t *)rgba[c])[qi] = dst_x;
484eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
485eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
486eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   default:
487eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      assert(!"Unexpected TGSI opcode in sp_tgsi_op");
488eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
489eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
490eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   util_format_write_4ui(params->format, sdata, 0, data_ptr, stride,
491eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                         s, t, 1, 1);
492eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
493eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
494eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/*
495eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Implement atomic operations on signed integers.
496eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */
497eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void
498eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliehandle_op_int(const struct pipe_image_view *iview,
499eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              const struct tgsi_image_params *params,
500eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              bool just_read,
501eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              char *data_ptr,
502eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              uint qi,
503eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              unsigned stride,
504eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              unsigned opcode,
505eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              int s,
506eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              int t,
507eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
508eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie              float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
509eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
510eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   uint c;
511eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   int nc = util_format_get_nr_components(params->format);
512eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   int sdata[4];
513eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   util_format_read_4i(params->format,
514eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                       sdata, 0,
515eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                       data_ptr, stride,
516eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                       s, t, 1, 1);
517eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
518eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (just_read) {
519eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
520eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((int32_t *)rgba[c])[qi] = sdata[c];
521eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
522eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
523eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
524eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   switch (opcode) {
525eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMUADD:
526eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
527eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int temp = sdata[c];
528eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] += ((int32_t *)rgba[c])[qi];
529eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((int32_t *)rgba[c])[qi] = temp;
530eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
531eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
532eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMXCHG:
533eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
534eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int temp = sdata[c];
535eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] = ((int32_t *)rgba[c])[qi];
536eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((int32_t *)rgba[c])[qi] = temp;
537eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
538eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
539eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMCAS:
540eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
541eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int dst_x = sdata[c];
542eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int cmp_x = ((int32_t *)rgba[c])[qi];
543eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int src_x = ((int32_t *)rgba2[c])[qi];
544eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int temp = sdata[c];
545eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] = (dst_x == cmp_x) ? src_x : dst_x;
546eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((int32_t *)rgba[c])[qi] = temp;
547eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
548eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
549eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMAND:
550eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
551eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int temp = sdata[c];
552eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] &= ((int32_t *)rgba[c])[qi];
553eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((int32_t *)rgba[c])[qi] = temp;
554eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
555eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
556eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMOR:
557eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
558eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int temp = sdata[c];
559eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] |= ((int32_t *)rgba[c])[qi];
560eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((int32_t *)rgba[c])[qi] = temp;
561eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
562eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
563eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMXOR:
564eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
565eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int temp = sdata[c];
566eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] ^= ((int32_t *)rgba[c])[qi];
567eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((int32_t *)rgba[c])[qi] = temp;
568eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
569eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
570eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMUMIN:
571eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
572eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int dst_x = sdata[c];
573eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int src_x = ((int32_t *)rgba[c])[qi];
574eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] = MIN2(dst_x, src_x);
575eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((int32_t *)rgba[c])[qi] = dst_x;
576eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
577eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
578eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMUMAX:
579eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
580eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int dst_x = sdata[c];
581eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int src_x = ((int32_t *)rgba[c])[qi];
582eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] = MAX2(dst_x, src_x);
583eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((int32_t *)rgba[c])[qi] = dst_x;
584eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
585eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
586eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMIMIN:
587eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
588eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int dst_x = sdata[c];
589eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int src_x = ((int32_t *)rgba[c])[qi];
590eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] = MIN2(dst_x, src_x);
591eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((int32_t *)rgba[c])[qi] = dst_x;
592eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
593eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
594eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_OPCODE_ATOMIMAX:
595eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < nc; c++) {
596eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int dst_x = sdata[c];
597eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int src_x = ((int32_t *)rgba[c])[qi];
598eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         sdata[c] = MAX2(dst_x, src_x);
599eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         ((int32_t *)rgba[c])[qi] = dst_x;
600eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
601eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
602eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   default:
603eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      assert(!"Unexpected TGSI opcode in sp_tgsi_op");
604eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
605eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
606eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   util_format_write_4i(params->format, sdata, 0, data_ptr, stride,
607eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                        s, t, 1, 1);
608eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
609eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
610277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie/* GLES OES_shader_image_atomic.txt allows XCHG on R32F */
611277170eeea00e001635aa0c8ac90012a6f98f299Dave Airliestatic void
612277170eeea00e001635aa0c8ac90012a6f98f299Dave Airliehandle_op_r32f_xchg(const struct pipe_image_view *iview,
613277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                    const struct tgsi_image_params *params,
614277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                    bool just_read,
615277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                    char *data_ptr,
616277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                    uint qi,
617277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                    unsigned stride,
618277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                    unsigned opcode,
619277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                    int s,
620277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                    int t,
621277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
622277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie{
623277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie   float sdata[4];
624277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie   uint c;
625277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie   int nc = 1;
626277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie   util_format_read_4f(params->format,
627277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                       sdata, 0,
628277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                       data_ptr, stride,
629277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                       s, t, 1, 1);
630277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie   if (just_read) {
631277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie      for (c = 0; c < nc; c++) {
632277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie         ((int32_t *)rgba[c])[qi] = sdata[c];
633277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie      }
634277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie      return;
635277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie   }
636277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie
637277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie   for (c = 0; c < nc; c++) {
638277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie      int temp = sdata[c];
639277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie      sdata[c] = ((float *)rgba[c])[qi];
640277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie      ((float *)rgba[c])[qi] = temp;
641277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie   }
642277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie   util_format_write_4f(params->format, sdata, 0, data_ptr, stride,
643277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                        s, t, 1, 1);
644277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie}
645277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie
646eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie/*
647eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie * Implement atomic image operations.
648eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie */
649eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void
650eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliesp_tgsi_op(const struct tgsi_image *image,
651eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           const struct tgsi_image_params *params,
652eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           unsigned opcode,
653eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           const int s[TGSI_QUAD_SIZE],
654eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           const int t[TGSI_QUAD_SIZE],
655eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           const int r[TGSI_QUAD_SIZE],
656eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           const int sample[TGSI_QUAD_SIZE],
657eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
658eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie           float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
659eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
660eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct sp_tgsi_image *sp_img = (struct sp_tgsi_image *)image;
661eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct pipe_image_view *iview;
662eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct softpipe_resource *spr;
663eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   unsigned width, height, depth;
664eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   unsigned stride;
665eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   int j, c;
666eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   unsigned offset;
667eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   char *data_ptr;
668eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
6696d6525a377250865cc6baa2c9cd5c6c0b6cd3f9cThomas Hindoe Paaboel Andersen   if (params->unit >= PIPE_MAX_SHADER_IMAGES)
670eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
671eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   iview = &sp_img->sp_iview[params->unit];
672eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   spr = (struct softpipe_resource *)iview->resource;
673eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (!spr)
674eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      goto fail_write_all_zero;
675eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (!has_compat_target(spr->base.target, params->tgsi_tex_instr))
676eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      goto fail_write_all_zero;
677eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
678eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (!get_dimensions(iview, spr, params->tgsi_tex_instr,
679eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                       params->format, &width, &height, &depth))
680eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      goto fail_write_all_zero;
681eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
682eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   stride = util_format_get_stride(spr->base.format, width);
683eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
684eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
685eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      int s_coord, t_coord, r_coord;
686eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      bool just_read = false;
687eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
688eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      fill_coords(params, j, s, t, r, &s_coord, &t_coord, &r_coord);
689eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (!bounds_check(width, height, depth,
690eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                        s_coord, t_coord, r_coord)) {
691eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int nc = util_format_get_nr_components(params->format);
692eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int ival = util_format_is_pure_integer(params->format);
693eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         int c;
694eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         for (c = 0; c < 4; c++) {
695eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            rgba[c][j] = 0;
696eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            if (c == 3 && nc < 4) {
697eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               if (ival)
698eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                  ((int32_t *)rgba[c])[j] = 1;
699eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie               else
700eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                  rgba[c][j] = 1.0;
701eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie            }
702eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         }
703eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         continue;
704eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
705eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
706eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      /* just readback the value for atomic if execmask isn't set */
707eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (!(params->execmask & (1 << j))) {
708eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         just_read = true;
709eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      }
710eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
711eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      offset = get_image_offset(spr, iview, params->format, r_coord);
712eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      data_ptr = (char *)spr->data + offset;
713eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
714eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      /* we should see atomic operations on r32 formats */
715eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      if (util_format_is_pure_uint(params->format))
716eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         handle_op_uint(iview, params, just_read, data_ptr, j, stride,
717eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                        opcode, s_coord, t_coord, rgba, rgba2);
718eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      else if (util_format_is_pure_sint(params->format))
719eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         handle_op_int(iview, params, just_read, data_ptr, j, stride,
720eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                       opcode, s_coord, t_coord, rgba, rgba2);
721277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie      else if (params->format == PIPE_FORMAT_R32_FLOAT &&
722277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie               opcode == TGSI_OPCODE_ATOMXCHG)
723277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie         handle_op_r32f_xchg(iview, params, just_read, data_ptr, j, stride,
724277170eeea00e001635aa0c8ac90012a6f98f299Dave Airlie                             opcode, s_coord, t_coord, rgba);
725eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      else
726eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         assert(0);
727eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
728eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   return;
729eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliefail_write_all_zero:
730eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
731eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      for (c = 0; c < 4; c++)
732eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie         rgba[c][j] = 0;
733eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
734eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   return;
735eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
736eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
737eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestatic void
738eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliesp_tgsi_get_dims(const struct tgsi_image *image,
739eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                 const struct tgsi_image_params *params,
740eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie                 int dims[4])
741eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
742eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct sp_tgsi_image *sp_img = (struct sp_tgsi_image *)image;
743eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct pipe_image_view *iview;
744eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct softpipe_resource *spr;
745eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   int level;
746eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
7476d6525a377250865cc6baa2c9cd5c6c0b6cd3f9cThomas Hindoe Paaboel Andersen   if (params->unit >= PIPE_MAX_SHADER_IMAGES)
748eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
749eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   iview = &sp_img->sp_iview[params->unit];
750eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   spr = (struct softpipe_resource *)iview->resource;
751eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (!spr)
752eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
753eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
754eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (params->tgsi_tex_instr == TGSI_TEXTURE_BUFFER) {
755325379096f54dde39171d1b8804e29a8003bb3c7Marek Olšák      dims[0] = iview->u.buf.size / util_format_get_blocksize(iview->format);
756eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      dims[1] = dims[2] = dims[3] = 0;
757eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
758eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
759eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
760eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   level = iview->u.tex.level;
761eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   dims[0] = u_minify(spr->base.width0, level);
762eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   switch (params->tgsi_tex_instr) {
763eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_TEXTURE_1D_ARRAY:
764eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      dims[1] = iview->u.tex.last_layer - iview->u.tex.first_layer + 1;
765eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      /* fallthrough */
766eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_TEXTURE_1D:
767eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
768eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_TEXTURE_2D_ARRAY:
769eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      dims[2] = iview->u.tex.last_layer - iview->u.tex.first_layer + 1;
770eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      /* fallthrough */
771eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_TEXTURE_2D:
772eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_TEXTURE_CUBE:
773eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_TEXTURE_RECT:
774eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      dims[1] = u_minify(spr->base.height0, level);
775eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
776eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_TEXTURE_3D:
777eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      dims[1] = u_minify(spr->base.height0, level);
778eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      dims[2] = u_minify(spr->base.depth0, level);
779eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
780eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   case TGSI_TEXTURE_CUBE_ARRAY:
781eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      dims[1] = u_minify(spr->base.height0, level);
782eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      dims[2] = (iview->u.tex.last_layer - iview->u.tex.first_layer + 1) / 6;
783eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      break;
784eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   default:
785eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      assert(!"unexpected texture target in sp_get_dims()");
786eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return;
787eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   }
788eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie}
789eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
790eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliestruct sp_tgsi_image *
791eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airliesp_create_tgsi_image(void)
792eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie{
793eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   struct sp_tgsi_image *img = CALLOC_STRUCT(sp_tgsi_image);
794eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   if (!img)
795eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie      return NULL;
796eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie
797eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   img->base.load = sp_tgsi_load;
798eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   img->base.store = sp_tgsi_store;
799eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   img->base.op = sp_tgsi_op;
800eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   img->base.get_dims = sp_tgsi_get_dims;
801eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie   return img;
802eb9ad9faa3975fc4f044b81d3b4b793866ef5563Dave Airlie};
803