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