Home | History | Annotate | Line # | Download | only in d3d12
      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