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_VIDEO_TYPES_H
25 #define D3D12_VIDEO_TYPES_H
26
27 #include <stdarg.h>
28 #include <memory>
29 #include <vector>
30 #include <functional>
31
32 #include "pipe/p_context.h"
33 #include "pipe/p_video_codec.h"
34 #include "d3d12_fence.h"
35 #include "d3d12_debug.h"
36
37 #include <directx/d3d12video.h>
38 #include <dxguids/dxguids.h>
39
40 #include <wrl/client.h>
41 using Microsoft::WRL::ComPtr;
42
43 #define D3D12_VIDEO_ANY_DECODER_ENABLED (VIDEO_CODEC_H264DEC || VIDEO_CODEC_H265DEC || VIDEO_CODEC_AV1DEC || VIDEO_CODEC_VP9DEC)
44
45 #if !defined(_WIN32) || defined(_MSC_VER)
46 inline D3D12_VIDEO_DECODER_HEAP_DESC
GetDesc(ID3D12VideoDecoderHeap * heap)47 GetDesc(ID3D12VideoDecoderHeap *heap)
48 {
49 return heap->GetDesc();
50 }
51 #else
52 inline D3D12_VIDEO_DECODER_HEAP_DESC
GetDesc(ID3D12VideoDecoderHeap * heap)53 GetDesc(ID3D12VideoDecoderHeap *heap)
54 {
55 D3D12_VIDEO_DECODER_HEAP_DESC ret;
56 heap->GetDesc(&ret);
57 return ret;
58 }
59 #endif
60
61 /* For CBR mode, to guarantee bitrate of generated stream complies with
62 * target bitrate (e.g. no over +/-10%), vbv_buffer_size should be same
63 * as target bitrate. Controlled by OS env var D3D12_VIDEO_ENC_CBR_FORCE_VBV_EQUAL_BITRATE
64 */
65 const bool D3D12_VIDEO_ENC_CBR_FORCE_VBV_EQUAL_BITRATE = debug_get_bool_option("D3D12_VIDEO_ENC_CBR_FORCE_VBV_EQUAL_BITRATE", false);
66
67 const bool D3D12_VIDEO_ENC_ASYNC = debug_get_bool_option("D3D12_VIDEO_ENC_ASYNC", true);
68
69 /**
70 * This indicates how many in-flight encode commands can happen before blocking on the next request
71 */
72 const uint64_t D3D12_VIDEO_ENC_ASYNC_DEPTH = debug_get_num_option("D3D12_VIDEO_ENC_ASYNC_DEPTH", 8);
73
74 const uint64_t D3D12_VIDEO_ENC_METADATA_BUFFERS_COUNT = debug_get_num_option("D3D12_VIDEO_ENC_METADATA_BUFFERS_COUNT", 2 * D3D12_VIDEO_ENC_ASYNC_DEPTH);
75
76 constexpr unsigned int D3D12_VIDEO_H264_MB_IN_PIXELS = 16;
77
78 constexpr size_t D3D12_DEFAULT_COMPBIT_STAGING_SIZE = (1024 /*1K*/ * 1024/*1MB*/) * 8/*8 MB*/; // 8MB
79
80 /* If enabled, the D3D12 AV1 encoder will use always ...CONFIGURABLE_GRID_PARTITION mode */
81 /* If disabled, the D3D12 AV1 encoder will try to use ...UNIFORM_GRID_PARTITION first and then fallback to ...CONFIGURABLE_GRID_PARTITION if not possible */
82 const bool D3D12_VIDEO_FORCE_TILE_MODE = debug_get_bool_option("D3D12_VIDEO_FORCE_TILE_MODE", false);
83
84 /**
85 * If enabled, the D3D12 AV1 encoder will insert a OBU_FRAME_HEADER with show_existing_frame = 1 after the current frame to show a previous
86 * show_frame = 0 encoded frame as reference and used by the current frame
87 */
88 const bool D3D12_VIDEO_AV1_INSERT_SHOW_EXISTING_FRAME_HEADER = debug_get_bool_option("D3D12_VIDEO_AV1_INSERT_SHOW_EXISTING_FRAME_HEADER", false);
89
90 enum d3d12_video_decode_config_specific_flags
91 {
92 d3d12_video_decode_config_specific_flag_none = 0,
93 d3d12_video_decode_config_specific_flag_alignment_height = 1 << 12, // set by accelerator
94 d3d12_video_decode_config_specific_flag_array_of_textures = 1 << 14, // set by accelerator
95 d3d12_video_decode_config_specific_flag_reuse_decoder =
96 1 << 15, // set by accelerator - This bit means that the decoder can be re-used with resolution change and bit
97 // depth change (including profile GUID change from 8bit to 10bit and vice versa).
98 d3d12_video_decode_config_specific_flag_reference_only_textures_required = 1 << 30, // custom created for WSL
99 };
100
101 enum d3d12_video_decode_profile_type
102 {
103 d3d12_video_decode_profile_type_none,
104 d3d12_video_decode_profile_type_h264,
105 d3d12_video_decode_profile_type_hevc,
106 d3d12_video_decode_profile_type_av1,
107 d3d12_video_decode_profile_type_vp9,
108 d3d12_video_decode_profile_type_max_valid
109 };
110
111 struct d3d12_video_decode_dpb_descriptor
112 {
113 DXGI_FORMAT Format = DXGI_FORMAT_UNKNOWN;
114 uint64_t Width = 0;
115 uint32_t Height = 0;
116 bool fArrayOfTexture = false;
117 bool fReferenceOnly = false;
118 uint16_t dpbSize = 0;
119 uint32_t m_NodeMask = 0;
120 };
121
122 struct d3d12_video_decode_output_conversion_arguments
123 {
124 BOOL Enable;
125 DXGI_COLOR_SPACE_TYPE OutputColorSpace;
126 D3D12_VIDEO_SAMPLE ReferenceInfo;
127 uint32_t ReferenceFrameCount;
128 };
129
130 void
131 d3d12_video_encoder_convert_from_d3d12_level_h264(D3D12_VIDEO_ENCODER_LEVELS_H264 level12,
132 uint32_t & specLevel);
133 void
134 d3d12_video_encoder_convert_from_d3d12_level_hevc(D3D12_VIDEO_ENCODER_LEVELS_HEVC level12,
135 uint32_t & specLevel);
136 void
137 d3d12_video_encoder_convert_d3d12_to_spec_level_av1(D3D12_VIDEO_ENCODER_AV1_LEVELS level12,
138 uint32_t & specLevel);
139 void
140 d3d12_video_encoder_convert_spec_to_d3d12_level_av1(uint32_t specLevel,
141 D3D12_VIDEO_ENCODER_AV1_LEVELS& level12);
142 void
143 d3d12_video_encoder_convert_spec_to_d3d12_tier_av1(uint32_t specTier,
144 D3D12_VIDEO_ENCODER_AV1_TIER & tier12);
145 D3D12_VIDEO_ENCODER_PROFILE_H264
146 d3d12_video_encoder_convert_profile_to_d3d12_enc_profile_h264(enum pipe_video_profile profile);
147 D3D12_VIDEO_ENCODER_PROFILE_HEVC
148 d3d12_video_encoder_convert_profile_to_d3d12_enc_profile_hevc(enum pipe_video_profile profile);
149 D3D12_VIDEO_ENCODER_AV1_PROFILE
150 d3d12_video_encoder_convert_profile_to_d3d12_enc_profile_av1(enum pipe_video_profile profile);
151 D3D12_VIDEO_ENCODER_CODEC
152 d3d12_video_encoder_convert_codec_to_d3d12_enc_codec(enum pipe_video_profile profile);
153 GUID
154 d3d12_video_decoder_convert_pipe_video_profile_to_d3d12_profile(enum pipe_video_profile profile);
155 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE
156 d3d12_video_encoder_convert_pixel_size_hevc_to_12tusize(const uint32_t& TUSize);
157 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE
158 d3d12_video_encoder_convert_pixel_size_hevc_to_12cusize(const uint32_t& cuSize);
159 uint8_t
160 d3d12_video_encoder_convert_12cusize_to_pixel_size_hevc(const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE& cuSize);
161 uint8_t
162 d3d12_video_encoder_convert_12tusize_to_pixel_size_hevc(const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE& TUSize);
163 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT
164 ConvertHEVCSupportFromProfile(D3D12_VIDEO_ENCODER_PROFILE_HEVC profile, D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC1* pSupport1);
165 D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA
166 ConvertHEVCPicParamsFromProfile(D3D12_VIDEO_ENCODER_PROFILE_HEVC profile, D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_HEVC1* pPictureParams1);
167
168 DEFINE_ENUM_FLAG_OPERATORS(pipe_enc_feature);
169 DEFINE_ENUM_FLAG_OPERATORS(pipe_h265_enc_pred_direction);
170 DEFINE_ENUM_FLAG_OPERATORS(codec_unit_location_flags);
171 DEFINE_ENUM_FLAG_OPERATORS(pipe_video_feedback_encode_result_flags);
172 DEFINE_ENUM_FLAG_OPERATORS(pipe_video_feedback_metadata_type);
173
174 #define D3D12_VIDEO_ENC_H264_MAX_TEMPORAL_LAYERS 1
175 #define D3D12_VIDEO_ENC_HEVC_MAX_TEMPORAL_LAYERS 1
176 #define D3D12_VIDEO_ENC_AV1_MAX_TEMPORAL_LAYERS 1
177 #define D3D12_VIDEO_ENC_MAX_RATE_CONTROL_TEMPORAL_LAYERS 4
178
179 static_assert(D3D12_VIDEO_ENC_MAX_RATE_CONTROL_TEMPORAL_LAYERS >= D3D12_VIDEO_ENC_H264_MAX_TEMPORAL_LAYERS, "Increase size of D3D12_VIDEO_ENC_MAX_RATE_CONTROL_TEMPORAL_LAYERS");
180 static_assert(D3D12_VIDEO_ENC_MAX_RATE_CONTROL_TEMPORAL_LAYERS >= D3D12_VIDEO_ENC_HEVC_MAX_TEMPORAL_LAYERS, "Increase size of D3D12_VIDEO_ENC_MAX_RATE_CONTROL_TEMPORAL_LAYERS");
181 static_assert(D3D12_VIDEO_ENC_MAX_RATE_CONTROL_TEMPORAL_LAYERS >= D3D12_VIDEO_ENC_AV1_MAX_TEMPORAL_LAYERS, "Increase size of D3D12_VIDEO_ENC_MAX_RATE_CONTROL_TEMPORAL_LAYERS");
182
183 static_assert(ARRAY_SIZE(pipe_h264_enc_picture_desc::rate_ctrl) >= D3D12_VIDEO_ENC_H264_MAX_TEMPORAL_LAYERS, "Increase size of pipe_h264_enc_picture_desc::rate_ctrl[] array");
184 static_assert(ARRAY_SIZE(pipe_h265_enc_picture_desc::rc) >= D3D12_VIDEO_ENC_HEVC_MAX_TEMPORAL_LAYERS, "Increase size of pipe_h265_enc_picture_desc::rc[] array");
185 static_assert(ARRAY_SIZE(pipe_av1_enc_picture_desc::rc) >= D3D12_VIDEO_ENC_AV1_MAX_TEMPORAL_LAYERS, "Increase size of pipe_h265_enc_picture_desc::rc[] array");
186 #endif
187