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 #include "d3d12_nir_lower_texcmp.h" 31 32 #include "dxil_nir_lower_int_samplers.h" 33 34 #include "pipe/p_context.h" 35 #include "pipe/p_state.h" 36 #include "util/list.h" 37 #include "util/slab.h" 38 #include "util/u_suballoc.h" 39 40 #include <directx/d3d12.h> 41 42 #define D3D12_GFX_SHADER_STAGES (PIPE_SHADER_TYPES - 1) 43 44 enum d3d12_dirty_flags 45 { 46 D3D12_DIRTY_NONE = 0, 47 D3D12_DIRTY_BLEND = (1 << 0), 48 D3D12_DIRTY_RASTERIZER = (1 << 1), 49 D3D12_DIRTY_ZSA = (1 << 2), 50 D3D12_DIRTY_VERTEX_ELEMENTS = (1 << 3), 51 D3D12_DIRTY_BLEND_COLOR = (1 << 4), 52 D3D12_DIRTY_STENCIL_REF = (1 << 5), 53 D3D12_DIRTY_SAMPLE_MASK = (1 << 6), 54 D3D12_DIRTY_VIEWPORT = (1 << 7), 55 D3D12_DIRTY_FRAMEBUFFER = (1 << 8), 56 D3D12_DIRTY_SCISSOR = (1 << 9), 57 D3D12_DIRTY_VERTEX_BUFFERS = (1 << 10), 58 D3D12_DIRTY_INDEX_BUFFER = (1 << 11), 59 D3D12_DIRTY_PRIM_MODE = (1 << 12), 60 D3D12_DIRTY_SHADER = (1 << 13), 61 D3D12_DIRTY_ROOT_SIGNATURE = (1 << 14), 62 D3D12_DIRTY_STREAM_OUTPUT = (1 << 15), 63 D3D12_DIRTY_STRIP_CUT_VALUE = (1 << 16), 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 }; 72 73 #define D3D12_DIRTY_PSO (D3D12_DIRTY_BLEND | D3D12_DIRTY_RASTERIZER | D3D12_DIRTY_ZSA | \ 74 D3D12_DIRTY_FRAMEBUFFER | D3D12_DIRTY_SAMPLE_MASK | \ 75 D3D12_DIRTY_VERTEX_ELEMENTS | D3D12_DIRTY_PRIM_MODE | \ 76 D3D12_DIRTY_SHADER | D3D12_DIRTY_ROOT_SIGNATURE | \ 77 D3D12_DIRTY_STRIP_CUT_VALUE) 78 79 #define D3D12_SHADER_DIRTY_ALL (D3D12_SHADER_DIRTY_CONSTBUF | D3D12_SHADER_DIRTY_SAMPLER_VIEWS | \ 80 D3D12_SHADER_DIRTY_SAMPLERS) 81 82 enum d3d12_binding_type { 83 D3D12_BINDING_CONSTANT_BUFFER, 84 D3D12_BINDING_SHADER_RESOURCE_VIEW, 85 D3D12_BINDING_SAMPLER, 86 D3D12_BINDING_STATE_VARS, 87 D3D12_NUM_BINDING_TYPES 88 }; 89 90 struct d3d12_sampler_state { 91 struct d3d12_descriptor_handle handle, handle_without_shadow; 92 bool is_integer_texture; 93 bool is_shadow_sampler; 94 enum pipe_tex_wrap wrap_r; 95 enum pipe_tex_wrap wrap_s; 96 enum pipe_tex_wrap wrap_t; 97 enum pipe_tex_filter filter; 98 float lod_bias; 99 float min_lod, max_lod; 100 float border_color[4]; 101 enum pipe_compare_func compare_func; 102 }; 103 104 enum d3d12_blend_factor_flags { 105 D3D12_BLEND_FACTOR_NONE = 0, 106 D3D12_BLEND_FACTOR_COLOR = 1 << 0, 107 D3D12_BLEND_FACTOR_ALPHA = 1 << 1, 108 D3D12_BLEND_FACTOR_ANY = 1 << 2, 109 }; 110 111 struct d3d12_sampler_view { 112 struct pipe_sampler_view base; 113 struct d3d12_descriptor_handle handle; 114 unsigned mip_levels; 115 unsigned array_size; 116 unsigned swizzle_override_r:3; /**< PIPE_SWIZZLE_x for red component */ 117 unsigned swizzle_override_g:3; /**< PIPE_SWIZZLE_x for green component */ 118 unsigned swizzle_override_b:3; /**< PIPE_SWIZZLE_x for blue component */ 119 unsigned swizzle_override_a:3; /**< PIPE_SWIZZLE_x for alpha component */ 120 }; 121 122 static inline struct d3d12_sampler_view * 123 d3d12_sampler_view(struct pipe_sampler_view *pview) 124 { 125 return (struct d3d12_sampler_view *)pview; 126 } 127 128 struct d3d12_stream_output_target { 129 struct pipe_stream_output_target base; 130 struct pipe_resource *fill_buffer; 131 unsigned fill_buffer_offset; 132 uint64_t cached_filled_size; 133 }; 134 135 struct d3d12_shader_state { 136 struct d3d12_shader *current; 137 unsigned state_dirty; 138 }; 139 140 struct blitter_context; 141 struct primconvert_context; 142 struct d3d12_validation_tools; 143 144 #ifdef __cplusplus 145 class ResourceStateManager; 146 #endif 147 148 struct d3d12_context { 149 struct pipe_context base; 150 struct slab_child_pool transfer_pool; 151 struct primconvert_context *primconvert; 152 struct blitter_context *blitter; 153 struct u_suballocator query_allocator; 154 struct u_suballocator so_allocator; 155 struct hash_table *pso_cache; 156 struct hash_table *root_signature_cache; 157 struct hash_table *gs_variant_cache; 158 159 struct d3d12_batch batches[4]; 160 unsigned current_batch_idx; 161 162 struct pipe_constant_buffer cbufs[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; 163 struct pipe_framebuffer_state fb; 164 struct pipe_vertex_buffer vbs[PIPE_MAX_ATTRIBS]; 165 D3D12_VERTEX_BUFFER_VIEW vbvs[PIPE_MAX_ATTRIBS]; 166 unsigned num_vbs; 167 float flip_y; 168 bool need_zero_one_depth_range; 169 enum pipe_prim_type initial_api_prim; 170 struct pipe_viewport_state viewport_states[PIPE_MAX_VIEWPORTS]; 171 D3D12_VIEWPORT viewports[PIPE_MAX_VIEWPORTS]; 172 unsigned num_viewports; 173 struct pipe_scissor_state scissor_states[PIPE_MAX_VIEWPORTS]; 174 D3D12_RECT scissors[PIPE_MAX_VIEWPORTS]; 175 float blend_factor[4]; 176 struct pipe_stencil_ref stencil_ref; 177 struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; 178 unsigned num_sampler_views[PIPE_SHADER_TYPES]; 179 unsigned has_int_samplers; 180 struct d3d12_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; 181 unsigned num_samplers[PIPE_SHADER_TYPES]; 182 D3D12_INDEX_BUFFER_VIEW ibv; 183 dxil_wrap_sampler_state tex_wrap_states[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; 184 dxil_texture_swizzle_state tex_swizzle_state[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; 185 enum compare_func tex_compare_func[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; 186 187 struct { 188 bool enabled; 189 uint32_t pattern[32]; 190 struct pipe_resource *texture; 191 struct pipe_sampler_view *sampler_view; 192 struct d3d12_sampler_state *sampler_cso; 193 } pstipple; 194 195 struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS]; 196 D3D12_STREAM_OUTPUT_BUFFER_VIEW so_buffer_views[PIPE_MAX_SO_BUFFERS]; 197 struct pipe_stream_output_target *fake_so_targets[PIPE_MAX_SO_BUFFERS]; 198 D3D12_STREAM_OUTPUT_BUFFER_VIEW fake_so_buffer_views[PIPE_MAX_SO_BUFFERS]; 199 unsigned fake_so_buffer_factor; 200 201 struct d3d12_shader_selector *gfx_stages[D3D12_GFX_SHADER_STAGES]; 202 203 struct d3d12_gfx_pipeline_state gfx_pipeline_state; 204 unsigned shader_dirty[D3D12_GFX_SHADER_STAGES]; 205 unsigned state_dirty; 206 unsigned cmdlist_dirty; 207 ID3D12PipelineState *current_pso; 208 bool reverse_depth_range; 209 210 ID3D12Fence *cmdqueue_fence; 211 uint64_t fence_value; 212 ID3D12GraphicsCommandList *cmdlist; 213 214 struct list_head active_queries; 215 bool queries_disabled; 216 217 struct d3d12_descriptor_pool *sampler_pool; 218 struct d3d12_descriptor_handle null_sampler; 219 220 PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignature; 221 struct d3d12_validation_tools *validation_tools; 222 223 struct d3d12_resource *current_predication; 224 225 #ifdef __cplusplus 226 ResourceStateManager *resource_state_manager; 227 #else 228 void *resource_state_manager; /* opaque pointer; we don't know about classes in C */ 229 #endif 230 struct pipe_query *timestamp_query; 231 232 /* used by d3d12_blit.cpp */ 233 void *stencil_resolve_vs, *stencil_resolve_fs, *stencil_resolve_fs_no_flip, *sampler_state; 234 }; 235 236 static inline struct d3d12_context * 237 d3d12_context(struct pipe_context *context) 238 { 239 return (struct d3d12_context *)context; 240 } 241 242 static inline struct d3d12_batch * 243 d3d12_current_batch(struct d3d12_context *ctx) 244 { 245 assert(ctx->current_batch_idx < ARRAY_SIZE(ctx->batches)); 246 return ctx->batches + ctx->current_batch_idx; 247 } 248 249 #define d3d12_foreach_submitted_batch(ctx, batch) \ 250 unsigned oldest = (ctx->current_batch_idx + 1) % ARRAY_SIZE(ctx->batches); \ 251 while (ctx->batches[oldest].fence == NULL && oldest != ctx->current_batch_idx) \ 252 oldest = (oldest + 1) % ARRAY_SIZE(ctx->batches); \ 253 struct d3d12_batch *batch = &ctx->batches[oldest]; \ 254 for (; oldest != ctx->current_batch_idx; \ 255 oldest = (oldest + 1) % ARRAY_SIZE(ctx->batches), \ 256 batch = &ctx->batches[oldest]) 257 258 struct pipe_context * 259 d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags); 260 261 bool 262 d3d12_enable_fake_so_buffers(struct d3d12_context *ctx, unsigned factor); 263 264 bool 265 d3d12_disable_fake_so_buffers(struct d3d12_context *ctx); 266 267 void 268 d3d12_flush_cmdlist(struct d3d12_context *ctx); 269 270 void 271 d3d12_flush_cmdlist_and_wait(struct d3d12_context *ctx); 272 273 274 enum d3d12_bind_invalidate_option { 275 D3D12_BIND_INVALIDATE_NONE, 276 D3D12_BIND_INVALIDATE_FULL, 277 }; 278 279 void 280 d3d12_transition_resource_state(struct d3d12_context* ctx, 281 struct d3d12_resource* res, 282 D3D12_RESOURCE_STATES state, 283 d3d12_bind_invalidate_option bind_invalidate); 284 285 void 286 d3d12_transition_subresources_state(struct d3d12_context *ctx, 287 struct d3d12_resource *res, 288 unsigned start_level, unsigned num_levels, 289 unsigned start_layer, unsigned num_layers, 290 unsigned start_plane, unsigned num_planes, 291 D3D12_RESOURCE_STATES state, 292 d3d12_bind_invalidate_option bind_invalidate); 293 294 void 295 d3d12_apply_resource_states(struct d3d12_context* ctx); 296 297 void 298 d3d12_draw_vbo(struct pipe_context *pctx, 299 const struct pipe_draw_info *dinfo, 300 unsigned drawid_offset, 301 const struct pipe_draw_indirect_info *indirect, 302 const struct pipe_draw_start_count_bias *draws, 303 unsigned num_draws); 304 305 void 306 d3d12_blit(struct pipe_context *pctx, 307 const struct pipe_blit_info *info); 308 309 void 310 d3d12_context_query_init(struct pipe_context *pctx); 311 312 bool 313 d3d12_need_zero_one_depth_range(struct d3d12_context *ctx); 314 315 #endif 316