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