17ec681f3Smrg/* 27ec681f3Smrg * Copyright © Microsoft Corporation 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 97ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 217ec681f3Smrg * IN THE SOFTWARE. 227ec681f3Smrg */ 237ec681f3Smrg 247ec681f3Smrg#ifndef D3D12_CONTEXT_H 257ec681f3Smrg#define D3D12_CONTEXT_H 267ec681f3Smrg 277ec681f3Smrg#include "d3d12_batch.h" 287ec681f3Smrg#include "d3d12_descriptor_pool.h" 297ec681f3Smrg#include "d3d12_pipeline_state.h" 307ec681f3Smrg#include "d3d12_nir_lower_texcmp.h" 317ec681f3Smrg 327ec681f3Smrg#include "dxil_nir_lower_int_samplers.h" 337ec681f3Smrg 347ec681f3Smrg#include "pipe/p_context.h" 357ec681f3Smrg#include "pipe/p_state.h" 367ec681f3Smrg#include "util/list.h" 377ec681f3Smrg#include "util/slab.h" 387ec681f3Smrg#include "util/u_suballoc.h" 397ec681f3Smrg 407ec681f3Smrg#include <directx/d3d12.h> 417ec681f3Smrg 427ec681f3Smrg#define D3D12_GFX_SHADER_STAGES (PIPE_SHADER_TYPES - 1) 437ec681f3Smrg 447ec681f3Smrgenum d3d12_dirty_flags 457ec681f3Smrg{ 467ec681f3Smrg D3D12_DIRTY_NONE = 0, 477ec681f3Smrg D3D12_DIRTY_BLEND = (1 << 0), 487ec681f3Smrg D3D12_DIRTY_RASTERIZER = (1 << 1), 497ec681f3Smrg D3D12_DIRTY_ZSA = (1 << 2), 507ec681f3Smrg D3D12_DIRTY_VERTEX_ELEMENTS = (1 << 3), 517ec681f3Smrg D3D12_DIRTY_BLEND_COLOR = (1 << 4), 527ec681f3Smrg D3D12_DIRTY_STENCIL_REF = (1 << 5), 537ec681f3Smrg D3D12_DIRTY_SAMPLE_MASK = (1 << 6), 547ec681f3Smrg D3D12_DIRTY_VIEWPORT = (1 << 7), 557ec681f3Smrg D3D12_DIRTY_FRAMEBUFFER = (1 << 8), 567ec681f3Smrg D3D12_DIRTY_SCISSOR = (1 << 9), 577ec681f3Smrg D3D12_DIRTY_VERTEX_BUFFERS = (1 << 10), 587ec681f3Smrg D3D12_DIRTY_INDEX_BUFFER = (1 << 11), 597ec681f3Smrg D3D12_DIRTY_PRIM_MODE = (1 << 12), 607ec681f3Smrg D3D12_DIRTY_SHADER = (1 << 13), 617ec681f3Smrg D3D12_DIRTY_ROOT_SIGNATURE = (1 << 14), 627ec681f3Smrg D3D12_DIRTY_STREAM_OUTPUT = (1 << 15), 637ec681f3Smrg D3D12_DIRTY_STRIP_CUT_VALUE = (1 << 16), 647ec681f3Smrg}; 657ec681f3Smrg 667ec681f3Smrgenum d3d12_shader_dirty_flags 677ec681f3Smrg{ 687ec681f3Smrg D3D12_SHADER_DIRTY_CONSTBUF = (1 << 0), 697ec681f3Smrg D3D12_SHADER_DIRTY_SAMPLER_VIEWS = (1 << 1), 707ec681f3Smrg D3D12_SHADER_DIRTY_SAMPLERS = (1 << 2), 717ec681f3Smrg}; 727ec681f3Smrg 737ec681f3Smrg#define D3D12_DIRTY_PSO (D3D12_DIRTY_BLEND | D3D12_DIRTY_RASTERIZER | D3D12_DIRTY_ZSA | \ 747ec681f3Smrg D3D12_DIRTY_FRAMEBUFFER | D3D12_DIRTY_SAMPLE_MASK | \ 757ec681f3Smrg D3D12_DIRTY_VERTEX_ELEMENTS | D3D12_DIRTY_PRIM_MODE | \ 767ec681f3Smrg D3D12_DIRTY_SHADER | D3D12_DIRTY_ROOT_SIGNATURE | \ 777ec681f3Smrg D3D12_DIRTY_STRIP_CUT_VALUE) 787ec681f3Smrg 797ec681f3Smrg#define D3D12_SHADER_DIRTY_ALL (D3D12_SHADER_DIRTY_CONSTBUF | D3D12_SHADER_DIRTY_SAMPLER_VIEWS | \ 807ec681f3Smrg D3D12_SHADER_DIRTY_SAMPLERS) 817ec681f3Smrg 827ec681f3Smrgenum d3d12_binding_type { 837ec681f3Smrg D3D12_BINDING_CONSTANT_BUFFER, 847ec681f3Smrg D3D12_BINDING_SHADER_RESOURCE_VIEW, 857ec681f3Smrg D3D12_BINDING_SAMPLER, 867ec681f3Smrg D3D12_BINDING_STATE_VARS, 877ec681f3Smrg D3D12_NUM_BINDING_TYPES 887ec681f3Smrg}; 897ec681f3Smrg 907ec681f3Smrgstruct d3d12_sampler_state { 917ec681f3Smrg struct d3d12_descriptor_handle handle, handle_without_shadow; 927ec681f3Smrg bool is_integer_texture; 937ec681f3Smrg bool is_shadow_sampler; 947ec681f3Smrg enum pipe_tex_wrap wrap_r; 957ec681f3Smrg enum pipe_tex_wrap wrap_s; 967ec681f3Smrg enum pipe_tex_wrap wrap_t; 977ec681f3Smrg enum pipe_tex_filter filter; 987ec681f3Smrg float lod_bias; 997ec681f3Smrg float min_lod, max_lod; 1007ec681f3Smrg float border_color[4]; 1017ec681f3Smrg enum pipe_compare_func compare_func; 1027ec681f3Smrg}; 1037ec681f3Smrg 1047ec681f3Smrgenum d3d12_blend_factor_flags { 1057ec681f3Smrg D3D12_BLEND_FACTOR_NONE = 0, 1067ec681f3Smrg D3D12_BLEND_FACTOR_COLOR = 1 << 0, 1077ec681f3Smrg D3D12_BLEND_FACTOR_ALPHA = 1 << 1, 1087ec681f3Smrg D3D12_BLEND_FACTOR_ANY = 1 << 2, 1097ec681f3Smrg}; 1107ec681f3Smrg 1117ec681f3Smrgstruct d3d12_sampler_view { 1127ec681f3Smrg struct pipe_sampler_view base; 1137ec681f3Smrg struct d3d12_descriptor_handle handle; 1147ec681f3Smrg unsigned mip_levels; 1157ec681f3Smrg unsigned array_size; 1167ec681f3Smrg unsigned swizzle_override_r:3; /**< PIPE_SWIZZLE_x for red component */ 1177ec681f3Smrg unsigned swizzle_override_g:3; /**< PIPE_SWIZZLE_x for green component */ 1187ec681f3Smrg unsigned swizzle_override_b:3; /**< PIPE_SWIZZLE_x for blue component */ 1197ec681f3Smrg unsigned swizzle_override_a:3; /**< PIPE_SWIZZLE_x for alpha component */ 1207ec681f3Smrg}; 1217ec681f3Smrg 1227ec681f3Smrgstatic inline struct d3d12_sampler_view * 1237ec681f3Smrgd3d12_sampler_view(struct pipe_sampler_view *pview) 1247ec681f3Smrg{ 1257ec681f3Smrg return (struct d3d12_sampler_view *)pview; 1267ec681f3Smrg} 1277ec681f3Smrg 1287ec681f3Smrgstruct d3d12_stream_output_target { 1297ec681f3Smrg struct pipe_stream_output_target base; 1307ec681f3Smrg struct pipe_resource *fill_buffer; 1317ec681f3Smrg unsigned fill_buffer_offset; 1327ec681f3Smrg uint64_t cached_filled_size; 1337ec681f3Smrg}; 1347ec681f3Smrg 1357ec681f3Smrgstruct d3d12_shader_state { 1367ec681f3Smrg struct d3d12_shader *current; 1377ec681f3Smrg unsigned state_dirty; 1387ec681f3Smrg}; 1397ec681f3Smrg 1407ec681f3Smrgstruct blitter_context; 1417ec681f3Smrgstruct primconvert_context; 1427ec681f3Smrgstruct d3d12_validation_tools; 1437ec681f3Smrg 1447ec681f3Smrg#ifdef __cplusplus 1457ec681f3Smrgclass ResourceStateManager; 1467ec681f3Smrg#endif 1477ec681f3Smrg 1487ec681f3Smrgstruct d3d12_context { 1497ec681f3Smrg struct pipe_context base; 1507ec681f3Smrg struct slab_child_pool transfer_pool; 1517ec681f3Smrg struct primconvert_context *primconvert; 1527ec681f3Smrg struct blitter_context *blitter; 1537ec681f3Smrg struct u_suballocator query_allocator; 1547ec681f3Smrg struct u_suballocator so_allocator; 1557ec681f3Smrg struct hash_table *pso_cache; 1567ec681f3Smrg struct hash_table *root_signature_cache; 1577ec681f3Smrg struct hash_table *gs_variant_cache; 1587ec681f3Smrg 1597ec681f3Smrg struct d3d12_batch batches[4]; 1607ec681f3Smrg unsigned current_batch_idx; 1617ec681f3Smrg 1627ec681f3Smrg struct pipe_constant_buffer cbufs[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; 1637ec681f3Smrg struct pipe_framebuffer_state fb; 1647ec681f3Smrg struct pipe_vertex_buffer vbs[PIPE_MAX_ATTRIBS]; 1657ec681f3Smrg D3D12_VERTEX_BUFFER_VIEW vbvs[PIPE_MAX_ATTRIBS]; 1667ec681f3Smrg unsigned num_vbs; 1677ec681f3Smrg float flip_y; 1687ec681f3Smrg bool need_zero_one_depth_range; 1697ec681f3Smrg enum pipe_prim_type initial_api_prim; 1707ec681f3Smrg struct pipe_viewport_state viewport_states[PIPE_MAX_VIEWPORTS]; 1717ec681f3Smrg D3D12_VIEWPORT viewports[PIPE_MAX_VIEWPORTS]; 1727ec681f3Smrg unsigned num_viewports; 1737ec681f3Smrg struct pipe_scissor_state scissor_states[PIPE_MAX_VIEWPORTS]; 1747ec681f3Smrg D3D12_RECT scissors[PIPE_MAX_VIEWPORTS]; 1757ec681f3Smrg float blend_factor[4]; 1767ec681f3Smrg struct pipe_stencil_ref stencil_ref; 1777ec681f3Smrg struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; 1787ec681f3Smrg unsigned num_sampler_views[PIPE_SHADER_TYPES]; 1797ec681f3Smrg unsigned has_int_samplers; 1807ec681f3Smrg struct d3d12_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; 1817ec681f3Smrg unsigned num_samplers[PIPE_SHADER_TYPES]; 1827ec681f3Smrg D3D12_INDEX_BUFFER_VIEW ibv; 1837ec681f3Smrg dxil_wrap_sampler_state tex_wrap_states[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; 1847ec681f3Smrg dxil_texture_swizzle_state tex_swizzle_state[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; 1857ec681f3Smrg enum compare_func tex_compare_func[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; 1867ec681f3Smrg 1877ec681f3Smrg struct { 1887ec681f3Smrg bool enabled; 1897ec681f3Smrg uint32_t pattern[32]; 1907ec681f3Smrg struct pipe_resource *texture; 1917ec681f3Smrg struct pipe_sampler_view *sampler_view; 1927ec681f3Smrg struct d3d12_sampler_state *sampler_cso; 1937ec681f3Smrg } pstipple; 1947ec681f3Smrg 1957ec681f3Smrg struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS]; 1967ec681f3Smrg D3D12_STREAM_OUTPUT_BUFFER_VIEW so_buffer_views[PIPE_MAX_SO_BUFFERS]; 1977ec681f3Smrg struct pipe_stream_output_target *fake_so_targets[PIPE_MAX_SO_BUFFERS]; 1987ec681f3Smrg D3D12_STREAM_OUTPUT_BUFFER_VIEW fake_so_buffer_views[PIPE_MAX_SO_BUFFERS]; 1997ec681f3Smrg unsigned fake_so_buffer_factor; 2007ec681f3Smrg 2017ec681f3Smrg struct d3d12_shader_selector *gfx_stages[D3D12_GFX_SHADER_STAGES]; 2027ec681f3Smrg 2037ec681f3Smrg struct d3d12_gfx_pipeline_state gfx_pipeline_state; 2047ec681f3Smrg unsigned shader_dirty[D3D12_GFX_SHADER_STAGES]; 2057ec681f3Smrg unsigned state_dirty; 2067ec681f3Smrg unsigned cmdlist_dirty; 2077ec681f3Smrg ID3D12PipelineState *current_pso; 2087ec681f3Smrg bool reverse_depth_range; 2097ec681f3Smrg 2107ec681f3Smrg ID3D12Fence *cmdqueue_fence; 2117ec681f3Smrg uint64_t fence_value; 2127ec681f3Smrg ID3D12GraphicsCommandList *cmdlist; 2137ec681f3Smrg 2147ec681f3Smrg struct list_head active_queries; 2157ec681f3Smrg bool queries_disabled; 2167ec681f3Smrg 2177ec681f3Smrg struct d3d12_descriptor_pool *sampler_pool; 2187ec681f3Smrg struct d3d12_descriptor_handle null_sampler; 2197ec681f3Smrg 2207ec681f3Smrg PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignature; 2217ec681f3Smrg struct d3d12_validation_tools *validation_tools; 2227ec681f3Smrg 2237ec681f3Smrg struct d3d12_resource *current_predication; 2247ec681f3Smrg 2257ec681f3Smrg#ifdef __cplusplus 2267ec681f3Smrg ResourceStateManager *resource_state_manager; 2277ec681f3Smrg#else 2287ec681f3Smrg void *resource_state_manager; /* opaque pointer; we don't know about classes in C */ 2297ec681f3Smrg#endif 2307ec681f3Smrg struct pipe_query *timestamp_query; 2317ec681f3Smrg 2327ec681f3Smrg /* used by d3d12_blit.cpp */ 2337ec681f3Smrg void *stencil_resolve_vs, *stencil_resolve_fs, *stencil_resolve_fs_no_flip, *sampler_state; 2347ec681f3Smrg}; 2357ec681f3Smrg 2367ec681f3Smrgstatic inline struct d3d12_context * 2377ec681f3Smrgd3d12_context(struct pipe_context *context) 2387ec681f3Smrg{ 2397ec681f3Smrg return (struct d3d12_context *)context; 2407ec681f3Smrg} 2417ec681f3Smrg 2427ec681f3Smrgstatic inline struct d3d12_batch * 2437ec681f3Smrgd3d12_current_batch(struct d3d12_context *ctx) 2447ec681f3Smrg{ 2457ec681f3Smrg assert(ctx->current_batch_idx < ARRAY_SIZE(ctx->batches)); 2467ec681f3Smrg return ctx->batches + ctx->current_batch_idx; 2477ec681f3Smrg} 2487ec681f3Smrg 2497ec681f3Smrg#define d3d12_foreach_submitted_batch(ctx, batch) \ 2507ec681f3Smrg unsigned oldest = (ctx->current_batch_idx + 1) % ARRAY_SIZE(ctx->batches); \ 2517ec681f3Smrg while (ctx->batches[oldest].fence == NULL && oldest != ctx->current_batch_idx) \ 2527ec681f3Smrg oldest = (oldest + 1) % ARRAY_SIZE(ctx->batches); \ 2537ec681f3Smrg struct d3d12_batch *batch = &ctx->batches[oldest]; \ 2547ec681f3Smrg for (; oldest != ctx->current_batch_idx; \ 2557ec681f3Smrg oldest = (oldest + 1) % ARRAY_SIZE(ctx->batches), \ 2567ec681f3Smrg batch = &ctx->batches[oldest]) 2577ec681f3Smrg 2587ec681f3Smrgstruct pipe_context * 2597ec681f3Smrgd3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags); 2607ec681f3Smrg 2617ec681f3Smrgbool 2627ec681f3Smrgd3d12_enable_fake_so_buffers(struct d3d12_context *ctx, unsigned factor); 2637ec681f3Smrg 2647ec681f3Smrgbool 2657ec681f3Smrgd3d12_disable_fake_so_buffers(struct d3d12_context *ctx); 2667ec681f3Smrg 2677ec681f3Smrgvoid 2687ec681f3Smrgd3d12_flush_cmdlist(struct d3d12_context *ctx); 2697ec681f3Smrg 2707ec681f3Smrgvoid 2717ec681f3Smrgd3d12_flush_cmdlist_and_wait(struct d3d12_context *ctx); 2727ec681f3Smrg 2737ec681f3Smrg 2747ec681f3Smrgenum d3d12_bind_invalidate_option { 2757ec681f3Smrg D3D12_BIND_INVALIDATE_NONE, 2767ec681f3Smrg D3D12_BIND_INVALIDATE_FULL, 2777ec681f3Smrg}; 2787ec681f3Smrg 2797ec681f3Smrgvoid 2807ec681f3Smrgd3d12_transition_resource_state(struct d3d12_context* ctx, 2817ec681f3Smrg struct d3d12_resource* res, 2827ec681f3Smrg D3D12_RESOURCE_STATES state, 2837ec681f3Smrg d3d12_bind_invalidate_option bind_invalidate); 2847ec681f3Smrg 2857ec681f3Smrgvoid 2867ec681f3Smrgd3d12_transition_subresources_state(struct d3d12_context *ctx, 2877ec681f3Smrg struct d3d12_resource *res, 2887ec681f3Smrg unsigned start_level, unsigned num_levels, 2897ec681f3Smrg unsigned start_layer, unsigned num_layers, 2907ec681f3Smrg unsigned start_plane, unsigned num_planes, 2917ec681f3Smrg D3D12_RESOURCE_STATES state, 2927ec681f3Smrg d3d12_bind_invalidate_option bind_invalidate); 2937ec681f3Smrg 2947ec681f3Smrgvoid 2957ec681f3Smrgd3d12_apply_resource_states(struct d3d12_context* ctx); 2967ec681f3Smrg 2977ec681f3Smrgvoid 2987ec681f3Smrgd3d12_draw_vbo(struct pipe_context *pctx, 2997ec681f3Smrg const struct pipe_draw_info *dinfo, 3007ec681f3Smrg unsigned drawid_offset, 3017ec681f3Smrg const struct pipe_draw_indirect_info *indirect, 3027ec681f3Smrg const struct pipe_draw_start_count_bias *draws, 3037ec681f3Smrg unsigned num_draws); 3047ec681f3Smrg 3057ec681f3Smrgvoid 3067ec681f3Smrgd3d12_blit(struct pipe_context *pctx, 3077ec681f3Smrg const struct pipe_blit_info *info); 3087ec681f3Smrg 3097ec681f3Smrgvoid 3107ec681f3Smrgd3d12_context_query_init(struct pipe_context *pctx); 3117ec681f3Smrg 3127ec681f3Smrgbool 3137ec681f3Smrgd3d12_need_zero_one_depth_range(struct d3d12_context *ctx); 3147ec681f3Smrg 3157ec681f3Smrg#endif 316