xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/d3d12/d3d12_context.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © Microsoft 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 D3D12_CONTEXT_H
25 #define D3D12_CONTEXT_H
26 
27 #include "d3d12_batch.h"
28 #include "d3d12_descriptor_pool.h"
29 #include "d3d12_pipeline_state.h"
30 
31 #include "dxil_nir_lower_int_samplers.h"
32 
33 #include "pipe/p_context.h"
34 #include "pipe/p_state.h"
35 #include "util/list.h"
36 #include "util/slab.h"
37 #include "util/u_suballoc.h"
38 #include "util/u_threaded_context.h"
39 
40 #define D3D12_GFX_SHADER_STAGES (PIPE_SHADER_TYPES - 1)
41 
42 enum d3d12_dirty_flags
43 {
44    D3D12_DIRTY_NONE             = 0,
45    D3D12_DIRTY_BLEND            = (1 << 0),
46    D3D12_DIRTY_RASTERIZER       = (1 << 1),
47    D3D12_DIRTY_ZSA              = (1 << 2),
48    D3D12_DIRTY_VERTEX_ELEMENTS  = (1 << 3),
49    D3D12_DIRTY_BLEND_COLOR      = (1 << 4),
50    D3D12_DIRTY_STENCIL_REF      = (1 << 5),
51    D3D12_DIRTY_SAMPLE_MASK      = (1 << 6),
52    D3D12_DIRTY_VIEWPORT         = (1 << 7),
53    D3D12_DIRTY_FRAMEBUFFER      = (1 << 8),
54    D3D12_DIRTY_SCISSOR          = (1 << 9),
55    D3D12_DIRTY_VERTEX_BUFFERS   = (1 << 10),
56    D3D12_DIRTY_INDEX_BUFFER     = (1 << 11),
57    D3D12_DIRTY_PRIM_MODE        = (1 << 12),
58    D3D12_DIRTY_SHADER           = (1 << 13),
59    D3D12_DIRTY_ROOT_SIGNATURE   = (1 << 14),
60    D3D12_DIRTY_STREAM_OUTPUT    = (1 << 15),
61    D3D12_DIRTY_STRIP_CUT_VALUE  = (1 << 16),
62    D3D12_DIRTY_COMPUTE_SHADER   = (1 << 17),
63    D3D12_DIRTY_COMPUTE_ROOT_SIGNATURE = (1 << 18),
64 };
65 
66 enum d3d12_shader_dirty_flags
67 {
68    D3D12_SHADER_DIRTY_CONSTBUF      = (1 << 0),
69    D3D12_SHADER_DIRTY_SAMPLER_VIEWS = (1 << 1),
70    D3D12_SHADER_DIRTY_SAMPLERS      = (1 << 2),
71    D3D12_SHADER_DIRTY_SSBO          = (1 << 3),
72    D3D12_SHADER_DIRTY_IMAGE         = (1 << 4),
73 };
74 
75 #define D3D12_DIRTY_GFX_PSO (D3D12_DIRTY_BLEND | D3D12_DIRTY_RASTERIZER | D3D12_DIRTY_ZSA | \
76                              D3D12_DIRTY_FRAMEBUFFER | D3D12_DIRTY_SAMPLE_MASK | \
77                              D3D12_DIRTY_VERTEX_ELEMENTS | D3D12_DIRTY_PRIM_MODE | \
78                              D3D12_DIRTY_SHADER | D3D12_DIRTY_ROOT_SIGNATURE | \
79                              D3D12_DIRTY_STRIP_CUT_VALUE | D3D12_DIRTY_STREAM_OUTPUT)
80 #define D3D12_DIRTY_COMPUTE_PSO (D3D12_DIRTY_COMPUTE_SHADER | D3D12_DIRTY_COMPUTE_ROOT_SIGNATURE)
81 
82 #define D3D12_DIRTY_COMPUTE_MASK (D3D12_DIRTY_COMPUTE_SHADER | D3D12_DIRTY_COMPUTE_ROOT_SIGNATURE)
83 #define D3D12_DIRTY_GFX_MASK ~D3D12_DIRTY_COMPUTE_MASK
84 
85 
86 #define D3D12_SHADER_DIRTY_ALL (D3D12_SHADER_DIRTY_CONSTBUF | D3D12_SHADER_DIRTY_SAMPLER_VIEWS | \
87                                 D3D12_SHADER_DIRTY_SAMPLERS | D3D12_SHADER_DIRTY_SSBO | \
88                                 D3D12_SHADER_DIRTY_IMAGE)
89 
90 enum d3d12_binding_type {
91    D3D12_BINDING_CONSTANT_BUFFER,
92    D3D12_BINDING_SHADER_RESOURCE_VIEW,
93    D3D12_BINDING_SAMPLER,
94    D3D12_BINDING_STATE_VARS,
95    D3D12_BINDING_SSBO,
96    D3D12_BINDING_IMAGE,
97    D3D12_NUM_BINDING_TYPES
98 };
99 
100 struct d3d12_sampler_state {
101    struct d3d12_descriptor_handle handle, handle_without_shadow;
102    bool is_integer_texture;
103    bool is_shadow_sampler;
104    enum pipe_tex_wrap wrap_r;
105    enum pipe_tex_wrap wrap_s;
106    enum pipe_tex_wrap wrap_t;
107    enum pipe_tex_filter filter;
108    float lod_bias;
109    float min_lod, max_lod;
110    float border_color[4];
111    enum pipe_compare_func compare_func;
112 };
113 
114 enum d3d12_blend_factor_flags {
115    D3D12_BLEND_FACTOR_NONE  = 0,
116    D3D12_BLEND_FACTOR_COLOR = 1 << 0,
117    D3D12_BLEND_FACTOR_ALPHA = 1 << 1,
118    D3D12_BLEND_FACTOR_ANY   = 1 << 2,
119 };
120 
121 struct d3d12_sampler_view {
122    struct pipe_sampler_view base;
123    struct d3d12_descriptor_handle handle;
124    unsigned mip_levels;
125    unsigned array_size;
126    unsigned texture_generation_id;
127    unsigned swizzle_override_r:3;         /**< PIPE_SWIZZLE_x for red component */
128    unsigned swizzle_override_g:3;         /**< PIPE_SWIZZLE_x for green component */
129    unsigned swizzle_override_b:3;         /**< PIPE_SWIZZLE_x for blue component */
130    unsigned swizzle_override_a:3;         /**< PIPE_SWIZZLE_x for alpha component */
131 };
132 
133 static inline struct d3d12_sampler_view *
d3d12_sampler_view(struct pipe_sampler_view * pview)134 d3d12_sampler_view(struct pipe_sampler_view *pview)
135 {
136    return (struct d3d12_sampler_view *)pview;
137 }
138 
139 struct d3d12_stream_output_target {
140    struct pipe_stream_output_target base;
141    struct pipe_resource *fill_buffer;
142    unsigned fill_buffer_offset;
143 };
144 
145 struct d3d12_shader_state {
146    struct d3d12_shader *current;
147    unsigned state_dirty;
148 };
149 
150 struct blitter_context;
151 struct primconvert_context;
152 
153 #ifdef _WIN32
154 struct dxil_validator;
155 #endif
156 
157 #ifdef __cplusplus
158 class ResourceStateManager;
159 #endif
160 
161 #define D3D12_CONTEXT_NO_ID 0xffffffff
162 
163 struct d3d12_context {
164    struct pipe_context base;
165 
166    unsigned id;
167    struct slab_child_pool transfer_pool;
168    struct slab_child_pool transfer_pool_unsync;
169    struct list_head context_list_entry;
170    struct threaded_context *threaded_context;
171    struct d3d12_batch batches[8];
172    unsigned current_batch_idx;
173    struct util_dynarray recently_destroyed_bos;
174    struct util_dynarray barrier_scratch;
175    struct set *pending_barriers_bos;
176    struct util_dynarray local_pending_barriers_bos;
177    uint64_t submit_id;
178    ID3D12GraphicsCommandList *cmdlist;
179    ID3D12GraphicsCommandList2 *cmdlist2;
180    ID3D12GraphicsCommandList8 *cmdlist8;
181    ID3D12GraphicsCommandList *state_fixup_cmdlist;
182    struct hash_table_u64 *bo_state_table;
183    struct blitter_context *blitter;
184    uint flags;
185    bool queries_disabled;
186 
187 #ifdef __cplusplus
188    ResourceStateManager *resource_state_manager;
189 #else
190    void *resource_state_manager; /* opaque pointer; we don't know about classes in C */
191 #endif
192 
193 #ifdef HAVE_GALLIUM_D3D12_GRAPHICS
194    struct primconvert_context *primconvert;
195    struct u_suballocator query_allocator;
196    struct u_suballocator so_allocator;
197    struct hash_table *pso_cache;
198    struct hash_table *compute_pso_cache;
199    struct hash_table *root_signature_cache;
200    struct hash_table *cmd_signature_cache;
201    struct hash_table *gs_variant_cache;
202    struct hash_table *tcs_variant_cache;
203    struct hash_table *compute_transform_cache;
204 
205    struct pipe_constant_buffer cbufs[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
206    struct pipe_framebuffer_state fb;
207    struct pipe_vertex_buffer vbs[PIPE_MAX_ATTRIBS];
208    D3D12_VERTEX_BUFFER_VIEW vbvs[PIPE_MAX_ATTRIBS];
209    unsigned num_vbs;
210    float flip_y;
211    bool need_zero_one_depth_range;
212    enum mesa_prim initial_api_prim;
213    struct pipe_viewport_state viewport_states[PIPE_MAX_VIEWPORTS];
214    D3D12_VIEWPORT viewports[PIPE_MAX_VIEWPORTS];
215    unsigned num_viewports;
216    struct pipe_scissor_state scissor_states[PIPE_MAX_VIEWPORTS];
217    D3D12_RECT scissors[PIPE_MAX_VIEWPORTS];
218    float blend_factor[4];
219    struct pipe_stencil_ref stencil_ref;
220    struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
221    unsigned num_sampler_views[PIPE_SHADER_TYPES];
222    unsigned has_int_samplers;
223    struct pipe_shader_buffer ssbo_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
224    unsigned num_ssbo_views[PIPE_SHADER_TYPES];
225    struct pipe_image_view image_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
226    enum pipe_format image_view_emulation_formats[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
227    unsigned num_image_views[PIPE_SHADER_TYPES];
228    struct d3d12_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
229    unsigned num_samplers[PIPE_SHADER_TYPES];
230    D3D12_INDEX_BUFFER_VIEW ibv;
231 
232    dxil_wrap_sampler_state tex_wrap_states[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
233    dxil_wrap_sampler_state tex_wrap_states_shader_key[PIPE_MAX_SHADER_SAMPLER_VIEWS];
234 
235    dxil_texture_swizzle_state tex_swizzle_state[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
236    enum compare_func tex_compare_func[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
237 
238    struct {
239       bool enabled;
240       uint32_t pattern[32];
241       struct pipe_resource *texture;
242       struct pipe_sampler_view *sampler_view;
243       struct d3d12_sampler_state *sampler_cso;
244    } pstipple;
245 
246    struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
247    D3D12_STREAM_OUTPUT_BUFFER_VIEW so_buffer_views[PIPE_MAX_SO_BUFFERS];
248    struct pipe_stream_output_target *fake_so_targets[PIPE_MAX_SO_BUFFERS];
249    D3D12_STREAM_OUTPUT_BUFFER_VIEW fake_so_buffer_views[PIPE_MAX_SO_BUFFERS];
250    unsigned fake_so_buffer_factor;
251    uint8_t patch_vertices;
252    float default_outer_tess_factor[4];
253    float default_inner_tess_factor[2];
254 
255    struct d3d12_shader_selector *gfx_stages[D3D12_GFX_SHADER_STAGES];
256    struct d3d12_shader_selector *compute_state;
257 
258    bool has_flat_varyings;
259    bool missing_dual_src_outputs;
260    bool manual_depth_range;
261 
262    struct d3d12_gfx_pipeline_state gfx_pipeline_state;
263    struct d3d12_compute_pipeline_state compute_pipeline_state;
264    unsigned shader_dirty[PIPE_SHADER_TYPES];
265    unsigned state_dirty;
266    unsigned cmdlist_dirty;
267    ID3D12PipelineState *current_gfx_pso;
268    ID3D12PipelineState *current_compute_pso;
269    uint16_t reverse_depth_range;
270 
271    struct list_head active_queries;
272 
273    struct d3d12_descriptor_pool *sampler_pool;
274    struct d3d12_descriptor_handle null_sampler;
275 
276    PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignature;
277 #ifndef _GAMING_XBOX
278    ID3D12DeviceConfiguration *dev_config;
279 #endif
280 #ifdef _WIN32
281    struct dxil_validator *dxil_validator;
282 #endif
283 
284    struct d3d12_resource *current_predication;
285    bool predication_condition;
286    bool queries_suspended;
287 
288    uint32_t transform_state_vars[8];
289    struct pipe_query *timestamp_query;
290 
291    /* used by d3d12_blit.cpp */
292    void *stencil_resolve_vs, *stencil_resolve_fs, *stencil_resolve_fs_no_flip, *sampler_state;
293 #endif // HAVE_GALLIUM_D3D12_GRAPHICS
294 };
295 
296 static inline struct d3d12_context *
d3d12_context(struct pipe_context * context)297 d3d12_context(struct pipe_context *context)
298 {
299    return (struct d3d12_context *)context;
300 }
301 
302 static inline struct d3d12_batch *
d3d12_current_batch(struct d3d12_context * ctx)303 d3d12_current_batch(struct d3d12_context *ctx)
304 {
305    assert(ctx->current_batch_idx < ARRAY_SIZE(ctx->batches));
306    return ctx->batches + ctx->current_batch_idx;
307 }
308 
309 #define d3d12_foreach_submitted_batch(ctx, batch) \
310    unsigned oldest = (ctx->current_batch_idx + 1) % ARRAY_SIZE(ctx->batches); \
311    while (ctx->batches[oldest].fence == NULL && oldest != ctx->current_batch_idx) \
312       oldest = (oldest + 1) % ARRAY_SIZE(ctx->batches); \
313    struct d3d12_batch *batch = &ctx->batches[oldest]; \
314    for (; oldest != ctx->current_batch_idx; \
315         oldest = (oldest + 1) % ARRAY_SIZE(ctx->batches), \
316         batch = &ctx->batches[oldest])
317 
318 struct pipe_context *
319 d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags);
320 
321 bool
322 d3d12_enable_fake_so_buffers(struct d3d12_context *ctx, unsigned factor);
323 
324 bool
325 d3d12_disable_fake_so_buffers(struct d3d12_context *ctx);
326 
327 void
328 d3d12_flush_cmdlist(struct d3d12_context *ctx);
329 
330 void
331 d3d12_flush_cmdlist_and_wait(struct d3d12_context *ctx);
332 
333 
334 enum d3d12_transition_flags {
335    D3D12_TRANSITION_FLAG_NONE = 0,
336    D3D12_TRANSITION_FLAG_INVALIDATE_BINDINGS = 1,
337    D3D12_TRANSITION_FLAG_ACCUMULATE_STATE = 2,
338    D3D12_TRANSITION_FLAG_PENDING_MEMORY_BARRIER = 4,
339 };
340 
341 void
342 d3d12_transition_resource_state(struct d3d12_context* ctx,
343                                 struct d3d12_resource* res,
344                                 D3D12_RESOURCE_STATES state,
345                                 d3d12_transition_flags flags);
346 
347 void
348 d3d12_transition_subresources_state(struct d3d12_context *ctx,
349                                     struct d3d12_resource *res,
350                                     unsigned start_level, unsigned num_levels,
351                                     unsigned start_layer, unsigned num_layers,
352                                     unsigned start_plane, unsigned num_planes,
353                                     D3D12_RESOURCE_STATES state,
354                                     d3d12_transition_flags flags);
355 
356 void
357 d3d12_apply_resource_states(struct d3d12_context* ctx, bool is_implicit_dispatch);
358 
359 void
360 d3d12_draw_vbo(struct pipe_context *pctx,
361                const struct pipe_draw_info *dinfo,
362                unsigned drawid_offset,
363                const struct pipe_draw_indirect_info *indirect,
364                const struct pipe_draw_start_count_bias *draws,
365                unsigned num_draws);
366 
367 void
368 d3d12_launch_grid(struct pipe_context *pctx,
369                   const struct pipe_grid_info *info);
370 
371 void
372 d3d12_blit(struct pipe_context *pctx,
373            const struct pipe_blit_info *info);
374 
375 void
376 d3d12_context_query_init(struct pipe_context *pctx);
377 
378 bool
379 d3d12_need_zero_one_depth_range(struct d3d12_context *ctx);
380 
381 void
382 d3d12_init_sampler_view_descriptor(struct d3d12_sampler_view *sampler_view);
383 
384 void
385 d3d12_invalidate_context_bindings(struct d3d12_context *ctx, struct d3d12_resource *res);
386 
387 void
388 d3d12_rebind_buffer(struct d3d12_context *ctx, struct d3d12_resource *res);
389 
390 void
391 d3d12_init_null_sampler(struct d3d12_context *ctx);
392 
393 bool
394 d3d12_init_polygon_stipple(struct pipe_context *pctx);
395 
396 void
397 d3d12_init_graphics_context_functions(struct d3d12_context *ctx);
398 
399 #ifdef HAVE_GALLIUM_D3D12_VIDEO
400 struct pipe_video_codec* d3d12_video_create_codec( struct pipe_context *context,
401                                                 const struct pipe_video_codec *t);
402 #endif
403 
404 #endif
405