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 primconvert_context *primconvert;
172 struct blitter_context *blitter;
173 struct u_suballocator query_allocator;
174 struct u_suballocator so_allocator;
175 struct hash_table *pso_cache;
176 struct hash_table *compute_pso_cache;
177 struct hash_table *root_signature_cache;
178 struct hash_table *cmd_signature_cache;
179 struct hash_table *gs_variant_cache;
180 struct hash_table *tcs_variant_cache;
181 struct hash_table *compute_transform_cache;
182 struct hash_table_u64 *bo_state_table;
183
184 struct d3d12_batch batches[8];
185 unsigned current_batch_idx;
186
187 struct util_dynarray recently_destroyed_bos;
188 struct util_dynarray barrier_scratch;
189 struct set *pending_barriers_bos;
190 struct util_dynarray local_pending_barriers_bos;
191
192 struct pipe_constant_buffer cbufs[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
193 struct pipe_framebuffer_state fb;
194 struct pipe_vertex_buffer vbs[PIPE_MAX_ATTRIBS];
195 D3D12_VERTEX_BUFFER_VIEW vbvs[PIPE_MAX_ATTRIBS];
196 unsigned num_vbs;
197 float flip_y;
198 bool need_zero_one_depth_range;
199 enum mesa_prim initial_api_prim;
200 struct pipe_viewport_state viewport_states[PIPE_MAX_VIEWPORTS];
201 D3D12_VIEWPORT viewports[PIPE_MAX_VIEWPORTS];
202 unsigned num_viewports;
203 struct pipe_scissor_state scissor_states[PIPE_MAX_VIEWPORTS];
204 D3D12_RECT scissors[PIPE_MAX_VIEWPORTS];
205 float blend_factor[4];
206 struct pipe_stencil_ref stencil_ref;
207 struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
208 unsigned num_sampler_views[PIPE_SHADER_TYPES];
209 unsigned has_int_samplers;
210 struct pipe_shader_buffer ssbo_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
211 unsigned num_ssbo_views[PIPE_SHADER_TYPES];
212 struct pipe_image_view image_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
213 enum pipe_format image_view_emulation_formats[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
214 unsigned num_image_views[PIPE_SHADER_TYPES];
215 struct d3d12_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
216 unsigned num_samplers[PIPE_SHADER_TYPES];
217 D3D12_INDEX_BUFFER_VIEW ibv;
218
219 dxil_wrap_sampler_state tex_wrap_states[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
220 dxil_wrap_sampler_state tex_wrap_states_shader_key[PIPE_MAX_SHADER_SAMPLER_VIEWS];
221
222 dxil_texture_swizzle_state tex_swizzle_state[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
223 enum compare_func tex_compare_func[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
224
225 struct {
226 bool enabled;
227 uint32_t pattern[32];
228 struct pipe_resource *texture;
229 struct pipe_sampler_view *sampler_view;
230 struct d3d12_sampler_state *sampler_cso;
231 } pstipple;
232
233 struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
234 D3D12_STREAM_OUTPUT_BUFFER_VIEW so_buffer_views[PIPE_MAX_SO_BUFFERS];
235 struct pipe_stream_output_target *fake_so_targets[PIPE_MAX_SO_BUFFERS];
236 D3D12_STREAM_OUTPUT_BUFFER_VIEW fake_so_buffer_views[PIPE_MAX_SO_BUFFERS];
237 unsigned fake_so_buffer_factor;
238 uint8_t patch_vertices;
239 float default_outer_tess_factor[4];
240 float default_inner_tess_factor[2];
241
242 struct d3d12_shader_selector *gfx_stages[D3D12_GFX_SHADER_STAGES];
243 struct d3d12_shader_selector *compute_state;
244
245 bool has_flat_varyings;
246 bool missing_dual_src_outputs;
247 bool manual_depth_range;
248
249 struct d3d12_gfx_pipeline_state gfx_pipeline_state;
250 struct d3d12_compute_pipeline_state compute_pipeline_state;
251 unsigned shader_dirty[PIPE_SHADER_TYPES];
252 unsigned state_dirty;
253 unsigned cmdlist_dirty;
254 ID3D12PipelineState *current_gfx_pso;
255 ID3D12PipelineState *current_compute_pso;
256 uint16_t reverse_depth_range;
257
258 uint64_t submit_id;
259 ID3D12GraphicsCommandList *cmdlist;
260 ID3D12GraphicsCommandList2 *cmdlist2;
261 ID3D12GraphicsCommandList8 *cmdlist8;
262 ID3D12GraphicsCommandList *state_fixup_cmdlist;
263
264 struct list_head active_queries;
265 bool queries_disabled;
266
267 struct d3d12_descriptor_pool *sampler_pool;
268 struct d3d12_descriptor_handle null_sampler;
269
270 PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignature;
271 #ifndef _GAMING_XBOX
272 ID3D12DeviceConfiguration *dev_config;
273 #endif
274 #ifdef _WIN32
275 struct dxil_validator *dxil_validator;
276 #endif
277
278 struct d3d12_resource *current_predication;
279 bool predication_condition;
280 bool queries_suspended;
281
282 uint32_t transform_state_vars[8];
283
284 #ifdef __cplusplus
285 ResourceStateManager *resource_state_manager;
286 #else
287 void *resource_state_manager; /* opaque pointer; we don't know about classes in C */
288 #endif
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 };
294
295 static inline struct d3d12_context *
d3d12_context(struct pipe_context * context)296 d3d12_context(struct pipe_context *context)
297 {
298 return (struct d3d12_context *)context;
299 }
300
301 static inline struct d3d12_batch *
d3d12_current_batch(struct d3d12_context * ctx)302 d3d12_current_batch(struct d3d12_context *ctx)
303 {
304 assert(ctx->current_batch_idx < ARRAY_SIZE(ctx->batches));
305 return ctx->batches + ctx->current_batch_idx;
306 }
307
308 #define d3d12_foreach_submitted_batch(ctx, batch) \
309 unsigned oldest = (ctx->current_batch_idx + 1) % ARRAY_SIZE(ctx->batches); \
310 while (ctx->batches[oldest].fence == NULL && oldest != ctx->current_batch_idx) \
311 oldest = (oldest + 1) % ARRAY_SIZE(ctx->batches); \
312 struct d3d12_batch *batch = &ctx->batches[oldest]; \
313 for (; oldest != ctx->current_batch_idx; \
314 oldest = (oldest + 1) % ARRAY_SIZE(ctx->batches), \
315 batch = &ctx->batches[oldest])
316
317 struct pipe_context *
318 d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags);
319
320 bool
321 d3d12_enable_fake_so_buffers(struct d3d12_context *ctx, unsigned factor);
322
323 bool
324 d3d12_disable_fake_so_buffers(struct d3d12_context *ctx);
325
326 void
327 d3d12_flush_cmdlist(struct d3d12_context *ctx);
328
329 void
330 d3d12_flush_cmdlist_and_wait(struct d3d12_context *ctx);
331
332
333 enum d3d12_transition_flags {
334 D3D12_TRANSITION_FLAG_NONE = 0,
335 D3D12_TRANSITION_FLAG_INVALIDATE_BINDINGS = 1,
336 D3D12_TRANSITION_FLAG_ACCUMULATE_STATE = 2,
337 D3D12_TRANSITION_FLAG_PENDING_MEMORY_BARRIER = 4,
338 };
339
340 void
341 d3d12_transition_resource_state(struct d3d12_context* ctx,
342 struct d3d12_resource* res,
343 D3D12_RESOURCE_STATES state,
344 d3d12_transition_flags flags);
345
346 void
347 d3d12_transition_subresources_state(struct d3d12_context *ctx,
348 struct d3d12_resource *res,
349 unsigned start_level, unsigned num_levels,
350 unsigned start_layer, unsigned num_layers,
351 unsigned start_plane, unsigned num_planes,
352 D3D12_RESOURCE_STATES state,
353 d3d12_transition_flags flags);
354
355 void
356 d3d12_apply_resource_states(struct d3d12_context* ctx, bool is_implicit_dispatch);
357
358 void
359 d3d12_draw_vbo(struct pipe_context *pctx,
360 const struct pipe_draw_info *dinfo,
361 unsigned drawid_offset,
362 const struct pipe_draw_indirect_info *indirect,
363 const struct pipe_draw_start_count_bias *draws,
364 unsigned num_draws);
365
366 void
367 d3d12_launch_grid(struct pipe_context *pctx,
368 const struct pipe_grid_info *info);
369
370 void
371 d3d12_blit(struct pipe_context *pctx,
372 const struct pipe_blit_info *info);
373
374 void
375 d3d12_context_query_init(struct pipe_context *pctx);
376
377 bool
378 d3d12_need_zero_one_depth_range(struct d3d12_context *ctx);
379
380 void
381 d3d12_init_sampler_view_descriptor(struct d3d12_sampler_view *sampler_view);
382
383 void
384 d3d12_invalidate_context_bindings(struct d3d12_context *ctx, struct d3d12_resource *res);
385
386 #ifdef HAVE_GALLIUM_D3D12_VIDEO
387 struct pipe_video_codec* d3d12_video_create_codec( struct pipe_context *context,
388 const struct pipe_video_codec *t);
389 #endif
390
391 #endif
392