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