About Social Code
aboutsummaryrefslogtreecommitdiff
path: root/src/freedreno/vulkan/tu_pipeline.h
blob: 300a7b458ed57ed9d0e5662289888cb6658bf499 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
/*
 * Copyright © 2016 Red Hat.
 * Copyright © 2016 Bas Nieuwenhuizen
 * SPDX-License-Identifier: MIT
 *
 * based in part on anv driver which is:
 * Copyright © 2015 Intel Corporation
 */

#ifndef TU_PIPELINE_H
#define TU_PIPELINE_H

#include "tu_common.h"

#include "tu_cs.h"
#include "tu_descriptor_set.h"
#include "tu_shader.h"
#include "tu_suballoc.h"

enum tu_dynamic_state
{
   TU_DYNAMIC_STATE_VIEWPORT,
   TU_DYNAMIC_STATE_SCISSOR,
   TU_DYNAMIC_STATE_RAST,
   TU_DYNAMIC_STATE_DEPTH_BIAS,
   TU_DYNAMIC_STATE_BLEND_CONSTANTS,
   TU_DYNAMIC_STATE_DS,
   TU_DYNAMIC_STATE_RB_DEPTH_CNTL,
   TU_DYNAMIC_STATE_SAMPLE_LOCATIONS,
   TU_DYNAMIC_STATE_VB_STRIDE,
   TU_DYNAMIC_STATE_BLEND,
   TU_DYNAMIC_STATE_VERTEX_INPUT,
   TU_DYNAMIC_STATE_PATCH_CONTROL_POINTS,
   TU_DYNAMIC_STATE_PRIM_MODE_SYSMEM,
   TU_DYNAMIC_STATE_A7XX_FRAGMENT_SHADING_RATE = TU_DYNAMIC_STATE_PRIM_MODE_SYSMEM,
   TU_DYNAMIC_STATE_COUNT,
};

struct cache_entry;

enum tu_lrz_blend_status {
   TU_LRZ_BLEND_SAFE_FOR_LRZ,
   TU_LRZ_BLEND_READS_DEST_OR_PARTIAL_WRITE,
   TU_LRZ_BLEND_ALL_COLOR_WRITES_SKIPPED,
};
struct tu_lrz_blend
{
   bool valid;
   enum tu_lrz_blend_status lrz_blend_status;
};

struct tu_bandwidth
{
   uint32_t color_bandwidth_per_sample;
   uint32_t depth_cpp_per_sample;
   uint32_t stencil_cpp_per_sample;
   bool valid;
};

struct tu_disable_fs
{
   bool disable_fs;
   bool valid;
};

struct tu_nir_shaders
{
   struct vk_pipeline_cache_object base;

   /* This is optional, and is only filled out when a library pipeline is
    * compiled with RETAIN_LINK_TIME_OPTIMIZATION_INFO.
    */
   nir_shader *nir[MESA_SHADER_STAGES];
};

extern const struct vk_pipeline_cache_object_ops tu_nir_shaders_ops;

static bool inline
tu6_shared_constants_enable(const struct tu_pipeline_layout *layout,
                            const struct ir3_compiler *compiler)
{
   return layout->push_constant_size > 0 &&
          layout->push_constant_size <= (compiler->shared_consts_size * 16);
}

enum ir3_push_consts_type
tu_push_consts_type(const struct tu_pipeline_layout *layout,
                    const struct ir3_compiler *compiler);

struct tu_program_descriptor_linkage
{
   struct ir3_const_state const_state;

   uint32_t constlen;

   struct tu_const_state tu_const_state;
};

struct tu_program_state
{
      struct tu_draw_state config_state;
      struct tu_draw_state vs_state, vs_binning_state;
      struct tu_draw_state hs_state;
      struct tu_draw_state ds_state;
      struct tu_draw_state gs_state, gs_binning_state;
      struct tu_draw_state vpc_state;
      struct tu_draw_state fs_state;

      struct tu_push_constant_range shared_consts;

      struct tu_program_descriptor_linkage link[MESA_SHADER_STAGES];

      char stage_sha1[MESA_SHADER_STAGES][SHA1_DIGEST_STRING_LENGTH];

      unsigned dynamic_descriptor_offsets[MAX_SETS];

      /* With FDM, we control the fragment area by overriding the viewport and
       * scsissor. In order to have different areas for different views, we
       * need to have a viewport/scissor per FDM layer. There are various
       * possible scenarios based on the shader and whether multiview or
       * per-layer sampling is enabled, that are communicated to the driver
       * via the struct members below:
       * 
       * - The shader writes gl_ViewportIndex, managing multiple viewports in
       *   a way that may not correspond to FDM layer:
       *   - Set everything to false. The driver will set shared_scale and
       *     apply the same scaling to all viewports/scissors.
       * - Multiview is enabled:
       *   - Set per_view_viewport.
       *   - Set fake_single_viewport to splat viewport 0 to all viewports.
       *       - (Not implemented yet) if the user requests per-view
       *         viewports, don't set fake_single_viewport and let the user
       *         set multiple viewports that are transformed independently.
       * - Multiview is not enabled and per-layer FDM sampling is enabled:
       *   - Inject code into shader and set per_layer_viewport.
       *   - Set fake_single_viewport to splat viewport 0 to all viewports.
       */

      /* Whether the per-view-viewport feature should be enabled in HW. This
       * implicitly adds gl_ViewIndex to gl_ViewportIndex so that from a HW
       * point of view (but not necessarily the user's point of view!) there
       * is a viewport per view.
       */
      bool per_view_viewport;
      /* Whether gl_ViewportIndex has been set to gl_Layer, so that from a HW
       * point of view (but not necessarily the user's point of view!) there
       * is a viewport per view.
       */
      bool per_layer_viewport;
      /* If per_view_viewport or per_layer_viewport is true and this is true,
       * the app has provided a single viewport and we need to fake it by
       * duplicating the viewport across views before transforming each
       * viewport separately using FDM state.
       */
      bool fake_single_viewport;

      bool writes_shading_rate;
      bool reads_shading_rate;
      bool uses_ray_intersection;
};

struct tu_pipeline_executable {
   mesa_shader_stage stage;

   struct ir3_info stats;
   bool is_binning;

   char *nir_from_spirv;
   char *nir_final;
   char *disasm;
};

enum tu_pipeline_type {
   TU_PIPELINE_GRAPHICS,
   TU_PIPELINE_GRAPHICS_LIB,
   TU_PIPELINE_COMPUTE,
};

struct tu_pipeline
{
   struct vk_object_base base;
   enum tu_pipeline_type type;

   struct tu_cs cs;
   struct tu_suballoc_bo bo;

   VkShaderStageFlags active_stages;
   uint32_t active_desc_sets;

   /* mask of enabled dynamic states
    * if BIT(i) is set, pipeline->dynamic_state[i] is used
    */
   uint32_t set_state_mask;
   struct tu_draw_state dynamic_state[TU_DYNAMIC_STATE_COUNT];

   BITSET_DECLARE(static_state_mask, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);

   struct {
      bool raster_order_attachment_access;
   } ds;

   /* Misc. info from the fragment output interface state that is used
    * elsewhere.
    */
   struct {
      bool raster_order_attachment_access;
   } output;

   /* In other words - framebuffer fetch support */
   struct {
      /* If the pipeline sets SINGLE_PRIM_MODE for sysmem. */
      bool sysmem_single_prim_mode;
      struct tu_draw_state state_gmem;
   } prim_order;

   /* draw states for the pipeline */
   struct tu_draw_state load_state;

   struct tu_shader *shaders[MESA_SHADER_STAGES];

   struct tu_program_state program;

   struct tu_lrz_blend lrz_blend;
   struct tu_bandwidth bandwidth;
   struct tu_disable_fs disable_fs;

   void *executables_mem_ctx;
   /* tu_pipeline_executable */
   struct util_dynarray executables;
};

struct tu_graphics_lib_pipeline {
   struct tu_pipeline base;

   VkGraphicsPipelineLibraryFlagsEXT state;

   struct vk_graphics_pipeline_state graphics_state;

   /* For vk_graphics_pipeline_state */
   void *state_data;

   struct tu_nir_shaders *nir_shaders;
   struct {
      nir_shader *nir;
      struct tu_shader_key key;
   } shaders[MESA_SHADER_FRAGMENT + 1];

   /* Used to stitch together an overall layout for the final pipeline. */
   struct tu_descriptor_set_layout *layouts[MAX_SETS];
   unsigned num_sets;
   unsigned push_constant_size;
   bool independent_sets;
};

struct tu_graphics_pipeline {
   struct tu_pipeline base;

   struct vk_dynamic_graphics_state dynamic_state;

   /* Only used if the sample locations are static but the enable is dynamic.
    * Otherwise we should be able to precompile the draw state.
    */
   struct vk_sample_locations_state sample_locations;

   VkImageAspectFlags feedback_loops;
   bool feedback_loop_may_involve_textures;
};

struct tu_compute_pipeline {
   struct tu_pipeline base;

   uint32_t local_size[3];
   uint32_t instrlen;
};

VK_DEFINE_NONDISP_HANDLE_CASTS(tu_pipeline, base, VkPipeline,
                               VK_OBJECT_TYPE_PIPELINE)

#define TU_DECL_PIPELINE_DOWNCAST(pipe_type, pipe_enum)              \
   static inline struct tu_##pipe_type##_pipeline *                  \
   tu_pipeline_to_##pipe_type(struct tu_pipeline *pipeline)          \
   {                                                                 \
      assert(pipeline->type == pipe_enum);                           \
      return (struct tu_##pipe_type##_pipeline *) pipeline;          \
   }

TU_DECL_PIPELINE_DOWNCAST(graphics, TU_PIPELINE_GRAPHICS)
TU_DECL_PIPELINE_DOWNCAST(graphics_lib, TU_PIPELINE_GRAPHICS_LIB)
TU_DECL_PIPELINE_DOWNCAST(compute, TU_PIPELINE_COMPUTE)

VkOffset2D tu_fdm_per_bin_offset(VkExtent2D frag_area, VkRect2D bin,
                                 VkOffset2D common_bin_offset);

template <chip CHIP>
uint32_t tu_emit_draw_state(struct tu_cmd_buffer *cmd);

struct tu_pvtmem_config {
   uint64_t iova;
   uint32_t per_fiber_size;
   uint32_t per_sp_size;
   bool per_wave;
};

template <chip CHIP>
void
tu6_emit_xs_config(struct tu_cs *cs,
                   mesa_shader_stage stage,
                   const struct ir3_shader_variant *xs);

template <chip CHIP>
void
tu6_emit_shared_consts_enable(struct tu_cs *cs, bool shared_consts_enable);

template <chip CHIP>
void
tu6_emit_vpc(struct tu_cs *cs,
             const struct ir3_shader_variant *vs,
             const struct ir3_shader_variant *hs,
             const struct ir3_shader_variant *ds,
             const struct ir3_shader_variant *gs,
             const struct ir3_shader_variant *fs);

void
tu_fill_render_pass_state(struct vk_render_pass_state *rp,
                          const struct tu_render_pass *pass,
                          const struct tu_subpass *subpass);

#endif /* TU_PIPELINE_H */