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