1
2#ifndef __NV50_BLIT_H__
3#define __NV50_BLIT_H__
4
5#include "util/u_inlines.h"
6#include "util/u_format.h"
7
8void *
9nv50_blitter_make_fp(struct pipe_context *,
10                     unsigned mode,
11                     enum pipe_texture_target);
12
13unsigned
14nv50_blit_select_mode(const struct pipe_blit_info *);
15
16/* Converted to a pipe->blit. */
17void
18nv50_resource_resolve(struct pipe_context *, const struct pipe_resolve_info *);
19
20#define NV50_BLIT_MODE_PASS  0 /* pass through TEX $t0/$s0 output */
21#define NV50_BLIT_MODE_Z24S8 1 /* encode ZS values for RGBA unorm8 */
22#define NV50_BLIT_MODE_S8Z24 2
23#define NV50_BLIT_MODE_X24S8 3
24#define NV50_BLIT_MODE_S8X24 4
25#define NV50_BLIT_MODE_Z24X8 5
26#define NV50_BLIT_MODE_X8Z24 6
27#define NV50_BLIT_MODE_ZS    7 /* put $t0/$s0 into R, $t1/$s1 into G */
28#define NV50_BLIT_MODE_XS    8 /* put $t1/$s1 into G */
29#define NV50_BLIT_MODES      9
30
31/* CUBE and RECT textures are reinterpreted as 2D(_ARRAY) */
32#define NV50_BLIT_TEXTURE_BUFFER    0
33#define NV50_BLIT_TEXTURE_1D        1
34#define NV50_BLIT_TEXTURE_2D        2
35#define NV50_BLIT_TEXTURE_3D        3
36#define NV50_BLIT_TEXTURE_1D_ARRAY  4
37#define NV50_BLIT_TEXTURE_2D_ARRAY  5
38#define NV50_BLIT_MAX_TEXTURE_TYPES 6
39
40static inline unsigned
41nv50_blit_texture_type(enum pipe_texture_target target)
42{
43   switch (target) {
44   case PIPE_TEXTURE_1D: return NV50_BLIT_TEXTURE_1D;
45   case PIPE_TEXTURE_2D: return NV50_BLIT_TEXTURE_2D;
46   case PIPE_TEXTURE_3D: return NV50_BLIT_TEXTURE_3D;
47   case PIPE_TEXTURE_1D_ARRAY: return NV50_BLIT_TEXTURE_1D_ARRAY;
48   case PIPE_TEXTURE_2D_ARRAY: return NV50_BLIT_TEXTURE_2D_ARRAY;
49   default:
50      assert(target == PIPE_BUFFER);
51      return NV50_BLIT_TEXTURE_BUFFER;
52   }
53}
54
55static inline unsigned
56nv50_blit_get_tgsi_texture_target(enum pipe_texture_target target)
57{
58   switch (target) {
59   case PIPE_TEXTURE_1D: return TGSI_TEXTURE_1D;
60   case PIPE_TEXTURE_2D: return TGSI_TEXTURE_2D;
61   case PIPE_TEXTURE_3D: return TGSI_TEXTURE_3D;
62   case PIPE_TEXTURE_1D_ARRAY: return TGSI_TEXTURE_1D_ARRAY;
63   case PIPE_TEXTURE_2D_ARRAY: return TGSI_TEXTURE_2D_ARRAY;
64   default:
65      assert(target == PIPE_BUFFER);
66      return TGSI_TEXTURE_BUFFER;
67   }
68}
69
70static inline enum pipe_texture_target
71nv50_blit_reinterpret_pipe_texture_target(enum pipe_texture_target target)
72{
73   switch (target) {
74   case PIPE_TEXTURE_CUBE:
75   case PIPE_TEXTURE_CUBE_ARRAY:
76      return PIPE_TEXTURE_2D_ARRAY;
77   case PIPE_TEXTURE_RECT:
78      return PIPE_TEXTURE_2D;
79   default:
80      return target;
81   }
82}
83
84static inline unsigned
85nv50_blit_get_filter(const struct pipe_blit_info *info)
86{
87   if (info->dst.resource->nr_samples < info->src.resource->nr_samples)
88      return util_format_is_depth_or_stencil(info->src.format) ? 0 : 1;
89
90   if (info->filter != PIPE_TEX_FILTER_LINEAR)
91      return 0;
92
93   if ((info->dst.box.width ==  info->src.box.width ||
94        info->dst.box.width == -info->src.box.width) &&
95       (info->dst.box.height ==  info->src.box.height ||
96        info->dst.box.height == -info->src.box.height))
97      return 0;
98
99   return 1;
100}
101
102/* Since shaders cannot export stencil, we cannot copy stencil values when
103 * rendering to ZETA, so we attach the ZS surface to a colour render target.
104 */
105static inline enum pipe_format
106nv50_blit_zeta_to_colour_format(enum pipe_format format)
107{
108   switch (format) {
109   case PIPE_FORMAT_Z16_UNORM:
110      return PIPE_FORMAT_R16_UNORM;
111   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
112   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
113   case PIPE_FORMAT_Z24X8_UNORM:
114   case PIPE_FORMAT_X8Z24_UNORM:
115   case PIPE_FORMAT_X24S8_UINT:
116   case PIPE_FORMAT_S8X24_UINT:
117      return PIPE_FORMAT_R8G8B8A8_UNORM;
118   case PIPE_FORMAT_Z32_FLOAT:
119      return PIPE_FORMAT_R32_FLOAT;
120   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
121   case PIPE_FORMAT_X32_S8X24_UINT:
122      return PIPE_FORMAT_R32G32_FLOAT;
123   default:
124      assert(0);
125      return PIPE_FORMAT_NONE;
126   }
127}
128
129
130static inline uint16_t
131nv50_blit_derive_color_mask(const struct pipe_blit_info *info)
132{
133   const unsigned mask = info->mask;
134
135   uint16_t color_mask = 0;
136
137   switch (info->dst.format) {
138   case PIPE_FORMAT_Z24X8_UNORM:
139   case PIPE_FORMAT_X24S8_UINT:
140   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
141      if (mask & PIPE_MASK_S)
142         color_mask |= 0x1000;
143      if (mask & PIPE_MASK_Z)
144         color_mask |= 0x0111;
145      break;
146   case PIPE_FORMAT_X8Z24_UNORM:
147   case PIPE_FORMAT_S8X24_UINT:
148   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
149      if (mask & PIPE_MASK_S)
150         color_mask |= 0x0001;
151      if (mask & PIPE_MASK_Z)
152         color_mask |= 0x1110;
153      break;
154   default:
155      if (mask & (PIPE_MASK_R | PIPE_MASK_Z)) color_mask |= 0x0001;
156      if (mask & (PIPE_MASK_G | PIPE_MASK_S)) color_mask |= 0x0010;
157      if (mask & PIPE_MASK_B) color_mask |= 0x0100;
158      if (mask & PIPE_MASK_A) color_mask |= 0x1000;
159      break;
160   }
161
162   return color_mask;
163}
164
165static inline uint32_t
166nv50_blit_eng2d_get_mask(const struct pipe_blit_info *info)
167{
168   uint32_t mask = 0;
169
170   switch (info->dst.format) {
171   case PIPE_FORMAT_Z24X8_UNORM:
172   case PIPE_FORMAT_X24S8_UINT:
173   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
174      if (info->mask & PIPE_MASK_Z) mask |= 0x00ffffff;
175      if (info->mask & PIPE_MASK_S) mask |= 0xff000000;
176      break;
177   case PIPE_FORMAT_X8Z24_UNORM:
178   case PIPE_FORMAT_S8X24_UINT:
179   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
180      if (info->mask & PIPE_MASK_Z) mask |= 0xffffff00;
181      if (info->mask & PIPE_MASK_S) mask |= 0x000000ff;
182      break;
183   default:
184      mask = 0xffffffff;
185      break;
186   }
187   return mask;
188}
189
190#if NOUVEAU_DRIVER == 0xc0
191# define nv50_format_table nvc0_format_table
192#endif
193
194/* return true for formats that can be converted among each other by NVC0_2D */
195static inline bool
196nv50_2d_dst_format_faithful(enum pipe_format format)
197{
198   const uint64_t mask =
199       NV50_ENG2D_SUPPORTED_FORMATS &
200      ~NV50_ENG2D_NOCONVERT_FORMATS;
201   uint8_t id = nv50_format_table[format].rt;
202   return (id >= 0xc0) && (mask & (1ULL << (id - 0xc0)));
203}
204static inline bool
205nv50_2d_src_format_faithful(enum pipe_format format)
206{
207   const uint64_t mask =
208      NV50_ENG2D_SUPPORTED_FORMATS &
209    ~(NV50_ENG2D_LUMINANCE_FORMATS | NV50_ENG2D_INTENSITY_FORMATS);
210   uint8_t id = nv50_format_table[format].rt;
211   return (id >= 0xc0) && (mask & (1ULL << (id - 0xc0)));
212}
213
214static inline bool
215nv50_2d_format_supported(enum pipe_format format)
216{
217   uint8_t id = nv50_format_table[format].rt;
218   return (id >= 0xc0) &&
219      (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0)));
220}
221
222static inline bool
223nv50_2d_dst_format_ops_supported(enum pipe_format format)
224{
225   uint8_t id = nv50_format_table[format].rt;
226   return (id >= 0xc0) &&
227      (NV50_ENG2D_OPERATION_FORMATS & (1ULL << (id - 0xc0)));
228}
229
230#endif /* __NV50_BLIT_H__ */
231