1 /*
2 * Copyright © 2012 Intel Corporation
3 *
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
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
13 * Software.
14 *
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 NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #ifndef BLORP_PRIV_H
25 #define BLORP_PRIV_H
26
27 #include <stdint.h>
28
29 #include "common/intel_measure.h"
30 #include "compiler/nir/nir.h"
31
32 #include "blorp.h"
33
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37
38 void blorp_init(struct blorp_context *blorp, void *driver_ctx,
39 struct isl_device *isl_dev, const struct blorp_config *config);
40
41 struct blorp_compiler {
42 const struct brw_compiler *brw;
43 const struct elk_compiler *elk;
44
45 struct blorp_program (*compile_fs)(struct blorp_context *blorp, void *mem_ctx,
46 struct nir_shader *nir,
47 bool multisample_fbo,
48 bool use_repclear);
49 struct blorp_program (*compile_vs)(struct blorp_context *blorp, void *mem_ctx,
50 struct nir_shader *nir);
51
52 struct blorp_program (*compile_cs)(struct blorp_context *blorp, void *mem_ctx,
53 struct nir_shader *nir);
54
55 bool (*ensure_sf_program)(struct blorp_batch *batch,
56 struct blorp_params *params);
57
58 bool (*params_get_layer_offset_vs)(struct blorp_batch *batch,
59 struct blorp_params *params);
60 };
61
62 /**
63 * Binding table indices used by BLORP.
64 */
65 enum {
66 BLORP_RENDERBUFFER_BT_INDEX,
67 BLORP_TEXTURE_BT_INDEX,
68 BLORP_NUM_BT_ENTRIES
69 };
70
71 #define BLORP_SAMPLER_INDEX 0
72
73 struct blorp_surface_info
74 {
75 bool enabled;
76
77 struct isl_surf surf;
78 struct blorp_address addr;
79
80 struct isl_surf aux_surf;
81 struct blorp_address aux_addr;
82 enum isl_aux_usage aux_usage;
83
84 union isl_color_value clear_color;
85 struct blorp_address clear_color_addr;
86
87 struct isl_view view;
88
89 /* Z offset into a 3-D texture or slice of a 2-D array texture. */
90 float z_offset;
91
92 uint32_t tile_x_sa, tile_y_sa;
93 };
94
95 void
96 blorp_surface_info_init(struct blorp_batch *batch,
97 struct blorp_surface_info *info,
98 const struct blorp_surf *surf,
99 unsigned int level, float layer,
100 enum isl_format format, bool is_dest);
101 void
102 blorp_surf_convert_to_single_slice(const struct isl_device *isl_dev,
103 struct blorp_surface_info *info);
104 void
105 surf_fake_rgb_with_red(const struct isl_device *isl_dev,
106 struct blorp_surface_info *info);
107 void
108 blorp_surf_convert_to_uncompressed(const struct isl_device *isl_dev,
109 struct blorp_surface_info *info,
110 uint32_t *x, uint32_t *y,
111 uint32_t *width, uint32_t *height);
112 void
113 blorp_surf_fake_interleaved_msaa(const struct isl_device *isl_dev,
114 struct blorp_surface_info *info);
115 void
116 blorp_surf_retile_w_to_y(const struct isl_device *isl_dev,
117 struct blorp_surface_info *info);
118
119
120 struct blorp_coord_transform
121 {
122 float multiplier;
123 float offset;
124 };
125
126 /**
127 * Bounding rectangle telling pixel discard which pixels are to be touched.
128 * This is needed in when surfaces are configured as something else what they
129 * really are:
130 *
131 * - writing W-tiled stencil as Y-tiled
132 * - writing interleaved multisampled as single sampled.
133 *
134 * See blorp_check_in_bounds().
135 */
136 struct blorp_bounds_rect
137 {
138 uint32_t x0;
139 uint32_t x1;
140 uint32_t y0;
141 uint32_t y1;
142 };
143
144 /**
145 * Grid needed for blended and scaled blits of integer formats, see
146 * blorp_nir_manual_blend_bilinear().
147 */
148 struct blorp_rect_grid
149 {
150 float x1;
151 float y1;
152 float pad[2];
153 };
154
155 struct blorp_surf_offset {
156 uint32_t x;
157 uint32_t y;
158 };
159
160 struct blorp_wm_inputs
161 {
162 uint32_t clear_color[4];
163
164 struct blorp_bounds_rect bounds_rect;
165 struct blorp_rect_grid rect_grid;
166 struct blorp_coord_transform coord_transform[2];
167
168 struct blorp_surf_offset src_offset;
169 struct blorp_surf_offset dst_offset;
170
171 /* (1/width, 1/height) for the source surface */
172 float src_inv_size[2];
173
174 /* Minimum layer setting works for all the textures types but texture_3d
175 * for which the setting has no effect. Use the z-coordinate instead.
176 */
177 float src_z;
178
179 /* Note: Pad out to an integral number of registers when extending, but
180 * make sure subgroup_id is the last 32-bit item.
181 */
182 /* uint32_t pad[?]; */
183 uint32_t subgroup_id;
184 };
185
186 static inline nir_variable *
blorp_create_nir_input(struct nir_shader * nir,const char * name,const struct glsl_type * type,unsigned int offset)187 blorp_create_nir_input(struct nir_shader *nir,
188 const char *name,
189 const struct glsl_type *type,
190 unsigned int offset)
191 {
192 nir_variable *input;
193 if (nir->info.stage == MESA_SHADER_COMPUTE) {
194 input = nir_variable_create(nir, nir_var_uniform, type, name);
195 input->data.driver_location = offset;
196 input->data.location = offset;
197 } else {
198 input = nir_variable_create(nir, nir_var_shader_in, type, name);
199 input->data.location = VARYING_SLOT_VAR0 + offset / (4 * sizeof(float));
200 input->data.location_frac = (offset / sizeof(float)) % 4;
201 }
202 if (nir->info.stage == MESA_SHADER_FRAGMENT)
203 input->data.interpolation = INTERP_MODE_FLAT;
204 return input;
205 }
206
207 #define BLORP_CREATE_NIR_INPUT(shader, name, type) \
208 blorp_create_nir_input((shader), #name, (type), \
209 offsetof(struct blorp_wm_inputs, name))
210
211 struct blorp_vs_inputs {
212 uint32_t base_layer;
213 uint32_t _instance_id; /* Set in hardware by SGVS */
214 uint32_t pad[2];
215 };
216
217 enum blorp_shader_type {
218 BLORP_SHADER_TYPE_COPY,
219 BLORP_SHADER_TYPE_BLIT,
220 BLORP_SHADER_TYPE_CLEAR,
221 BLORP_SHADER_TYPE_MCS_PARTIAL_RESOLVE,
222 BLORP_SHADER_TYPE_LAYER_OFFSET_VS,
223 BLORP_SHADER_TYPE_GFX4_SF,
224 };
225
226 enum blorp_shader_pipeline {
227 BLORP_SHADER_PIPELINE_RENDER,
228 BLORP_SHADER_PIPELINE_COMPUTE,
229 };
230
231 struct blorp_params
232 {
233 enum blorp_op op;
234 uint32_t x0;
235 uint32_t y0;
236 uint32_t x1;
237 uint32_t y1;
238 float z;
239 uint8_t stencil_mask;
240 uint8_t stencil_ref;
241 struct blorp_surface_info depth;
242 struct blorp_surface_info stencil;
243 uint32_t depth_format;
244 struct blorp_surface_info src;
245 struct blorp_surface_info dst;
246 enum isl_aux_op hiz_op;
247 bool full_surface_hiz_op;
248 enum isl_aux_op fast_clear_op;
249 uint8_t color_write_disable;
250 struct blorp_wm_inputs wm_inputs;
251 struct blorp_vs_inputs vs_inputs;
252 bool dst_clear_color_as_input;
253 unsigned num_samples;
254 unsigned num_draw_buffers;
255 unsigned num_layers;
256 uint32_t vs_prog_kernel;
257 void *vs_prog_data;
258 uint32_t sf_prog_kernel;
259 void *sf_prog_data;
260 uint32_t wm_prog_kernel;
261 void *wm_prog_data;
262 uint32_t cs_prog_kernel;
263 void *cs_prog_data;
264
265 bool use_pre_baked_binding_table;
266 uint32_t pre_baked_binding_table_offset;
267 enum blorp_shader_type shader_type;
268 enum blorp_shader_pipeline shader_pipeline;
269 };
270
271 enum intel_measure_snapshot_type
272 blorp_op_to_intel_measure_snapshot(enum blorp_op op);
273
274 const char *blorp_op_to_name(enum blorp_op op);
275
276 void blorp_params_init(struct blorp_params *params);
277
278 struct blorp_base_key
279 {
280 char name[8];
281 enum blorp_shader_type shader_type;
282 enum blorp_shader_pipeline shader_pipeline;
283 };
284
285 #define BLORP_BASE_KEY_INIT(_type) \
286 (struct blorp_base_key) { \
287 .name = "blorp", \
288 .shader_type = _type, \
289 .shader_pipeline = BLORP_SHADER_PIPELINE_RENDER, \
290 }
291
292 struct blorp_blit_prog_key
293 {
294 struct blorp_base_key base;
295
296 /* Number of samples per pixel that have been configured in the surface
297 * state for texturing from.
298 */
299 unsigned tex_samples;
300
301 /* MSAA layout that has been configured in the surface state for texturing
302 * from.
303 */
304 enum isl_msaa_layout tex_layout;
305
306 enum isl_aux_usage tex_aux_usage;
307
308 /* Actual number of samples per pixel in the source image. */
309 unsigned src_samples;
310
311 /* Actual MSAA layout used by the source image. */
312 enum isl_msaa_layout src_layout;
313
314 /* The swizzle to apply to the source in the shader */
315 struct isl_swizzle src_swizzle;
316
317 /* The format of the source if format-specific workarounds are needed
318 * and 0 (ISL_FORMAT_R32G32B32A32_FLOAT) if the destination is natively
319 * renderable.
320 */
321 enum isl_format src_format;
322
323 /* True if the source requires normalized coordinates */
324 bool src_coords_normalized;
325
326 /* Number of samples per pixel that have been configured in the render
327 * target.
328 */
329 unsigned rt_samples;
330
331 /* MSAA layout that has been configured in the render target. */
332 enum isl_msaa_layout rt_layout;
333
334 /* Actual number of samples per pixel in the destination image. */
335 unsigned dst_samples;
336
337 /* Actual MSAA layout used by the destination image. */
338 enum isl_msaa_layout dst_layout;
339
340 /* The swizzle to apply to the destination in the shader */
341 struct isl_swizzle dst_swizzle;
342
343 /* The format of the destination if format-specific workarounds are needed
344 * and 0 (ISL_FORMAT_R32G32B32A32_FLOAT) if the destination is natively
345 * renderable.
346 */
347 enum isl_format dst_format;
348
349 /* Whether or not the format workarounds are a bitcast operation */
350 bool format_bit_cast;
351
352 /** True if we need to perform SINT -> UINT clamping. */
353 bool sint32_to_uint;
354
355 /** True if we need to perform UINT -> SINT clamping. */
356 bool uint32_to_sint;
357
358 /* Type of the data to be read from the texture (one of
359 * nir_type_(int|uint|float)).
360 */
361 nir_alu_type texture_data_type;
362
363 /* True if the source image is W tiled. If true, the surface state for the
364 * source image must be configured as Y tiled, and tex_samples must be 0.
365 */
366 bool src_tiled_w;
367
368 /* True if the destination image is W tiled. If true, the surface state
369 * for the render target must be configured as Y tiled, and rt_samples must
370 * be 0.
371 */
372 bool dst_tiled_w;
373
374 /* True if the destination is an RGB format. If true, the surface state
375 * for the render target must be configured as red with three times the
376 * normal width. We need to do this because you cannot render to
377 * non-power-of-two formats.
378 */
379 bool dst_rgb;
380
381 isl_surf_usage_flags_t dst_usage;
382
383 enum blorp_filter filter;
384
385 /* True if the rectangle being sent through the rendering pipeline might be
386 * larger than the destination rectangle, so the WM program should kill any
387 * pixels that are outside the destination rectangle.
388 */
389 bool use_kill;
390
391 /**
392 * True if the WM program should be run in MSDISPMODE_PERSAMPLE with more
393 * than one sample per pixel.
394 */
395 bool persample_msaa_dispatch;
396
397 /* True if this blit operation may involve intratile offsets on the source.
398 * In this case, we need to add the offset before texturing.
399 */
400 bool need_src_offset;
401
402 /* True if this blit operation may involve intratile offsets on the
403 * destination. In this case, we need to add the offset to gl_FragCoord.
404 */
405 bool need_dst_offset;
406
407 /* Scale factors between the pixel grid and the grid of samples. We're
408 * using grid of samples for bilinear filetring in multisample scaled blits.
409 */
410 float x_scale;
411 float y_scale;
412
413 /* If a compute shader is used, this is the local size y dimension.
414 */
415 uint8_t local_y;
416 };
417
418 /**
419 * \name BLORP internals
420 * \{
421 *
422 * Used internally by gfx6_blorp_exec() and gfx7_blorp_exec().
423 */
424
425 bool blorp_blitter_supports_aux(const struct intel_device_info *devinfo,
426 enum isl_aux_usage aux_usage);
427
428 const char *blorp_shader_type_to_name(enum blorp_shader_type type);
429 const char *blorp_shader_pipeline_to_name(enum blorp_shader_pipeline pipe);
430
431 struct blorp_program {
432 const void *kernel;
433 uint32_t kernel_size;
434
435 const void *prog_data;
436 uint32_t prog_data_size;
437 };
438
439 static inline struct blorp_program
blorp_compile_fs(struct blorp_context * blorp,void * mem_ctx,struct nir_shader * nir,bool multisample_fbo,bool use_repclear)440 blorp_compile_fs(struct blorp_context *blorp, void *mem_ctx,
441 struct nir_shader *nir,
442 bool multisample_fbo,
443 bool use_repclear)
444 {
445 return blorp->compiler->compile_fs(blorp, mem_ctx, nir, multisample_fbo, use_repclear);
446 }
447
448 static inline struct blorp_program
blorp_compile_vs(struct blorp_context * blorp,void * mem_ctx,struct nir_shader * nir)449 blorp_compile_vs(struct blorp_context *blorp, void *mem_ctx,
450 struct nir_shader *nir)
451 {
452 return blorp->compiler->compile_vs(blorp, mem_ctx, nir);
453 }
454
455 static inline bool
blorp_ensure_sf_program(struct blorp_batch * batch,struct blorp_params * params)456 blorp_ensure_sf_program(struct blorp_batch *batch,
457 struct blorp_params *params)
458 {
459 struct blorp_compiler *c = batch->blorp->compiler;
460 /* Absence of callback indicates it is not needed. This is the case for
461 * brw, which is Gfx9+.
462 */
463 return !c->ensure_sf_program || c->ensure_sf_program(batch, params);
464 }
465
466 static inline uint8_t
blorp_get_cs_local_y(struct blorp_params * params)467 blorp_get_cs_local_y(struct blorp_params *params)
468 {
469 uint32_t height = params->y1 - params->y0;
470 uint32_t or_ys = params->y0 | params->y1;
471 if (height > 32 || (or_ys & 3) == 0) {
472 return 4;
473 } else if ((or_ys & 1) == 0) {
474 return 2;
475 } else {
476 return 1;
477 }
478 }
479
480 static inline void
blorp_set_cs_dims(struct nir_shader * nir,uint8_t local_y)481 blorp_set_cs_dims(struct nir_shader *nir, uint8_t local_y)
482 {
483 assert(local_y != 0 && (16 % local_y == 0));
484 nir->info.workgroup_size[0] = 16 / local_y;
485 nir->info.workgroup_size[1] = local_y;
486 nir->info.workgroup_size[2] = 1;
487 }
488
489 static inline struct blorp_program
blorp_compile_cs(struct blorp_context * blorp,void * mem_ctx,struct nir_shader * nir)490 blorp_compile_cs(struct blorp_context *blorp, void *mem_ctx,
491 struct nir_shader *nir)
492 {
493 return blorp->compiler->compile_cs(blorp, mem_ctx, nir);
494 }
495
496 static inline bool
blorp_params_get_layer_offset_vs(struct blorp_batch * batch,struct blorp_params * params)497 blorp_params_get_layer_offset_vs(struct blorp_batch *batch,
498 struct blorp_params *params)
499 {
500 return batch->blorp->compiler->params_get_layer_offset_vs(batch, params);
501 }
502
503 /** \} */
504
505 #ifdef __cplusplus
506 } /* end extern "C" */
507 #endif /* __cplusplus */
508
509 #endif /* BLORP_PRIV_H */
510