summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/gpu/d3d12
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/gpu/d3d12')
-rw-r--r--contrib/SDL-3.2.8/src/gpu/d3d12/D3D12_Blit.h3349
-rw-r--r--contrib/SDL-3.2.8/src/gpu/d3d12/D3D_Blit.hlsl97
-rw-r--r--contrib/SDL-3.2.8/src/gpu/d3d12/SDL_gpu_d3d12.c9113
-rw-r--r--contrib/SDL-3.2.8/src/gpu/d3d12/compile_shaders.bat18
-rw-r--r--contrib/SDL-3.2.8/src/gpu/d3d12/compile_shaders_xbox.bat13
5 files changed, 12590 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/gpu/d3d12/D3D12_Blit.h b/contrib/SDL-3.2.8/src/gpu/d3d12/D3D12_Blit.h
new file mode 100644
index 0000000..d8cfbaf
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/gpu/d3d12/D3D12_Blit.h
@@ -0,0 +1,3349 @@
1#if 0
2;
3; Input signature:
4;
5; Name Index Mask Register SysValue Format Used
6; -------------------- ----- ------ -------- -------- ------- ------
7; SV_VertexID 0 x 0 VERTID uint x
8;
9;
10; Output signature:
11;
12; Name Index Mask Register SysValue Format Used
13; -------------------- ----- ------ -------- -------- ------- ------
14; TEXCOORD 0 xy 0 NONE float xy
15; SV_Position 0 xyzw 1 POS float xyzw
16;
17; shader hash: 347572259f9a9ea84d2f90bafbd0e1ae
18;
19; Pipeline Runtime Information:
20;
21; Vertex Shader
22; OutputPositionPresent=1
23;
24;
25; Input signature:
26;
27; Name Index InterpMode DynIdx
28; -------------------- ----- ---------------------- ------
29; SV_VertexID 0
30;
31; Output signature:
32;
33; Name Index InterpMode DynIdx
34; -------------------- ----- ---------------------- ------
35; TEXCOORD 0 linear
36; SV_Position 0 noperspective
37;
38; Buffer Definitions:
39;
40;
41; Resource Bindings:
42;
43; Name Type Format Dim ID HLSL Bind Count
44; ------------------------------ ---------- ------- ----------- ------- -------------- ------
45;
46;
47; ViewId state:
48;
49; Number of inputs: 1, outputs: 8
50; Outputs dependent on ViewId: { }
51; Inputs contributing to computation of Outputs:
52; output 0 depends on inputs: { 0 }
53; output 1 depends on inputs: { 0 }
54; output 4 depends on inputs: { 0 }
55; output 5 depends on inputs: { 0 }
56;
57target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
58target triple = "dxil-ms-dx"
59
60define void @FullscreenVert() {
61 %1 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
62 %2 = shl i32 %1, 1
63 %3 = and i32 %2, 2
64 %4 = uitofp i32 %3 to float
65 %5 = and i32 %1, 2
66 %6 = uitofp i32 %5 to float
67 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float 0.000000e+00) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
68 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float 0.000000e+00) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
69 call void @dx.op.storeOutput.f32(i32 5, i32 1, i32 0, i8 0, float 0.000000e+00) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
70 call void @dx.op.storeOutput.f32(i32 5, i32 1, i32 0, i8 1, float 0.000000e+00) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
71 call void @dx.op.storeOutput.f32(i32 5, i32 1, i32 0, i8 2, float 0.000000e+00) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
72 call void @dx.op.storeOutput.f32(i32 5, i32 1, i32 0, i8 3, float 0.000000e+00) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
73 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %4) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
74 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %6) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
75 %7 = fmul fast float %4, 2.000000e+00
76 %8 = fmul fast float %6, 2.000000e+00
77 %9 = fadd fast float %7, -1.000000e+00
78 %10 = fsub fast float 1.000000e+00, %8
79 call void @dx.op.storeOutput.f32(i32 5, i32 1, i32 0, i8 0, float %9) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
80 call void @dx.op.storeOutput.f32(i32 5, i32 1, i32 0, i8 1, float %10) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
81 call void @dx.op.storeOutput.f32(i32 5, i32 1, i32 0, i8 2, float 0.000000e+00) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
82 call void @dx.op.storeOutput.f32(i32 5, i32 1, i32 0, i8 3, float 1.000000e+00) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
83 ret void
84}
85
86; Function Attrs: nounwind readnone
87declare i32 @dx.op.loadInput.i32(i32, i32, i32, i8, i32) #0
88
89; Function Attrs: nounwind
90declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
91
92attributes #0 = { nounwind readnone }
93attributes #1 = { nounwind }
94
95!llvm.ident = !{!0}
96!dx.version = !{!1}
97!dx.valver = !{!2}
98!dx.shaderModel = !{!3}
99!dx.viewIdState = !{!4}
100!dx.entryPoints = !{!5}
101
102!0 = !{!"clang version 3.7 (tags/RELEASE_370/final)"}
103!1 = !{i32 1, i32 0}
104!2 = !{i32 1, i32 6}
105!3 = !{!"vs", i32 6, i32 0}
106!4 = !{[3 x i32] [i32 1, i32 8, i32 51]}
107!5 = !{void ()* @FullscreenVert, !"FullscreenVert", !6, null, null}
108!6 = !{!7, !11, null}
109!7 = !{!8}
110!8 = !{i32 0, !"SV_VertexID", i8 5, i8 1, !9, i8 0, i32 1, i8 1, i32 0, i8 0, !10}
111!9 = !{i32 0}
112!10 = !{i32 3, i32 1}
113!11 = !{!12, !14}
114!12 = !{i32 0, !"TEXCOORD", i8 9, i8 0, !9, i8 2, i32 1, i8 2, i32 0, i8 0, !13}
115!13 = !{i32 3, i32 3}
116!14 = !{i32 1, !"SV_Position", i8 9, i8 3, !9, i8 4, i32 1, i8 4, i32 1, i8 0, !15}
117!15 = !{i32 3, i32 15}
118
119#endif
120
121const unsigned char g_FullscreenVert[] = {
122 0x44, 0x58, 0x42, 0x43, 0x81, 0xc4, 0x09, 0xbf, 0x6d, 0xef, 0xac, 0x67,
123 0x8f, 0x1d, 0x64, 0xb4, 0xf2, 0x1e, 0x4b, 0xca, 0x01, 0x00, 0x00, 0x00,
124 0x4d, 0x0d, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
125 0x50, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00,
126 0x8d, 0x01, 0x00, 0x00, 0x1d, 0x02, 0x00, 0x00, 0xa9, 0x07, 0x00, 0x00,
127 0xc5, 0x07, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31,
129 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x56,
133 0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x31,
134 0x5d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x03, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
139 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44,
141 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
142 0x00, 0x50, 0x53, 0x56, 0x30, 0x94, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
143 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
145 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x02, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x54, 0x45,
148 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x01, 0x01, 0x00, 0x00,
151 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42,
152 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x01, 0x01, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x33, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x52, 0x54, 0x53, 0x30, 0x88, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
156 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x05, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
160 0x00, 0x05, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
161 0x00, 0x44, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
166 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0x53, 0x54, 0x41, 0x54, 0x84, 0x05, 0x00, 0x00, 0x60, 0x00, 0x01,
168 0x00, 0x61, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00,
169 0x00, 0x10, 0x00, 0x00, 0x00, 0x6c, 0x05, 0x00, 0x00, 0x42, 0x43, 0xc0,
170 0xde, 0x21, 0x0c, 0x00, 0x00, 0x58, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20,
171 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23,
172 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84,
173 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, 0x45,
174 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18,
175 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88,
176 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x22, 0xc4,
177 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, 0x46,
178 0x06, 0x51, 0x18, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0,
179 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff,
180 0xff, 0xff, 0xff, 0x03, 0x20, 0x01, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00,
181 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x00, 0x00,
182 0x00, 0x89, 0x20, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08,
183 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22,
184 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84,
185 0x4c, 0x10, 0x3c, 0x23, 0x00, 0x25, 0x00, 0x8a, 0x39, 0x02, 0x30, 0x98,
186 0x23, 0x40, 0x8a, 0x31, 0x33, 0x43, 0x43, 0x35, 0x03, 0x50, 0x0c, 0x98,
187 0x19, 0x3a, 0xc2, 0x81, 0x80, 0x61, 0x04, 0xe1, 0x18, 0x46, 0x20, 0x8e,
188 0xa3, 0xa4, 0x29, 0xa2, 0x84, 0xc9, 0x7f, 0x89, 0x68, 0x22, 0xae, 0xd6,
189 0x49, 0x91, 0x8b, 0x58, 0x90, 0xb0, 0x9c, 0x03, 0x03, 0x13, 0x14, 0x72,
190 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72,
191 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e,
192 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07,
193 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e,
194 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07,
195 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07,
196 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07,
197 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07,
198 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06,
199 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e,
200 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07,
201 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x05, 0x10, 0x00, 0x01, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00,
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x0e, 0x00, 0x00,
205 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26,
206 0x47, 0xc6, 0x04, 0x43, 0x9a, 0x12, 0x18, 0x01, 0x28, 0x86, 0x02, 0x2a,
207 0x83, 0x42, 0x28, 0x87, 0x92, 0x28, 0x90, 0xf2, 0x28, 0x97, 0xc2, 0x20,
208 0x2a, 0x85, 0x12, 0x18, 0x01, 0x28, 0x89, 0x22, 0x28, 0x83, 0x42, 0xa0,
209 0x9e, 0x01, 0x20, 0x1f, 0x6b, 0x08, 0x90, 0x39, 0x00, 0x79, 0x18, 0x00,
210 0x00, 0x84, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13,
211 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b,
212 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b,
213 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9,
214 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13,
215 0x84, 0x61, 0x98, 0x20, 0x0c, 0xc4, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04,
216 0x41, 0xc1, 0x6e, 0x6e, 0x82, 0x30, 0x14, 0x1b, 0x86, 0x03, 0x21, 0x26,
217 0x08, 0x8d, 0x35, 0x41, 0x18, 0x0c, 0x0e, 0x74, 0x65, 0x78, 0x13, 0x84,
218 0xe1, 0x98, 0x20, 0x0c, 0x08, 0x13, 0xaa, 0x22, 0xac, 0xa1, 0xa7, 0x27,
219 0x29, 0x22, 0x98, 0x09, 0xc2, 0x90, 0x4c, 0x10, 0x06, 0x65, 0x03, 0x82,
220 0x30, 0x0d, 0xe1, 0x3c, 0x50, 0xc4, 0x01, 0xee, 0x6d, 0x6e, 0x82, 0x30,
221 0x2c, 0x5c, 0xa6, 0xac, 0xbe, 0xa0, 0x9e, 0xa6, 0x92, 0xa8, 0x92, 0x9e,
222 0x9c, 0x36, 0x20, 0xc8, 0xd4, 0x50, 0x4e, 0x05, 0x45, 0x1b, 0x86, 0x45,
223 0xb2, 0x36, 0x0c, 0x84, 0x72, 0x4d, 0x10, 0x04, 0x60, 0x03, 0xb0, 0x61,
224 0x20, 0x34, 0x6d, 0x43, 0xb0, 0x6d, 0x18, 0x86, 0x8c, 0x9b, 0x20, 0x38,
225 0xd7, 0x86, 0xc0, 0xa3, 0x63, 0x54, 0xc7, 0xc6, 0x36, 0x37, 0x26, 0x57,
226 0x56, 0xe6, 0x66, 0x55, 0x26, 0x47, 0xc7, 0x65, 0xca, 0xea, 0xcb, 0xaa,
227 0x4c, 0x8e, 0xae, 0x0c, 0x2f, 0x89, 0x68, 0x82, 0x40, 0x3c, 0x13, 0x04,
228 0x02, 0xda, 0x10, 0x10, 0x13, 0x04, 0x22, 0xda, 0x20, 0x34, 0xc3, 0x86,
229 0x85, 0x08, 0x03, 0x31, 0x18, 0x03, 0x32, 0x28, 0x83, 0x61, 0x0c, 0x88,
230 0x32, 0x30, 0x83, 0x0d, 0xc1, 0x19, 0x10, 0xa1, 0x2a, 0xc2, 0x1a, 0x7a,
231 0x7a, 0x92, 0x22, 0x9a, 0x20, 0x10, 0xd2, 0x04, 0x81, 0x98, 0x36, 0x08,
232 0x4d, 0xb3, 0x61, 0x21, 0xd2, 0x40, 0x0d, 0xca, 0x80, 0x0c, 0xd6, 0x60,
233 0x58, 0x03, 0xa2, 0x0c, 0xd8, 0x80, 0xcb, 0x94, 0xd5, 0x17, 0xd4, 0xdb,
234 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0xdb, 0x04, 0x81, 0xa0, 0x26, 0x08, 0x44,
235 0x35, 0x41, 0x18, 0x98, 0x0d, 0x42, 0x13, 0x07, 0x1b, 0x96, 0xc1, 0x0d,
236 0xd4, 0xe0, 0x0d, 0xc8, 0x00, 0x0e, 0x06, 0x38, 0x18, 0xca, 0x40, 0x0e,
237 0x36, 0x08, 0x6d, 0x30, 0x07, 0x1b, 0x06, 0x34, 0xa0, 0x03, 0x60, 0x43,
238 0x91, 0x81, 0x41, 0x1d, 0x00, 0x00, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0xba,
239 0x39, 0x16, 0x69, 0x6e, 0x73, 0x74, 0x73, 0x13, 0x84, 0xa1, 0xa1, 0x31,
240 0x97, 0x76, 0xf6, 0xc5, 0x46, 0x46, 0x63, 0x2e, 0xed, 0xec, 0x6b, 0x8e,
241 0x6e, 0x82, 0x30, 0x38, 0x2c, 0xea, 0xd2, 0xdc, 0xe8, 0xe6, 0x36, 0x28,
242 0x77, 0x80, 0xe0, 0x41, 0x1e, 0xe8, 0xc1, 0xb0, 0x07, 0x7c, 0xd0, 0x07,
243 0x4d, 0x15, 0x36, 0x36, 0xbb, 0x36, 0x97, 0x34, 0xb2, 0x32, 0x37, 0xba,
244 0x29, 0x41, 0x50, 0x85, 0x0c, 0xcf, 0xc5, 0xae, 0x4c, 0x6e, 0x2e, 0xed,
245 0xcd, 0x6d, 0x4a, 0x40, 0x34, 0x21, 0xc3, 0x73, 0xb1, 0x0b, 0x63, 0xb3,
246 0x2b, 0x93, 0x9b, 0x12, 0x14, 0x75, 0xc8, 0xf0, 0x5c, 0xe6, 0xd0, 0xc2,
247 0xc8, 0xca, 0xe4, 0x9a, 0xde, 0xc8, 0xca, 0xd8, 0xa6, 0x04, 0x48, 0x25,
248 0x32, 0x3c, 0x17, 0xba, 0x3c, 0xb8, 0xb2, 0x20, 0x37, 0xb7, 0x37, 0xba,
249 0x30, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x29, 0xc2, 0xc5, 0xd5, 0x21, 0xc3,
250 0x73, 0xb1, 0x4b, 0x2b, 0xbb, 0x4b, 0x22, 0x9b, 0xa2, 0x0b, 0xa3, 0x2b,
251 0x9b, 0x12, 0x78, 0x75, 0xc8, 0xf0, 0x5c, 0xca, 0xdc, 0xe8, 0xe4, 0xf2,
252 0xa0, 0xde, 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, 0x04, 0x75, 0xd0, 0x85, 0x0c,
253 0xcf, 0x65, 0xec, 0xad, 0xce, 0x8d, 0xae, 0x4c, 0x6e, 0x6e, 0x4a, 0xd0,
254 0x07, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00,
255 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d,
256 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07,
257 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80,
258 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66,
259 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d,
260 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07,
261 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03,
262 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90,
263 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50,
264 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2,
265 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39,
266 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14,
267 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07,
268 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07,
269 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87,
270 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0,
271 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8,
272 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc,
273 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6,
274 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39,
275 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f,
276 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c,
277 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87,
278 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0,
279 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50,
280 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00,
281 0x00, 0x06, 0xe0, 0x7c, 0xd4, 0xb2, 0x48, 0x42, 0x44, 0x10, 0xcd, 0x4b,
282 0x44, 0x93, 0x05, 0x4c, 0xc3, 0xe5, 0x3b, 0x8f, 0xbf, 0x38, 0xc0, 0x20,
283 0x36, 0x0f, 0x35, 0xf9, 0xc8, 0x6d, 0x9b, 0x40, 0x35, 0x5c, 0xbe, 0xf3,
284 0xf8, 0xd2, 0xe4, 0x44, 0x04, 0x4a, 0x4d, 0x0f, 0x35, 0xf9, 0xc5, 0x6d,
285 0x03, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x75, 0x72, 0x25, 0x9f, 0x9a, 0x9e,
287 0xa8, 0x4d, 0x2f, 0x90, 0xba, 0xfb, 0xd0, 0xe1, 0xae, 0x44, 0x58, 0x49,
288 0x4c, 0x80, 0x05, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0x60, 0x01, 0x00,
289 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00,
290 0x00, 0x68, 0x05, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00,
291 0x00, 0x57, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00,
292 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04,
293 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08,
294 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b,
295 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x42,
296 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32,
297 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81,
298 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, 0x46, 0x06, 0x51, 0x18, 0x00,
299 0x00, 0x06, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff,
300 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03,
301 0x20, 0x01, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00,
302 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00,
303 0x00, 0x0f, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85,
304 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90,
305 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x30, 0x23,
306 0x00, 0x25, 0x00, 0x8a, 0x39, 0x02, 0x30, 0x98, 0x23, 0x40, 0x8a, 0x31,
307 0x33, 0x43, 0x43, 0x35, 0x03, 0x50, 0x0c, 0x98, 0x19, 0x3a, 0xc2, 0x81,
308 0x80, 0x1c, 0x18, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60,
309 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf,
310 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a,
311 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71,
312 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73,
313 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72,
314 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d,
315 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6,
316 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73,
317 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74,
318 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71,
319 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43,
320 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x86, 0x3c, 0x05, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0xc8, 0x02, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98,
324 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43,
325 0x9a, 0x12, 0x18, 0x01, 0x28, 0x86, 0x32, 0x28, 0x0f, 0xa2, 0x52, 0x28,
326 0x81, 0x11, 0x80, 0x92, 0x28, 0x82, 0x32, 0x28, 0x04, 0xda, 0xb1, 0x86,
327 0x00, 0x99, 0x03, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x51, 0x00, 0x00,
328 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63,
329 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03,
330 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a,
331 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b,
332 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x84, 0x61, 0x98, 0x20,
333 0x0c, 0xc4, 0x06, 0x61, 0x20, 0x26, 0x08, 0x43, 0xb1, 0x41, 0x18, 0x0c,
334 0x0a, 0x76, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0xcb, 0xb3, 0x21,
335 0x50, 0x26, 0x08, 0x02, 0x40, 0xc7, 0xa8, 0x8e, 0x8d, 0x6d, 0x6e, 0x4c,
336 0xae, 0xac, 0xcc, 0xcd, 0xaa, 0x4c, 0x8e, 0x8e, 0xcb, 0x94, 0xd5, 0x97,
337 0x55, 0x99, 0x1c, 0x5d, 0x19, 0x5e, 0x12, 0xd1, 0x04, 0x81, 0x40, 0x26,
338 0x08, 0x44, 0xb2, 0x21, 0x20, 0x26, 0x08, 0x84, 0x32, 0x41, 0x18, 0x8c,
339 0x0d, 0xc2, 0x34, 0x6c, 0x58, 0x08, 0xe7, 0x81, 0x22, 0x69, 0x80, 0x08,
340 0x89, 0xda, 0x10, 0x54, 0x44, 0xa8, 0x8a, 0xb0, 0x86, 0x9e, 0x9e, 0xa4,
341 0x88, 0x26, 0x08, 0xc4, 0x32, 0x41, 0x20, 0x98, 0x0d, 0xc2, 0x34, 0x6d,
342 0x58, 0x88, 0x0b, 0x93, 0xa2, 0x6c, 0xc8, 0x08, 0x49, 0xe3, 0x32, 0x65,
343 0xf5, 0x05, 0xf5, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x36, 0x41, 0x20,
344 0x9a, 0x09, 0x02, 0xe1, 0x4c, 0x10, 0x86, 0x63, 0x83, 0x30, 0x7d, 0x1b,
345 0x96, 0x81, 0xc3, 0xba, 0xc8, 0x1b, 0xbc, 0x41, 0x02, 0x83, 0x0d, 0xc2,
346 0x16, 0x06, 0x1b, 0x06, 0x4b, 0x0c, 0x80, 0x0d, 0x05, 0xd3, 0x8c, 0x01,
347 0x00, 0x54, 0x61, 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73, 0xa3,
348 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, 0x5c, 0xec, 0xca, 0xe4, 0xe6, 0xd2,
349 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, 0x32, 0x3c, 0x17, 0xbb, 0x30, 0x36,
350 0xbb, 0x32, 0xb9, 0x29, 0x81, 0x51, 0x87, 0x0c, 0xcf, 0x65, 0x0e, 0x2d,
351 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0x80, 0xd4,
352 0x21, 0xc3, 0x73, 0xb1, 0x4b, 0x2b, 0xbb, 0x4b, 0x22, 0x9b, 0xa2, 0x0b,
353 0xa3, 0x2b, 0x9b, 0x12, 0x28, 0x75, 0xc8, 0xf0, 0x5c, 0xca, 0xdc, 0xe8,
354 0xe4, 0xf2, 0xa0, 0xde, 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, 0x04, 0x63, 0x00,
355 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80,
356 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84,
357 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c,
358 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42,
359 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88,
360 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c,
361 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79,
362 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70,
363 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f,
364 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4,
365 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30,
366 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc,
367 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b,
368 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70,
369 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76,
370 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72,
371 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e,
372 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1,
373 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21,
374 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8,
375 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94,
376 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc,
377 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c,
378 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e,
379 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e,
380 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00,
381 0x00, 0x71, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0xe0, 0x7c,
382 0xd4, 0xb2, 0x48, 0x42, 0x44, 0x10, 0xcd, 0x4b, 0x44, 0x93, 0x05, 0x4c,
383 0xc3, 0xe5, 0x3b, 0x8f, 0xbf, 0x38, 0xc0, 0x20, 0x36, 0x0f, 0x35, 0xf9,
384 0xc8, 0x6d, 0x9b, 0x40, 0x35, 0x5c, 0xbe, 0xf3, 0xf8, 0xd2, 0xe4, 0x44,
385 0x04, 0x4a, 0x4d, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x03, 0x61, 0x20, 0x00,
386 0x00, 0x39, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00,
387 0x00, 0x08, 0x00, 0x00, 0x00, 0x34, 0xa5, 0x50, 0x04, 0x85, 0x30, 0x03,
388 0x40, 0x37, 0x02, 0x30, 0x46, 0x00, 0x82, 0x20, 0x08, 0x82, 0xc1, 0x18,
389 0x01, 0x08, 0x82, 0x20, 0xfe, 0x8d, 0x11, 0x80, 0x20, 0x08, 0xe2, 0xbf,
390 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x50, 0x5c, 0x06, 0x45, 0x39,
391 0x45, 0x05, 0xd6, 0x55, 0x90, 0xe8, 0x05, 0x57, 0x45, 0x2c, 0x7a, 0xc1,
392 0xd5, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, 0x9c, 0xa3, 0x69, 0x94,
393 0x32, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x08, 0xe7, 0x68, 0x5a, 0xa5,
394 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0xc2, 0x39, 0x9b, 0x46, 0x29,
395 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0x70, 0xce, 0xa6, 0x55, 0xca,
396 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, 0x9c, 0xb3, 0x69, 0x92, 0x32,
397 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x08, 0xe7, 0x6c, 0x5a, 0xa4, 0x8c,
398 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0xc2, 0x39, 0x9a, 0x46, 0x0d, 0x23,
399 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0x70, 0x8e, 0xa6, 0x55, 0x81, 0x0d,
400 0x89, 0x7c, 0x4c, 0x50, 0xe4, 0x63, 0x42, 0x02, 0x1f, 0x5b, 0x84, 0xf8,
401 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0x02, 0x06, 0xd2, 0xe7, 0x61,
402 0xc2, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, 0x60, 0x20, 0x7d, 0x5e,
403 0x16, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0x02, 0x06, 0xd2, 0xe7,
404 0x59, 0xce, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, 0x60, 0x20, 0x7d,
405 0x5e, 0xc5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
406};
407#if 0
408;
409; Input signature:
410;
411; Name Index Mask Register SysValue Format Used
412; -------------------- ----- ------ -------- -------- ------- ------
413; TEXCOORD 0 xy 0 NONE float xy
414; SV_Position 0 xyzw 1 POS float
415;
416;
417; Output signature:
418;
419; Name Index Mask Register SysValue Format Used
420; -------------------- ----- ------ -------- -------- ------- ------
421; SV_Target 0 xyzw 0 TARGET float xyzw
422;
423; shader hash: 964a7513a7ff5558ed84391b53971f63
424;
425; Pipeline Runtime Information:
426;
427; Pixel Shader
428; DepthOutput=0
429; SampleFrequency=0
430;
431;
432; Input signature:
433;
434; Name Index InterpMode DynIdx
435; -------------------- ----- ---------------------- ------
436; TEXCOORD 0 linear
437; SV_Position 0 noperspective
438;
439; Output signature:
440;
441; Name Index InterpMode DynIdx
442; -------------------- ----- ---------------------- ------
443; SV_Target 0
444;
445; Buffer Definitions:
446;
447; cbuffer SourceRegionBuffer
448; {
449;
450; struct SourceRegionBuffer
451; {
452;
453; float2 UVLeftTop; ; Offset: 0
454; float2 UVDimensions; ; Offset: 8
455; uint MipLevel; ; Offset: 16
456; float LayerOrDepth; ; Offset: 20
457;
458; } SourceRegionBuffer; ; Offset: 0 Size: 24
459;
460; }
461;
462;
463; Resource Bindings:
464;
465; Name Type Format Dim ID HLSL Bind Count
466; ------------------------------ ---------- ------- ----------- ------- -------------- ------
467; SourceRegionBuffer cbuffer NA NA CB0 cb0,space3 1
468; SourceSampler sampler NA NA S0 s0,space2 1
469; SourceTexture2D texture f32 2d T0 t0,space2 1
470;
471;
472; ViewId state:
473;
474; Number of inputs: 8, outputs: 4
475; Outputs dependent on ViewId: { }
476; Inputs contributing to computation of Outputs:
477; output 0 depends on inputs: { 0, 1 }
478; output 1 depends on inputs: { 0, 1 }
479; output 2 depends on inputs: { 0, 1 }
480; output 3 depends on inputs: { 0, 1 }
481;
482target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
483target triple = "dxil-ms-dx"
484
485%dx.types.Handle = type { i8* }
486%dx.types.CBufRet.f32 = type { float, float, float, float }
487%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
488%dx.types.ResRet.f32 = type { float, float, float, float, i32 }
489%"class.Texture2D<vector<float, 4> >" = type { <4 x float>, %"class.Texture2D<vector<float, 4> >::mips_type" }
490%"class.Texture2D<vector<float, 4> >::mips_type" = type { i32 }
491%SourceRegionBuffer = type { <2 x float>, <2 x float>, i32, float }
492%struct.SamplerState = type { i32 }
493
494define void @BlitFrom2D() {
495 %1 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
496 %2 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 3, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
497 %3 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
498 %4 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
499 %5 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
500 %6 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %3, i32 0) ; CBufferLoadLegacy(handle,regIndex)
501 %7 = extractvalue %dx.types.CBufRet.f32 %6, 0
502 %8 = extractvalue %dx.types.CBufRet.f32 %6, 1
503 %9 = extractvalue %dx.types.CBufRet.f32 %6, 2
504 %10 = extractvalue %dx.types.CBufRet.f32 %6, 3
505 %11 = fmul fast float %9, %4
506 %12 = fmul fast float %10, %5
507 %13 = fadd fast float %11, %7
508 %14 = fadd fast float %12, %8
509 %15 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %3, i32 1) ; CBufferLoadLegacy(handle,regIndex)
510 %16 = extractvalue %dx.types.CBufRet.i32 %15, 0
511 %17 = uitofp i32 %16 to float
512 %18 = call %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32 62, %dx.types.Handle %1, %dx.types.Handle %2, float %13, float %14, float undef, float undef, i32 0, i32 0, i32 undef, float %17) ; SampleLevel(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,LOD)
513 %19 = extractvalue %dx.types.ResRet.f32 %18, 0
514 %20 = extractvalue %dx.types.ResRet.f32 %18, 1
515 %21 = extractvalue %dx.types.ResRet.f32 %18, 2
516 %22 = extractvalue %dx.types.ResRet.f32 %18, 3
517 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %19) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
518 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %20) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
519 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %21) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
520 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %22) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
521 ret void
522}
523
524; Function Attrs: nounwind readnone
525declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
526
527; Function Attrs: nounwind
528declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
529
530; Function Attrs: nounwind readonly
531declare %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32, %dx.types.Handle, %dx.types.Handle, float, float, float, float, i32, i32, i32, float) #2
532
533; Function Attrs: nounwind readonly
534declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #2
535
536; Function Attrs: nounwind readonly
537declare %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32, %dx.types.Handle, i32) #2
538
539; Function Attrs: nounwind readonly
540declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #2
541
542attributes #0 = { nounwind readnone }
543attributes #1 = { nounwind }
544attributes #2 = { nounwind readonly }
545
546!llvm.ident = !{!0}
547!dx.version = !{!1}
548!dx.valver = !{!2}
549!dx.shaderModel = !{!3}
550!dx.resources = !{!4}
551!dx.viewIdState = !{!12}
552!dx.entryPoints = !{!13}
553
554!0 = !{!"clang version 3.7 (tags/RELEASE_370/final)"}
555!1 = !{i32 1, i32 0}
556!2 = !{i32 1, i32 6}
557!3 = !{!"ps", i32 6, i32 0}
558!4 = !{!5, null, !8, !10}
559!5 = !{!6}
560!6 = !{i32 0, %"class.Texture2D<vector<float, 4> >"* undef, !"", i32 2, i32 0, i32 1, i32 2, i32 0, !7}
561!7 = !{i32 0, i32 9}
562!8 = !{!9}
563!9 = !{i32 0, %SourceRegionBuffer* undef, !"", i32 3, i32 0, i32 1, i32 24, null}
564!10 = !{!11}
565!11 = !{i32 0, %struct.SamplerState* undef, !"", i32 2, i32 0, i32 1, i32 0, null}
566!12 = !{[10 x i32] [i32 8, i32 4, i32 15, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0]}
567!13 = !{void ()* @BlitFrom2D, !"BlitFrom2D", !14, !4, null}
568!14 = !{!15, !20, null}
569!15 = !{!16, !19}
570!16 = !{i32 0, !"TEXCOORD", i8 9, i8 0, !17, i8 2, i32 1, i8 2, i32 0, i8 0, !18}
571!17 = !{i32 0}
572!18 = !{i32 3, i32 3}
573!19 = !{i32 1, !"SV_Position", i8 9, i8 3, !17, i8 4, i32 1, i8 4, i32 1, i8 0, null}
574!20 = !{!21}
575!21 = !{i32 0, !"SV_Target", i8 9, i8 16, !17, i8 0, i32 1, i8 4, i32 0, i8 0, !22}
576!22 = !{i32 3, i32 15}
577
578#endif
579
580const unsigned char g_BlitFrom2D[] = {
581 0x44, 0x58, 0x42, 0x43, 0x18, 0x05, 0x35, 0x74, 0x86, 0x3d, 0x7b, 0xa8,
582 0x8e, 0x1e, 0xae, 0xc3, 0xeb, 0x7f, 0x9a, 0xd9, 0x01, 0x00, 0x00, 0x00,
583 0x2b, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
584 0x50, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00,
585 0xe7, 0x01, 0x00, 0x00, 0x77, 0x02, 0x00, 0x00, 0x5b, 0x0a, 0x00, 0x00,
586 0x77, 0x0a, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31,
588 0x5d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
593 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44,
595 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
596 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
597 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x50,
601 0x53, 0x56, 0x30, 0xf0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
604 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
606 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
611 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
613 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x00, 0x00, 0x01,
614 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
615 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x03,
616 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
617 0x01, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, 0x00, 0x0f,
619 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x88,
622 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18,
623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00,
624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c,
625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5c,
626 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x7c,
627 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03,
628 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01,
630 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x03,
633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x54, 0x41, 0x54, 0xdc,
634 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xf7, 0x01, 0x00, 0x00, 0x44,
635 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xc4,
636 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xee,
637 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
638 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06,
639 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e,
640 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4,
641 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48,
642 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4,
643 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1,
644 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08,
645 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40,
646 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d,
647 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49,
648 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20,
649 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x58,
650 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13,
651 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12,
652 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x8c, 0xc1, 0x08, 0x40,
653 0x09, 0x00, 0x0a, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29,
654 0xc6, 0x40, 0x10, 0x44, 0x41, 0x90, 0x51, 0x0c, 0x80, 0x20, 0x88, 0x62,
655 0x20, 0xe4, 0xa6, 0xe1, 0xf2, 0x27, 0xec, 0x21, 0x24, 0x7f, 0x25, 0xa4,
656 0x95, 0x98, 0xfc, 0xe2, 0xb6, 0x51, 0x31, 0x0c, 0xc3, 0x40, 0x50, 0x71,
657 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, 0x10,
658 0x28, 0x58, 0x0a, 0xa3, 0x10, 0x0c, 0x33, 0x0c, 0xc3, 0x40, 0x10, 0xc4,
659 0x40, 0xcd, 0x51, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, 0x3e, 0xb7, 0x51,
660 0xc5, 0x4a, 0x4c, 0x3e, 0x72, 0xdb, 0x88, 0x20, 0x08, 0x82, 0x28, 0xc4,
661 0x43, 0x30, 0x04, 0x41, 0x47, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9,
662 0xdc, 0x46, 0x15, 0x2b, 0x31, 0xf9, 0xc5, 0x6d, 0x23, 0x62, 0x18, 0x86,
663 0xa1, 0x10, 0x12, 0xc1, 0x10, 0x34, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0x88,
664 0x82, 0x20, 0x2a, 0xb2, 0x06, 0x02, 0x86, 0x11, 0x88, 0x61, 0xa6, 0x36,
665 0x18, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07, 0x37, 0xa0, 0x85, 0x72,
666 0xc0, 0x07, 0x7a, 0xa8, 0x07, 0x79, 0x28, 0x07, 0x39, 0x20, 0x05, 0x3e,
667 0xb0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0xe0, 0x03, 0x73,
668 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x60, 0x03, 0x30, 0xa0, 0x03, 0x3f,
669 0x00, 0x03, 0x3f, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x74, 0x80, 0x87, 0x79,
670 0xf8, 0x05, 0x7a, 0xc8, 0x07, 0x78, 0x28, 0x07, 0x14, 0x10, 0x33, 0x89,
671 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94,
672 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, 0x43, 0x39, 0xc8, 0x01, 0x29, 0xf0,
673 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98,
674 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8,
675 0x01, 0x18, 0xf8, 0x01, 0x12, 0x32, 0x8d, 0xb6, 0x61, 0x04, 0x61, 0x38,
676 0x89, 0x75, 0xa8, 0x48, 0x20, 0x56, 0xc2, 0x40, 0x9c, 0x66, 0xa3, 0x8a,
677 0x82, 0x88, 0x10, 0xd1, 0x75, 0xc4, 0x40, 0xde, 0x4d, 0xd2, 0x14, 0x51,
678 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0,
679 0x80, 0x20, 0x30, 0x15, 0x08, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87,
680 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87,
681 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00,
682 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90,
683 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0,
684 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30,
685 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20,
686 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0,
687 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60,
688 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60,
689 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0,
690 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40,
691 0x07, 0x43, 0x9e, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
693 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00,
695 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x81, 0x80, 0x00, 0x18, 0x00,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30,
697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xc7, 0x02, 0x02,
698 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x14,
699 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, 0x90, 0x8c,
700 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x22, 0x4a, 0x60, 0x04, 0xa0, 0x18,
701 0x8a, 0xa0, 0x24, 0xca, 0xa0, 0x60, 0xca, 0xa1, 0x20, 0x0a, 0xa4, 0x14,
702 0x0a, 0xa5, 0x3c, 0xca, 0xa6, 0x10, 0xa8, 0x28, 0x89, 0x11, 0x80, 0x22,
703 0x28, 0x83, 0x42, 0x28, 0x10, 0xaa, 0x6a, 0x80, 0xb8, 0x19, 0x00, 0xf2,
704 0x66, 0x00, 0xe8, 0x9b, 0x01, 0xa0, 0x70, 0x06, 0x80, 0xc4, 0xb1, 0x14,
705 0x84, 0x78, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79,
706 0x18, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46,
707 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b,
708 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1,
709 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa,
710 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10,
711 0x04, 0x13, 0x04, 0xe2, 0x98, 0x20, 0x10, 0xc8, 0x06, 0x61, 0x20, 0x36,
712 0x08, 0x04, 0x41, 0x01, 0x6e, 0x6e, 0x82, 0x40, 0x24, 0x1b, 0x86, 0x03,
713 0x21, 0x26, 0x08, 0x5c, 0xc7, 0x67, 0xea, 0xad, 0x4e, 0x6e, 0xac, 0x8c,
714 0xaa, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0x68, 0x82, 0x40, 0x28,
715 0x13, 0x04, 0x62, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84, 0x50, 0x16, 0x86,
716 0x18, 0x18, 0xc2, 0xd9, 0x10, 0x3c, 0x13, 0x84, 0xef, 0xa3, 0x34, 0xf5,
717 0x56, 0x27, 0x37, 0x56, 0x26, 0x55, 0x76, 0x96, 0xf6, 0xe6, 0x26, 0x54,
718 0x67, 0x66, 0x56, 0x26, 0x37, 0x41, 0x20, 0x98, 0x09, 0x02, 0xd1, 0x6c,
719 0x40, 0x88, 0x48, 0x9a, 0x88, 0x81, 0x02, 0x36, 0x04, 0xd5, 0x04, 0x21,
720 0x0c, 0xc0, 0x80, 0xcd, 0xd4, 0x5b, 0x9d, 0xdc, 0x58, 0xd9, 0x54, 0x58,
721 0x1b, 0x1c, 0x5b, 0x99, 0xdc, 0x06, 0x84, 0xb8, 0x30, 0x86, 0x18, 0x08,
722 0x60, 0x43, 0x90, 0x6d, 0x20, 0x20, 0xc0, 0xd2, 0x26, 0x08, 0x9e, 0xc7,
723 0xa4, 0xca, 0x8a, 0xa9, 0xcc, 0x8c, 0x8e, 0xea, 0x0d, 0x6e, 0x82, 0x40,
724 0x38, 0x13, 0x84, 0x8a, 0xdb, 0x80, 0x20, 0xdd, 0x44, 0x78, 0x4d, 0xf3,
725 0x91, 0xa9, 0xb2, 0x22, 0x4a, 0x6b, 0x2b, 0x73, 0x9b, 0x4b, 0x7b, 0x73,
726 0x9b, 0x9b, 0x20, 0x10, 0xcf, 0x06, 0x04, 0x09, 0x83, 0x49, 0x0c, 0xbc,
727 0xa6, 0xf9, 0x88, 0x34, 0xa5, 0xc1, 0x31, 0x95, 0xd9, 0x95, 0xb1, 0x4d,
728 0x10, 0x08, 0x68, 0x82, 0x40, 0x44, 0x1b, 0x10, 0x84, 0x0c, 0xa6, 0x32,
729 0xf0, 0xcc, 0xa0, 0xf9, 0xc8, 0x30, 0x85, 0xe5, 0x95, 0xc9, 0x3d, 0xc9,
730 0x11, 0x95, 0xc1, 0xd1, 0xa1, 0x4d, 0x10, 0x08, 0x69, 0x83, 0x81, 0xa0,
731 0xc1, 0x94, 0x06, 0x5e, 0xb3, 0xa1, 0xa0, 0xc0, 0x60, 0x0c, 0xce, 0x40,
732 0x0d, 0x36, 0x0c, 0x04, 0xb7, 0x06, 0x13, 0x04, 0x01, 0xd8, 0x00, 0x6c,
733 0x18, 0x08, 0x37, 0x70, 0x83, 0x0d, 0xc1, 0x1b, 0x6c, 0x18, 0x86, 0x36,
734 0x80, 0x83, 0x09, 0x82, 0x18, 0x84, 0xc1, 0x86, 0x40, 0x0e, 0xa8, 0x08,
735 0xb1, 0xa5, 0xd1, 0x19, 0xc9, 0xbd, 0xb5, 0xc9, 0x10, 0x11, 0xa1, 0x2a,
736 0xc2, 0x1a, 0x7a, 0x7a, 0x92, 0x22, 0x9a, 0x20, 0x14, 0xd6, 0x04, 0xa1,
737 0xb8, 0x36, 0x04, 0xc4, 0x04, 0xa1, 0xc0, 0x36, 0x08, 0xd3, 0xb4, 0x61,
738 0x21, 0xea, 0xc0, 0x0e, 0xee, 0x00, 0x0f, 0xf2, 0x60, 0xc8, 0x03, 0xe2,
739 0x0e, 0xf4, 0x80, 0xcb, 0x94, 0xd5, 0x17, 0xd4, 0xdb, 0x5c, 0x1a, 0x5d,
740 0xda, 0x9b, 0xdb, 0x04, 0xa1, 0xc8, 0x26, 0x08, 0x85, 0xb6, 0x61, 0x19,
741 0xf8, 0xc0, 0x0e, 0xfa, 0x00, 0x0f, 0xfc, 0x60, 0xf0, 0x83, 0xe1, 0x0e,
742 0x80, 0x0d, 0xc2, 0x1e, 0xfc, 0x01, 0x93, 0x29, 0xab, 0x2f, 0xaa, 0x30,
743 0xb9, 0xb3, 0x32, 0xba, 0x09, 0x42, 0xb1, 0x4d, 0x10, 0x88, 0x69, 0x83,
744 0x30, 0x8d, 0xc2, 0x86, 0x85, 0x08, 0x05, 0x3b, 0x10, 0x05, 0x3c, 0xb8,
745 0x83, 0xc1, 0x0f, 0x88, 0x3b, 0x20, 0x85, 0x0d, 0x41, 0x29, 0x6c, 0x18,
746 0x40, 0xc1, 0x14, 0x80, 0x0d, 0x45, 0x1b, 0xd0, 0xc1, 0x29, 0x6c, 0x00,
747 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0xba, 0x39, 0x16, 0x69, 0x6e, 0x73, 0x74,
748 0x73, 0x13, 0x04, 0x82, 0xa2, 0x31, 0x97, 0x76, 0xf6, 0xc5, 0x46, 0x46,
749 0x63, 0x2e, 0xed, 0xec, 0x6b, 0x8e, 0x6e, 0x82, 0x40, 0x54, 0x44, 0xe8,
750 0xca, 0xf0, 0xbe, 0xdc, 0xde, 0xe4, 0xda, 0x36, 0x28, 0xa9, 0x60, 0x06,
751 0xaa, 0xb0, 0x0a, 0xac, 0xc0, 0xb4, 0x82, 0x2b, 0xbc, 0xc2, 0x50, 0x85,
752 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x4a, 0x10,
753 0x54, 0x21, 0xc3, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x9b,
754 0x12, 0x10, 0x4d, 0xc8, 0xf0, 0x5c, 0xec, 0xc2, 0xd8, 0xec, 0xca, 0xe4,
755 0xa6, 0x04, 0x45, 0x1d, 0x32, 0x3c, 0x97, 0x39, 0xb4, 0x30, 0xb2, 0x32,
756 0xb9, 0xa6, 0x37, 0xb2, 0x32, 0xb6, 0x29, 0x01, 0x52, 0x86, 0x0c, 0xcf,
757 0x45, 0xae, 0x6c, 0xee, 0xad, 0x4e, 0x6e, 0xac, 0x6c, 0x6e, 0x4a, 0xa0,
758 0x55, 0x22, 0xc3, 0x73, 0xa1, 0xcb, 0x83, 0x2b, 0x0b, 0x72, 0x73, 0x7b,
759 0xa3, 0x0b, 0xa3, 0x4b, 0x7b, 0x73, 0x9b, 0x9b, 0x22, 0xac, 0x01, 0x1c,
760 0xd4, 0x21, 0xc3, 0x73, 0xb1, 0x4b, 0x2b, 0xbb, 0x4b, 0x22, 0x9b, 0xa2,
761 0x0b, 0xa3, 0x2b, 0x9b, 0x12, 0xc8, 0x41, 0x1d, 0x32, 0x3c, 0x97, 0x32,
762 0x37, 0x3a, 0xb9, 0x3c, 0xa8, 0xb7, 0x34, 0x37, 0xba, 0xb9, 0x29, 0xc1,
763 0x29, 0x74, 0x21, 0xc3, 0x73, 0x19, 0x7b, 0xab, 0x73, 0xa3, 0x2b, 0x93,
764 0x9b, 0x9b, 0x12, 0xbc, 0x02, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c,
765 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14,
766 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79,
767 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e,
768 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1,
769 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc,
770 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74,
771 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a,
772 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e,
773 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e,
774 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21,
775 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0,
776 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc,
777 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72,
778 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76,
779 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f,
780 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c,
781 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03,
782 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1,
783 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61,
784 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8,
785 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94,
786 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0,
787 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76,
788 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e,
789 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f,
790 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x1f,
791 0x00, 0x00, 0x00, 0x06, 0xa0, 0x6c, 0x0b, 0x32, 0x7d, 0x91, 0xc3, 0xd8,
792 0x9d, 0x15, 0x6c, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x04, 0x54, 0x51, 0x10,
793 0x51, 0xe9, 0x00, 0x43, 0x49, 0x18, 0x80, 0x80, 0xf9, 0xc5, 0x6d, 0x1b,
794 0xc1, 0x36, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x40, 0x15, 0x05, 0x11, 0x95,
795 0x0e, 0x30, 0x94, 0x84, 0x01, 0x08, 0x98, 0x8f, 0xdc, 0xb6, 0x19, 0x48,
796 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x44, 0x04, 0x30, 0x11, 0x21, 0xd0, 0x0c,
797 0x0b, 0x61, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3, 0x2f, 0x0e, 0x30, 0x88,
798 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x50, 0x0d, 0x97, 0xef, 0x3c,
799 0xbe, 0x04, 0x30, 0xcf, 0x42, 0x94, 0x44, 0x45, 0x2c, 0x7e, 0x71, 0xdb,
800 0x26, 0x50, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x34, 0x39, 0x11, 0x81, 0x52,
801 0xd3, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
802 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96,
803 0x4a, 0x75, 0x13, 0xa7, 0xff, 0x55, 0x58, 0xed, 0x84, 0x39, 0x1b, 0x53,
804 0x97, 0x1f, 0x63, 0x44, 0x58, 0x49, 0x4c, 0xac, 0x07, 0x00, 0x00, 0x60,
805 0x00, 0x00, 0x00, 0xeb, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00,
806 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x94, 0x07, 0x00, 0x00, 0x42,
807 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xe2, 0x01, 0x00, 0x00, 0x0b,
808 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07,
809 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92,
810 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80,
811 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4, 0x10, 0x32, 0x14, 0x38,
812 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43,
813 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11,
814 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04,
815 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b,
816 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84,
817 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff,
818 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03,
819 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00,
820 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x32,
821 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x23, 0xa4, 0x84, 0x04,
822 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8c, 0x8c, 0x0b,
823 0x84, 0xc4, 0x4c, 0x10, 0x8c, 0xc1, 0x08, 0x40, 0x09, 0x00, 0x0a, 0x66,
824 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29, 0xc6, 0x40, 0x10, 0x44,
825 0x41, 0x90, 0x51, 0x0c, 0x80, 0x20, 0x88, 0x62, 0x20, 0xe4, 0xa6, 0xe1,
826 0xf2, 0x27, 0xec, 0x21, 0x24, 0x7f, 0x25, 0xa4, 0x95, 0x98, 0xfc, 0xe2,
827 0xb6, 0x51, 0x31, 0x0c, 0xc3, 0x40, 0x50, 0x71, 0xcf, 0x70, 0xf9, 0x13,
828 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, 0x10, 0x28, 0x58, 0x0a, 0xa3,
829 0x10, 0x0c, 0x33, 0x0c, 0xc3, 0x40, 0x10, 0xc4, 0x40, 0xcd, 0x51, 0xc3,
830 0xe5, 0x4f, 0xd8, 0x43, 0x48, 0x3e, 0xb7, 0x51, 0xc5, 0x4a, 0x4c, 0x3e,
831 0x72, 0xdb, 0x88, 0x20, 0x08, 0x82, 0x28, 0xc4, 0x43, 0x30, 0x04, 0x41,
832 0x47, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9, 0xdc, 0x46, 0x15, 0x2b,
833 0x31, 0xf9, 0xc5, 0x6d, 0x23, 0x62, 0x18, 0x86, 0xa1, 0x10, 0x12, 0xc1,
834 0x10, 0x34, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0x88, 0x82, 0x20, 0x2a, 0xb2,
835 0x06, 0x02, 0x86, 0x11, 0x88, 0x61, 0xa6, 0x36, 0x18, 0x07, 0x76, 0x08,
836 0x87, 0x79, 0x98, 0x07, 0x37, 0xa0, 0x85, 0x72, 0xc0, 0x07, 0x7a, 0xa8,
837 0x07, 0x79, 0x28, 0x07, 0x39, 0x20, 0x05, 0x3e, 0xb0, 0x87, 0x72, 0x18,
838 0x07, 0x7a, 0x78, 0x07, 0x79, 0xe0, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08,
839 0x07, 0x7a, 0x60, 0x03, 0x30, 0xa0, 0x03, 0x3f, 0x00, 0x03, 0x3f, 0xd0,
840 0x03, 0x3d, 0x68, 0x87, 0x74, 0x80, 0x87, 0x79, 0xf8, 0x05, 0x7a, 0xc8,
841 0x07, 0x78, 0x28, 0x07, 0x14, 0x10, 0x33, 0x89, 0xc1, 0x38, 0xb0, 0x43,
842 0x38, 0xcc, 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43,
843 0x3d, 0xc8, 0x43, 0x39, 0xc8, 0x01, 0x29, 0xf0, 0x81, 0x3d, 0x94, 0xc3,
844 0x38, 0xd0, 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43,
845 0x38, 0xd0, 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x01,
846 0x12, 0x32, 0x8d, 0xb6, 0x61, 0x04, 0x61, 0x38, 0x89, 0x75, 0xa8, 0x48,
847 0x20, 0x56, 0xc2, 0x40, 0x9c, 0x66, 0xa3, 0x8a, 0x82, 0x88, 0x10, 0xd1,
848 0x75, 0xc4, 0x40, 0xde, 0x4d, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00,
849 0xf3, 0x2c, 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0, 0x80, 0x20, 0x30, 0x15,
850 0x08, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36,
851 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e,
852 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07,
853 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07,
854 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07,
855 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06,
856 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e,
857 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07,
858 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07,
859 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07,
860 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07,
861 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00,
862 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c,
863 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
864 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
865 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
866 0x00, 0x30, 0xe4, 0x81, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
867 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00,
868 0x00, 0x00, 0x00, 0xc0, 0x90, 0xc7, 0x02, 0x02, 0x60, 0x00, 0x00, 0x00,
869 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x32,
870 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6,
871 0x04, 0x43, 0x22, 0x4a, 0x60, 0x04, 0xa0, 0x18, 0x8a, 0xa0, 0x24, 0xca,
872 0xa0, 0x60, 0xca, 0x83, 0x8a, 0x92, 0x18, 0x01, 0x28, 0x82, 0x32, 0x28,
873 0x84, 0x02, 0x21, 0x6e, 0x06, 0x80, 0xbe, 0x19, 0x00, 0x0a, 0x67, 0x00,
874 0x48, 0x1c, 0x4b, 0x41, 0x88, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
875 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x1a,
876 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73,
877 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71,
878 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a,
879 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b,
880 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0xe2, 0x98, 0x20, 0x10, 0xc8,
881 0x06, 0x61, 0x20, 0x26, 0x08, 0x44, 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x70,
882 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0x5c, 0x45, 0x60, 0x82, 0x40,
883 0x28, 0x13, 0x04, 0x62, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84, 0x50, 0x16,
884 0x86, 0x18, 0x18, 0xc2, 0xd9, 0x10, 0x3c, 0x13, 0x84, 0xcf, 0x9a, 0x20,
885 0x10, 0xcc, 0x04, 0x81, 0x68, 0x36, 0x20, 0x44, 0xb4, 0x48, 0xc4, 0x30,
886 0x01, 0x1b, 0x02, 0x6a, 0x82, 0x10, 0x06, 0xd7, 0x06, 0x84, 0xb0, 0x16,
887 0x86, 0x18, 0x08, 0x60, 0x43, 0x70, 0x6d, 0x20, 0x20, 0xa0, 0xc2, 0x26,
888 0x08, 0x62, 0x80, 0x6d, 0x08, 0xb4, 0x09, 0x82, 0x00, 0x50, 0x11, 0x62,
889 0x4b, 0xa3, 0x33, 0x92, 0x7b, 0x6b, 0x93, 0x21, 0x22, 0x42, 0x55, 0x84,
890 0x35, 0xf4, 0xf4, 0x24, 0x45, 0x34, 0x41, 0x28, 0x9e, 0x09, 0x42, 0x01,
891 0x6d, 0x08, 0x88, 0x09, 0x42, 0x11, 0x6d, 0x10, 0x24, 0x69, 0xc3, 0x42,
892 0x78, 0x1f, 0x18, 0x84, 0x81, 0x18, 0x0c, 0x62, 0x40, 0x80, 0xc1, 0x18,
893 0x70, 0x99, 0xb2, 0xfa, 0x82, 0x7a, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73,
894 0x9b, 0x20, 0x14, 0xd2, 0x04, 0xa1, 0x98, 0x36, 0x2c, 0x43, 0x19, 0x7c,
895 0x66, 0x10, 0x06, 0x67, 0x30, 0x9c, 0xc1, 0x00, 0x06, 0xc0, 0x06, 0x81,
896 0x0c, 0xd0, 0x80, 0xc9, 0x94, 0xd5, 0x17, 0x55, 0x98, 0xdc, 0x59, 0x19,
897 0xdd, 0x04, 0xa1, 0xa0, 0x26, 0x08, 0x84, 0xb3, 0x41, 0x90, 0xd8, 0x60,
898 0xc3, 0x42, 0xa8, 0xc1, 0xb7, 0x06, 0x61, 0x00, 0x06, 0xc3, 0x19, 0x10,
899 0x60, 0xd0, 0x06, 0x1b, 0x02, 0x37, 0xd8, 0x30, 0xa4, 0xc1, 0x1b, 0x00,
900 0x1b, 0x0a, 0xae, 0x83, 0x83, 0x0c, 0xa8, 0xc2, 0xc6, 0x66, 0xd7, 0xe6,
901 0x92, 0x46, 0x56, 0xe6, 0x46, 0x37, 0x25, 0x08, 0xaa, 0x90, 0xe1, 0xb9,
902 0xd8, 0x95, 0xc9, 0xcd, 0xa5, 0xbd, 0xb9, 0x4d, 0x09, 0x88, 0x26, 0x64,
903 0x78, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x02, 0xa3, 0x0e,
904 0x19, 0x9e, 0xcb, 0x1c, 0x5a, 0x18, 0x59, 0x99, 0x5c, 0xd3, 0x1b, 0x59,
905 0x19, 0xdb, 0x94, 0x00, 0x29, 0x43, 0x86, 0xe7, 0x22, 0x57, 0x36, 0xf7,
906 0x56, 0x27, 0x37, 0x56, 0x36, 0x37, 0x25, 0xc0, 0xea, 0x90, 0xe1, 0xb9,
907 0xd8, 0xa5, 0x95, 0xdd, 0x25, 0x91, 0x4d, 0xd1, 0x85, 0xd1, 0x95, 0x4d,
908 0x09, 0xb4, 0x3a, 0x64, 0x78, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50,
909 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x53, 0x02, 0x38, 0x00, 0x00, 0x00, 0x79,
910 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4,
911 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c,
912 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00,
913 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2,
914 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38,
915 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d,
916 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87,
917 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87,
918 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30,
919 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde,
920 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b,
921 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c,
922 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07,
923 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87,
924 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87,
925 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87,
926 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0,
927 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc,
928 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4,
929 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39,
930 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38,
931 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b,
932 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03,
933 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0,
934 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0,
935 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71,
936 0x20, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x06, 0xa0, 0x6c, 0x0b, 0x32,
937 0x7d, 0x91, 0xc3, 0xd8, 0x9d, 0x15, 0x6c, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f,
938 0x04, 0x54, 0x51, 0x10, 0x51, 0xe9, 0x00, 0x43, 0x49, 0x18, 0x80, 0x80,
939 0xf9, 0xc5, 0x6d, 0x1b, 0xc1, 0x36, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x40,
940 0x15, 0x05, 0x11, 0x95, 0x0e, 0x30, 0x94, 0x84, 0x01, 0x08, 0x98, 0x8f,
941 0xdc, 0xb6, 0x19, 0x48, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x44, 0x04, 0x30,
942 0x11, 0x21, 0xd0, 0x0c, 0x0b, 0x61, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3,
943 0x2f, 0x0e, 0x30, 0x88, 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x50,
944 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x04, 0x30, 0xcf, 0x42, 0x94, 0x44, 0x45,
945 0x2c, 0x7e, 0x71, 0xdb, 0x26, 0x50, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x34,
946 0x39, 0x11, 0x81, 0x52, 0xd3, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x00, 0x61,
947 0x20, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10,
948 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54, 0x8d, 0x00, 0x10, 0x51,
949 0x0a, 0x25, 0x37, 0x03, 0x50, 0x08, 0x65, 0x57, 0x7c, 0x54, 0x94, 0x00,
950 0x0d, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82,
951 0x60, 0x60, 0x71, 0x87, 0xa4, 0x69, 0xc9, 0x88, 0x41, 0x02, 0x80, 0x20,
952 0x18, 0x58, 0x1d, 0x12, 0x6d, 0x9b, 0x32, 0x62, 0x90, 0x00, 0x20, 0x08,
953 0x06, 0x96, 0x97, 0x4c, 0x1c, 0xb7, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82,
954 0x81, 0x41, 0x06, 0x48, 0xd7, 0x55, 0xc9, 0x88, 0x41, 0x02, 0x80, 0x20,
955 0x18, 0x18, 0x65, 0x90, 0x78, 0x9e, 0xa1, 0x8c, 0x18, 0x1c, 0x00, 0x08,
956 0x82, 0xc1, 0x24, 0x06, 0xc9, 0xf0, 0x8d, 0x26, 0x04, 0xc0, 0x68, 0x82,
957 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x68, 0x02, 0x31, 0x98, 0x70, 0xc8, 0xc7,
958 0x84, 0x43, 0x3e, 0x26, 0x18, 0xf0, 0x31, 0xc1, 0x80, 0xcf, 0x88, 0xc1,
959 0x01, 0x80, 0x20, 0x18, 0x40, 0x6c, 0x20, 0x31, 0x69, 0x30, 0x9a, 0x10,
960 0x00, 0x17, 0x0c, 0x35, 0x62, 0xf0, 0x00, 0x20, 0x08, 0x06, 0x0d, 0x1c,
961 0x50, 0x11, 0x54, 0x10, 0x92, 0xb4, 0x06, 0x6b, 0x70, 0x05, 0xa3, 0x09,
962 0x01, 0x30, 0x9a, 0x20, 0x04, 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40, 0x0c,
963 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0xd8, 0x81, 0x07, 0x07, 0x70,
964 0x80, 0x06, 0xc4, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, 0x76, 0xe0,
965 0xc1, 0x01, 0x1c, 0x60, 0xc3, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20,
966 0x76, 0xe0, 0xc1, 0x01, 0x1c, 0x9c, 0x81, 0x30, 0x62, 0x90, 0x00, 0x20,
967 0x08, 0x06, 0x88, 0x1d, 0x78, 0x70, 0x00, 0x07, 0x66, 0x10, 0x20, 0x00,
968 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
969};
970#if 0
971;
972; Input signature:
973;
974; Name Index Mask Register SysValue Format Used
975; -------------------- ----- ------ -------- -------- ------- ------
976; TEXCOORD 0 xy 0 NONE float xy
977; SV_Position 0 xyzw 1 POS float
978;
979;
980; Output signature:
981;
982; Name Index Mask Register SysValue Format Used
983; -------------------- ----- ------ -------- -------- ------- ------
984; SV_Target 0 xyzw 0 TARGET float xyzw
985;
986; shader hash: 2e13f04e8780c355f36dba74b811bc6f
987;
988; Pipeline Runtime Information:
989;
990; Pixel Shader
991; DepthOutput=0
992; SampleFrequency=0
993;
994;
995; Input signature:
996;
997; Name Index InterpMode DynIdx
998; -------------------- ----- ---------------------- ------
999; TEXCOORD 0 linear
1000; SV_Position 0 noperspective
1001;
1002; Output signature:
1003;
1004; Name Index InterpMode DynIdx
1005; -------------------- ----- ---------------------- ------
1006; SV_Target 0
1007;
1008; Buffer Definitions:
1009;
1010; cbuffer SourceRegionBuffer
1011; {
1012;
1013; struct SourceRegionBuffer
1014; {
1015;
1016; float2 UVLeftTop; ; Offset: 0
1017; float2 UVDimensions; ; Offset: 8
1018; uint MipLevel; ; Offset: 16
1019; float LayerOrDepth; ; Offset: 20
1020;
1021; } SourceRegionBuffer; ; Offset: 0 Size: 24
1022;
1023; }
1024;
1025;
1026; Resource Bindings:
1027;
1028; Name Type Format Dim ID HLSL Bind Count
1029; ------------------------------ ---------- ------- ----------- ------- -------------- ------
1030; SourceRegionBuffer cbuffer NA NA CB0 cb0,space3 1
1031; SourceSampler sampler NA NA S0 s0,space2 1
1032; SourceTexture2DArray texture f32 2darray T0 t0,space2 1
1033;
1034;
1035; ViewId state:
1036;
1037; Number of inputs: 8, outputs: 4
1038; Outputs dependent on ViewId: { }
1039; Inputs contributing to computation of Outputs:
1040; output 0 depends on inputs: { 0, 1 }
1041; output 1 depends on inputs: { 0, 1 }
1042; output 2 depends on inputs: { 0, 1 }
1043; output 3 depends on inputs: { 0, 1 }
1044;
1045target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
1046target triple = "dxil-ms-dx"
1047
1048%dx.types.Handle = type { i8* }
1049%dx.types.CBufRet.f32 = type { float, float, float, float }
1050%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
1051%dx.types.ResRet.f32 = type { float, float, float, float, i32 }
1052%"class.Texture2DArray<vector<float, 4> >" = type { <4 x float>, %"class.Texture2DArray<vector<float, 4> >::mips_type" }
1053%"class.Texture2DArray<vector<float, 4> >::mips_type" = type { i32 }
1054%SourceRegionBuffer = type { <2 x float>, <2 x float>, i32, float }
1055%struct.SamplerState = type { i32 }
1056
1057define void @BlitFrom2DArray() {
1058 %1 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
1059 %2 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 3, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
1060 %3 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
1061 %4 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
1062 %5 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
1063 %6 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %3, i32 0) ; CBufferLoadLegacy(handle,regIndex)
1064 %7 = extractvalue %dx.types.CBufRet.f32 %6, 0
1065 %8 = extractvalue %dx.types.CBufRet.f32 %6, 1
1066 %9 = extractvalue %dx.types.CBufRet.f32 %6, 2
1067 %10 = extractvalue %dx.types.CBufRet.f32 %6, 3
1068 %11 = fmul fast float %9, %4
1069 %12 = fmul fast float %10, %5
1070 %13 = fadd fast float %11, %7
1071 %14 = fadd fast float %12, %8
1072 %15 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %3, i32 1) ; CBufferLoadLegacy(handle,regIndex)
1073 %16 = extractvalue %dx.types.CBufRet.f32 %15, 1
1074 %17 = fptoui float %16 to i32
1075 %18 = uitofp i32 %17 to float
1076 %19 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %3, i32 1) ; CBufferLoadLegacy(handle,regIndex)
1077 %20 = extractvalue %dx.types.CBufRet.i32 %19, 0
1078 %21 = uitofp i32 %20 to float
1079 %22 = call %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32 62, %dx.types.Handle %1, %dx.types.Handle %2, float %13, float %14, float %18, float undef, i32 0, i32 0, i32 undef, float %21) ; SampleLevel(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,LOD)
1080 %23 = extractvalue %dx.types.ResRet.f32 %22, 0
1081 %24 = extractvalue %dx.types.ResRet.f32 %22, 1
1082 %25 = extractvalue %dx.types.ResRet.f32 %22, 2
1083 %26 = extractvalue %dx.types.ResRet.f32 %22, 3
1084 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %23) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
1085 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %24) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
1086 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %25) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
1087 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %26) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
1088 ret void
1089}
1090
1091; Function Attrs: nounwind readnone
1092declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
1093
1094; Function Attrs: nounwind
1095declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
1096
1097; Function Attrs: nounwind readonly
1098declare %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32, %dx.types.Handle, %dx.types.Handle, float, float, float, float, i32, i32, i32, float) #2
1099
1100; Function Attrs: nounwind readonly
1101declare %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32, %dx.types.Handle, i32) #2
1102
1103; Function Attrs: nounwind readonly
1104declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #2
1105
1106; Function Attrs: nounwind readonly
1107declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #2
1108
1109attributes #0 = { nounwind readnone }
1110attributes #1 = { nounwind }
1111attributes #2 = { nounwind readonly }
1112
1113!llvm.ident = !{!0}
1114!dx.version = !{!1}
1115!dx.valver = !{!2}
1116!dx.shaderModel = !{!3}
1117!dx.resources = !{!4}
1118!dx.viewIdState = !{!12}
1119!dx.entryPoints = !{!13}
1120
1121!0 = !{!"clang version 3.7 (tags/RELEASE_370/final)"}
1122!1 = !{i32 1, i32 0}
1123!2 = !{i32 1, i32 6}
1124!3 = !{!"ps", i32 6, i32 0}
1125!4 = !{!5, null, !8, !10}
1126!5 = !{!6}
1127!6 = !{i32 0, %"class.Texture2DArray<vector<float, 4> >"* undef, !"", i32 2, i32 0, i32 1, i32 7, i32 0, !7}
1128!7 = !{i32 0, i32 9}
1129!8 = !{!9}
1130!9 = !{i32 0, %SourceRegionBuffer* undef, !"", i32 3, i32 0, i32 1, i32 24, null}
1131!10 = !{!11}
1132!11 = !{i32 0, %struct.SamplerState* undef, !"", i32 2, i32 0, i32 1, i32 0, null}
1133!12 = !{[10 x i32] [i32 8, i32 4, i32 15, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0]}
1134!13 = !{void ()* @BlitFrom2DArray, !"BlitFrom2DArray", !14, !4, null}
1135!14 = !{!15, !20, null}
1136!15 = !{!16, !19}
1137!16 = !{i32 0, !"TEXCOORD", i8 9, i8 0, !17, i8 2, i32 1, i8 2, i32 0, i8 0, !18}
1138!17 = !{i32 0}
1139!18 = !{i32 3, i32 3}
1140!19 = !{i32 1, !"SV_Position", i8 9, i8 3, !17, i8 4, i32 1, i8 4, i32 1, i8 0, null}
1141!20 = !{!21}
1142!21 = !{i32 0, !"SV_Target", i8 9, i8 16, !17, i8 0, i32 1, i8 4, i32 0, i8 0, !22}
1143!22 = !{i32 3, i32 15}
1144
1145#endif
1146
1147const unsigned char g_BlitFrom2DArray[] = {
1148 0x44, 0x58, 0x42, 0x43, 0xdf, 0xde, 0xbd, 0x23, 0xe2, 0x83, 0x0e, 0x5d,
1149 0xfb, 0xe3, 0x84, 0xf0, 0x8c, 0x87, 0xbb, 0x3c, 0x01, 0x00, 0x00, 0x00,
1150 0x83, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
1151 0x50, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00,
1152 0xe7, 0x01, 0x00, 0x00, 0x77, 0x02, 0x00, 0x00, 0x7b, 0x0a, 0x00, 0x00,
1153 0x97, 0x0a, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
1154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31,
1155 0x5d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1156 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1157 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1158 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1159 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1160 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1161 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44,
1162 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
1163 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
1164 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
1165 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
1166 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1167 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x50,
1168 0x53, 0x56, 0x30, 0xf0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
1171 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
1172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
1173 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
1174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
1175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
1176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,
1177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
1178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
1179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
1180 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x00, 0x00, 0x01,
1181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
1182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x03,
1183 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1184 0x01, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1185 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, 0x00, 0x0f,
1186 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x88,
1189 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18,
1190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00,
1191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c,
1192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5c,
1193 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x7c,
1194 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03,
1195 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01,
1197 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
1199 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x03,
1200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x54, 0x41, 0x54, 0xfc,
1201 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x44,
1202 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe4,
1203 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xf6,
1204 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
1205 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06,
1206 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e,
1207 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4,
1208 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48,
1209 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4,
1210 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1,
1211 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08,
1212 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40,
1213 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d,
1214 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49,
1215 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20,
1216 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x5c,
1217 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13,
1218 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12,
1219 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x8c, 0xc1, 0x08, 0x40,
1220 0x09, 0x00, 0x0a, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29,
1221 0xc6, 0x40, 0x10, 0x44, 0x41, 0x90, 0x51, 0x0c, 0x80, 0x20, 0x88, 0x62,
1222 0x20, 0xe4, 0xa6, 0xe1, 0xf2, 0x27, 0xec, 0x21, 0x24, 0x7f, 0x25, 0xa4,
1223 0x95, 0x98, 0xfc, 0xe2, 0xb6, 0x51, 0x31, 0x0c, 0xc3, 0x40, 0x50, 0x71,
1224 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, 0x10,
1225 0x28, 0x58, 0x0a, 0xa3, 0x10, 0x0c, 0x33, 0x0c, 0xc3, 0x40, 0x10, 0xc4,
1226 0x40, 0xcd, 0x51, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, 0x3e, 0xb7, 0x51,
1227 0xc5, 0x4a, 0x4c, 0x7e, 0x71, 0xdb, 0x88, 0x18, 0x86, 0x61, 0x28, 0xc4,
1228 0x43, 0x30, 0x04, 0x41, 0x47, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9,
1229 0xdc, 0x46, 0x15, 0x2b, 0x31, 0xf9, 0xc8, 0x6d, 0x23, 0x82, 0x20, 0x08,
1230 0xa2, 0x10, 0x12, 0xc1, 0x10, 0x34, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0x88,
1231 0x82, 0x20, 0x2a, 0xb2, 0x06, 0x02, 0x86, 0x11, 0x88, 0x61, 0x26, 0x39,
1232 0x18, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07, 0x37, 0xa0, 0x85, 0x72,
1233 0xc0, 0x07, 0x7a, 0xa8, 0x07, 0x79, 0x28, 0x07, 0x39, 0x20, 0x85, 0x50,
1234 0x90, 0x07, 0x79, 0x08, 0x87, 0x7c, 0xe0, 0x03, 0x7b, 0x28, 0x87, 0x71,
1235 0xa0, 0x87, 0x77, 0x90, 0x07, 0x3e, 0x30, 0x07, 0x76, 0x78, 0x87, 0x70,
1236 0xa0, 0x07, 0x36, 0x00, 0x03, 0x3a, 0xf0, 0x03, 0x30, 0xf0, 0x03, 0x3d,
1237 0xd0, 0x83, 0x76, 0x48, 0x07, 0x78, 0x98, 0x87, 0x5f, 0xa0, 0x87, 0x7c,
1238 0x80, 0x87, 0x72, 0x40, 0x01, 0x31, 0xd3, 0x19, 0x8c, 0x03, 0x3b, 0x84,
1239 0xc3, 0x3c, 0xcc, 0x83, 0x1b, 0xd0, 0x42, 0x39, 0xe0, 0x03, 0x3d, 0xd4,
1240 0x83, 0x3c, 0x94, 0x83, 0x1c, 0x90, 0x42, 0x28, 0xc8, 0x83, 0x3c, 0x84,
1241 0x43, 0x3e, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, 0xc3, 0x3b, 0xc8,
1242 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, 0x03, 0x1b, 0x80,
1243 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x01, 0x12, 0x32, 0x8d, 0xb6, 0x61,
1244 0x04, 0x61, 0x38, 0x89, 0x75, 0xa8, 0x48, 0x20, 0x56, 0xc2, 0x40, 0x9c,
1245 0x66, 0xa3, 0x8a, 0x82, 0x88, 0x10, 0xd1, 0x75, 0xc4, 0x40, 0xde, 0x4d,
1246 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, 0x44, 0xc4, 0x4e,
1247 0xc0, 0x44, 0xa0, 0x80, 0x20, 0x30, 0x15, 0x08, 0x00, 0x00, 0x00, 0x13,
1248 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68,
1249 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a,
1250 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73,
1251 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d,
1252 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71,
1253 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72,
1254 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a,
1255 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73,
1256 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72,
1257 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d,
1258 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72,
1259 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x08, 0x00, 0x00, 0x00,
1260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01,
1261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00,
1262 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40,
1263 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x81,
1264 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8,
1265 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
1266 0x90, 0xc7, 0x02, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1267 0x80, 0x2c, 0x10, 0x14, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19,
1268 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x22, 0x4a,
1269 0x60, 0x04, 0xa0, 0x18, 0x8a, 0xa0, 0x1c, 0x4a, 0xa2, 0x0c, 0x0a, 0xa6,
1270 0x20, 0x0a, 0xa4, 0x14, 0x0a, 0xa5, 0x3c, 0xca, 0xa7, 0x10, 0xa8, 0x28,
1271 0x89, 0x11, 0x80, 0x22, 0x28, 0x83, 0x42, 0x28, 0x10, 0xaa, 0x6a, 0x80,
1272 0xb8, 0x19, 0x00, 0xf2, 0x66, 0x00, 0xe8, 0x9b, 0x01, 0xa0, 0x70, 0x06,
1273 0x80, 0xc4, 0xb1, 0x14, 0x84, 0x78, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,
1274 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x1a,
1275 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73,
1276 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71,
1277 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a,
1278 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b,
1279 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0xe2, 0x98, 0x20, 0x10, 0xc8,
1280 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, 0x41, 0x01, 0x6e, 0x6e, 0x82, 0x40,
1281 0x24, 0x1b, 0x86, 0x03, 0x21, 0x26, 0x08, 0x5c, 0x47, 0x6a, 0xea, 0xad,
1282 0x4e, 0x6e, 0xac, 0x8c, 0xaa, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86,
1283 0x28, 0x48, 0x4e, 0x2e, 0x2c, 0x6f, 0x82, 0x40, 0x28, 0x13, 0x04, 0x62,
1284 0x99, 0x20, 0x10, 0xcc, 0x06, 0x81, 0x70, 0x36, 0x24, 0x84, 0xb2, 0x30,
1285 0xc4, 0xd0, 0x10, 0xcf, 0x86, 0x00, 0x9a, 0x20, 0x7c, 0x1f, 0xa5, 0xa9,
1286 0xb7, 0x3a, 0xb9, 0xb1, 0x32, 0xa9, 0xb2, 0xb3, 0xb4, 0x37, 0x37, 0xa1,
1287 0x3a, 0x33, 0xb3, 0x32, 0xb9, 0x09, 0x02, 0xd1, 0x4c, 0x10, 0x08, 0x67,
1288 0x03, 0x42, 0x48, 0x13, 0x45, 0x0c, 0x15, 0xb0, 0x21, 0xb0, 0x26, 0x08,
1289 0x61, 0x00, 0x06, 0x6c, 0xa6, 0xde, 0xea, 0xe4, 0xc6, 0xca, 0xa6, 0xc2,
1290 0xda, 0xe0, 0xd8, 0xca, 0xe4, 0x36, 0x20, 0x04, 0x96, 0x31, 0xc4, 0x40,
1291 0x00, 0x1b, 0x02, 0x6d, 0x03, 0x11, 0x01, 0xd7, 0x36, 0x41, 0xf0, 0x3c,
1292 0x26, 0x55, 0x56, 0x4c, 0x65, 0x66, 0x74, 0x54, 0x6f, 0x70, 0x13, 0x84,
1293 0x8a, 0xdb, 0x80, 0x20, 0x1e, 0x45, 0x34, 0x8e, 0xf3, 0x91, 0xa9, 0xb2,
1294 0x22, 0x4a, 0x6b, 0x2b, 0x73, 0x9b, 0x4b, 0x7b, 0x73, 0x9b, 0x9b, 0x20,
1295 0x10, 0xcf, 0x06, 0x04, 0x09, 0x03, 0x4a, 0x0c, 0x1a, 0xc7, 0xf9, 0x88,
1296 0x34, 0xa5, 0xc1, 0x31, 0x95, 0xd9, 0x95, 0xb1, 0x4d, 0x10, 0x08, 0x68,
1297 0x82, 0x40, 0x44, 0x1b, 0x10, 0x84, 0x0c, 0xa8, 0x32, 0x68, 0xcc, 0xc0,
1298 0xf9, 0xc8, 0x30, 0x85, 0xe5, 0x95, 0xc9, 0x3d, 0xc9, 0x11, 0x95, 0xc1,
1299 0xd1, 0xa1, 0x4d, 0x10, 0x08, 0x69, 0x03, 0x82, 0xa0, 0x01, 0x95, 0x06,
1300 0x8d, 0xe3, 0x7c, 0x1b, 0x8a, 0x0a, 0x0c, 0xc6, 0xe0, 0x0c, 0xd4, 0x60,
1301 0xc3, 0x40, 0x74, 0x6b, 0x30, 0x41, 0x10, 0x80, 0x0d, 0xc0, 0x86, 0x81,
1302 0x70, 0x03, 0x37, 0xd8, 0x10, 0xbc, 0xc1, 0x86, 0x61, 0x68, 0x03, 0x38,
1303 0x98, 0x20, 0x88, 0x41, 0x18, 0x6c, 0x08, 0xe4, 0x80, 0x8f, 0x10, 0x5b,
1304 0x1a, 0x9d, 0x91, 0xdc, 0x5b, 0x9b, 0x0c, 0x51, 0x90, 0x9c, 0x5c, 0x58,
1305 0x1e, 0x11, 0xaa, 0x22, 0xac, 0xa1, 0xa7, 0x27, 0x29, 0xa2, 0x09, 0x42,
1306 0x61, 0x4d, 0x10, 0x8a, 0x6b, 0x43, 0x40, 0x4c, 0x10, 0x0a, 0x6c, 0x83,
1307 0x40, 0x51, 0x1b, 0x16, 0xa2, 0x0e, 0xec, 0xe0, 0x0e, 0xf0, 0x20, 0x0f,
1308 0x86, 0x3c, 0x20, 0xee, 0x40, 0x0f, 0xb8, 0x4c, 0x59, 0x7d, 0x41, 0xbd,
1309 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, 0xb9, 0x4d, 0x10, 0x8a, 0x6c, 0x82, 0x50,
1310 0x68, 0x1b, 0x96, 0x81, 0x0f, 0xec, 0xa0, 0x0f, 0xf0, 0xc0, 0x0f, 0x06,
1311 0x3f, 0x18, 0xee, 0x00, 0xd8, 0x20, 0xec, 0xc1, 0x1f, 0x30, 0x99, 0xb2,
1312 0xfa, 0xa2, 0x0a, 0x93, 0x3b, 0x2b, 0xa3, 0x9b, 0x20, 0x14, 0xdb, 0x04,
1313 0x81, 0x98, 0x36, 0x08, 0xd4, 0x28, 0x6c, 0x58, 0x88, 0x50, 0xb0, 0x03,
1314 0x51, 0xc0, 0x83, 0x3b, 0x18, 0xfc, 0x80, 0xb8, 0x03, 0x52, 0xd8, 0x10,
1315 0x94, 0xc2, 0x86, 0x01, 0x14, 0x4c, 0x01, 0xd8, 0x50, 0xb4, 0x01, 0x1d,
1316 0x9c, 0x02, 0x07, 0xd0, 0x30, 0x63, 0x7b, 0x0b, 0xa3, 0x9b, 0x63, 0x91,
1317 0xe6, 0x36, 0x47, 0x37, 0x37, 0x41, 0x20, 0x28, 0x1a, 0x73, 0x69, 0x67,
1318 0x5f, 0x6c, 0x64, 0x34, 0xe6, 0xd2, 0xce, 0xbe, 0xe6, 0xe8, 0x26, 0x08,
1319 0x44, 0x45, 0x84, 0xae, 0x0c, 0xef, 0xcb, 0xed, 0x4d, 0xae, 0x6d, 0x83,
1320 0x92, 0x0a, 0x8d, 0x2a, 0xac, 0x02, 0x2b, 0x30, 0xad, 0xe0, 0x0a, 0xaf,
1321 0x30, 0x54, 0x61, 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73, 0xa3,
1322 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, 0x5c, 0xec, 0xca, 0xe4, 0xe6, 0xd2,
1323 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, 0x32, 0x3c, 0x17, 0xbb, 0x30, 0x36,
1324 0xbb, 0x32, 0xb9, 0x29, 0x41, 0x51, 0x87, 0x0c, 0xcf, 0x65, 0x0e, 0x2d,
1325 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0x80, 0x94,
1326 0x21, 0xc3, 0x73, 0x91, 0x2b, 0x9b, 0x7b, 0xab, 0x93, 0x1b, 0x2b, 0x9b,
1327 0x9b, 0x12, 0x6c, 0x95, 0xc8, 0xf0, 0x5c, 0xe8, 0xf2, 0xe0, 0xca, 0x82,
1328 0xdc, 0xdc, 0xde, 0xe8, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xe6, 0xa6, 0x08,
1329 0x6b, 0x00, 0x07, 0x75, 0xc8, 0xf0, 0x5c, 0xec, 0xd2, 0xca, 0xee, 0x92,
1330 0xc8, 0xa6, 0xe8, 0xc2, 0xe8, 0xca, 0xa6, 0x04, 0x72, 0x50, 0x87, 0x0c,
1331 0xcf, 0xa5, 0xcc, 0x8d, 0x4e, 0x2e, 0x0f, 0xea, 0x2d, 0xcd, 0x8d, 0x6e,
1332 0x6e, 0x4a, 0x70, 0x0a, 0x5d, 0xc8, 0xf0, 0x5c, 0xc6, 0xde, 0xea, 0xdc,
1333 0xe8, 0xca, 0xe4, 0xe6, 0xa6, 0x04, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x79,
1334 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4,
1335 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c,
1336 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00,
1337 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2,
1338 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38,
1339 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d,
1340 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87,
1341 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87,
1342 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30,
1343 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde,
1344 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b,
1345 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c,
1346 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07,
1347 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87,
1348 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87,
1349 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87,
1350 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0,
1351 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc,
1352 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4,
1353 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39,
1354 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38,
1355 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b,
1356 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03,
1357 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0,
1358 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0,
1359 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71,
1360 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0xf0, 0x6c, 0x0b, 0x32,
1361 0x7d, 0x91, 0xc3, 0xd8, 0x9d, 0x16, 0x45, 0x00, 0x66, 0x04, 0xdb, 0x70,
1362 0xf9, 0xce, 0xe3, 0x0b, 0x01, 0x55, 0x14, 0x44, 0x54, 0x3a, 0xc0, 0x50,
1363 0x12, 0x06, 0x20, 0x60, 0x7e, 0x71, 0xdb, 0x56, 0xb0, 0x0d, 0x97, 0xef,
1364 0x3c, 0xbe, 0x10, 0x50, 0x45, 0x41, 0x44, 0xa5, 0x03, 0x0c, 0x25, 0x61,
1365 0x00, 0x02, 0xe6, 0x23, 0xb7, 0x6d, 0x06, 0xd2, 0x70, 0xf9, 0xce, 0xe3,
1366 0x0b, 0x11, 0x01, 0x4c, 0x44, 0x08, 0x34, 0xc3, 0x42, 0x58, 0xc0, 0x34,
1367 0x5c, 0xbe, 0xf3, 0xf8, 0x8b, 0x03, 0x0c, 0x62, 0xf3, 0x50, 0x93, 0x5f,
1368 0xdc, 0xb6, 0x0d, 0x54, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x01, 0xcc, 0xb3,
1369 0x10, 0x25, 0x51, 0x11, 0x8b, 0x5f, 0xdc, 0xb6, 0x09, 0x54, 0xc3, 0xe5,
1370 0x3b, 0x8f, 0x2f, 0x4d, 0x4e, 0x44, 0xa0, 0xd4, 0xf4, 0x50, 0x93, 0x5f,
1371 0xdc, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14,
1372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x13, 0xf0, 0x4e, 0x87,
1373 0x80, 0xc3, 0x55, 0xf3, 0x6d, 0xba, 0x74, 0xb8, 0x11, 0xbc, 0x6f, 0x44,
1374 0x58, 0x49, 0x4c, 0xe4, 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xf9,
1375 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10,
1376 0x00, 0x00, 0x00, 0xcc, 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21,
1377 0x0c, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02,
1378 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41,
1379 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25,
1380 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42,
1381 0x92, 0x0b, 0x42, 0xc4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a,
1382 0x32, 0x62, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00,
1383 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41,
1384 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51,
1385 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff,
1386 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff,
1387 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00,
1388 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13,
1389 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89,
1390 0x20, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20,
1391 0x64, 0x85, 0x04, 0x13, 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84,
1392 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10,
1393 0x8c, 0xc1, 0x08, 0x40, 0x09, 0x00, 0x0a, 0x66, 0x00, 0xe6, 0x08, 0xc0,
1394 0x60, 0x8e, 0x00, 0x29, 0xc6, 0x40, 0x10, 0x44, 0x41, 0x90, 0x51, 0x0c,
1395 0x80, 0x20, 0x88, 0x62, 0x20, 0xe4, 0xa6, 0xe1, 0xf2, 0x27, 0xec, 0x21,
1396 0x24, 0x7f, 0x25, 0xa4, 0x95, 0x98, 0xfc, 0xe2, 0xb6, 0x51, 0x31, 0x0c,
1397 0xc3, 0x40, 0x50, 0x71, 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0x1f,
1398 0x02, 0xcd, 0xb0, 0x10, 0x28, 0x58, 0x0a, 0xa3, 0x10, 0x0c, 0x33, 0x0c,
1399 0xc3, 0x40, 0x10, 0xc4, 0x40, 0xcd, 0x51, 0xc3, 0xe5, 0x4f, 0xd8, 0x43,
1400 0x48, 0x3e, 0xb7, 0x51, 0xc5, 0x4a, 0x4c, 0x7e, 0x71, 0xdb, 0x88, 0x18,
1401 0x86, 0x61, 0x28, 0xc4, 0x43, 0x30, 0x04, 0x41, 0x47, 0x0d, 0x97, 0x3f,
1402 0x61, 0x0f, 0x21, 0xf9, 0xdc, 0x46, 0x15, 0x2b, 0x31, 0xf9, 0xc8, 0x6d,
1403 0x23, 0x82, 0x20, 0x08, 0xa2, 0x10, 0x12, 0xc1, 0x10, 0x34, 0xcd, 0x11,
1404 0x04, 0xc5, 0x60, 0x88, 0x82, 0x20, 0x2a, 0xb2, 0x06, 0x02, 0x86, 0x11,
1405 0x88, 0x61, 0x26, 0x39, 0x18, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07,
1406 0x37, 0xa0, 0x85, 0x72, 0xc0, 0x07, 0x7a, 0xa8, 0x07, 0x79, 0x28, 0x07,
1407 0x39, 0x20, 0x85, 0x50, 0x90, 0x07, 0x79, 0x08, 0x87, 0x7c, 0xe0, 0x03,
1408 0x7b, 0x28, 0x87, 0x71, 0xa0, 0x87, 0x77, 0x90, 0x07, 0x3e, 0x30, 0x07,
1409 0x76, 0x78, 0x87, 0x70, 0xa0, 0x07, 0x36, 0x00, 0x03, 0x3a, 0xf0, 0x03,
1410 0x30, 0xf0, 0x03, 0x3d, 0xd0, 0x83, 0x76, 0x48, 0x07, 0x78, 0x98, 0x87,
1411 0x5f, 0xa0, 0x87, 0x7c, 0x80, 0x87, 0x72, 0x40, 0x01, 0x31, 0xd3, 0x19,
1412 0x8c, 0x03, 0x3b, 0x84, 0xc3, 0x3c, 0xcc, 0x83, 0x1b, 0xd0, 0x42, 0x39,
1413 0xe0, 0x03, 0x3d, 0xd4, 0x83, 0x3c, 0x94, 0x83, 0x1c, 0x90, 0x42, 0x28,
1414 0xc8, 0x83, 0x3c, 0x84, 0x43, 0x3e, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38,
1415 0xd0, 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38,
1416 0xd0, 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x01, 0x12,
1417 0x32, 0x8d, 0xb6, 0x61, 0x04, 0x61, 0x38, 0x89, 0x75, 0xa8, 0x48, 0x20,
1418 0x56, 0xc2, 0x40, 0x9c, 0x66, 0xa3, 0x8a, 0x82, 0x88, 0x10, 0xd1, 0x75,
1419 0xc4, 0x40, 0xde, 0x4d, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3,
1420 0x2c, 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0, 0x80, 0x20, 0x30, 0x15, 0x08,
1421 0x00, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36,
1422 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e,
1423 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07,
1424 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07,
1425 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07,
1426 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06,
1427 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e,
1428 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07,
1429 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07,
1430 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07,
1431 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07,
1432 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00,
1433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c,
1434 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
1435 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1436 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1437 0x00, 0x30, 0xe4, 0x81, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
1438 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00,
1439 0x00, 0x00, 0x00, 0xc0, 0x90, 0xc7, 0x02, 0x02, 0x60, 0x00, 0x00, 0x00,
1440 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x32,
1441 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6,
1442 0x04, 0x43, 0x22, 0x4a, 0x60, 0x04, 0xa0, 0x18, 0x8a, 0xa0, 0x1c, 0x4a,
1443 0xa2, 0x0c, 0x0a, 0xa6, 0x3c, 0xa8, 0x28, 0x89, 0x11, 0x80, 0x22, 0x28,
1444 0x83, 0x42, 0x28, 0x10, 0xe2, 0x66, 0x00, 0xe8, 0x9b, 0x01, 0xa0, 0x70,
1445 0x06, 0x80, 0xc4, 0xb1, 0x14, 0x84, 0x78, 0x1e, 0x00, 0x00, 0x00, 0x00,
1446 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x1a,
1447 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73,
1448 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71,
1449 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a,
1450 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b,
1451 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0xe2, 0x98, 0x20, 0x10, 0xc8,
1452 0x06, 0x61, 0x20, 0x26, 0x08, 0x44, 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x70,
1453 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0x9c, 0x45, 0x60, 0x82, 0x40,
1454 0x28, 0x13, 0x04, 0x62, 0x99, 0x20, 0x10, 0xcc, 0x06, 0x81, 0x70, 0x36,
1455 0x24, 0x84, 0xb2, 0x30, 0xc4, 0xd0, 0x10, 0xcf, 0x86, 0x00, 0x9a, 0x20,
1456 0x7c, 0xd7, 0x04, 0x81, 0x68, 0x26, 0x08, 0x84, 0xb3, 0x01, 0x21, 0xa4,
1457 0x65, 0x22, 0x06, 0x0a, 0xd8, 0x10, 0x54, 0x13, 0x84, 0x30, 0xc0, 0x36,
1458 0x20, 0xc4, 0xb5, 0x30, 0xc4, 0x40, 0x00, 0x1b, 0x02, 0x6c, 0x03, 0x11,
1459 0x01, 0x56, 0x36, 0x41, 0x10, 0x83, 0x6c, 0x43, 0xb0, 0x4d, 0x10, 0x04,
1460 0x80, 0x8f, 0x10, 0x5b, 0x1a, 0x9d, 0x91, 0xdc, 0x5b, 0x9b, 0x0c, 0x51,
1461 0x90, 0x9c, 0x5c, 0x58, 0x1e, 0x11, 0xaa, 0x22, 0xac, 0xa1, 0xa7, 0x27,
1462 0x29, 0xa2, 0x09, 0x42, 0x01, 0x4d, 0x10, 0x8a, 0x68, 0x43, 0x40, 0x4c,
1463 0x10, 0x0a, 0x69, 0x83, 0x30, 0x4d, 0x1b, 0x16, 0xe2, 0x03, 0x83, 0x30,
1464 0x10, 0x83, 0x31, 0x18, 0xc6, 0x80, 0x08, 0x03, 0x32, 0xe0, 0x32, 0x65,
1465 0xf5, 0x05, 0xf5, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x36, 0x41, 0x28,
1466 0xa6, 0x09, 0x42, 0x41, 0x6d, 0x58, 0x06, 0x33, 0x00, 0x83, 0x33, 0x10,
1467 0x03, 0x34, 0x18, 0xd0, 0x60, 0x08, 0x03, 0x60, 0x83, 0x50, 0x06, 0x69,
1468 0xc0, 0x64, 0xca, 0xea, 0x8b, 0x2a, 0x4c, 0xee, 0xac, 0x8c, 0x6e, 0x82,
1469 0x50, 0x54, 0x13, 0x04, 0xe2, 0xd9, 0x20, 0x4c, 0x6d, 0xb0, 0x61, 0x21,
1470 0xd6, 0x00, 0x0c, 0xd8, 0x40, 0x0c, 0xc2, 0x60, 0x40, 0x03, 0x22, 0x0c,
1471 0xdc, 0x60, 0x43, 0xf0, 0x06, 0x1b, 0x06, 0x35, 0x80, 0x03, 0x60, 0x43,
1472 0xd1, 0x79, 0x71, 0xa0, 0x01, 0x55, 0xd8, 0xd8, 0xec, 0xda, 0x5c, 0xd2,
1473 0xc8, 0xca, 0xdc, 0xe8, 0xa6, 0x04, 0x41, 0x15, 0x32, 0x3c, 0x17, 0xbb,
1474 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x29, 0x01, 0xd1, 0x84, 0x0c, 0xcf,
1475 0xc5, 0x2e, 0x8c, 0xcd, 0xae, 0x4c, 0x6e, 0x4a, 0x60, 0xd4, 0x21, 0xc3,
1476 0x73, 0x99, 0x43, 0x0b, 0x23, 0x2b, 0x93, 0x6b, 0x7a, 0x23, 0x2b, 0x63,
1477 0x9b, 0x12, 0x20, 0x65, 0xc8, 0xf0, 0x5c, 0xe4, 0xca, 0xe6, 0xde, 0xea,
1478 0xe4, 0xc6, 0xca, 0xe6, 0xa6, 0x04, 0x59, 0x1d, 0x32, 0x3c, 0x17, 0xbb,
1479 0xb4, 0xb2, 0xbb, 0x24, 0xb2, 0x29, 0xba, 0x30, 0xba, 0xb2, 0x29, 0xc1,
1480 0x56, 0x87, 0x0c, 0xcf, 0xa5, 0xcc, 0x8d, 0x4e, 0x2e, 0x0f, 0xea, 0x2d,
1481 0xcd, 0x8d, 0x6e, 0x6e, 0x4a, 0x10, 0x07, 0x00, 0x00, 0x00, 0x00, 0x79,
1482 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4,
1483 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c,
1484 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00,
1485 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2,
1486 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38,
1487 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d,
1488 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87,
1489 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87,
1490 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30,
1491 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde,
1492 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b,
1493 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c,
1494 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07,
1495 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87,
1496 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87,
1497 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87,
1498 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0,
1499 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc,
1500 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4,
1501 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39,
1502 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38,
1503 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b,
1504 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03,
1505 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0,
1506 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0,
1507 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71,
1508 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0xf0, 0x6c, 0x0b, 0x32,
1509 0x7d, 0x91, 0xc3, 0xd8, 0x9d, 0x16, 0x45, 0x00, 0x66, 0x04, 0xdb, 0x70,
1510 0xf9, 0xce, 0xe3, 0x0b, 0x01, 0x55, 0x14, 0x44, 0x54, 0x3a, 0xc0, 0x50,
1511 0x12, 0x06, 0x20, 0x60, 0x7e, 0x71, 0xdb, 0x56, 0xb0, 0x0d, 0x97, 0xef,
1512 0x3c, 0xbe, 0x10, 0x50, 0x45, 0x41, 0x44, 0xa5, 0x03, 0x0c, 0x25, 0x61,
1513 0x00, 0x02, 0xe6, 0x23, 0xb7, 0x6d, 0x06, 0xd2, 0x70, 0xf9, 0xce, 0xe3,
1514 0x0b, 0x11, 0x01, 0x4c, 0x44, 0x08, 0x34, 0xc3, 0x42, 0x58, 0xc0, 0x34,
1515 0x5c, 0xbe, 0xf3, 0xf8, 0x8b, 0x03, 0x0c, 0x62, 0xf3, 0x50, 0x93, 0x5f,
1516 0xdc, 0xb6, 0x0d, 0x54, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x01, 0xcc, 0xb3,
1517 0x10, 0x25, 0x51, 0x11, 0x8b, 0x5f, 0xdc, 0xb6, 0x09, 0x54, 0xc3, 0xe5,
1518 0x3b, 0x8f, 0x2f, 0x4d, 0x4e, 0x44, 0xa0, 0xd4, 0xf4, 0x50, 0x93, 0x5f,
1519 0xdc, 0x36, 0x00, 0x61, 0x20, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x13,
1520 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x54,
1521 0x8d, 0x00, 0x10, 0x51, 0x0a, 0x25, 0x37, 0x03, 0x50, 0x76, 0x85, 0x50,
1522 0x7c, 0x54, 0x94, 0x00, 0x0d, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23,
1523 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x75, 0x87, 0xb4, 0x6d, 0xc9, 0x88,
1524 0x41, 0x02, 0x80, 0x20, 0x18, 0x58, 0x1e, 0x12, 0x71, 0x9c, 0x32, 0x62,
1525 0x90, 0x00, 0x20, 0x08, 0x06, 0xd6, 0x97, 0x4c, 0x5d, 0xb7, 0x8c, 0x18,
1526 0x24, 0x00, 0x08, 0x82, 0x81, 0x51, 0x06, 0x87, 0xe7, 0x55, 0xc9, 0x88,
1527 0x41, 0x02, 0x80, 0x20, 0x18, 0x18, 0x66, 0x80, 0x7c, 0x9f, 0xa1, 0x8c,
1528 0x18, 0x1c, 0x00, 0x08, 0x82, 0x01, 0x44, 0x06, 0xca, 0x00, 0x06, 0xa3,
1529 0x09, 0x01, 0x30, 0x9a, 0x20, 0x04, 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40,
1530 0x0c, 0x26, 0x1c, 0xf2, 0x31, 0xe1, 0x90, 0x8f, 0x09, 0x06, 0x7c, 0x4c,
1531 0x30, 0xe0, 0x33, 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0x50, 0x1b, 0x4c,
1532 0x8c, 0x1a, 0x8c, 0x26, 0x04, 0xc1, 0x05, 0xc4, 0x5c, 0x30, 0xd4, 0x88,
1533 0xc1, 0x01, 0x80, 0x20, 0x18, 0x4c, 0x70, 0x70, 0x41, 0x6e, 0x30, 0x9a,
1534 0x10, 0x00, 0x17, 0x0c, 0x35, 0x62, 0xf0, 0x00, 0x20, 0x08, 0x06, 0x4d,
1535 0x1d, 0x60, 0x15, 0x95, 0x20, 0x84, 0x05, 0x07, 0x70, 0xb0, 0x05, 0xa3,
1536 0x09, 0x01, 0x30, 0x9a, 0x20, 0x04, 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40,
1537 0x0c, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0xec, 0x81, 0x18, 0xd4,
1538 0x41, 0x1d, 0xb0, 0x01, 0x31, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0xc8,
1539 0x1e, 0x88, 0x41, 0x1d, 0xd4, 0x01, 0x37, 0x8c, 0x18, 0x24, 0x00, 0x08,
1540 0x82, 0x01, 0xb2, 0x07, 0x62, 0x50, 0x07, 0x75, 0xb0, 0x06, 0xc2, 0x88,
1541 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, 0x7b, 0x20, 0x06, 0x75, 0x50, 0x07,
1542 0x6a, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1543};
1544#if 0
1545;
1546; Input signature:
1547;
1548; Name Index Mask Register SysValue Format Used
1549; -------------------- ----- ------ -------- -------- ------- ------
1550; TEXCOORD 0 xy 0 NONE float xy
1551; SV_Position 0 xyzw 1 POS float
1552;
1553;
1554; Output signature:
1555;
1556; Name Index Mask Register SysValue Format Used
1557; -------------------- ----- ------ -------- -------- ------- ------
1558; SV_Target 0 xyzw 0 TARGET float xyzw
1559;
1560; shader hash: 49c2f4be133400e07c3f23e9798b27f4
1561;
1562; Pipeline Runtime Information:
1563;
1564; Pixel Shader
1565; DepthOutput=0
1566; SampleFrequency=0
1567;
1568;
1569; Input signature:
1570;
1571; Name Index InterpMode DynIdx
1572; -------------------- ----- ---------------------- ------
1573; TEXCOORD 0 linear
1574; SV_Position 0 noperspective
1575;
1576; Output signature:
1577;
1578; Name Index InterpMode DynIdx
1579; -------------------- ----- ---------------------- ------
1580; SV_Target 0
1581;
1582; Buffer Definitions:
1583;
1584; cbuffer SourceRegionBuffer
1585; {
1586;
1587; struct SourceRegionBuffer
1588; {
1589;
1590; float2 UVLeftTop; ; Offset: 0
1591; float2 UVDimensions; ; Offset: 8
1592; uint MipLevel; ; Offset: 16
1593; float LayerOrDepth; ; Offset: 20
1594;
1595; } SourceRegionBuffer; ; Offset: 0 Size: 24
1596;
1597; }
1598;
1599;
1600; Resource Bindings:
1601;
1602; Name Type Format Dim ID HLSL Bind Count
1603; ------------------------------ ---------- ------- ----------- ------- -------------- ------
1604; SourceRegionBuffer cbuffer NA NA CB0 cb0,space3 1
1605; SourceSampler sampler NA NA S0 s0,space2 1
1606; SourceTexture3D texture f32 3d T0 t0,space2 1
1607;
1608;
1609; ViewId state:
1610;
1611; Number of inputs: 8, outputs: 4
1612; Outputs dependent on ViewId: { }
1613; Inputs contributing to computation of Outputs:
1614; output 0 depends on inputs: { 0, 1 }
1615; output 1 depends on inputs: { 0, 1 }
1616; output 2 depends on inputs: { 0, 1 }
1617; output 3 depends on inputs: { 0, 1 }
1618;
1619target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
1620target triple = "dxil-ms-dx"
1621
1622%dx.types.Handle = type { i8* }
1623%dx.types.CBufRet.f32 = type { float, float, float, float }
1624%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
1625%dx.types.ResRet.f32 = type { float, float, float, float, i32 }
1626%"class.Texture3D<vector<float, 4> >" = type { <4 x float>, %"class.Texture3D<vector<float, 4> >::mips_type" }
1627%"class.Texture3D<vector<float, 4> >::mips_type" = type { i32 }
1628%SourceRegionBuffer = type { <2 x float>, <2 x float>, i32, float }
1629%struct.SamplerState = type { i32 }
1630
1631define void @BlitFrom3D() {
1632 %1 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
1633 %2 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 3, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
1634 %3 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
1635 %4 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
1636 %5 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
1637 %6 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %3, i32 0) ; CBufferLoadLegacy(handle,regIndex)
1638 %7 = extractvalue %dx.types.CBufRet.f32 %6, 0
1639 %8 = extractvalue %dx.types.CBufRet.f32 %6, 1
1640 %9 = extractvalue %dx.types.CBufRet.f32 %6, 2
1641 %10 = extractvalue %dx.types.CBufRet.f32 %6, 3
1642 %11 = fmul fast float %9, %4
1643 %12 = fmul fast float %10, %5
1644 %13 = fadd fast float %11, %7
1645 %14 = fadd fast float %12, %8
1646 %15 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %3, i32 1) ; CBufferLoadLegacy(handle,regIndex)
1647 %16 = extractvalue %dx.types.CBufRet.f32 %15, 1
1648 %17 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %3, i32 1) ; CBufferLoadLegacy(handle,regIndex)
1649 %18 = extractvalue %dx.types.CBufRet.i32 %17, 0
1650 %19 = uitofp i32 %18 to float
1651 %20 = call %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32 62, %dx.types.Handle %1, %dx.types.Handle %2, float %13, float %14, float %16, float undef, i32 0, i32 0, i32 0, float %19) ; SampleLevel(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,LOD)
1652 %21 = extractvalue %dx.types.ResRet.f32 %20, 0
1653 %22 = extractvalue %dx.types.ResRet.f32 %20, 1
1654 %23 = extractvalue %dx.types.ResRet.f32 %20, 2
1655 %24 = extractvalue %dx.types.ResRet.f32 %20, 3
1656 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %21) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
1657 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %22) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
1658 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %23) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
1659 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %24) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
1660 ret void
1661}
1662
1663; Function Attrs: nounwind readnone
1664declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
1665
1666; Function Attrs: nounwind
1667declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
1668
1669; Function Attrs: nounwind readonly
1670declare %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32, %dx.types.Handle, %dx.types.Handle, float, float, float, float, i32, i32, i32, float) #2
1671
1672; Function Attrs: nounwind readonly
1673declare %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32, %dx.types.Handle, i32) #2
1674
1675; Function Attrs: nounwind readonly
1676declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #2
1677
1678; Function Attrs: nounwind readonly
1679declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #2
1680
1681attributes #0 = { nounwind readnone }
1682attributes #1 = { nounwind }
1683attributes #2 = { nounwind readonly }
1684
1685!llvm.ident = !{!0}
1686!dx.version = !{!1}
1687!dx.valver = !{!2}
1688!dx.shaderModel = !{!3}
1689!dx.resources = !{!4}
1690!dx.viewIdState = !{!12}
1691!dx.entryPoints = !{!13}
1692
1693!0 = !{!"clang version 3.7 (tags/RELEASE_370/final)"}
1694!1 = !{i32 1, i32 0}
1695!2 = !{i32 1, i32 6}
1696!3 = !{!"ps", i32 6, i32 0}
1697!4 = !{!5, null, !8, !10}
1698!5 = !{!6}
1699!6 = !{i32 0, %"class.Texture3D<vector<float, 4> >"* undef, !"", i32 2, i32 0, i32 1, i32 4, i32 0, !7}
1700!7 = !{i32 0, i32 9}
1701!8 = !{!9}
1702!9 = !{i32 0, %SourceRegionBuffer* undef, !"", i32 3, i32 0, i32 1, i32 24, null}
1703!10 = !{!11}
1704!11 = !{i32 0, %struct.SamplerState* undef, !"", i32 2, i32 0, i32 1, i32 0, null}
1705!12 = !{[10 x i32] [i32 8, i32 4, i32 15, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0]}
1706!13 = !{void ()* @BlitFrom3D, !"BlitFrom3D", !14, !4, null}
1707!14 = !{!15, !20, null}
1708!15 = !{!16, !19}
1709!16 = !{i32 0, !"TEXCOORD", i8 9, i8 0, !17, i8 2, i32 1, i8 2, i32 0, i8 0, !18}
1710!17 = !{i32 0}
1711!18 = !{i32 3, i32 3}
1712!19 = !{i32 1, !"SV_Position", i8 9, i8 3, !17, i8 4, i32 1, i8 4, i32 1, i8 0, null}
1713!20 = !{!21}
1714!21 = !{i32 0, !"SV_Target", i8 9, i8 16, !17, i8 0, i32 1, i8 4, i32 0, i8 0, !22}
1715!22 = !{i32 3, i32 15}
1716
1717#endif
1718
1719const unsigned char g_BlitFrom3D[] = {
1720 0x44, 0x58, 0x42, 0x43, 0x02, 0xc7, 0x0f, 0x7e, 0xe3, 0x5a, 0xf4, 0x9b,
1721 0xc5, 0xb2, 0xf8, 0xed, 0xa6, 0x79, 0xed, 0xf4, 0x01, 0x00, 0x00, 0x00,
1722 0x3f, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
1723 0x50, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00,
1724 0xe7, 0x01, 0x00, 0x00, 0x77, 0x02, 0x00, 0x00, 0x5f, 0x0a, 0x00, 0x00,
1725 0x7b, 0x0a, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
1726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31,
1727 0x5d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1728 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1729 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1730 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1731 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1732 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1733 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44,
1734 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
1735 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
1736 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
1737 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
1738 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1739 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x50,
1740 0x53, 0x56, 0x30, 0xf0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1742 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
1743 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
1744 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
1745 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
1746 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
1747 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
1748 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,
1749 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
1750 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
1751 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
1752 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x00, 0x00, 0x01,
1753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
1754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x03,
1755 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1756 0x01, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1757 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, 0x00, 0x0f,
1758 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1759 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1760 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x88,
1761 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18,
1762 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00,
1763 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c,
1764 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5c,
1765 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x7c,
1766 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03,
1767 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1768 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01,
1769 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1770 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
1771 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x03,
1772 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x54, 0x41, 0x54, 0xe0,
1773 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x44,
1774 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xc8,
1775 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xef,
1776 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
1777 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06,
1778 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e,
1779 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4,
1780 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48,
1781 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4,
1782 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1,
1783 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08,
1784 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40,
1785 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d,
1786 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49,
1787 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20,
1788 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x58,
1789 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13,
1790 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12,
1791 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x8c, 0xc1, 0x08, 0x40,
1792 0x09, 0x00, 0x0a, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29,
1793 0xc6, 0x40, 0x10, 0x44, 0x41, 0x90, 0x51, 0x0c, 0x80, 0x20, 0x88, 0x62,
1794 0x20, 0xe4, 0xa6, 0xe1, 0xf2, 0x27, 0xec, 0x21, 0x24, 0x7f, 0x25, 0xa4,
1795 0x95, 0x98, 0xfc, 0xe2, 0xb6, 0x51, 0x31, 0x0c, 0xc3, 0x40, 0x50, 0x71,
1796 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, 0x10,
1797 0x28, 0x58, 0x0a, 0xa3, 0x10, 0x0c, 0x33, 0x0c, 0xc3, 0x40, 0x10, 0xc4,
1798 0x40, 0xcd, 0x51, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, 0x3e, 0xb7, 0x51,
1799 0xc5, 0x4a, 0x4c, 0x7e, 0x71, 0xdb, 0x88, 0x18, 0x86, 0x61, 0x28, 0xc4,
1800 0x43, 0x30, 0x04, 0x41, 0x47, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9,
1801 0xdc, 0x46, 0x15, 0x2b, 0x31, 0xf9, 0xc8, 0x6d, 0x23, 0x82, 0x20, 0x08,
1802 0xa2, 0x10, 0x12, 0xc1, 0x10, 0x34, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0x88,
1803 0x82, 0x20, 0x2a, 0xb2, 0x06, 0x02, 0x86, 0x11, 0x88, 0x61, 0xa6, 0x36,
1804 0x18, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07, 0x37, 0xa0, 0x85, 0x72,
1805 0xc0, 0x07, 0x7a, 0xa8, 0x07, 0x79, 0x28, 0x87, 0x39, 0x20, 0x05, 0x3e,
1806 0xb0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0xe0, 0x03, 0x73,
1807 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x60, 0x03, 0x30, 0xa0, 0x03, 0x3f,
1808 0x00, 0x03, 0x3f, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x74, 0x80, 0x87, 0x79,
1809 0xf8, 0x05, 0x7a, 0xc8, 0x07, 0x78, 0x28, 0x07, 0x14, 0x10, 0x33, 0x89,
1810 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94,
1811 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, 0x43, 0x39, 0xcc, 0x01, 0x29, 0xf0,
1812 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98,
1813 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8,
1814 0x01, 0x18, 0xf8, 0x01, 0x12, 0x32, 0x8d, 0xb6, 0x61, 0x04, 0x61, 0x38,
1815 0x89, 0x75, 0xa8, 0x48, 0x20, 0x56, 0xc2, 0x40, 0x9c, 0x66, 0xa3, 0x8a,
1816 0x82, 0x88, 0x10, 0xd1, 0x75, 0xc4, 0x40, 0xde, 0x4d, 0xd2, 0x14, 0x51,
1817 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0,
1818 0x80, 0x20, 0x30, 0x15, 0x08, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87,
1819 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87,
1820 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00,
1821 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90,
1822 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0,
1823 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30,
1824 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20,
1825 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0,
1826 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60,
1827 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60,
1828 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0,
1829 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40,
1830 0x07, 0x43, 0x9e, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1831 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
1832 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00,
1833 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00,
1834 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x81, 0x80, 0x00, 0x18, 0x00,
1835 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30,
1836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xc7, 0x02, 0x02,
1837 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x14,
1838 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, 0x90, 0x8c,
1839 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x22, 0x4a, 0x60, 0x04, 0xa0, 0x18,
1840 0x8a, 0xa0, 0x10, 0x4a, 0xa2, 0x0c, 0x0a, 0xa6, 0x1c, 0x0a, 0xa2, 0x40,
1841 0x4a, 0xa1, 0x50, 0xca, 0xa3, 0x74, 0xa8, 0x28, 0x89, 0x11, 0x80, 0x22,
1842 0x28, 0x83, 0x42, 0x28, 0x10, 0xaa, 0x6a, 0x80, 0xb8, 0x19, 0x00, 0xf2,
1843 0x66, 0x00, 0xe8, 0x9b, 0x01, 0xa0, 0x70, 0x06, 0x80, 0xc4, 0xb1, 0x14,
1844 0x84, 0x78, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79,
1845 0x18, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46,
1846 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b,
1847 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1,
1848 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa,
1849 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10,
1850 0x04, 0x13, 0x04, 0xe2, 0x98, 0x20, 0x10, 0xc8, 0x06, 0x61, 0x20, 0x36,
1851 0x08, 0x04, 0x41, 0x01, 0x6e, 0x6e, 0x82, 0x40, 0x24, 0x1b, 0x86, 0x03,
1852 0x21, 0x26, 0x08, 0x5c, 0xc7, 0x67, 0xea, 0xad, 0x4e, 0x6e, 0xac, 0x8c,
1853 0xaa, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x6c, 0x86, 0x68, 0x82, 0x40, 0x28,
1854 0x13, 0x04, 0x62, 0x99, 0x20, 0x10, 0xcc, 0x06, 0x81, 0x70, 0x36, 0x24,
1855 0x84, 0xb2, 0x30, 0xc4, 0xd0, 0x10, 0xcf, 0x86, 0x00, 0x9a, 0x20, 0x7c,
1856 0x1f, 0xa5, 0xa9, 0xb7, 0x3a, 0xb9, 0xb1, 0x32, 0xa9, 0xb2, 0xb3, 0xb4,
1857 0x37, 0x37, 0xa1, 0x3a, 0x33, 0xb3, 0x32, 0xb9, 0x09, 0x02, 0xd1, 0x4c,
1858 0x10, 0x08, 0x67, 0x03, 0x42, 0x48, 0x13, 0x45, 0x0c, 0x15, 0xb0, 0x21,
1859 0xb0, 0x26, 0x08, 0x61, 0x00, 0x06, 0x6c, 0xa6, 0xde, 0xea, 0xe4, 0xc6,
1860 0xca, 0xa6, 0xc2, 0xda, 0xe0, 0xd8, 0xca, 0xe4, 0x36, 0x20, 0x04, 0x96,
1861 0x31, 0xc4, 0x40, 0x00, 0x1b, 0x02, 0x6d, 0x03, 0x11, 0x01, 0xd7, 0x36,
1862 0x41, 0xf0, 0x3c, 0x26, 0x55, 0x56, 0x4c, 0x65, 0x66, 0x74, 0x54, 0x6f,
1863 0x70, 0x13, 0x04, 0xe2, 0x99, 0x20, 0x54, 0xdc, 0x06, 0x04, 0xf1, 0x28,
1864 0xe2, 0x73, 0x1c, 0x30, 0x20, 0x53, 0x65, 0x45, 0x94, 0xd6, 0x56, 0xe6,
1865 0x36, 0x97, 0xf6, 0xe6, 0x36, 0x37, 0x41, 0x20, 0xa0, 0x0d, 0x08, 0x22,
1866 0x06, 0xd4, 0x18, 0x7c, 0x8e, 0x03, 0x06, 0x44, 0x9a, 0xd2, 0xe0, 0x98,
1867 0xca, 0xec, 0xca, 0xd8, 0x26, 0x08, 0x44, 0x34, 0x41, 0x20, 0xa4, 0x0d,
1868 0x08, 0x52, 0x06, 0x94, 0x19, 0x7c, 0x67, 0xe0, 0x80, 0x01, 0x19, 0xa6,
1869 0xb0, 0xbc, 0x32, 0xb9, 0x27, 0x39, 0xa2, 0x32, 0x38, 0x3a, 0xb4, 0x09,
1870 0x02, 0x31, 0x6d, 0x40, 0x90, 0x34, 0xa0, 0xd4, 0xe0, 0x73, 0x1c, 0x30,
1871 0xd8, 0x50, 0x54, 0x61, 0x40, 0x06, 0x68, 0xb0, 0x06, 0x1b, 0x06, 0xa2,
1872 0x63, 0x83, 0x09, 0x82, 0x00, 0x6c, 0x00, 0x36, 0x0c, 0xc4, 0x1b, 0xbc,
1873 0xc1, 0x86, 0x00, 0x0e, 0x36, 0x0c, 0x83, 0x1b, 0xc4, 0xc1, 0x04, 0x41,
1874 0x0c, 0xc2, 0x60, 0x43, 0x30, 0x07, 0x54, 0x84, 0xd8, 0xd2, 0xe8, 0x8c,
1875 0xe4, 0xde, 0xda, 0x66, 0x88, 0x88, 0x50, 0x15, 0x61, 0x0d, 0x3d, 0x3d,
1876 0x49, 0x11, 0x4d, 0x10, 0x0a, 0x6b, 0x82, 0x50, 0x5c, 0x1b, 0x02, 0x62,
1877 0x82, 0x50, 0x60, 0x1b, 0x04, 0x8a, 0xda, 0xb0, 0x10, 0x76, 0x70, 0x07,
1878 0x78, 0x90, 0x07, 0x7a, 0x30, 0xe8, 0x01, 0x81, 0x07, 0x7b, 0xc0, 0x65,
1879 0xca, 0xea, 0x0b, 0xea, 0x6d, 0x2e, 0x8d, 0x2e, 0xed, 0xcd, 0x6d, 0x82,
1880 0x50, 0x64, 0x13, 0x84, 0x42, 0xdb, 0xb0, 0x0c, 0x7d, 0x70, 0x07, 0x7e,
1881 0x90, 0x07, 0x7f, 0x30, 0xfc, 0xc1, 0x80, 0x07, 0xc0, 0x06, 0x81, 0x0f,
1882 0x40, 0x81, 0xc9, 0x94, 0xd5, 0x17, 0x55, 0x98, 0xdc, 0x59, 0x19, 0xdd,
1883 0x04, 0xa1, 0xd8, 0x26, 0x08, 0x04, 0xb5, 0x41, 0xa0, 0x48, 0x61, 0xc3,
1884 0x42, 0x88, 0xc2, 0x1d, 0x8c, 0x42, 0x1e, 0xe0, 0xc1, 0xf0, 0x07, 0x04,
1885 0x1e, 0x94, 0xc2, 0x86, 0xc0, 0x14, 0x36, 0x0c, 0xa1, 0x70, 0x0a, 0xc0,
1886 0x86, 0xc2, 0x0d, 0xea, 0x00, 0x15, 0x38, 0x80, 0x86, 0x19, 0xdb, 0x5b,
1887 0x18, 0xdd, 0x1c, 0x8b, 0x34, 0xb7, 0x39, 0xba, 0xb9, 0x09, 0x02, 0x51,
1888 0xd1, 0x98, 0x4b, 0x3b, 0xfb, 0x62, 0x23, 0xa3, 0x31, 0x97, 0x76, 0xf6,
1889 0x35, 0x47, 0x47, 0x84, 0xae, 0x0c, 0xef, 0xcb, 0xed, 0x4d, 0xae, 0x6d,
1890 0x83, 0xa2, 0x0a, 0x67, 0xb0, 0x0a, 0xac, 0xd0, 0x0a, 0x8c, 0x2b, 0x34,
1891 0xaf, 0x30, 0x54, 0x61, 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73,
1892 0xa3, 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, 0x5c, 0xec, 0xca, 0xe4, 0xe6,
1893 0xd2, 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, 0x32, 0x3c, 0x17, 0xbb, 0x30,
1894 0x36, 0xbb, 0x32, 0xb9, 0x29, 0x41, 0x51, 0x87, 0x0c, 0xcf, 0x65, 0x0e,
1895 0x2d, 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0x80,
1896 0x94, 0x21, 0xc3, 0x73, 0x91, 0x2b, 0x9b, 0x7b, 0xab, 0x93, 0x1b, 0x2b,
1897 0x9b, 0x9b, 0x12, 0x6c, 0x95, 0xc8, 0xf0, 0x5c, 0xe8, 0xf2, 0xe0, 0xca,
1898 0x82, 0xdc, 0xdc, 0xde, 0xe8, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xe6, 0xa6,
1899 0x08, 0x6c, 0x10, 0x07, 0x75, 0xc8, 0xf0, 0x5c, 0xec, 0xd2, 0xca, 0xee,
1900 0x92, 0xc8, 0xa6, 0xe8, 0xc2, 0xe8, 0xca, 0xa6, 0x04, 0x73, 0x50, 0x87,
1901 0x0c, 0xcf, 0xa5, 0xcc, 0x8d, 0x4e, 0x2e, 0x0f, 0xea, 0x2d, 0xcd, 0x8d,
1902 0x6e, 0x6e, 0x4a, 0x80, 0x0a, 0x5d, 0xc8, 0xf0, 0x5c, 0xc6, 0xde, 0xea,
1903 0xdc, 0xe8, 0xca, 0xe4, 0xe6, 0xa6, 0x04, 0xaf, 0x00, 0x00, 0x00, 0x79,
1904 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4,
1905 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c,
1906 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00,
1907 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2,
1908 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38,
1909 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d,
1910 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87,
1911 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87,
1912 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30,
1913 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde,
1914 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b,
1915 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c,
1916 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07,
1917 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87,
1918 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87,
1919 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87,
1920 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0,
1921 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc,
1922 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4,
1923 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39,
1924 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38,
1925 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b,
1926 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03,
1927 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0,
1928 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0,
1929 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71,
1930 0x20, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x06, 0xa0, 0x6c, 0x0b, 0x32,
1931 0x7d, 0x91, 0xc3, 0xdc, 0x9d, 0x11, 0x6c, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f,
1932 0x04, 0x54, 0x51, 0x10, 0x51, 0xe9, 0x00, 0x43, 0x49, 0x18, 0x80, 0x80,
1933 0xf9, 0xc5, 0x6d, 0x5b, 0xc1, 0x36, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x40,
1934 0x15, 0x05, 0x11, 0x95, 0x0e, 0x30, 0x94, 0x84, 0x01, 0x08, 0x98, 0x8f,
1935 0xdc, 0xb6, 0x19, 0x48, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x44, 0x04, 0x30,
1936 0x11, 0x21, 0xd0, 0x0c, 0x0b, 0x61, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3,
1937 0x2f, 0x0e, 0x30, 0x88, 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x50,
1938 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x04, 0x30, 0xcf, 0x42, 0x94, 0x44, 0x45,
1939 0x2c, 0x7e, 0x71, 0xdb, 0x26, 0x50, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x34,
1940 0x39, 0x11, 0x81, 0x52, 0xd3, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x00, 0x00,
1941 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00,
1942 0x00, 0x00, 0x00, 0x49, 0xc2, 0xf4, 0xbe, 0x13, 0x34, 0x00, 0xe0, 0x7c,
1943 0x3f, 0x23, 0xe9, 0x79, 0x8b, 0x27, 0xf4, 0x44, 0x58, 0x49, 0x4c, 0xbc,
1944 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xef, 0x01, 0x00, 0x00, 0x44,
1945 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xa4,
1946 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xe6,
1947 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
1948 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06,
1949 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e,
1950 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4,
1951 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48,
1952 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4,
1953 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1,
1954 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08,
1955 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40,
1956 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d,
1957 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49,
1958 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20,
1959 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x58,
1960 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13,
1961 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12,
1962 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x8c, 0xc1, 0x08, 0x40,
1963 0x09, 0x00, 0x0a, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29,
1964 0xc6, 0x40, 0x10, 0x44, 0x41, 0x90, 0x51, 0x0c, 0x80, 0x20, 0x88, 0x62,
1965 0x20, 0xe4, 0xa6, 0xe1, 0xf2, 0x27, 0xec, 0x21, 0x24, 0x7f, 0x25, 0xa4,
1966 0x95, 0x98, 0xfc, 0xe2, 0xb6, 0x51, 0x31, 0x0c, 0xc3, 0x40, 0x50, 0x71,
1967 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, 0x10,
1968 0x28, 0x58, 0x0a, 0xa3, 0x10, 0x0c, 0x33, 0x0c, 0xc3, 0x40, 0x10, 0xc4,
1969 0x40, 0xcd, 0x51, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, 0x3e, 0xb7, 0x51,
1970 0xc5, 0x4a, 0x4c, 0x7e, 0x71, 0xdb, 0x88, 0x18, 0x86, 0x61, 0x28, 0xc4,
1971 0x43, 0x30, 0x04, 0x41, 0x47, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9,
1972 0xdc, 0x46, 0x15, 0x2b, 0x31, 0xf9, 0xc8, 0x6d, 0x23, 0x82, 0x20, 0x08,
1973 0xa2, 0x10, 0x12, 0xc1, 0x10, 0x34, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0x88,
1974 0x82, 0x20, 0x2a, 0xb2, 0x06, 0x02, 0x86, 0x11, 0x88, 0x61, 0xa6, 0x36,
1975 0x18, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07, 0x37, 0xa0, 0x85, 0x72,
1976 0xc0, 0x07, 0x7a, 0xa8, 0x07, 0x79, 0x28, 0x87, 0x39, 0x20, 0x05, 0x3e,
1977 0xb0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0xe0, 0x03, 0x73,
1978 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x60, 0x03, 0x30, 0xa0, 0x03, 0x3f,
1979 0x00, 0x03, 0x3f, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x74, 0x80, 0x87, 0x79,
1980 0xf8, 0x05, 0x7a, 0xc8, 0x07, 0x78, 0x28, 0x07, 0x14, 0x10, 0x33, 0x89,
1981 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94,
1982 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, 0x43, 0x39, 0xcc, 0x01, 0x29, 0xf0,
1983 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98,
1984 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8,
1985 0x01, 0x18, 0xf8, 0x01, 0x12, 0x32, 0x8d, 0xb6, 0x61, 0x04, 0x61, 0x38,
1986 0x89, 0x75, 0xa8, 0x48, 0x20, 0x56, 0xc2, 0x40, 0x9c, 0x66, 0xa3, 0x8a,
1987 0x82, 0x88, 0x10, 0xd1, 0x75, 0xc4, 0x40, 0xde, 0x4d, 0xd2, 0x14, 0x51,
1988 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0,
1989 0x80, 0x20, 0x30, 0x15, 0x08, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87,
1990 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87,
1991 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00,
1992 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90,
1993 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0,
1994 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30,
1995 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20,
1996 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0,
1997 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60,
1998 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60,
1999 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0,
2000 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40,
2001 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2002 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
2003 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00,
2004 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00,
2005 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x81, 0x80, 0x00, 0x18, 0x00,
2006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30,
2007 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xc7, 0x02, 0x02,
2008 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x10,
2009 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c,
2010 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x22, 0x4a, 0x60, 0x04, 0xa0, 0x18,
2011 0x8a, 0xa0, 0x10, 0x4a, 0xa2, 0x0c, 0x0a, 0xa6, 0x3c, 0xa8, 0x28, 0x89,
2012 0x11, 0x80, 0x22, 0x28, 0x83, 0x42, 0x28, 0x10, 0xe2, 0x66, 0x00, 0xe8,
2013 0x9b, 0x01, 0xa0, 0x70, 0x06, 0x80, 0xc4, 0xb1, 0x14, 0x84, 0x78, 0x1e,
2014 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x67,
2015 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35,
2016 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b,
2017 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b,
2018 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79,
2019 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0xe2,
2020 0x98, 0x20, 0x10, 0xc8, 0x06, 0x61, 0x20, 0x26, 0x08, 0x44, 0xb2, 0x41,
2021 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0x9c,
2022 0x45, 0x60, 0x82, 0x40, 0x28, 0x13, 0x04, 0x62, 0x99, 0x20, 0x10, 0xcc,
2023 0x06, 0x81, 0x70, 0x36, 0x24, 0x84, 0xb2, 0x30, 0xc4, 0xd0, 0x10, 0xcf,
2024 0x86, 0x00, 0x9a, 0x20, 0x7c, 0xd7, 0x04, 0x81, 0x68, 0x26, 0x08, 0x84,
2025 0xb3, 0x01, 0x21, 0xa4, 0x65, 0x22, 0x06, 0x0a, 0xd8, 0x10, 0x54, 0x13,
2026 0x84, 0x30, 0xc0, 0x36, 0x20, 0xc4, 0xb5, 0x30, 0xc4, 0x40, 0x00, 0x1b,
2027 0x02, 0x6c, 0x03, 0x11, 0x01, 0x56, 0x36, 0x41, 0x10, 0x83, 0x6c, 0x43,
2028 0xb0, 0x4d, 0x10, 0x04, 0x80, 0x8a, 0x10, 0x5b, 0x1a, 0x9d, 0x91, 0xdc,
2029 0x5b, 0xdb, 0x0c, 0x11, 0x11, 0xaa, 0x22, 0xac, 0xa1, 0xa7, 0x27, 0x29,
2030 0xa2, 0x09, 0x42, 0x01, 0x4d, 0x10, 0x8a, 0x68, 0x43, 0x40, 0x4c, 0x10,
2031 0x0a, 0x69, 0x83, 0x30, 0x4d, 0x1b, 0x16, 0xe2, 0x03, 0x83, 0x30, 0x10,
2032 0x83, 0x31, 0x18, 0xc6, 0x80, 0x08, 0x03, 0x32, 0xe0, 0x32, 0x65, 0xf5,
2033 0x05, 0xf5, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x36, 0x41, 0x28, 0xa6,
2034 0x09, 0x42, 0x41, 0x6d, 0x58, 0x06, 0x33, 0x00, 0x83, 0x33, 0x10, 0x03,
2035 0x34, 0x18, 0xd0, 0x60, 0x08, 0x03, 0x60, 0x83, 0x50, 0x06, 0x69, 0xc0,
2036 0x64, 0xca, 0xea, 0x8b, 0x2a, 0x4c, 0xee, 0xac, 0x8c, 0x6e, 0x82, 0x50,
2037 0x54, 0x13, 0x04, 0xe2, 0xd9, 0x20, 0x4c, 0x6d, 0xb0, 0x61, 0x21, 0xd6,
2038 0x00, 0x0c, 0xd8, 0x40, 0x0c, 0xc2, 0x60, 0x40, 0x03, 0x22, 0x0c, 0xdc,
2039 0x60, 0x43, 0xf0, 0x06, 0x1b, 0x06, 0x35, 0x80, 0x03, 0x60, 0x43, 0xd1,
2040 0x79, 0x71, 0xa0, 0x01, 0x55, 0xd8, 0xd8, 0xec, 0xda, 0x5c, 0xd2, 0xc8,
2041 0xca, 0xdc, 0xe8, 0xa6, 0x04, 0x41, 0x15, 0x32, 0x3c, 0x17, 0xbb, 0x32,
2042 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x29, 0x01, 0xd1, 0x84, 0x0c, 0xcf, 0xc5,
2043 0x2e, 0x8c, 0xcd, 0xae, 0x4c, 0x6e, 0x4a, 0x60, 0xd4, 0x21, 0xc3, 0x73,
2044 0x99, 0x43, 0x0b, 0x23, 0x2b, 0x93, 0x6b, 0x7a, 0x23, 0x2b, 0x63, 0x9b,
2045 0x12, 0x20, 0x65, 0xc8, 0xf0, 0x5c, 0xe4, 0xca, 0xe6, 0xde, 0xea, 0xe4,
2046 0xc6, 0xca, 0xe6, 0xa6, 0x04, 0x59, 0x1d, 0x32, 0x3c, 0x17, 0xbb, 0xb4,
2047 0xb2, 0xbb, 0x24, 0xb2, 0x29, 0xba, 0x30, 0xba, 0xb2, 0x29, 0xc1, 0x56,
2048 0x87, 0x0c, 0xcf, 0xa5, 0xcc, 0x8d, 0x4e, 0x2e, 0x0f, 0xea, 0x2d, 0xcd,
2049 0x8d, 0x6e, 0x6e, 0x4a, 0x10, 0x07, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c,
2050 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14,
2051 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79,
2052 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e,
2053 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1,
2054 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc,
2055 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74,
2056 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a,
2057 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e,
2058 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e,
2059 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21,
2060 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0,
2061 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc,
2062 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72,
2063 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76,
2064 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f,
2065 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c,
2066 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03,
2067 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1,
2068 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61,
2069 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8,
2070 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94,
2071 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0,
2072 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76,
2073 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e,
2074 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f,
2075 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x1f,
2076 0x00, 0x00, 0x00, 0x06, 0xa0, 0x6c, 0x0b, 0x32, 0x7d, 0x91, 0xc3, 0xdc,
2077 0x9d, 0x11, 0x6c, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x04, 0x54, 0x51, 0x10,
2078 0x51, 0xe9, 0x00, 0x43, 0x49, 0x18, 0x80, 0x80, 0xf9, 0xc5, 0x6d, 0x5b,
2079 0xc1, 0x36, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x40, 0x15, 0x05, 0x11, 0x95,
2080 0x0e, 0x30, 0x94, 0x84, 0x01, 0x08, 0x98, 0x8f, 0xdc, 0xb6, 0x19, 0x48,
2081 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x44, 0x04, 0x30, 0x11, 0x21, 0xd0, 0x0c,
2082 0x0b, 0x61, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3, 0x2f, 0x0e, 0x30, 0x88,
2083 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x50, 0x0d, 0x97, 0xef, 0x3c,
2084 0xbe, 0x04, 0x30, 0xcf, 0x42, 0x94, 0x44, 0x45, 0x2c, 0x7e, 0x71, 0xdb,
2085 0x26, 0x50, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x34, 0x39, 0x11, 0x81, 0x52,
2086 0xd3, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x00, 0x61, 0x20, 0x00, 0x00, 0x41,
2087 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x05,
2088 0x00, 0x00, 0x00, 0x54, 0x8d, 0x00, 0x10, 0x51, 0x0a, 0x25, 0x57, 0x76,
2089 0x33, 0x00, 0xc5, 0x47, 0x45, 0x09, 0xd0, 0x30, 0x03, 0x00, 0x00, 0x23,
2090 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x71, 0x46, 0xa4, 0x69, 0xc8, 0x88,
2091 0x41, 0x02, 0x80, 0x20, 0x18, 0x58, 0xdd, 0x01, 0x6d, 0x5b, 0x32, 0x62,
2092 0x90, 0x00, 0x20, 0x08, 0x06, 0x96, 0x87, 0x48, 0x1c, 0xa7, 0x8c, 0x18,
2093 0x24, 0x00, 0x08, 0x82, 0x81, 0x41, 0x06, 0x5a, 0xd7, 0x51, 0xc7, 0x88,
2094 0x41, 0x02, 0x80, 0x20, 0x18, 0x18, 0x65, 0xb0, 0x79, 0x9e, 0x81, 0x8c,
2095 0x18, 0x1c, 0x00, 0x08, 0x82, 0x01, 0x34, 0x06, 0xca, 0xf0, 0x8d, 0x26,
2096 0x04, 0xc0, 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x68, 0x02, 0x31,
2097 0x98, 0x70, 0xc8, 0xc7, 0x84, 0x43, 0x3e, 0x26, 0x18, 0xf0, 0x31, 0xc1,
2098 0x80, 0xcf, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x40, 0x6c, 0x30, 0x31,
2099 0x69, 0x30, 0x9a, 0x10, 0x04, 0x23, 0x06, 0x07, 0x00, 0x82, 0x60, 0x30,
2100 0xb5, 0x41, 0xe5, 0xac, 0xc1, 0x68, 0x42, 0x00, 0x5c, 0x30, 0xd4, 0x88,
2101 0xc1, 0x03, 0x80, 0x20, 0x18, 0x34, 0x72, 0x60, 0x4d, 0xd2, 0x61, 0x10,
2102 0x54, 0x1b, 0xb4, 0x41, 0x1b, 0x04, 0xa3, 0x09, 0x01, 0x30, 0x9a, 0x20,
2103 0x04, 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40, 0x0c, 0x23, 0x06, 0x09, 0x00,
2104 0x82, 0x60, 0x80, 0xe0, 0xc1, 0x27, 0x07, 0x72, 0x90, 0x06, 0xc4, 0x88,
2105 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, 0x78, 0xf0, 0xc9, 0x81, 0x1c, 0x68,
2106 0xc3, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, 0x78, 0xf0, 0xc9, 0x81,
2107 0x1c, 0xa0, 0x81, 0x30, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x08, 0x1e,
2108 0x7c, 0x72, 0x20, 0x07, 0x67, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
2109 0x00, 0x00, 0x00
2110};
2111#if 0
2112;
2113; Input signature:
2114;
2115; Name Index Mask Register SysValue Format Used
2116; -------------------- ----- ------ -------- -------- ------- ------
2117; TEXCOORD 0 xy 0 NONE float xy
2118; SV_Position 0 xyzw 1 POS float
2119;
2120;
2121; Output signature:
2122;
2123; Name Index Mask Register SysValue Format Used
2124; -------------------- ----- ------ -------- -------- ------- ------
2125; SV_Target 0 xyzw 0 TARGET float xyzw
2126;
2127; shader hash: e88bd1fd8f6be3ae3e613ed8989b06d7
2128;
2129; Pipeline Runtime Information:
2130;
2131; Pixel Shader
2132; DepthOutput=0
2133; SampleFrequency=0
2134;
2135;
2136; Input signature:
2137;
2138; Name Index InterpMode DynIdx
2139; -------------------- ----- ---------------------- ------
2140; TEXCOORD 0 linear
2141; SV_Position 0 noperspective
2142;
2143; Output signature:
2144;
2145; Name Index InterpMode DynIdx
2146; -------------------- ----- ---------------------- ------
2147; SV_Target 0
2148;
2149; Buffer Definitions:
2150;
2151; cbuffer SourceRegionBuffer
2152; {
2153;
2154; struct SourceRegionBuffer
2155; {
2156;
2157; float2 UVLeftTop; ; Offset: 0
2158; float2 UVDimensions; ; Offset: 8
2159; uint MipLevel; ; Offset: 16
2160; float LayerOrDepth; ; Offset: 20
2161;
2162; } SourceRegionBuffer; ; Offset: 0 Size: 24
2163;
2164; }
2165;
2166;
2167; Resource Bindings:
2168;
2169; Name Type Format Dim ID HLSL Bind Count
2170; ------------------------------ ---------- ------- ----------- ------- -------------- ------
2171; SourceRegionBuffer cbuffer NA NA CB0 cb0,space3 1
2172; SourceSampler sampler NA NA S0 s0,space2 1
2173; SourceTextureCube texture f32 cube T0 t0,space2 1
2174;
2175;
2176; ViewId state:
2177;
2178; Number of inputs: 8, outputs: 4
2179; Outputs dependent on ViewId: { }
2180; Inputs contributing to computation of Outputs:
2181; output 0 depends on inputs: { 0, 1 }
2182; output 1 depends on inputs: { 0, 1 }
2183; output 2 depends on inputs: { 0, 1 }
2184; output 3 depends on inputs: { 0, 1 }
2185;
2186target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
2187target triple = "dxil-ms-dx"
2188
2189%dx.types.Handle = type { i8* }
2190%dx.types.CBufRet.f32 = type { float, float, float, float }
2191%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
2192%dx.types.ResRet.f32 = type { float, float, float, float, i32 }
2193%"class.TextureCube<vector<float, 4> >" = type { <4 x float> }
2194%SourceRegionBuffer = type { <2 x float>, <2 x float>, i32, float }
2195%struct.SamplerState = type { i32 }
2196
2197define void @BlitFromCube() {
2198 %1 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
2199 %2 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 3, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
2200 %3 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
2201 %4 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
2202 %5 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
2203 %6 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %3, i32 0) ; CBufferLoadLegacy(handle,regIndex)
2204 %7 = extractvalue %dx.types.CBufRet.f32 %6, 0
2205 %8 = extractvalue %dx.types.CBufRet.f32 %6, 1
2206 %9 = extractvalue %dx.types.CBufRet.f32 %6, 2
2207 %10 = extractvalue %dx.types.CBufRet.f32 %6, 3
2208 %11 = fmul fast float %9, %4
2209 %12 = fmul fast float %10, %5
2210 %13 = fadd fast float %11, %7
2211 %14 = fadd fast float %12, %8
2212 %15 = fmul fast float %13, 2.000000e+00
2213 %16 = fadd fast float %15, -1.000000e+00
2214 %17 = fmul fast float %14, 2.000000e+00
2215 %18 = fadd fast float %17, -1.000000e+00
2216 %19 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %3, i32 1) ; CBufferLoadLegacy(handle,regIndex)
2217 %20 = extractvalue %dx.types.CBufRet.f32 %19, 1
2218 %21 = fptoui float %20 to i32
2219 switch i32 %21, label %35 [
2220 i32 0, label %22
2221 i32 1, label %25
2222 i32 2, label %27
2223 i32 3, label %29
2224 i32 4, label %30
2225 i32 5, label %32
2226 ]
2227
2228; <label>:22 ; preds = %0
2229 %23 = fsub fast float -0.000000e+00, %18
2230 %24 = fsub fast float -0.000000e+00, %16
2231 br label %35
2232
2233; <label>:25 ; preds = %0
2234 %26 = fsub fast float -0.000000e+00, %18
2235 br label %35
2236
2237; <label>:27 ; preds = %0
2238 %28 = fsub fast float -0.000000e+00, %18
2239 br label %35
2240
2241; <label>:29 ; preds = %0
2242 br label %35
2243
2244; <label>:30 ; preds = %0
2245 %31 = fsub fast float -0.000000e+00, %18
2246 br label %35
2247
2248; <label>:32 ; preds = %0
2249 %33 = fsub fast float -0.000000e+00, %16
2250 %34 = fsub fast float -0.000000e+00, %18
2251 br label %35
2252
2253; <label>:35 ; preds = %32, %30, %29, %27, %25, %22, %0
2254 %36 = phi float [ %33, %32 ], [ %16, %30 ], [ %16, %29 ], [ %16, %27 ], [ -1.000000e+00, %25 ], [ 1.000000e+00, %22 ], [ 0.000000e+00, %0 ]
2255 %37 = phi float [ %34, %32 ], [ %31, %30 ], [ -1.000000e+00, %29 ], [ 1.000000e+00, %27 ], [ %26, %25 ], [ %23, %22 ], [ 0.000000e+00, %0 ]
2256 %38 = phi float [ -1.000000e+00, %32 ], [ 1.000000e+00, %30 ], [ %18, %29 ], [ %28, %27 ], [ %16, %25 ], [ %24, %22 ], [ 0.000000e+00, %0 ]
2257 %39 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %3, i32 1) ; CBufferLoadLegacy(handle,regIndex)
2258 %40 = extractvalue %dx.types.CBufRet.i32 %39, 0
2259 %41 = uitofp i32 %40 to float
2260 %42 = call %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32 62, %dx.types.Handle %1, %dx.types.Handle %2, float %36, float %37, float %38, float undef, i32 undef, i32 undef, i32 undef, float %41) ; SampleLevel(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,LOD)
2261 %43 = extractvalue %dx.types.ResRet.f32 %42, 0
2262 %44 = extractvalue %dx.types.ResRet.f32 %42, 1
2263 %45 = extractvalue %dx.types.ResRet.f32 %42, 2
2264 %46 = extractvalue %dx.types.ResRet.f32 %42, 3
2265 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %43) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
2266 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %44) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
2267 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %45) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
2268 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %46) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
2269 ret void
2270}
2271
2272; Function Attrs: nounwind readnone
2273declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
2274
2275; Function Attrs: nounwind
2276declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
2277
2278; Function Attrs: nounwind readonly
2279declare %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32, %dx.types.Handle, %dx.types.Handle, float, float, float, float, i32, i32, i32, float) #2
2280
2281; Function Attrs: nounwind readonly
2282declare %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32, %dx.types.Handle, i32) #2
2283
2284; Function Attrs: nounwind readonly
2285declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #2
2286
2287; Function Attrs: nounwind readonly
2288declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #2
2289
2290attributes #0 = { nounwind readnone }
2291attributes #1 = { nounwind }
2292attributes #2 = { nounwind readonly }
2293
2294!llvm.ident = !{!0}
2295!dx.version = !{!1}
2296!dx.valver = !{!2}
2297!dx.shaderModel = !{!3}
2298!dx.resources = !{!4}
2299!dx.viewIdState = !{!12}
2300!dx.entryPoints = !{!13}
2301
2302!0 = !{!"clang version 3.7 (tags/RELEASE_370/final)"}
2303!1 = !{i32 1, i32 0}
2304!2 = !{i32 1, i32 6}
2305!3 = !{!"ps", i32 6, i32 0}
2306!4 = !{!5, null, !8, !10}
2307!5 = !{!6}
2308!6 = !{i32 0, %"class.TextureCube<vector<float, 4> >"* undef, !"", i32 2, i32 0, i32 1, i32 5, i32 0, !7}
2309!7 = !{i32 0, i32 9}
2310!8 = !{!9}
2311!9 = !{i32 0, %SourceRegionBuffer* undef, !"", i32 3, i32 0, i32 1, i32 24, null}
2312!10 = !{!11}
2313!11 = !{i32 0, %struct.SamplerState* undef, !"", i32 2, i32 0, i32 1, i32 0, null}
2314!12 = !{[10 x i32] [i32 8, i32 4, i32 15, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0]}
2315!13 = !{void ()* @BlitFromCube, !"BlitFromCube", !14, !4, null}
2316!14 = !{!15, !20, null}
2317!15 = !{!16, !19}
2318!16 = !{i32 0, !"TEXCOORD", i8 9, i8 0, !17, i8 2, i32 1, i8 2, i32 0, i8 0, !18}
2319!17 = !{i32 0}
2320!18 = !{i32 3, i32 3}
2321!19 = !{i32 1, !"SV_Position", i8 9, i8 3, !17, i8 4, i32 1, i8 4, i32 1, i8 0, null}
2322!20 = !{!21}
2323!21 = !{i32 0, !"SV_Target", i8 9, i8 16, !17, i8 0, i32 1, i8 4, i32 0, i8 0, !22}
2324!22 = !{i32 3, i32 15}
2325
2326#endif
2327
2328const unsigned char g_BlitFromCube[] = {
2329 0x44, 0x58, 0x42, 0x43, 0xaf, 0x86, 0xcc, 0x12, 0xb2, 0xe2, 0x55, 0xc6,
2330 0x30, 0x3a, 0x18, 0x47, 0x98, 0xfe, 0x96, 0xb7, 0x01, 0x00, 0x00, 0x00,
2331 0x97, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
2332 0x50, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00,
2333 0xe7, 0x01, 0x00, 0x00, 0x77, 0x02, 0x00, 0x00, 0x3b, 0x0a, 0x00, 0x00,
2334 0x57, 0x0a, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
2335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31,
2336 0x5d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
2337 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2338 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2339 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2340 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2341 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
2342 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44,
2343 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
2344 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
2345 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
2346 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
2347 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2348 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x50,
2349 0x53, 0x56, 0x30, 0xf0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
2350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
2352 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
2353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
2354 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
2355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
2356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
2357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,
2358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
2359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
2360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
2361 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x00, 0x00, 0x01,
2362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
2363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x03,
2364 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
2365 0x01, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2366 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, 0x00, 0x0f,
2367 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x88,
2370 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18,
2371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00,
2372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c,
2373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5c,
2374 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x7c,
2375 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03,
2376 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
2377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01,
2378 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
2379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
2380 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x03,
2381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x54, 0x41, 0x54, 0xbc,
2382 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xef, 0x01, 0x00, 0x00, 0x44,
2383 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xa4,
2384 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xe6,
2385 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
2386 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06,
2387 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e,
2388 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4,
2389 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48,
2390 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4,
2391 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1,
2392 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08,
2393 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40,
2394 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d,
2395 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49,
2396 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20,
2397 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x47,
2398 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13,
2399 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12,
2400 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x88, 0xc1, 0x08, 0x40,
2401 0x09, 0x00, 0x0a, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29,
2402 0xc6, 0x40, 0x10, 0x44, 0x41, 0x90, 0x51, 0x0c, 0x80, 0x20, 0x88, 0x62,
2403 0x20, 0xe4, 0xa6, 0xe1, 0xf2, 0x27, 0xec, 0x21, 0x24, 0x7f, 0x25, 0xa4,
2404 0x95, 0x98, 0xfc, 0xe2, 0xb6, 0x51, 0x31, 0x0c, 0xc3, 0x40, 0x50, 0x71,
2405 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, 0x10,
2406 0x28, 0x58, 0x0a, 0xa3, 0x10, 0x0c, 0x33, 0x0c, 0xc3, 0x40, 0x10, 0xc4,
2407 0x40, 0xcd, 0x51, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, 0x3e, 0xb7, 0x51,
2408 0xc5, 0x4a, 0x4c, 0x7e, 0x71, 0xdb, 0x88, 0x18, 0x86, 0x61, 0x28, 0xc4,
2409 0x43, 0x30, 0x04, 0x41, 0x47, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9,
2410 0xdc, 0x46, 0x15, 0x2b, 0x31, 0xf9, 0xc8, 0x6d, 0x23, 0x82, 0x20, 0x08,
2411 0xa2, 0x10, 0x12, 0xc1, 0x10, 0x34, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0x88,
2412 0x82, 0x20, 0x2a, 0xb2, 0x06, 0x02, 0x86, 0x11, 0x88, 0x61, 0x26, 0x32,
2413 0x18, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07, 0x37, 0xa0, 0x85, 0x72,
2414 0xc0, 0x07, 0x7a, 0xa8, 0x07, 0x79, 0x28, 0x87, 0x51, 0xa8, 0x07, 0x71,
2415 0x28, 0x07, 0x3e, 0xb0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79,
2416 0xe0, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x60, 0x03, 0x30,
2417 0xa0, 0x03, 0x3f, 0x00, 0x03, 0x3f, 0x40, 0x41, 0x46, 0xda, 0x30, 0x82,
2418 0x30, 0x9c, 0xc4, 0x3a, 0x54, 0x24, 0x10, 0x2b, 0x61, 0x20, 0x4e, 0xb3,
2419 0x51, 0x45, 0x41, 0x44, 0x88, 0xe0, 0x38, 0x62, 0xa0, 0xee, 0x26, 0x69,
2420 0x8a, 0x28, 0x61, 0xf2, 0x59, 0x80, 0x79, 0x16, 0x22, 0x62, 0x27, 0x60,
2421 0x22, 0x50, 0x40, 0xd0, 0x97, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13,
2422 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68,
2423 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a,
2424 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73,
2425 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d,
2426 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71,
2427 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72,
2428 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a,
2429 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73,
2430 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72,
2431 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d,
2432 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72,
2433 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x08, 0x00, 0x00, 0x00,
2434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01,
2435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00,
2436 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40,
2437 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x81,
2438 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8,
2439 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
2440 0x90, 0xc7, 0x02, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2441 0x80, 0x2c, 0x10, 0x14, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19,
2442 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x22, 0x4a,
2443 0x60, 0x04, 0xa0, 0x18, 0x8a, 0xa0, 0x14, 0x4a, 0xa2, 0x0c, 0x0a, 0xa6,
2444 0x1c, 0x0a, 0xa2, 0x40, 0x0a, 0xa5, 0x3c, 0x4a, 0xa4, 0xcc, 0x0a, 0x81,
2445 0x8a, 0x92, 0x18, 0x01, 0x28, 0x82, 0x32, 0x28, 0x84, 0x02, 0xa1, 0xaa,
2446 0x06, 0x68, 0x9b, 0x01, 0xa0, 0x6e, 0x06, 0x80, 0xbc, 0x19, 0x00, 0x02,
2447 0x67, 0x00, 0x28, 0x1c, 0x4b, 0x41, 0x88, 0xe7, 0x01, 0x00, 0x00, 0x00,
2448 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x1a,
2449 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73,
2450 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71,
2451 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a,
2452 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b,
2453 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0xe2, 0x98, 0x20, 0x10, 0xc8,
2454 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, 0x41, 0x01, 0x6e, 0x6e, 0x82, 0x40,
2455 0x24, 0x1b, 0x86, 0x03, 0x21, 0x26, 0x08, 0x9b, 0xc7, 0x68, 0xea, 0xad,
2456 0x4e, 0x6e, 0xac, 0x8c, 0xaa, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x6c, 0xa8,
2457 0x4e, 0xac, 0x6c, 0x82, 0x40, 0x28, 0x13, 0x04, 0x62, 0x99, 0x20, 0x10,
2458 0xcc, 0x06, 0x81, 0x70, 0x36, 0x24, 0x84, 0xb2, 0x30, 0xc4, 0xd0, 0x10,
2459 0xcf, 0x86, 0x00, 0x9a, 0x20, 0x78, 0x60, 0x40, 0x69, 0xea, 0xad, 0x4e,
2460 0x6e, 0xac, 0x4c, 0xaa, 0xec, 0x2c, 0xed, 0xcd, 0x4d, 0xa8, 0xce, 0xcc,
2461 0xac, 0x4c, 0x6e, 0x82, 0x40, 0x34, 0x13, 0x04, 0xc2, 0xd9, 0x80, 0x10,
2462 0xd2, 0x44, 0x11, 0x43, 0x05, 0x6c, 0x08, 0xac, 0x09, 0x02, 0x18, 0x84,
2463 0x01, 0x9b, 0xa9, 0xb7, 0x3a, 0xb9, 0xb1, 0xb2, 0xa9, 0xb0, 0x36, 0x38,
2464 0xb6, 0x32, 0xb9, 0x0d, 0x08, 0x81, 0x65, 0x0c, 0x31, 0x10, 0xc0, 0x86,
2465 0x40, 0xdb, 0x40, 0x44, 0xc0, 0xb5, 0x4d, 0x10, 0xba, 0x8f, 0x49, 0x95,
2466 0x15, 0x53, 0x99, 0x19, 0x1d, 0xd5, 0x1b, 0xdc, 0x04, 0x81, 0x78, 0x26,
2467 0x08, 0x55, 0xb7, 0x01, 0x41, 0x3c, 0x8a, 0xf8, 0x1c, 0x07, 0x0c, 0xc8,
2468 0x54, 0x59, 0x11, 0xa5, 0xb5, 0x95, 0xb9, 0xcd, 0xa5, 0xbd, 0xb9, 0xcd,
2469 0x4d, 0x10, 0x08, 0x68, 0x03, 0x82, 0x88, 0x01, 0x35, 0x06, 0x9f, 0xe3,
2470 0x80, 0x01, 0x91, 0xa6, 0x34, 0x38, 0xa6, 0x32, 0xbb, 0x32, 0xb6, 0x09,
2471 0x02, 0x11, 0x6d, 0x40, 0x90, 0x32, 0xa0, 0xcc, 0xe0, 0x6b, 0x1c, 0x30,
2472 0x20, 0xc3, 0x14, 0x96, 0x57, 0x26, 0xf7, 0x24, 0x47, 0x54, 0x06, 0x47,
2473 0x87, 0x36, 0x41, 0x20, 0xa4, 0x0d, 0x08, 0x82, 0x06, 0x54, 0x1a, 0x7c,
2474 0x8e, 0x03, 0x06, 0x1b, 0x8a, 0x2a, 0x0c, 0xc8, 0xe0, 0x0c, 0xd4, 0x60,
2475 0xc3, 0x40, 0x74, 0x6b, 0x30, 0x41, 0x10, 0x80, 0x0d, 0xc0, 0x86, 0x81,
2476 0x70, 0x03, 0x37, 0xd8, 0x10, 0xbc, 0xc1, 0x86, 0x61, 0x68, 0x03, 0x38,
2477 0x98, 0x20, 0x84, 0x81, 0x18, 0x6c, 0x08, 0xe4, 0x80, 0x8c, 0x10, 0x5b,
2478 0x1a, 0x9d, 0x91, 0xdc, 0x5b, 0xdb, 0x50, 0x9d, 0x58, 0x19, 0x11, 0xaa,
2479 0x22, 0xac, 0xa1, 0xa7, 0x27, 0x29, 0xa2, 0x09, 0x42, 0x71, 0x4d, 0x10,
2480 0x0a, 0x6c, 0x43, 0x40, 0x4c, 0x10, 0x8a, 0x6c, 0x83, 0x40, 0x51, 0x1b,
2481 0x16, 0xa2, 0x0e, 0xec, 0xe0, 0x0e, 0xf0, 0x20, 0x0f, 0x86, 0x3c, 0x20,
2482 0xee, 0x40, 0x0f, 0xb8, 0x4c, 0x59, 0x7d, 0x41, 0xbd, 0xcd, 0xa5, 0xd1,
2483 0xa5, 0xbd, 0xb9, 0x4d, 0x10, 0x0a, 0x6d, 0x82, 0x50, 0x6c, 0x1b, 0x96,
2484 0x81, 0x0f, 0xec, 0xa0, 0x0f, 0xf0, 0xc0, 0x0f, 0x06, 0x3f, 0x18, 0xee,
2485 0x00, 0xd8, 0x20, 0xec, 0xc1, 0x1f, 0x30, 0x99, 0xb2, 0xfa, 0xa2, 0x0a,
2486 0x93, 0x3b, 0x2b, 0xa3, 0x9b, 0x20, 0x14, 0xdc, 0x04, 0x81, 0x98, 0x36,
2487 0x08, 0xd4, 0x28, 0x6c, 0x58, 0x88, 0x50, 0xb0, 0x03, 0x51, 0xc0, 0x83,
2488 0x3b, 0x18, 0xfc, 0x80, 0xb8, 0x03, 0x52, 0xd8, 0x10, 0x94, 0xc2, 0x86,
2489 0x01, 0x14, 0x4c, 0x01, 0xd8, 0x50, 0xb4, 0x01, 0x1d, 0x9c, 0x02, 0x07,
2490 0xd0, 0x30, 0x63, 0x7b, 0x0b, 0xa3, 0x9b, 0x9b, 0x20, 0x10, 0x14, 0x8b,
2491 0x34, 0xb7, 0x39, 0xba, 0xb9, 0x09, 0x02, 0x51, 0xd1, 0x98, 0x4b, 0x3b,
2492 0xfb, 0x62, 0x23, 0xa3, 0x31, 0x97, 0x76, 0xf6, 0x35, 0x47, 0x37, 0x41,
2493 0x20, 0x2c, 0x22, 0x74, 0x65, 0x78, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x1b,
2494 0x94, 0x54, 0x50, 0x85, 0x55, 0x60, 0x85, 0x56, 0x60, 0x5c, 0xe1, 0x15,
2495 0x60, 0x61, 0xa8, 0xc2, 0xc6, 0x66, 0xd7, 0xe6, 0x92, 0x46, 0x56, 0xe6,
2496 0x46, 0x37, 0x25, 0x08, 0xaa, 0x90, 0xe1, 0xb9, 0xd8, 0x95, 0xc9, 0xcd,
2497 0xa5, 0xbd, 0xb9, 0x4d, 0x09, 0x88, 0x26, 0x64, 0x78, 0x2e, 0x76, 0x61,
2498 0x6c, 0x76, 0x65, 0x72, 0x53, 0x82, 0xa2, 0x0e, 0x19, 0x9e, 0xcb, 0x1c,
2499 0x5a, 0x18, 0x59, 0x99, 0x5c, 0xd3, 0x1b, 0x59, 0x19, 0xdb, 0x94, 0x00,
2500 0x29, 0x43, 0x86, 0xe7, 0x22, 0x57, 0x36, 0xf7, 0x56, 0x27, 0x37, 0x56,
2501 0x36, 0x37, 0x25, 0xd8, 0x2a, 0x91, 0xe1, 0xb9, 0xd0, 0xe5, 0xc1, 0x95,
2502 0x05, 0xb9, 0xb9, 0xbd, 0xd1, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0xcd, 0x4d,
2503 0x11, 0xd6, 0x00, 0x0e, 0xea, 0x90, 0xe1, 0xb9, 0xd8, 0xa5, 0x95, 0xdd,
2504 0x25, 0x91, 0x4d, 0xd1, 0x85, 0xd1, 0x95, 0x4d, 0x09, 0xe4, 0xa0, 0x0e,
2505 0x19, 0x9e, 0x4b, 0x99, 0x1b, 0x9d, 0x5c, 0x1e, 0xd4, 0x5b, 0x9a, 0x1b,
2506 0xdd, 0xdc, 0x94, 0xe0, 0x14, 0xba, 0x90, 0xe1, 0xb9, 0x8c, 0xbd, 0xd5,
2507 0xb9, 0xd1, 0x95, 0xc9, 0xcd, 0x4d, 0x09, 0x60, 0x01, 0x00, 0x00, 0x79,
2508 0x18, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4,
2509 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c,
2510 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00,
2511 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2,
2512 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38,
2513 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d,
2514 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87,
2515 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87,
2516 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30,
2517 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde,
2518 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b,
2519 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c,
2520 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07,
2521 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87,
2522 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87,
2523 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87,
2524 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0,
2525 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc,
2526 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4,
2527 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39,
2528 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38,
2529 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b,
2530 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03,
2531 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0,
2532 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0,
2533 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x30, 0x83, 0x81, 0xc8,
2534 0x01, 0x1f, 0xdc, 0x40, 0x1c, 0xe4, 0xa1, 0x1c, 0xc2, 0x61, 0x1d, 0xdc,
2535 0x40, 0x1c, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x20,
2536 0x00, 0x00, 0x00, 0x06, 0xc0, 0x6c, 0x0b, 0x32, 0x7d, 0x91, 0xc3, 0x70,
2537 0x54, 0x40, 0x18, 0xc1, 0x36, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x40, 0x15,
2538 0x05, 0x11, 0x95, 0x0e, 0x30, 0x94, 0x84, 0x01, 0x08, 0x98, 0x5f, 0xdc,
2539 0xb6, 0x15, 0x6c, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x04, 0x54, 0x51, 0x10,
2540 0x51, 0xe9, 0x00, 0x43, 0x49, 0x18, 0x80, 0x80, 0xf9, 0xc8, 0x6d, 0x9b,
2541 0x81, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44, 0x00, 0x13, 0x11, 0x02,
2542 0xcd, 0xb0, 0x10, 0x16, 0x30, 0x0d, 0x97, 0xef, 0x3c, 0xfe, 0xe2, 0x00,
2543 0x83, 0xd8, 0x3c, 0xd4, 0xe4, 0x17, 0xb7, 0x6d, 0x03, 0xd5, 0x70, 0xf9,
2544 0xce, 0xe3, 0x4b, 0x00, 0xf3, 0x2c, 0x44, 0x49, 0x54, 0xc4, 0xe2, 0x17,
2545 0xb7, 0x6d, 0x02, 0xd5, 0x70, 0xf9, 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11,
2546 0x28, 0x35, 0x3d, 0xd4, 0xe4, 0x17, 0xb7, 0x0d, 0x00, 0x00, 0x00, 0x00,
2547 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00,
2548 0x00, 0x00, 0x00, 0xe8, 0x8b, 0xd1, 0xfd, 0x8f, 0x6b, 0xe3, 0xae, 0x3e,
2549 0x61, 0x3e, 0xd8, 0x98, 0x9b, 0x06, 0xd7, 0x44, 0x58, 0x49, 0x4c, 0x38,
2550 0x08, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x0e, 0x02, 0x00, 0x00, 0x44,
2551 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20,
2552 0x08, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x05,
2553 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
2554 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06,
2555 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e,
2556 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4,
2557 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48,
2558 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4,
2559 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1,
2560 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08,
2561 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40,
2562 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d,
2563 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49,
2564 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20,
2565 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x47,
2566 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13,
2567 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12,
2568 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x8c, 0xc1, 0x08, 0x40,
2569 0x09, 0x00, 0x0a, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29,
2570 0xc6, 0x40, 0x10, 0x44, 0x41, 0x90, 0x51, 0x0c, 0x80, 0x20, 0x88, 0x62,
2571 0x20, 0xe4, 0xa6, 0xe1, 0xf2, 0x27, 0xec, 0x21, 0x24, 0x7f, 0x25, 0xa4,
2572 0x95, 0x98, 0xfc, 0xe2, 0xb6, 0x51, 0x31, 0x0c, 0xc3, 0x40, 0x50, 0x71,
2573 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, 0x10,
2574 0x28, 0x58, 0x0a, 0xa3, 0x10, 0x0c, 0x33, 0x0c, 0xc3, 0x40, 0x10, 0xc4,
2575 0x40, 0xcd, 0x51, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, 0x3e, 0xb7, 0x51,
2576 0xc5, 0x4a, 0x4c, 0x7e, 0x71, 0xdb, 0x88, 0x18, 0x86, 0x61, 0x28, 0xc4,
2577 0x43, 0x30, 0x04, 0x41, 0x47, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9,
2578 0xdc, 0x46, 0x15, 0x2b, 0x31, 0xf9, 0xc8, 0x6d, 0x23, 0x82, 0x20, 0x08,
2579 0xa2, 0x10, 0x12, 0xc1, 0x10, 0x34, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0x88,
2580 0x82, 0x20, 0x2a, 0xb2, 0x06, 0x02, 0x86, 0x11, 0x88, 0x61, 0x26, 0x32,
2581 0x18, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07, 0x37, 0xa0, 0x85, 0x72,
2582 0xc0, 0x07, 0x7a, 0xa8, 0x07, 0x79, 0x28, 0x87, 0x51, 0xa8, 0x07, 0x71,
2583 0x28, 0x07, 0x3e, 0xb0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79,
2584 0xe0, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x60, 0x03, 0x30,
2585 0xa0, 0x03, 0x3f, 0x00, 0x03, 0x3f, 0x40, 0x41, 0x46, 0xda, 0x30, 0x82,
2586 0x30, 0x9c, 0xc4, 0x3a, 0x54, 0x24, 0x10, 0x2b, 0x61, 0x20, 0x4e, 0xb3,
2587 0x51, 0x45, 0x41, 0x44, 0x88, 0xe0, 0x38, 0x62, 0xa0, 0xee, 0x26, 0x69,
2588 0x8a, 0x28, 0x61, 0xf2, 0x59, 0x80, 0x79, 0x16, 0x22, 0x62, 0x27, 0x60,
2589 0x22, 0x50, 0x40, 0xd0, 0x97, 0x0a, 0xc4, 0x14, 0x00, 0x00, 0x00, 0x13,
2590 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68,
2591 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a,
2592 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73,
2593 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d,
2594 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71,
2595 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72,
2596 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a,
2597 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73,
2598 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72,
2599 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d,
2600 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72,
2601 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00,
2602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01,
2603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00,
2604 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40,
2605 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x81,
2606 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8,
2607 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
2608 0x90, 0xc7, 0x02, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2609 0x80, 0x2c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19,
2610 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x22, 0x4a,
2611 0x60, 0x04, 0xa0, 0x18, 0x8a, 0xa0, 0x14, 0x4a, 0xa2, 0x0c, 0x0a, 0xa6,
2612 0x3c, 0xa8, 0x28, 0x89, 0x11, 0x80, 0x22, 0x28, 0x83, 0x42, 0x28, 0x10,
2613 0xda, 0x66, 0x00, 0xc8, 0x9b, 0x01, 0x20, 0x70, 0x06, 0x80, 0xc2, 0xb1,
2614 0x14, 0x84, 0x78, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79,
2615 0x18, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46,
2616 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b,
2617 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1,
2618 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa,
2619 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10,
2620 0x04, 0x13, 0x04, 0xe2, 0x98, 0x20, 0x10, 0xc8, 0x06, 0x61, 0x20, 0x26,
2621 0x08, 0x44, 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x1b, 0x06, 0xc4,
2622 0x20, 0x26, 0x08, 0x9b, 0x45, 0x60, 0x82, 0x40, 0x28, 0x13, 0x04, 0x62,
2623 0x99, 0x20, 0x10, 0xcc, 0x06, 0x81, 0x70, 0x36, 0x24, 0x84, 0xb2, 0x30,
2624 0xc4, 0xd0, 0x10, 0xcf, 0x86, 0x00, 0x9a, 0x20, 0x78, 0xd7, 0x04, 0x81,
2625 0x68, 0x26, 0x08, 0x84, 0xb3, 0x01, 0x21, 0xa4, 0x65, 0x22, 0x06, 0x0a,
2626 0xd8, 0x10, 0x54, 0x13, 0x04, 0x30, 0xc0, 0x36, 0x20, 0xc4, 0xb5, 0x30,
2627 0xc4, 0x40, 0x00, 0x1b, 0x02, 0x6c, 0x03, 0x11, 0x01, 0x56, 0x36, 0x41,
2628 0x08, 0x83, 0x6c, 0x43, 0xb0, 0x4d, 0x10, 0x04, 0x80, 0x8c, 0x10, 0x5b,
2629 0x1a, 0x9d, 0x91, 0xdc, 0x5b, 0xdb, 0x50, 0x9d, 0x58, 0x19, 0x11, 0xaa,
2630 0x22, 0xac, 0xa1, 0xa7, 0x27, 0x29, 0xa2, 0x09, 0x42, 0x01, 0x4d, 0x10,
2631 0x8a, 0x68, 0x43, 0x40, 0x4c, 0x10, 0x0a, 0x69, 0x83, 0x30, 0x4d, 0x1b,
2632 0x16, 0xe2, 0x03, 0x83, 0x30, 0x10, 0x83, 0x31, 0x18, 0xc6, 0x80, 0x08,
2633 0x03, 0x32, 0xe0, 0x32, 0x65, 0xf5, 0x05, 0xf5, 0x36, 0x97, 0x46, 0x97,
2634 0xf6, 0xe6, 0x36, 0x41, 0x28, 0xa6, 0x09, 0x42, 0x41, 0x6d, 0x58, 0x06,
2635 0x33, 0x00, 0x83, 0x33, 0x10, 0x03, 0x34, 0x18, 0xd0, 0x60, 0x08, 0x03,
2636 0x60, 0x83, 0x50, 0x06, 0x69, 0xc0, 0x64, 0xca, 0xea, 0x8b, 0x2a, 0x4c,
2637 0xee, 0xac, 0x8c, 0x6e, 0x82, 0x50, 0x54, 0x13, 0x04, 0xe2, 0xd9, 0x20,
2638 0x4c, 0x6d, 0xb0, 0x61, 0x21, 0xd6, 0x00, 0x0c, 0xd8, 0x40, 0x0c, 0xc2,
2639 0x60, 0x40, 0x03, 0x22, 0x0c, 0xdc, 0x60, 0x43, 0xf0, 0x06, 0x1b, 0x06,
2640 0x35, 0x80, 0x03, 0x60, 0x43, 0xd1, 0x79, 0x71, 0xa0, 0x01, 0x55, 0xd8,
2641 0xd8, 0xec, 0xda, 0x5c, 0xd2, 0xc8, 0xca, 0xdc, 0xe8, 0xa6, 0x04, 0x41,
2642 0x15, 0x32, 0x3c, 0x17, 0xbb, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x29,
2643 0x01, 0xd1, 0x84, 0x0c, 0xcf, 0xc5, 0x2e, 0x8c, 0xcd, 0xae, 0x4c, 0x6e,
2644 0x4a, 0x60, 0xd4, 0x21, 0xc3, 0x73, 0x99, 0x43, 0x0b, 0x23, 0x2b, 0x93,
2645 0x6b, 0x7a, 0x23, 0x2b, 0x63, 0x9b, 0x12, 0x20, 0x65, 0xc8, 0xf0, 0x5c,
2646 0xe4, 0xca, 0xe6, 0xde, 0xea, 0xe4, 0xc6, 0xca, 0xe6, 0xa6, 0x04, 0x59,
2647 0x1d, 0x32, 0x3c, 0x17, 0xbb, 0xb4, 0xb2, 0xbb, 0x24, 0xb2, 0x29, 0xba,
2648 0x30, 0xba, 0xb2, 0x29, 0xc1, 0x56, 0x87, 0x0c, 0xcf, 0xa5, 0xcc, 0x8d,
2649 0x4e, 0x2e, 0x0f, 0xea, 0x2d, 0xcd, 0x8d, 0x6e, 0x6e, 0x4a, 0x10, 0x07,
2650 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x33,
2651 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43,
2652 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98,
2653 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33,
2654 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05,
2655 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43,
2656 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08,
2657 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78,
2658 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1,
2659 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33,
2660 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e,
2661 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03,
2662 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60,
2663 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80,
2664 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8,
2665 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18,
2666 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee,
2667 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c,
2668 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c,
2669 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43,
2670 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3,
2671 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83,
2672 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21,
2673 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1,
2674 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6,
2675 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4,
2676 0x30, 0x83, 0x81, 0xc8, 0x01, 0x1f, 0xdc, 0x40, 0x1c, 0xe4, 0xa1, 0x1c,
2677 0xc2, 0x61, 0x1d, 0xdc, 0x40, 0x1c, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x71,
2678 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0xc0, 0x6c, 0x0b, 0x32,
2679 0x7d, 0x91, 0xc3, 0x70, 0x54, 0x40, 0x18, 0xc1, 0x36, 0x5c, 0xbe, 0xf3,
2680 0xf8, 0x42, 0x40, 0x15, 0x05, 0x11, 0x95, 0x0e, 0x30, 0x94, 0x84, 0x01,
2681 0x08, 0x98, 0x5f, 0xdc, 0xb6, 0x15, 0x6c, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f,
2682 0x04, 0x54, 0x51, 0x10, 0x51, 0xe9, 0x00, 0x43, 0x49, 0x18, 0x80, 0x80,
2683 0xf9, 0xc8, 0x6d, 0x9b, 0x81, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44,
2684 0x00, 0x13, 0x11, 0x02, 0xcd, 0xb0, 0x10, 0x16, 0x30, 0x0d, 0x97, 0xef,
2685 0x3c, 0xfe, 0xe2, 0x00, 0x83, 0xd8, 0x3c, 0xd4, 0xe4, 0x17, 0xb7, 0x6d,
2686 0x03, 0xd5, 0x70, 0xf9, 0xce, 0xe3, 0x4b, 0x00, 0xf3, 0x2c, 0x44, 0x49,
2687 0x54, 0xc4, 0xe2, 0x17, 0xb7, 0x6d, 0x02, 0xd5, 0x70, 0xf9, 0xce, 0xe3,
2688 0x4b, 0x93, 0x13, 0x11, 0x28, 0x35, 0x3d, 0xd4, 0xe4, 0x17, 0xb7, 0x0d,
2689 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x13,
2690 0x04, 0x48, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x54,
2691 0x8d, 0x00, 0x50, 0x51, 0x02, 0x44, 0x14, 0x5f, 0xd9, 0x15, 0x42, 0xc9,
2692 0xcd, 0x00, 0xd0, 0x30, 0x03, 0x30, 0x46, 0x00, 0x82, 0x20, 0x08, 0x82,
2693 0xc1, 0x08, 0xc0, 0x18, 0x01, 0x08, 0x82, 0x20, 0xfe, 0x8d, 0x11, 0x80,
2694 0x20, 0x08, 0xe2, 0xbf, 0x30, 0x46, 0x00, 0x82, 0x20, 0x08, 0x82, 0x02,
2695 0x00, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x85, 0x01,
2696 0x62, 0x7d, 0x5f, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x96, 0x18,
2697 0x24, 0x15, 0x18, 0x80, 0x81, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06,
2698 0xd6, 0x18, 0x28, 0x57, 0x18, 0x84, 0xc1, 0x33, 0x62, 0x90, 0x00, 0x20,
2699 0x08, 0x06, 0x46, 0x1a, 0x30, 0x62, 0x20, 0x06, 0x99, 0x32, 0x62, 0x90,
2700 0x00, 0x20, 0x08, 0x06, 0x86, 0x1a, 0x34, 0x63, 0x30, 0x06, 0xd0, 0x32,
2701 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0x10, 0x1a, 0x3c, 0x03, 0x19, 0x8c,
2702 0x26, 0x04, 0xc0, 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x68, 0x02,
2703 0x31, 0x98, 0x70, 0xc8, 0xc7, 0x84, 0x43, 0x3e, 0x26, 0x18, 0xf0, 0x31,
2704 0xc1, 0x80, 0x8f, 0x09, 0x93, 0x7c, 0x2c, 0x88, 0xe0, 0x63, 0x43, 0x25,
2705 0x1f, 0x0b, 0x26, 0xf8, 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82, 0x01, 0x54,
2706 0x07, 0x1c, 0x24, 0x07, 0xa3, 0x09, 0x41, 0x70, 0x01, 0x31, 0xc3, 0x3c,
2707 0x44, 0x70, 0x20, 0xc1, 0x21, 0x28, 0x43, 0x43, 0x78, 0xc5, 0x62, 0x98,
2708 0x45, 0xc4, 0xc7, 0xae, 0x23, 0x3e, 0xb3, 0x04, 0x87, 0x61, 0x46, 0x7c,
2709 0x66, 0x09, 0x0e, 0xcb, 0x8e, 0xf8, 0xcc, 0x12, 0x1c, 0xb3, 0x04, 0x87,
2710 0x69, 0x48, 0x7c, 0x66, 0x09, 0x0e, 0xdb, 0x96, 0xf8, 0x18, 0xa7, 0xc4,
2711 0x67, 0x96, 0xe0, 0x18, 0xe8, 0x19, 0x08, 0x43, 0x2b, 0x34, 0x42, 0x1b,
2712 0xf8, 0x40, 0xf0, 0x83, 0x00, 0x14, 0x80, 0x81, 0x9e, 0x81, 0x30, 0x90,
2713 0xc2, 0x0f, 0x08, 0x50, 0x18, 0x18, 0x01, 0x0a, 0x44, 0x01, 0x18, 0xe8,
2714 0x19, 0x40, 0xc1, 0x10, 0x85, 0x42, 0x23, 0x98, 0xc1, 0x13, 0xa0, 0x80,
2715 0x14, 0x80, 0x11, 0x83, 0x03, 0x00, 0x41, 0x30, 0x98, 0x42, 0x21, 0x0d,
2716 0xba, 0x3f, 0x18, 0x4d, 0x08, 0x80, 0x0b, 0x86, 0x1a, 0x31, 0x78, 0x00,
2717 0x10, 0x04, 0x83, 0xc6, 0x14, 0xda, 0x40, 0x0c, 0xc2, 0xc0, 0x28, 0x08,
2718 0x34, 0x48, 0x83, 0x34, 0x48, 0x83, 0x60, 0x34, 0x21, 0x00, 0x46, 0x13,
2719 0x84, 0x60, 0x34, 0x61, 0x10, 0x46, 0x13, 0x88, 0x61, 0xc4, 0x20, 0x01,
2720 0x40, 0x10, 0x0c, 0x10, 0x56, 0x18, 0x05, 0x53, 0x30, 0x85, 0x3e, 0x20,
2721 0x46, 0x0c, 0x12, 0x00, 0x04, 0xc1, 0x00, 0x61, 0x85, 0x51, 0x30, 0x05,
2722 0x53, 0x98, 0x83, 0x61, 0xc4, 0x20, 0x01, 0x40, 0x10, 0x0c, 0x10, 0x56,
2723 0x18, 0x05, 0x53, 0x30, 0x05, 0x3e, 0x10, 0x46, 0x0c, 0x12, 0x00, 0x04,
2724 0xc1, 0x00, 0x61, 0x85, 0x51, 0x30, 0x05, 0x53, 0xd8, 0x83, 0x00, 0x01,
2725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2726};
2727#if 0
2728;
2729; Input signature:
2730;
2731; Name Index Mask Register SysValue Format Used
2732; -------------------- ----- ------ -------- -------- ------- ------
2733; TEXCOORD 0 xy 0 NONE float xy
2734; SV_Position 0 xyzw 1 POS float
2735;
2736;
2737; Output signature:
2738;
2739; Name Index Mask Register SysValue Format Used
2740; -------------------- ----- ------ -------- -------- ------- ------
2741; SV_Target 0 xyzw 0 TARGET float xyzw
2742;
2743; shader hash: afa29d501205614a91b6ff9e9bd6cb82
2744;
2745; Pipeline Runtime Information:
2746;
2747; Pixel Shader
2748; DepthOutput=0
2749; SampleFrequency=0
2750;
2751;
2752; Input signature:
2753;
2754; Name Index InterpMode DynIdx
2755; -------------------- ----- ---------------------- ------
2756; TEXCOORD 0 linear
2757; SV_Position 0 noperspective
2758;
2759; Output signature:
2760;
2761; Name Index InterpMode DynIdx
2762; -------------------- ----- ---------------------- ------
2763; SV_Target 0
2764;
2765; Buffer Definitions:
2766;
2767; cbuffer SourceRegionBuffer
2768; {
2769;
2770; struct SourceRegionBuffer
2771; {
2772;
2773; float2 UVLeftTop; ; Offset: 0
2774; float2 UVDimensions; ; Offset: 8
2775; uint MipLevel; ; Offset: 16
2776; float LayerOrDepth; ; Offset: 20
2777;
2778; } SourceRegionBuffer; ; Offset: 0 Size: 24
2779;
2780; }
2781;
2782;
2783; Resource Bindings:
2784;
2785; Name Type Format Dim ID HLSL Bind Count
2786; ------------------------------ ---------- ------- ----------- ------- -------------- ------
2787; SourceRegionBuffer cbuffer NA NA CB0 cb0,space3 1
2788; SourceSampler sampler NA NA S0 s0,space2 1
2789; SourceTextureCubeArray texture f32 cubearray T0 t0,space2 1
2790;
2791;
2792; ViewId state:
2793;
2794; Number of inputs: 8, outputs: 4
2795; Outputs dependent on ViewId: { }
2796; Inputs contributing to computation of Outputs:
2797; output 0 depends on inputs: { 0, 1 }
2798; output 1 depends on inputs: { 0, 1 }
2799; output 2 depends on inputs: { 0, 1 }
2800; output 3 depends on inputs: { 0, 1 }
2801;
2802target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
2803target triple = "dxil-ms-dx"
2804
2805%dx.types.Handle = type { i8* }
2806%dx.types.CBufRet.f32 = type { float, float, float, float }
2807%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
2808%dx.types.ResRet.f32 = type { float, float, float, float, i32 }
2809%"class.TextureCubeArray<vector<float, 4> >" = type { <4 x float> }
2810%SourceRegionBuffer = type { <2 x float>, <2 x float>, i32, float }
2811%struct.SamplerState = type { i32 }
2812
2813define void @BlitFromCubeArray() {
2814 %1 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
2815 %2 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 3, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
2816 %3 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
2817 %4 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
2818 %5 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
2819 %6 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %3, i32 0) ; CBufferLoadLegacy(handle,regIndex)
2820 %7 = extractvalue %dx.types.CBufRet.f32 %6, 0
2821 %8 = extractvalue %dx.types.CBufRet.f32 %6, 1
2822 %9 = extractvalue %dx.types.CBufRet.f32 %6, 2
2823 %10 = extractvalue %dx.types.CBufRet.f32 %6, 3
2824 %11 = fmul fast float %9, %4
2825 %12 = fmul fast float %10, %5
2826 %13 = fadd fast float %11, %7
2827 %14 = fadd fast float %12, %8
2828 %15 = fmul fast float %13, 2.000000e+00
2829 %16 = fadd fast float %15, -1.000000e+00
2830 %17 = fmul fast float %14, 2.000000e+00
2831 %18 = fadd fast float %17, -1.000000e+00
2832 %19 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %3, i32 1) ; CBufferLoadLegacy(handle,regIndex)
2833 %20 = extractvalue %dx.types.CBufRet.f32 %19, 1
2834 %21 = fptoui float %20 to i32
2835 %22 = udiv i32 %21, 6
2836 %23 = urem i32 %21, 6
2837 switch i32 %23, label %37 [
2838 i32 0, label %24
2839 i32 1, label %27
2840 i32 2, label %29
2841 i32 3, label %31
2842 i32 4, label %32
2843 i32 5, label %34
2844 ]
2845
2846; <label>:24 ; preds = %0
2847 %25 = fsub fast float -0.000000e+00, %18
2848 %26 = fsub fast float -0.000000e+00, %16
2849 br label %37
2850
2851; <label>:27 ; preds = %0
2852 %28 = fsub fast float -0.000000e+00, %18
2853 br label %37
2854
2855; <label>:29 ; preds = %0
2856 %30 = fsub fast float -0.000000e+00, %18
2857 br label %37
2858
2859; <label>:31 ; preds = %0
2860 br label %37
2861
2862; <label>:32 ; preds = %0
2863 %33 = fsub fast float -0.000000e+00, %18
2864 br label %37
2865
2866; <label>:34 ; preds = %0
2867 %35 = fsub fast float -0.000000e+00, %16
2868 %36 = fsub fast float -0.000000e+00, %18
2869 br label %37
2870
2871; <label>:37 ; preds = %34, %32, %31, %29, %27, %24, %0
2872 %38 = phi float [ %35, %34 ], [ %16, %32 ], [ %16, %31 ], [ %16, %29 ], [ -1.000000e+00, %27 ], [ 1.000000e+00, %24 ], [ 0.000000e+00, %0 ]
2873 %39 = phi float [ %36, %34 ], [ %33, %32 ], [ -1.000000e+00, %31 ], [ 1.000000e+00, %29 ], [ %28, %27 ], [ %25, %24 ], [ 0.000000e+00, %0 ]
2874 %40 = phi float [ -1.000000e+00, %34 ], [ 1.000000e+00, %32 ], [ %18, %31 ], [ %30, %29 ], [ %16, %27 ], [ %26, %24 ], [ 0.000000e+00, %0 ]
2875 %41 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %3, i32 1) ; CBufferLoadLegacy(handle,regIndex)
2876 %42 = extractvalue %dx.types.CBufRet.i32 %41, 0
2877 %43 = uitofp i32 %42 to float
2878 %44 = uitofp i32 %22 to float
2879 %45 = call %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32 62, %dx.types.Handle %1, %dx.types.Handle %2, float %38, float %39, float %40, float %44, i32 undef, i32 undef, i32 undef, float %43) ; SampleLevel(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,LOD)
2880 %46 = extractvalue %dx.types.ResRet.f32 %45, 0
2881 %47 = extractvalue %dx.types.ResRet.f32 %45, 1
2882 %48 = extractvalue %dx.types.ResRet.f32 %45, 2
2883 %49 = extractvalue %dx.types.ResRet.f32 %45, 3
2884 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %46) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
2885 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %47) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
2886 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %48) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
2887 call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %49) ; StoreOutput(outputSigId,rowIndex,colIndex,value)
2888 ret void
2889}
2890
2891; Function Attrs: nounwind readnone
2892declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #0
2893
2894; Function Attrs: nounwind
2895declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
2896
2897; Function Attrs: nounwind readonly
2898declare %dx.types.ResRet.f32 @dx.op.sampleLevel.f32(i32, %dx.types.Handle, %dx.types.Handle, float, float, float, float, i32, i32, i32, float) #2
2899
2900; Function Attrs: nounwind readonly
2901declare %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32, %dx.types.Handle, i32) #2
2902
2903; Function Attrs: nounwind readonly
2904declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #2
2905
2906; Function Attrs: nounwind readonly
2907declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #2
2908
2909attributes #0 = { nounwind readnone }
2910attributes #1 = { nounwind }
2911attributes #2 = { nounwind readonly }
2912
2913!llvm.ident = !{!0}
2914!dx.version = !{!1}
2915!dx.valver = !{!2}
2916!dx.shaderModel = !{!3}
2917!dx.resources = !{!4}
2918!dx.viewIdState = !{!12}
2919!dx.entryPoints = !{!13}
2920
2921!0 = !{!"clang version 3.7 (tags/RELEASE_370/final)"}
2922!1 = !{i32 1, i32 0}
2923!2 = !{i32 1, i32 6}
2924!3 = !{!"ps", i32 6, i32 0}
2925!4 = !{!5, null, !8, !10}
2926!5 = !{!6}
2927!6 = !{i32 0, %"class.TextureCubeArray<vector<float, 4> >"* undef, !"", i32 2, i32 0, i32 1, i32 9, i32 0, !7}
2928!7 = !{i32 0, i32 9}
2929!8 = !{!9}
2930!9 = !{i32 0, %SourceRegionBuffer* undef, !"", i32 3, i32 0, i32 1, i32 24, null}
2931!10 = !{!11}
2932!11 = !{i32 0, %struct.SamplerState* undef, !"", i32 2, i32 0, i32 1, i32 0, null}
2933!12 = !{[10 x i32] [i32 8, i32 4, i32 15, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0]}
2934!13 = !{void ()* @BlitFromCubeArray, !"BlitFromCubeArray", !14, !4, null}
2935!14 = !{!15, !20, null}
2936!15 = !{!16, !19}
2937!16 = !{i32 0, !"TEXCOORD", i8 9, i8 0, !17, i8 2, i32 1, i8 2, i32 0, i8 0, !18}
2938!17 = !{i32 0}
2939!18 = !{i32 3, i32 3}
2940!19 = !{i32 1, !"SV_Position", i8 9, i8 3, !17, i8 4, i32 1, i8 4, i32 1, i8 0, null}
2941!20 = !{!21}
2942!21 = !{i32 0, !"SV_Target", i8 9, i8 16, !17, i8 0, i32 1, i8 4, i32 0, i8 0, !22}
2943!22 = !{i32 3, i32 15}
2944
2945#endif
2946
2947const unsigned char g_BlitFromCubeArray[] = {
2948 0x44, 0x58, 0x42, 0x43, 0x95, 0x0e, 0x7b, 0x55, 0x73, 0x94, 0x25, 0x5d,
2949 0xa7, 0xe7, 0xe6, 0x60, 0xdc, 0x5e, 0xcd, 0xfd, 0x01, 0x00, 0x00, 0x00,
2950 0xc3, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
2951 0x50, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00,
2952 0xe7, 0x01, 0x00, 0x00, 0x77, 0x02, 0x00, 0x00, 0x53, 0x0a, 0x00, 0x00,
2953 0x6f, 0x0a, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
2954 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31,
2955 0x5d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
2956 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2957 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2958 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2959 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2960 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
2961 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44,
2962 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
2963 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
2964 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
2965 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
2966 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2967 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x50,
2968 0x53, 0x56, 0x30, 0xf0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
2969 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2970 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
2971 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
2972 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
2973 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
2974 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
2975 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
2976 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,
2977 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
2978 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
2979 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
2980 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x00, 0x00, 0x01,
2981 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
2982 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x03,
2983 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
2984 0x01, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2985 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, 0x00, 0x0f,
2986 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2988 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x88,
2989 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18,
2990 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00,
2991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c,
2992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5c,
2993 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x7c,
2994 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03,
2995 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
2996 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01,
2997 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
2998 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
2999 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x03,
3000 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x54, 0x41, 0x54, 0xd4,
3001 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xf5, 0x01, 0x00, 0x00, 0x44,
3002 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xbc,
3003 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xec,
3004 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
3005 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06,
3006 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e,
3007 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4,
3008 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48,
3009 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4,
3010 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1,
3011 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08,
3012 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40,
3013 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d,
3014 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49,
3015 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20,
3016 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x48,
3017 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13,
3018 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12,
3019 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x88, 0xc1, 0x08, 0x40,
3020 0x09, 0x00, 0x0a, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29,
3021 0xc6, 0x40, 0x10, 0x44, 0x41, 0x90, 0x51, 0x0c, 0x80, 0x20, 0x88, 0x62,
3022 0x20, 0xe4, 0xa6, 0xe1, 0xf2, 0x27, 0xec, 0x21, 0x24, 0x7f, 0x25, 0xa4,
3023 0x95, 0x98, 0xfc, 0xe2, 0xb6, 0x51, 0x31, 0x0c, 0xc3, 0x40, 0x50, 0x71,
3024 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, 0x10,
3025 0x28, 0x58, 0x0a, 0xa3, 0x10, 0x0c, 0x33, 0x0c, 0xc3, 0x40, 0x10, 0xc4,
3026 0x40, 0xcd, 0x51, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, 0x3e, 0xb7, 0x51,
3027 0xc5, 0x4a, 0x4c, 0x7e, 0x71, 0xdb, 0x88, 0x18, 0x86, 0x61, 0x28, 0xc4,
3028 0x43, 0x30, 0x04, 0x41, 0x47, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9,
3029 0xdc, 0x46, 0x15, 0x2b, 0x31, 0xf9, 0xc8, 0x6d, 0x23, 0x82, 0x20, 0x08,
3030 0xa2, 0x10, 0x12, 0xc1, 0x10, 0x34, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0x88,
3031 0x82, 0x20, 0x2a, 0xb2, 0x06, 0x02, 0x86, 0x11, 0x88, 0x61, 0xa6, 0x34,
3032 0x18, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07, 0x37, 0xa0, 0x85, 0x72,
3033 0xc0, 0x07, 0x7a, 0xa8, 0x07, 0x79, 0x28, 0x87, 0x51, 0xa8, 0x07, 0x71,
3034 0x28, 0x87, 0x50, 0x90, 0x07, 0x79, 0x08, 0x87, 0x7c, 0xe0, 0x03, 0x7b,
3035 0x28, 0x87, 0x71, 0xa0, 0x87, 0x77, 0x90, 0x07, 0x3e, 0x30, 0x07, 0x76,
3036 0x78, 0x87, 0x70, 0xa0, 0x07, 0x36, 0x00, 0x03, 0x3a, 0xf0, 0x03, 0x30,
3037 0xf0, 0x03, 0x14, 0x64, 0xa4, 0x0d, 0x23, 0x08, 0xc3, 0x49, 0xac, 0x43,
3038 0x45, 0x02, 0xb1, 0x12, 0x06, 0xe2, 0x34, 0x1b, 0x55, 0x14, 0x44, 0x84,
3039 0x08, 0x8e, 0x23, 0x06, 0xea, 0x6e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0x9f,
3040 0x05, 0x98, 0x67, 0x21, 0x22, 0x76, 0x02, 0x26, 0x02, 0x05, 0x04, 0x7d,
3041 0xa9, 0x40, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36,
3042 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e,
3043 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07,
3044 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07,
3045 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07,
3046 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06,
3047 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e,
3048 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07,
3049 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07,
3050 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07,
3051 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07,
3052 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00,
3053 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c,
3054 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
3055 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3056 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3057 0x00, 0x30, 0xe4, 0x81, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
3058 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00,
3059 0x00, 0x00, 0x00, 0xc0, 0x90, 0xc7, 0x02, 0x02, 0x60, 0x00, 0x00, 0x00,
3060 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x14, 0x00, 0x00, 0x00, 0x32,
3061 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6,
3062 0x04, 0x43, 0x22, 0x4a, 0x60, 0x04, 0xa0, 0x18, 0x8a, 0xa0, 0x24, 0xca,
3063 0xa0, 0x60, 0xca, 0xa1, 0x20, 0x0a, 0xa4, 0x14, 0x0a, 0xa5, 0x3c, 0x8a,
3064 0xa4, 0xd8, 0x0a, 0x81, 0x8a, 0x92, 0x18, 0x01, 0x28, 0x82, 0x32, 0x28,
3065 0x84, 0x02, 0xa1, 0xaa, 0x06, 0x68, 0x9b, 0x01, 0xa0, 0x6e, 0x06, 0x80,
3066 0xbc, 0x19, 0x00, 0x02, 0x67, 0x00, 0x28, 0x1c, 0x4b, 0x41, 0x88, 0xe7,
3067 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xb5,
3068 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35,
3069 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b,
3070 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b,
3071 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79,
3072 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0xe2,
3073 0x98, 0x20, 0x10, 0xc8, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, 0x41, 0x01,
3074 0x6e, 0x6e, 0x82, 0x40, 0x24, 0x1b, 0x86, 0x03, 0x21, 0x26, 0x08, 0x9b,
3075 0x47, 0x6b, 0xea, 0xad, 0x4e, 0x6e, 0xac, 0x8c, 0xaa, 0x0c, 0x8f, 0xae,
3076 0x4e, 0xae, 0x6c, 0xa8, 0x4e, 0xac, 0x2c, 0x48, 0x4e, 0x2e, 0x2c, 0x6f,
3077 0x82, 0x40, 0x28, 0x13, 0x04, 0x62, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84,
3078 0x50, 0x16, 0x86, 0x18, 0x1a, 0xc2, 0xd9, 0x10, 0x3c, 0x13, 0x04, 0x0f,
3079 0x0c, 0x28, 0x4d, 0xbd, 0xd5, 0xc9, 0x8d, 0x95, 0x49, 0x95, 0x9d, 0xa5,
3080 0xbd, 0xb9, 0x09, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x4d, 0x10, 0x08, 0x66,
3081 0x82, 0x40, 0x34, 0x1b, 0x10, 0x22, 0x92, 0x26, 0x62, 0xa0, 0x80, 0x0d,
3082 0x41, 0x35, 0x41, 0x00, 0x83, 0x30, 0x60, 0x33, 0xf5, 0x56, 0x27, 0x37,
3083 0x56, 0x36, 0x15, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xb7, 0x01, 0x21, 0x2e,
3084 0x8c, 0x21, 0x06, 0x02, 0xd8, 0x10, 0x64, 0x1b, 0x08, 0x08, 0xb0, 0xb4,
3085 0x09, 0x42, 0xf7, 0x31, 0xa9, 0xb2, 0x62, 0x2a, 0x33, 0xa3, 0xa3, 0x7a,
3086 0x83, 0x9b, 0x20, 0x10, 0xce, 0x04, 0xa1, 0xea, 0x36, 0x20, 0x48, 0x37,
3087 0x11, 0x5e, 0xd3, 0x7c, 0x64, 0xaa, 0xac, 0x88, 0xd2, 0xda, 0xca, 0xdc,
3088 0xe6, 0xd2, 0xde, 0xdc, 0xe6, 0x26, 0x08, 0xc4, 0xb3, 0x01, 0x41, 0xc2,
3089 0x60, 0x12, 0x03, 0xaf, 0x69, 0x3e, 0x22, 0x4d, 0x69, 0x70, 0x4c, 0x65,
3090 0x76, 0x65, 0x6c, 0x13, 0x04, 0x02, 0x9a, 0x20, 0x10, 0xd1, 0x06, 0x04,
3091 0x21, 0x83, 0xa9, 0x0c, 0x3c, 0x33, 0x68, 0x3e, 0x32, 0x4c, 0x61, 0x79,
3092 0x65, 0x72, 0x4f, 0x72, 0x44, 0x65, 0x70, 0x74, 0x68, 0x13, 0x04, 0x42,
3093 0xda, 0x80, 0x20, 0x68, 0x30, 0xa5, 0x81, 0xd7, 0x34, 0xdf, 0x86, 0x82,
3094 0x02, 0x83, 0x31, 0x38, 0x03, 0x35, 0xd8, 0x30, 0x10, 0xdc, 0x1a, 0x4c,
3095 0x10, 0x04, 0x60, 0x03, 0xb0, 0x61, 0x20, 0xdc, 0xc0, 0x0d, 0x36, 0x04,
3096 0x6f, 0xb0, 0x61, 0x18, 0xda, 0x00, 0x0e, 0x26, 0x08, 0x61, 0x20, 0x06,
3097 0x1b, 0x02, 0x39, 0x60, 0x24, 0xc4, 0x96, 0x46, 0x67, 0x24, 0xf7, 0xd6,
3098 0x36, 0x54, 0x27, 0x56, 0x16, 0x24, 0x27, 0x17, 0x96, 0x47, 0x84, 0xaa,
3099 0x08, 0x6b, 0xe8, 0xe9, 0x49, 0x8a, 0x68, 0x82, 0x50, 0x5c, 0x13, 0x84,
3100 0x02, 0xdb, 0x10, 0x10, 0x13, 0x84, 0x22, 0xdb, 0x20, 0x4c, 0xd3, 0x86,
3101 0x85, 0xa8, 0x03, 0x3b, 0xb8, 0x03, 0x3c, 0xc8, 0x83, 0x21, 0x0f, 0x88,
3102 0x3b, 0xd0, 0x03, 0x2e, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74,
3103 0x69, 0x6f, 0x6e, 0x13, 0x84, 0x42, 0x9b, 0x20, 0x14, 0xdb, 0x86, 0x65,
3104 0xe0, 0x03, 0x3b, 0xe8, 0x03, 0x3c, 0xf0, 0x83, 0xc1, 0x0f, 0x86, 0x3b,
3105 0x00, 0x36, 0x08, 0x7b, 0xf0, 0x07, 0x4c, 0xa6, 0xac, 0xbe, 0xa8, 0xc2,
3106 0xe4, 0xce, 0xca, 0xe8, 0x26, 0x08, 0x05, 0x37, 0x41, 0x20, 0xa6, 0x0d,
3107 0xc2, 0x34, 0x0a, 0x1b, 0x16, 0x22, 0x14, 0xec, 0x40, 0x14, 0xf0, 0xe0,
3108 0x0e, 0x06, 0x3f, 0x20, 0xee, 0x80, 0x14, 0x36, 0x04, 0xa5, 0xb0, 0x61,
3109 0x00, 0x05, 0x53, 0x00, 0x36, 0x14, 0x6d, 0x40, 0x07, 0xa7, 0xb0, 0x01,
3110 0x34, 0xcc, 0xd8, 0xde, 0xc2, 0xe8, 0xe6, 0x26, 0x08, 0x04, 0xc5, 0x22,
3111 0xcd, 0x6d, 0x8e, 0x6e, 0x6e, 0x82, 0x40, 0x54, 0x34, 0xe6, 0xd2, 0xce,
3112 0xbe, 0xd8, 0xc8, 0x68, 0xcc, 0xa5, 0x9d, 0x7d, 0xcd, 0xd1, 0x4d, 0x10,
3113 0x08, 0x8b, 0x08, 0x5d, 0x19, 0xde, 0x97, 0xdb, 0x9b, 0x5c, 0x1b, 0x8b,
3114 0xba, 0x34, 0x37, 0xba, 0xb9, 0x0d, 0x4c, 0x2a, 0xa8, 0xc2, 0x2a, 0xb0,
3115 0x42, 0x2b, 0x30, 0xae, 0xf0, 0x0a, 0xb0, 0x30, 0xc4, 0x02, 0x53, 0x85,
3116 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x4a, 0x10,
3117 0x54, 0x21, 0xc3, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x9b,
3118 0x12, 0x10, 0x4d, 0xc8, 0xf0, 0x5c, 0xec, 0xc2, 0xd8, 0xec, 0xca, 0xe4,
3119 0xa6, 0x04, 0x45, 0x1d, 0x32, 0x3c, 0x97, 0x39, 0xb4, 0x30, 0xb2, 0x32,
3120 0xb9, 0xa6, 0x37, 0xb2, 0x32, 0xb6, 0x29, 0x01, 0x52, 0x86, 0x0c, 0xcf,
3121 0x45, 0xae, 0x6c, 0xee, 0xad, 0x4e, 0x6e, 0xac, 0x6c, 0x6e, 0x4a, 0xa0,
3122 0x55, 0x22, 0xc3, 0x73, 0xa1, 0xcb, 0x83, 0x2b, 0x0b, 0x72, 0x73, 0x7b,
3123 0xa3, 0x0b, 0xa3, 0x4b, 0x7b, 0x73, 0x9b, 0x9b, 0x22, 0xac, 0x01, 0x1c,
3124 0xd4, 0x21, 0xc3, 0x73, 0xb1, 0x4b, 0x2b, 0xbb, 0x4b, 0x22, 0x9b, 0xa2,
3125 0x0b, 0xa3, 0x2b, 0x9b, 0x12, 0xc8, 0x41, 0x1d, 0x32, 0x3c, 0x97, 0x32,
3126 0x37, 0x3a, 0xb9, 0x3c, 0xa8, 0xb7, 0x34, 0x37, 0xba, 0xb9, 0x29, 0xc1,
3127 0x29, 0x74, 0x21, 0xc3, 0x73, 0x19, 0x7b, 0xab, 0x73, 0xa3, 0x2b, 0x93,
3128 0x9b, 0x9b, 0x12, 0xc4, 0x02, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x51,
3129 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14,
3130 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79,
3131 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e,
3132 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1,
3133 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc,
3134 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74,
3135 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a,
3136 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e,
3137 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e,
3138 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21,
3139 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0,
3140 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc,
3141 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72,
3142 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76,
3143 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f,
3144 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c,
3145 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03,
3146 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1,
3147 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61,
3148 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8,
3149 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94,
3150 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0,
3151 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76,
3152 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e,
3153 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f,
3154 0xef, 0x50, 0x0f, 0xf4, 0x30, 0x83, 0x81, 0xc8, 0x01, 0x1f, 0xdc, 0x40,
3155 0x1c, 0xe4, 0xa1, 0x1c, 0xc2, 0x61, 0x1d, 0xdc, 0x40, 0x1c, 0xe4, 0x01,
3156 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x06,
3157 0x10, 0x6d, 0x0b, 0x32, 0x7d, 0x91, 0xc3, 0x70, 0x54, 0x40, 0x68, 0x51,
3158 0x04, 0x60, 0x46, 0xb0, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x50, 0x45,
3159 0x41, 0x44, 0xa5, 0x03, 0x0c, 0x25, 0x61, 0x00, 0x02, 0xe6, 0x17, 0xb7,
3160 0x6d, 0x05, 0xdb, 0x70, 0xf9, 0xce, 0xe3, 0x0b, 0x01, 0x55, 0x14, 0x44,
3161 0x54, 0x3a, 0xc0, 0x50, 0x12, 0x06, 0x20, 0x60, 0x3e, 0x72, 0xdb, 0x66,
3162 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, 0x84, 0x40,
3163 0x33, 0x2c, 0x84, 0x05, 0x4c, 0xc3, 0xe5, 0x3b, 0x8f, 0xbf, 0x38, 0xc0,
3164 0x20, 0x36, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0xdb, 0x40, 0x35, 0x5c, 0xbe,
3165 0xf3, 0xf8, 0x12, 0xc0, 0x3c, 0x0b, 0x51, 0x12, 0x15, 0xb1, 0xf8, 0xc5,
3166 0x6d, 0x9b, 0x40, 0x35, 0x5c, 0xbe, 0xf3, 0xf8, 0xd2, 0xe4, 0x44, 0x04,
3167 0x4a, 0x4d, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x03, 0x00, 0x00, 0x00, 0x00,
3168 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00,
3169 0x00, 0x00, 0x00, 0xaf, 0xa2, 0x9d, 0x50, 0x12, 0x05, 0x61, 0x4a, 0x91,
3170 0xb6, 0xff, 0x9e, 0x9b, 0xd6, 0xcb, 0x82, 0x44, 0x58, 0x49, 0x4c, 0x4c,
3171 0x08, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00, 0x44,
3172 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x34,
3173 0x08, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x0a,
3174 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
3175 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06,
3176 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e,
3177 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4,
3178 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48,
3179 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4,
3180 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1,
3181 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08,
3182 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40,
3183 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d,
3184 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49,
3185 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20,
3186 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x49,
3187 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13,
3188 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12,
3189 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x8c, 0xc1, 0x08, 0x40,
3190 0x09, 0x00, 0x0a, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29,
3191 0xc6, 0x40, 0x10, 0x44, 0x41, 0x90, 0x51, 0x0c, 0x80, 0x20, 0x88, 0x62,
3192 0x20, 0xe4, 0xa6, 0xe1, 0xf2, 0x27, 0xec, 0x21, 0x24, 0x7f, 0x25, 0xa4,
3193 0x95, 0x98, 0xfc, 0xe2, 0xb6, 0x51, 0x31, 0x0c, 0xc3, 0x40, 0x50, 0x71,
3194 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, 0x10,
3195 0x28, 0x58, 0x0a, 0xa3, 0x10, 0x0c, 0x33, 0x0c, 0xc3, 0x40, 0x10, 0xc4,
3196 0x40, 0xcd, 0x51, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, 0x3e, 0xb7, 0x51,
3197 0xc5, 0x4a, 0x4c, 0x7e, 0x71, 0xdb, 0x88, 0x18, 0x86, 0x61, 0x28, 0xc4,
3198 0x43, 0x30, 0x04, 0x41, 0x47, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9,
3199 0xdc, 0x46, 0x15, 0x2b, 0x31, 0xf9, 0xc8, 0x6d, 0x23, 0x82, 0x20, 0x08,
3200 0xa2, 0x10, 0x12, 0xc1, 0x10, 0x34, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0x88,
3201 0x82, 0x20, 0x2a, 0xb2, 0x06, 0x02, 0x86, 0x11, 0x88, 0x61, 0xa6, 0x34,
3202 0x18, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07, 0x37, 0xa0, 0x85, 0x72,
3203 0xc0, 0x07, 0x7a, 0xa8, 0x07, 0x79, 0x28, 0x87, 0x51, 0xa8, 0x07, 0x71,
3204 0x28, 0x87, 0x50, 0x90, 0x07, 0x79, 0x08, 0x87, 0x7c, 0xe0, 0x03, 0x7b,
3205 0x28, 0x87, 0x71, 0xa0, 0x87, 0x77, 0x90, 0x07, 0x3e, 0x30, 0x07, 0x76,
3206 0x78, 0x87, 0x70, 0xa0, 0x07, 0x36, 0x00, 0x03, 0x3a, 0xf0, 0x03, 0x30,
3207 0xf0, 0x03, 0x14, 0x64, 0xa4, 0x0d, 0x23, 0x08, 0xc3, 0x49, 0xac, 0x43,
3208 0x45, 0x02, 0xb1, 0x12, 0x06, 0xe2, 0x34, 0x1b, 0x55, 0x14, 0x44, 0x84,
3209 0x08, 0x8e, 0x23, 0x06, 0xea, 0x6e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0x9f,
3210 0x05, 0x98, 0x67, 0x21, 0x22, 0x76, 0x02, 0x26, 0x02, 0x05, 0x04, 0x7d,
3211 0xa9, 0x40, 0x4c, 0x01, 0x00, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87,
3212 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87,
3213 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00,
3214 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90,
3215 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0,
3216 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30,
3217 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20,
3218 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0,
3219 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60,
3220 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60,
3221 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0,
3222 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40,
3223 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3224 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3225 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00,
3226 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00,
3227 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x81, 0x80, 0x00, 0x18, 0x00,
3228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30,
3229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xc7, 0x02, 0x02,
3230 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x10,
3231 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c,
3232 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x22, 0x4a, 0x60, 0x04, 0xa0, 0x18,
3233 0x8a, 0xa0, 0x24, 0xca, 0xa0, 0x60, 0xca, 0x83, 0x8a, 0x92, 0x18, 0x01,
3234 0x28, 0x82, 0x32, 0x28, 0x84, 0x02, 0xa1, 0x6d, 0x06, 0x80, 0xbc, 0x19,
3235 0x00, 0x02, 0x67, 0x00, 0x28, 0x1c, 0x4b, 0x41, 0x88, 0xe7, 0x01, 0x00,
3236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x68,
3237 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35,
3238 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b,
3239 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b,
3240 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79,
3241 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0xe2,
3242 0x98, 0x20, 0x10, 0xc8, 0x06, 0x61, 0x20, 0x26, 0x08, 0x44, 0xb2, 0x41,
3243 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0x5b,
3244 0x45, 0x60, 0x82, 0x40, 0x28, 0x13, 0x04, 0x62, 0xd9, 0x20, 0x10, 0xcd,
3245 0x86, 0x84, 0x50, 0x16, 0x86, 0x18, 0x1a, 0xc2, 0xd9, 0x10, 0x3c, 0x13,
3246 0x04, 0xcf, 0x9a, 0x20, 0x10, 0xcc, 0x04, 0x81, 0x68, 0x36, 0x20, 0x44,
3247 0xb4, 0x48, 0xc4, 0x30, 0x01, 0x1b, 0x02, 0x6a, 0x82, 0x00, 0x06, 0xd7,
3248 0x06, 0x84, 0xb0, 0x16, 0x86, 0x18, 0x08, 0x60, 0x43, 0x70, 0x6d, 0x20,
3249 0x20, 0xa0, 0xc2, 0x26, 0x08, 0x61, 0x80, 0x6d, 0x08, 0xb4, 0x09, 0x82,
3250 0x00, 0x30, 0x12, 0x62, 0x4b, 0xa3, 0x33, 0x92, 0x7b, 0x6b, 0x1b, 0xaa,
3251 0x13, 0x2b, 0x0b, 0x92, 0x93, 0x0b, 0xcb, 0x23, 0x42, 0x55, 0x84, 0x35,
3252 0xf4, 0xf4, 0x24, 0x45, 0x34, 0x41, 0x28, 0x9e, 0x09, 0x42, 0x01, 0x6d,
3253 0x08, 0x88, 0x09, 0x42, 0x11, 0x6d, 0x10, 0x24, 0x69, 0xc3, 0x42, 0x78,
3254 0x1f, 0x18, 0x84, 0x81, 0x18, 0x0c, 0x62, 0x40, 0x80, 0xc1, 0x18, 0x70,
3255 0x99, 0xb2, 0xfa, 0x82, 0x7a, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0x9b,
3256 0x20, 0x14, 0xd2, 0x04, 0xa1, 0x98, 0x36, 0x2c, 0x43, 0x19, 0x7c, 0x66,
3257 0x10, 0x06, 0x67, 0x30, 0x9c, 0xc1, 0x00, 0x06, 0xc0, 0x06, 0x81, 0x0c,
3258 0xd0, 0x80, 0xc9, 0x94, 0xd5, 0x17, 0x55, 0x98, 0xdc, 0x59, 0x19, 0xdd,
3259 0x04, 0xa1, 0xa0, 0x26, 0x08, 0x84, 0xb3, 0x41, 0x90, 0xd8, 0x60, 0xc3,
3260 0x42, 0xa8, 0xc1, 0xb7, 0x06, 0x61, 0x00, 0x06, 0xc3, 0x19, 0x10, 0x60,
3261 0xd0, 0x06, 0x1b, 0x02, 0x37, 0xd8, 0x30, 0xa4, 0xc1, 0x1b, 0x00, 0x1b,
3262 0x0a, 0xae, 0x83, 0x83, 0x0c, 0xa8, 0xc2, 0xc6, 0x66, 0xd7, 0xe6, 0x92,
3263 0x46, 0x56, 0xe6, 0x46, 0x37, 0x25, 0x08, 0xaa, 0x90, 0xe1, 0xb9, 0xd8,
3264 0x95, 0xc9, 0xcd, 0xa5, 0xbd, 0xb9, 0x4d, 0x09, 0x88, 0x26, 0x64, 0x78,
3265 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x02, 0xa3, 0x0e, 0x19,
3266 0x9e, 0xcb, 0x1c, 0x5a, 0x18, 0x59, 0x99, 0x5c, 0xd3, 0x1b, 0x59, 0x19,
3267 0xdb, 0x94, 0x00, 0x29, 0x43, 0x86, 0xe7, 0x22, 0x57, 0x36, 0xf7, 0x56,
3268 0x27, 0x37, 0x56, 0x36, 0x37, 0x25, 0xc0, 0xea, 0x90, 0xe1, 0xb9, 0xd8,
3269 0xa5, 0x95, 0xdd, 0x25, 0x91, 0x4d, 0xd1, 0x85, 0xd1, 0x95, 0x4d, 0x09,
3270 0xb4, 0x3a, 0x64, 0x78, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f,
3271 0x69, 0x6e, 0x74, 0x73, 0x53, 0x02, 0x38, 0x00, 0x00, 0x00, 0x00, 0x79,
3272 0x18, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4,
3273 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c,
3274 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00,
3275 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2,
3276 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38,
3277 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d,
3278 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87,
3279 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87,
3280 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30,
3281 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde,
3282 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b,
3283 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c,
3284 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07,
3285 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87,
3286 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87,
3287 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87,
3288 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0,
3289 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc,
3290 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4,
3291 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39,
3292 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38,
3293 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b,
3294 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03,
3295 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0,
3296 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0,
3297 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x30, 0x83, 0x81, 0xc8,
3298 0x01, 0x1f, 0xdc, 0x40, 0x1c, 0xe4, 0xa1, 0x1c, 0xc2, 0x61, 0x1d, 0xdc,
3299 0x40, 0x1c, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x21,
3300 0x00, 0x00, 0x00, 0x06, 0x10, 0x6d, 0x0b, 0x32, 0x7d, 0x91, 0xc3, 0x70,
3301 0x54, 0x40, 0x68, 0x51, 0x04, 0x60, 0x46, 0xb0, 0x0d, 0x97, 0xef, 0x3c,
3302 0xbe, 0x10, 0x50, 0x45, 0x41, 0x44, 0xa5, 0x03, 0x0c, 0x25, 0x61, 0x00,
3303 0x02, 0xe6, 0x17, 0xb7, 0x6d, 0x05, 0xdb, 0x70, 0xf9, 0xce, 0xe3, 0x0b,
3304 0x01, 0x55, 0x14, 0x44, 0x54, 0x3a, 0xc0, 0x50, 0x12, 0x06, 0x20, 0x60,
3305 0x3e, 0x72, 0xdb, 0x66, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11,
3306 0xc0, 0x44, 0x84, 0x40, 0x33, 0x2c, 0x84, 0x05, 0x4c, 0xc3, 0xe5, 0x3b,
3307 0x8f, 0xbf, 0x38, 0xc0, 0x20, 0x36, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0xdb,
3308 0x40, 0x35, 0x5c, 0xbe, 0xf3, 0xf8, 0x12, 0xc0, 0x3c, 0x0b, 0x51, 0x12,
3309 0x15, 0xb1, 0xf8, 0xc5, 0x6d, 0x9b, 0x40, 0x35, 0x5c, 0xbe, 0xf3, 0xf8,
3310 0xd2, 0xe4, 0x44, 0x04, 0x4a, 0x4d, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x03,
3311 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x13,
3312 0x04, 0x48, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x54,
3313 0x8d, 0x00, 0x50, 0x51, 0x02, 0x44, 0x14, 0x5f, 0xd9, 0x15, 0xc2, 0x0c,
3314 0x40, 0x29, 0x94, 0x1c, 0x0d, 0x63, 0x04, 0x20, 0x08, 0x82, 0x20, 0x18,
3315 0x8c, 0x00, 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0xdf, 0x18, 0x01, 0x08,
3316 0x82, 0x20, 0xfe, 0x0b, 0x63, 0x04, 0x20, 0x08, 0x82, 0x20, 0x28, 0x00,
3317 0x00, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x81, 0x81,
3318 0x61, 0x79, 0x5e, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x56, 0x18,
3319 0x1c, 0xd5, 0xf7, 0x39, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x89,
3320 0x01, 0x72, 0x81, 0x01, 0x18, 0x3c, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60,
3321 0x60, 0xa0, 0x01, 0x13, 0x06, 0x61, 0x90, 0x2d, 0x23, 0x06, 0x09, 0x00,
3322 0x82, 0x60, 0x60, 0xa4, 0x41, 0x23, 0x06, 0x62, 0x00, 0x31, 0x23, 0x06,
3323 0x07, 0x00, 0x82, 0x60, 0x00, 0x9d, 0xc1, 0x33, 0x8c, 0xc1, 0x68, 0x42,
3324 0x00, 0x8c, 0x26, 0x08, 0xc1, 0x68, 0xc2, 0x20, 0x8c, 0x26, 0x10, 0x83,
3325 0x09, 0x87, 0x7c, 0x4c, 0x38, 0xe4, 0x63, 0x82, 0x01, 0x1f, 0x13, 0x0c,
3326 0xf8, 0x98, 0x30, 0xc9, 0xc7, 0x82, 0x08, 0x3e, 0x36, 0x54, 0xf2, 0xb1,
3327 0x60, 0x82, 0xcf, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x40, 0x74, 0xc0,
3328 0x41, 0x71, 0x30, 0x9a, 0x10, 0x04, 0x17, 0x10, 0x53, 0x81, 0x1c, 0x4c,
3329 0x09, 0x73, 0x50, 0xc3, 0x3c, 0x44, 0x70, 0x20, 0xc1, 0x21, 0x28, 0x03,
3330 0x43, 0x74, 0xc5, 0x67, 0x18, 0x66, 0xc4, 0xc7, 0xb2, 0x24, 0x3e, 0xb3,
3331 0x04, 0x87, 0x69, 0x48, 0x7c, 0x66, 0x09, 0x0e, 0xdb, 0x92, 0xf8, 0xcc,
3332 0x12, 0x1c, 0xb3, 0x04, 0x87, 0x71, 0x4a, 0x7c, 0x66, 0x09, 0x0e, 0xeb,
3333 0x9a, 0xf8, 0x98, 0xc7, 0xc4, 0x67, 0x96, 0xe0, 0x18, 0xe8, 0x19, 0x08,
3334 0xc3, 0x2b, 0x3c, 0xc2, 0x1b, 0x40, 0x41, 0x10, 0x85, 0x80, 0x14, 0x80,
3335 0x81, 0x9e, 0x81, 0x30, 0x90, 0x42, 0x14, 0x08, 0x52, 0x18, 0x18, 0x01,
3336 0x0a, 0x4c, 0x01, 0x18, 0xe8, 0x19, 0x48, 0xc1, 0x30, 0x85, 0xc2, 0x23,
3337 0x98, 0x41, 0x0c, 0x04, 0x28, 0x40, 0x05, 0x60, 0xc4, 0xe0, 0x00, 0x40,
3338 0x10, 0x0c, 0x26, 0x51, 0x58, 0x83, 0x0f, 0x14, 0x46, 0x13, 0x02, 0xe0,
3339 0x82, 0xa1, 0xee, 0x19, 0x6a, 0xc4, 0xe0, 0x01, 0x40, 0x10, 0x0c, 0x1a,
3340 0x54, 0x80, 0x83, 0x32, 0x20, 0x83, 0xc3, 0x28, 0x82, 0x36, 0x68, 0x83,
3341 0x36, 0x10, 0x46, 0x13, 0x02, 0x60, 0x34, 0x41, 0x08, 0x46, 0x13, 0x06,
3342 0x61, 0x34, 0x81, 0x18, 0x46, 0x0c, 0x12, 0x00, 0x04, 0xc1, 0x00, 0x71,
3343 0x85, 0x38, 0x40, 0x05, 0x54, 0x00, 0x05, 0x62, 0xc4, 0x20, 0x01, 0x40,
3344 0x10, 0x0c, 0x10, 0x57, 0x88, 0x03, 0x54, 0x40, 0x05, 0x3b, 0x18, 0x46,
3345 0x0c, 0x12, 0x00, 0x04, 0xc1, 0x00, 0x71, 0x85, 0x38, 0x40, 0x05, 0x54,
3346 0xf8, 0x03, 0x61, 0xc4, 0x20, 0x01, 0x40, 0x10, 0x0c, 0x10, 0x57, 0x88,
3347 0x03, 0x54, 0x40, 0x05, 0x3f, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
3348 0x00, 0x00, 0x00
3349};
diff --git a/contrib/SDL-3.2.8/src/gpu/d3d12/D3D_Blit.hlsl b/contrib/SDL-3.2.8/src/gpu/d3d12/D3D_Blit.hlsl
new file mode 100644
index 0000000..69748d4
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/gpu/d3d12/D3D_Blit.hlsl
@@ -0,0 +1,97 @@
1#define BlitRS \
2 "DescriptorTable ( Sampler(s0, space=2), visibility = SHADER_VISIBILITY_PIXEL ),"\
3 "DescriptorTable ( SRV(t0, space=2), visibility = SHADER_VISIBILITY_PIXEL ),"\
4 "CBV(b0, space=3, visibility = SHADER_VISIBILITY_PIXEL),"\
5
6struct VertexToPixel
7{
8 float2 tex : TEXCOORD0;
9 float4 pos : SV_POSITION;
10};
11
12cbuffer SourceRegionBuffer : register(b0, space3)
13{
14 float2 UVLeftTop;
15 float2 UVDimensions;
16 uint MipLevel;
17 float LayerOrDepth;
18};
19
20Texture2D SourceTexture2D : register(t0, space2);
21Texture2DArray SourceTexture2DArray : register(t0, space2);
22Texture3D SourceTexture3D : register(t0, space2);
23TextureCube SourceTextureCube : register(t0, space2);
24TextureCubeArray SourceTextureCubeArray : register(t0, space2);
25sampler SourceSampler : register(s0, space2);
26
27[RootSignature(BlitRS)]
28VertexToPixel FullscreenVert(uint vI : SV_VERTEXID)
29{
30 float2 inTex = float2((vI << 1) & 2, vI & 2);
31 VertexToPixel Out = (VertexToPixel)0;
32 Out.tex = inTex;
33 Out.pos = float4(inTex * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f);
34 return Out;
35}
36
37[RootSignature(BlitRS)]
38float4 BlitFrom2D(VertexToPixel input) : SV_Target0
39{
40 float2 newCoord = UVLeftTop + UVDimensions * input.tex;
41 return SourceTexture2D.SampleLevel(SourceSampler, newCoord, MipLevel);
42}
43
44[RootSignature(BlitRS)]
45float4 BlitFrom2DArray(VertexToPixel input) : SV_Target0
46{
47 float3 newCoord = float3(UVLeftTop + UVDimensions * input.tex, (uint)LayerOrDepth);
48 return SourceTexture2DArray.SampleLevel(SourceSampler, newCoord, MipLevel);
49}
50
51[RootSignature(BlitRS)]
52float4 BlitFrom3D(VertexToPixel input) : SV_Target0
53{
54 float3 newCoord = float3(UVLeftTop + UVDimensions * input.tex, LayerOrDepth);
55 return SourceTexture3D.SampleLevel(SourceSampler, newCoord, MipLevel);
56}
57
58[RootSignature(BlitRS)]
59float4 BlitFromCube(VertexToPixel input) : SV_Target0
60{
61 // Thanks, Wikipedia! https://en.wikipedia.org/wiki/Cube_mapping
62 float3 newCoord;
63 float2 scaledUV = UVLeftTop + UVDimensions * input.tex;
64 float u = 2.0 * scaledUV.x - 1.0;
65 float v = 2.0 * scaledUV.y - 1.0;
66 switch ((uint)LayerOrDepth) {
67 case 0: newCoord = float3(1.0, -v, -u); break; // POSITIVE X
68 case 1: newCoord = float3(-1.0, -v, u); break; // NEGATIVE X
69 case 2: newCoord = float3(u, 1.0, -v); break; // POSITIVE Y
70 case 3: newCoord = float3(u, -1.0, v); break; // NEGATIVE Y
71 case 4: newCoord = float3(u, -v, 1.0); break; // POSITIVE Z
72 case 5: newCoord = float3(-u, -v, -1.0); break; // NEGATIVE Z
73 default: newCoord = float3(0, 0, 0); break; // silences warning
74 }
75 return SourceTextureCube.SampleLevel(SourceSampler, newCoord, MipLevel);
76}
77
78[RootSignature(BlitRS)]
79float4 BlitFromCubeArray(VertexToPixel input) : SV_Target0
80{
81 // Thanks, Wikipedia! https://en.wikipedia.org/wiki/Cube_mapping
82 float3 newCoord;
83 float2 scaledUV = UVLeftTop + UVDimensions * input.tex;
84 float u = 2.0 * scaledUV.x - 1.0;
85 float v = 2.0 * scaledUV.y - 1.0;
86 uint ArrayIndex = (uint)LayerOrDepth / 6;
87 switch ((uint)LayerOrDepth % 6) {
88 case 0: newCoord = float3(1.0, -v, -u); break; // POSITIVE X
89 case 1: newCoord = float3(-1.0, -v, u); break; // NEGATIVE X
90 case 2: newCoord = float3(u, 1.0, -v); break; // POSITIVE Y
91 case 3: newCoord = float3(u, -1.0, v); break; // NEGATIVE Y
92 case 4: newCoord = float3(u, -v, 1.0); break; // POSITIVE Z
93 case 5: newCoord = float3(-u, -v, -1.0); break; // NEGATIVE Z
94 default: newCoord = float3(0, 0, 0); break; // silences warning
95 }
96 return SourceTextureCubeArray.SampleLevel(SourceSampler, float4(newCoord, float(ArrayIndex)), MipLevel);
97}
diff --git a/contrib/SDL-3.2.8/src/gpu/d3d12/SDL_gpu_d3d12.c b/contrib/SDL-3.2.8/src/gpu/d3d12/SDL_gpu_d3d12.c
new file mode 100644
index 0000000..be13d8d
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/gpu/d3d12/SDL_gpu_d3d12.c
@@ -0,0 +1,9113 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22#include "SDL_internal.h"
23
24#ifdef SDL_GPU_D3D12
25
26#include "../../core/windows/SDL_windows.h"
27#include "../../video/directx/SDL_d3d12.h"
28#include "../SDL_sysgpu.h"
29
30#ifdef __IDXGIInfoQueue_INTERFACE_DEFINED__
31#define HAVE_IDXGIINFOQUEUE
32#endif
33
34// Built-in shaders, compiled with compile_shaders.bat
35
36#define g_FullscreenVert D3D12_FullscreenVert
37#define g_BlitFrom2D D3D12_BlitFrom2D
38#define g_BlitFrom2DArray D3D12_BlitFrom2DArray
39#define g_BlitFrom3D D3D12_BlitFrom3D
40#define g_BlitFromCube D3D12_BlitFromCube
41#define g_BlitFromCubeArray D3D12_BlitFromCubeArray
42#if defined(SDL_PLATFORM_XBOXSERIES)
43#include "D3D12_Blit_Series.h"
44#elif defined(SDL_PLATFORM_XBOXONE)
45#include "D3D12_Blit_One.h"
46#else
47#include "D3D12_Blit.h"
48#endif
49#undef g_FullscreenVert
50#undef g_BlitFrom2D
51#undef g_BlitFrom2DArray
52#undef g_BlitFrom3D
53#undef g_BlitFromCube
54#undef g_BlitFromCubeArray
55
56// Macros
57
58#define SET_ERROR(fmt, msg) \
59 do { \
60 if (renderer->debug_mode) { \
61 SDL_LogError(SDL_LOG_CATEGORY_GPU, fmt, msg); \
62 } \
63 SDL_SetError(fmt, msg); \
64 } while (0)
65
66#define SET_ERROR_AND_RETURN(fmt, msg, ret) \
67 do { \
68 if (renderer->debug_mode) { \
69 SDL_LogError(SDL_LOG_CATEGORY_GPU, fmt, msg); \
70 } \
71 SDL_SetError(fmt, msg); \
72 return ret; \
73 } while (0)
74
75#define SET_STRING_ERROR_AND_RETURN(msg, ret) SET_ERROR_AND_RETURN("%s", msg, ret)
76
77#define CHECK_D3D12_ERROR_AND_RETURN(msg, ret) \
78 do { \
79 if (FAILED(res)) { \
80 D3D12_INTERNAL_SetError(renderer, msg, res); \
81 return (ret); \
82 } \
83 } while (0)
84
85// Defines
86#if defined(_WIN32)
87#if defined(SDL_PLATFORM_XBOXSERIES)
88#define D3D12_DLL "d3d12_xs.dll"
89#elif defined(SDL_PLATFORM_XBOXONE)
90#define D3D12_DLL "d3d12_x.dll"
91#else
92#define D3D12_DLL "d3d12.dll"
93#endif
94#define DXGI_DLL "dxgi.dll"
95#define DXGIDEBUG_DLL "dxgidebug.dll"
96#elif defined(__APPLE__)
97#define D3D12_DLL "libdxvk_d3d12.dylib"
98#define DXGI_DLL "libdxvk_dxgi.dylib"
99#define DXGIDEBUG_DLL "libdxvk_dxgidebug.dylib"
100#else
101#define D3D12_DLL "libdxvk_d3d12.so"
102#define DXGI_DLL "libdxvk_dxgi.so"
103#define DXGIDEBUG_DLL "libdxvk_dxgidebug.so"
104#endif
105
106#define D3D12_CREATE_DEVICE_FUNC "D3D12CreateDevice"
107#define D3D12_SERIALIZE_ROOT_SIGNATURE_FUNC "D3D12SerializeRootSignature"
108#define CREATE_DXGI_FACTORY1_FUNC "CreateDXGIFactory1"
109#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
110#define D3D12_GET_DEBUG_INTERFACE_FUNC "D3D12GetDebugInterface"
111#define WINDOW_PROPERTY_DATA "SDL_GPUD3D12WindowPropertyData"
112#define D3D_FEATURE_LEVEL_CHOICE D3D_FEATURE_LEVEL_11_1
113#define D3D_FEATURE_LEVEL_CHOICE_STR "11_1"
114#define MAX_ROOT_SIGNATURE_PARAMETERS 64
115#define D3D12_FENCE_UNSIGNALED_VALUE 0
116#define D3D12_FENCE_SIGNAL_VALUE 1
117// TODO: do these need to be tuned?
118#define VIEW_GPU_DESCRIPTOR_COUNT 65536
119#define SAMPLER_GPU_DESCRIPTOR_COUNT 2048
120#define STAGING_HEAP_DESCRIPTOR_COUNT 1024
121
122#define SDL_GPU_SHADERSTAGE_COMPUTE (SDL_GPUShaderStage)2
123
124#define EXPAND_ELEMENTS_IF_NEEDED(arr, initialValue, type) \
125 if (arr->count == arr->capacity) { \
126 if (arr->capacity == 0) { \
127 arr->capacity = initialValue; \
128 } else { \
129 arr->capacity *= 2; \
130 } \
131 arr->elements = (type *)SDL_realloc( \
132 arr->elements, \
133 arr->capacity * sizeof(type)); \
134 }
135
136#ifdef _WIN32
137#define HRESULT_FMT "(0x%08lX)"
138#else
139#define HRESULT_FMT "(0x%08X)"
140#endif
141
142// Function Pointer Signatures
143typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY1)(const GUID *riid, void **ppFactory);
144typedef HRESULT(WINAPI *PFN_DXGI_GET_DEBUG_INTERFACE)(const GUID *riid, void **ppDebug);
145
146// IIDs (from https://www.magnumdb.com/)
147static const IID D3D_IID_IDXGIFactory1 = { 0x770aae78, 0xf26f, 0x4dba, { 0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87 } };
148static const IID D3D_IID_IDXGIFactory4 = { 0x1bc6ea02, 0xef36, 0x464f, { 0xbf, 0x0c, 0x21, 0xca, 0x39, 0xe5, 0x16, 0x8a } };
149static const IID D3D_IID_IDXGIFactory5 = { 0x7632e1f5, 0xee65, 0x4dca, { 0x87, 0xfd, 0x84, 0xcd, 0x75, 0xf8, 0x83, 0x8d } };
150static const IID D3D_IID_IDXGIFactory6 = { 0xc1b6694f, 0xff09, 0x44a9, { 0xb0, 0x3c, 0x77, 0x90, 0x0a, 0x0a, 0x1d, 0x17 } };
151static const IID D3D_IID_IDXGIAdapter1 = { 0x29038f61, 0x3839, 0x4626, { 0x91, 0xfd, 0x08, 0x68, 0x79, 0x01, 0x1a, 0x05 } };
152#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
153static const IID D3D_IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } };
154#else
155static const IID D3D_IID_IDXGIDevice = { 0x54ec77fa, 0x1377, 0x44e6, { 0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c } };
156#endif
157static const IID D3D_IID_IDXGISwapChain3 = { 0x94d99bdb, 0xf1f8, 0x4ab0, { 0xb2, 0x36, 0x7d, 0xa0, 0x17, 0x0e, 0xda, 0xb1 } };
158#ifdef HAVE_IDXGIINFOQUEUE
159static const IID D3D_IID_IDXGIDebug = { 0x119e7452, 0xde9e, 0x40fe, { 0x88, 0x06, 0x88, 0xf9, 0x0c, 0x12, 0xb4, 0x41 } };
160static const IID D3D_IID_IDXGIInfoQueue = { 0xd67441c7, 0x672a, 0x476f, { 0x9e, 0x82, 0xcd, 0x55, 0xb4, 0x49, 0x49, 0xce } };
161#endif
162static const GUID D3D_IID_DXGI_DEBUG_ALL = { 0xe48ae283, 0xda80, 0x490b, { 0x87, 0xe6, 0x43, 0xe9, 0xa9, 0xcf, 0xda, 0x08 } };
163
164static const IID D3D_IID_ID3D12Device = { 0x189819f1, 0x1db6, 0x4b57, { 0xbe, 0x54, 0x18, 0x21, 0x33, 0x9b, 0x85, 0xf7 } };
165static const IID D3D_IID_ID3D12CommandQueue = { 0x0ec870a6, 0x5d7e, 0x4c22, { 0x8c, 0xfc, 0x5b, 0xaa, 0xe0, 0x76, 0x16, 0xed } };
166static const IID D3D_IID_ID3D12DescriptorHeap = { 0x8efb471d, 0x616c, 0x4f49, { 0x90, 0xf7, 0x12, 0x7b, 0xb7, 0x63, 0xfa, 0x51 } };
167static const IID D3D_IID_ID3D12Resource = { 0x696442be, 0xa72e, 0x4059, { 0xbc, 0x79, 0x5b, 0x5c, 0x98, 0x04, 0x0f, 0xad } };
168static const IID D3D_IID_ID3D12CommandAllocator = { 0x6102dee4, 0xaf59, 0x4b09, { 0xb9, 0x99, 0xb4, 0x4d, 0x73, 0xf0, 0x9b, 0x24 } };
169static const IID D3D_IID_ID3D12CommandList = { 0x7116d91c, 0xe7e4, 0x47ce, { 0xb8, 0xc6, 0xec, 0x81, 0x68, 0xf4, 0x37, 0xe5 } };
170static const IID D3D_IID_ID3D12GraphicsCommandList = { 0x5b160d0f, 0xac1b, 0x4185, { 0x8b, 0xa8, 0xb3, 0xae, 0x42, 0xa5, 0xa4, 0x55 } };
171static const IID D3D_IID_ID3D12Fence = { 0x0a753dcf, 0xc4d8, 0x4b91, { 0xad, 0xf6, 0xbe, 0x5a, 0x60, 0xd9, 0x5a, 0x76 } };
172static const IID D3D_IID_ID3D12RootSignature = { 0xc54a6b66, 0x72df, 0x4ee8, { 0x8b, 0xe5, 0xa9, 0x46, 0xa1, 0x42, 0x92, 0x14 } };
173static const IID D3D_IID_ID3D12CommandSignature = { 0xc36a797c, 0xec80, 0x4f0a, { 0x89, 0x85, 0xa7, 0xb2, 0x47, 0x50, 0x82, 0xd1 } };
174static const IID D3D_IID_ID3D12PipelineState = { 0x765a30f3, 0xf624, 0x4c6f, { 0xa8, 0x28, 0xac, 0xe9, 0x48, 0x62, 0x24, 0x45 } };
175static const IID D3D_IID_ID3D12Debug = { 0x344488b7, 0x6846, 0x474b, { 0xb9, 0x89, 0xf0, 0x27, 0x44, 0x82, 0x45, 0xe0 } };
176static const IID D3D_IID_ID3D12InfoQueue = { 0x0742a90b, 0xc387, 0x483f, { 0xb9, 0x46, 0x30, 0xa7, 0xe4, 0xe6, 0x14, 0x58 } };
177static const IID D3D_IID_ID3D12InfoQueue1 = { 0x2852dd88, 0xb484, 0x4c0c, { 0xb6, 0xb1, 0x67, 0x16, 0x85, 0x00, 0xe6, 0x00 } };
178
179// Enums
180
181typedef enum D3D12BufferType
182{
183 D3D12_BUFFER_TYPE_GPU,
184 D3D12_BUFFER_TYPE_UNIFORM,
185 D3D12_BUFFER_TYPE_UPLOAD,
186 D3D12_BUFFER_TYPE_DOWNLOAD
187} D3D12BufferType;
188
189// Conversions
190
191static SDL_GPUTextureFormat SwapchainCompositionToSDLTextureFormat[] = {
192 SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM, // SDR
193 SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB, // SDR_LINEAR
194 SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT, // HDR_EXTENDED_LINEAR
195 SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM, // HDR10_ST2084
196};
197
198static DXGI_FORMAT SwapchainCompositionToTextureFormat[] = {
199 DXGI_FORMAT_B8G8R8A8_UNORM, // SDR
200 DXGI_FORMAT_B8G8R8A8_UNORM, // SDR_LINEAR (NOTE: The RTV uses the sRGB format)
201 DXGI_FORMAT_R16G16B16A16_FLOAT, // HDR_EXTENDED_LINEAR
202 DXGI_FORMAT_R10G10B10A2_UNORM, // HDR10_ST2084
203};
204
205static DXGI_COLOR_SPACE_TYPE SwapchainCompositionToColorSpace[] = {
206 DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709, // SDR
207 DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709, // SDR_LINEAR
208 DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709, // HDR_EXTENDED_LINEAR
209 DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 // HDR10_ST2084
210};
211
212static D3D12_BLEND SDLToD3D12_BlendFactor[] = {
213 D3D12_BLEND_ZERO, // INVALID
214 D3D12_BLEND_ZERO, // ZERO
215 D3D12_BLEND_ONE, // ONE
216 D3D12_BLEND_SRC_COLOR, // SRC_COLOR
217 D3D12_BLEND_INV_SRC_COLOR, // ONE_MINUS_SRC_COLOR
218 D3D12_BLEND_DEST_COLOR, // DST_COLOR
219 D3D12_BLEND_INV_DEST_COLOR, // ONE_MINUS_DST_COLOR
220 D3D12_BLEND_SRC_ALPHA, // SRC_ALPHA
221 D3D12_BLEND_INV_SRC_ALPHA, // ONE_MINUS_SRC_ALPHA
222 D3D12_BLEND_DEST_ALPHA, // DST_ALPHA
223 D3D12_BLEND_INV_DEST_ALPHA, // ONE_MINUS_DST_ALPHA
224 D3D12_BLEND_BLEND_FACTOR, // CONSTANT_COLOR
225 D3D12_BLEND_INV_BLEND_FACTOR, // ONE_MINUS_CONSTANT_COLOR
226 D3D12_BLEND_SRC_ALPHA_SAT, // SRC_ALPHA_SATURATE
227};
228SDL_COMPILE_TIME_ASSERT(SDLToD3D12_BlendFactor, SDL_arraysize(SDLToD3D12_BlendFactor) == SDL_GPU_BLENDFACTOR_MAX_ENUM_VALUE);
229
230static D3D12_BLEND SDLToD3D12_BlendFactorAlpha[] = {
231 D3D12_BLEND_ZERO, // INVALID
232 D3D12_BLEND_ZERO, // ZERO
233 D3D12_BLEND_ONE, // ONE
234 D3D12_BLEND_SRC_ALPHA, // SRC_COLOR
235 D3D12_BLEND_INV_SRC_ALPHA, // ONE_MINUS_SRC_COLOR
236 D3D12_BLEND_DEST_ALPHA, // DST_COLOR
237 D3D12_BLEND_INV_DEST_ALPHA, // ONE_MINUS_DST_COLOR
238 D3D12_BLEND_SRC_ALPHA, // SRC_ALPHA
239 D3D12_BLEND_INV_SRC_ALPHA, // ONE_MINUS_SRC_ALPHA
240 D3D12_BLEND_DEST_ALPHA, // DST_ALPHA
241 D3D12_BLEND_INV_DEST_ALPHA, // ONE_MINUS_DST_ALPHA
242 D3D12_BLEND_BLEND_FACTOR, // CONSTANT_COLOR
243 D3D12_BLEND_INV_BLEND_FACTOR, // ONE_MINUS_CONSTANT_COLOR
244 D3D12_BLEND_SRC_ALPHA_SAT, // SRC_ALPHA_SATURATE
245};
246SDL_COMPILE_TIME_ASSERT(SDLToD3D12_BlendFactorAlpha, SDL_arraysize(SDLToD3D12_BlendFactorAlpha) == SDL_GPU_BLENDFACTOR_MAX_ENUM_VALUE);
247
248static D3D12_BLEND_OP SDLToD3D12_BlendOp[] = {
249 D3D12_BLEND_OP_ADD, // INVALID
250 D3D12_BLEND_OP_ADD, // ADD
251 D3D12_BLEND_OP_SUBTRACT, // SUBTRACT
252 D3D12_BLEND_OP_REV_SUBTRACT, // REVERSE_SUBTRACT
253 D3D12_BLEND_OP_MIN, // MIN
254 D3D12_BLEND_OP_MAX // MAX
255};
256SDL_COMPILE_TIME_ASSERT(SDLToD3D12_BlendOp, SDL_arraysize(SDLToD3D12_BlendOp) == SDL_GPU_BLENDOP_MAX_ENUM_VALUE);
257
258// These are actually color formats.
259// For some genius reason, D3D12 splits format capabilites for depth-stencil views.
260static DXGI_FORMAT SDLToD3D12_TextureFormat[] = {
261 DXGI_FORMAT_UNKNOWN, // INVALID
262 DXGI_FORMAT_A8_UNORM, // A8_UNORM
263 DXGI_FORMAT_R8_UNORM, // R8_UNORM
264 DXGI_FORMAT_R8G8_UNORM, // R8G8_UNORM
265 DXGI_FORMAT_R8G8B8A8_UNORM, // R8G8B8A8_UNORM
266 DXGI_FORMAT_R16_UNORM, // R16_UNORM
267 DXGI_FORMAT_R16G16_UNORM, // R16G16_UNORM
268 DXGI_FORMAT_R16G16B16A16_UNORM, // R16G16B16A16_UNORM
269 DXGI_FORMAT_R10G10B10A2_UNORM, // R10G10B10A2_UNORM
270 DXGI_FORMAT_B5G6R5_UNORM, // B5G6R5_UNORM
271 DXGI_FORMAT_B5G5R5A1_UNORM, // B5G5R5A1_UNORM
272 DXGI_FORMAT_B4G4R4A4_UNORM, // B4G4R4A4_UNORM
273 DXGI_FORMAT_B8G8R8A8_UNORM, // B8G8R8A8_UNORM
274 DXGI_FORMAT_BC1_UNORM, // BC1_UNORM
275 DXGI_FORMAT_BC2_UNORM, // BC2_UNORM
276 DXGI_FORMAT_BC3_UNORM, // BC3_UNORM
277 DXGI_FORMAT_BC4_UNORM, // BC4_UNORM
278 DXGI_FORMAT_BC5_UNORM, // BC5_UNORM
279 DXGI_FORMAT_BC7_UNORM, // BC7_UNORM
280 DXGI_FORMAT_BC6H_SF16, // BC6H_FLOAT
281 DXGI_FORMAT_BC6H_UF16, // BC6H_UFLOAT
282 DXGI_FORMAT_R8_SNORM, // R8_SNORM
283 DXGI_FORMAT_R8G8_SNORM, // R8G8_SNORM
284 DXGI_FORMAT_R8G8B8A8_SNORM, // R8G8B8A8_SNORM
285 DXGI_FORMAT_R16_SNORM, // R16_SNORM
286 DXGI_FORMAT_R16G16_SNORM, // R16G16_SNORM
287 DXGI_FORMAT_R16G16B16A16_SNORM, // R16G16B16A16_SNORM
288 DXGI_FORMAT_R16_FLOAT, // R16_FLOAT
289 DXGI_FORMAT_R16G16_FLOAT, // R16G16_FLOAT
290 DXGI_FORMAT_R16G16B16A16_FLOAT, // R16G16B16A16_FLOAT
291 DXGI_FORMAT_R32_FLOAT, // R32_FLOAT
292 DXGI_FORMAT_R32G32_FLOAT, // R32G32_FLOAT
293 DXGI_FORMAT_R32G32B32A32_FLOAT, // R32G32B32A32_FLOAT
294 DXGI_FORMAT_R11G11B10_FLOAT, // R11G11B10_UFLOAT
295 DXGI_FORMAT_R8_UINT, // R8_UINT
296 DXGI_FORMAT_R8G8_UINT, // R8G8_UINT
297 DXGI_FORMAT_R8G8B8A8_UINT, // R8G8B8A8_UINT
298 DXGI_FORMAT_R16_UINT, // R16_UINT
299 DXGI_FORMAT_R16G16_UINT, // R16G16_UINT
300 DXGI_FORMAT_R16G16B16A16_UINT, // R16G16B16A16_UINT
301 DXGI_FORMAT_R32_UINT, // R32_UINT
302 DXGI_FORMAT_R32G32_UINT, // R32G32_UINT
303 DXGI_FORMAT_R32G32B32A32_UINT, // R32G32B32A32_UINT
304 DXGI_FORMAT_R8_SINT, // R8_INT
305 DXGI_FORMAT_R8G8_SINT, // R8G8_INT
306 DXGI_FORMAT_R8G8B8A8_SINT, // R8G8B8A8_INT
307 DXGI_FORMAT_R16_SINT, // R16_INT
308 DXGI_FORMAT_R16G16_SINT, // R16G16_INT
309 DXGI_FORMAT_R16G16B16A16_SINT, // R16G16B16A16_INT
310 DXGI_FORMAT_R32_SINT, // R32_INT
311 DXGI_FORMAT_R32G32_SINT, // R32G32_INT
312 DXGI_FORMAT_R32G32B32A32_SINT, // R32G32B32A32_INT
313 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, // R8G8B8A8_UNORM_SRGB
314 DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, // B8G8R8A8_UNORM_SRGB
315 DXGI_FORMAT_BC1_UNORM_SRGB, // BC1_UNORM_SRGB
316 DXGI_FORMAT_BC2_UNORM_SRGB, // BC2_UNORM_SRGB
317 DXGI_FORMAT_BC3_UNORM_SRGB, // BC3_UNORM_SRGB
318 DXGI_FORMAT_BC7_UNORM_SRGB, // BC7_UNORM_SRGB
319 DXGI_FORMAT_R16_UNORM, // D16_UNORM
320 DXGI_FORMAT_R24_UNORM_X8_TYPELESS, // D24_UNORM
321 DXGI_FORMAT_R32_FLOAT, // D32_FLOAT
322 DXGI_FORMAT_R24_UNORM_X8_TYPELESS, // D24_UNORM_S8_UINT
323 DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, // D32_FLOAT_S8_UINT
324 DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM
325 DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM
326 DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM
327 DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM
328 DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM
329 DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM
330 DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM
331 DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM
332 DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM
333 DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM
334 DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM
335 DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM
336 DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM
337 DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM
338 DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM_SRGB
339 DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM_SRGB
340 DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM_SRGB
341 DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM_SRGB
342 DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM_SRGB
343 DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM_SRGB
344 DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM_SRGB
345 DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM_SRGB
346 DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM_SRGB
347 DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM_SRGB
348 DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM_SRGB
349 DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM_SRGB
350 DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM_SRGB
351 DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM_SRGB
352 DXGI_FORMAT_UNKNOWN, // ASTC_4x4_FLOAT
353 DXGI_FORMAT_UNKNOWN, // ASTC_5x4_FLOAT
354 DXGI_FORMAT_UNKNOWN, // ASTC_5x5_FLOAT
355 DXGI_FORMAT_UNKNOWN, // ASTC_6x5_FLOAT
356 DXGI_FORMAT_UNKNOWN, // ASTC_6x6_FLOAT
357 DXGI_FORMAT_UNKNOWN, // ASTC_8x5_FLOAT
358 DXGI_FORMAT_UNKNOWN, // ASTC_8x6_FLOAT
359 DXGI_FORMAT_UNKNOWN, // ASTC_8x8_FLOAT
360 DXGI_FORMAT_UNKNOWN, // ASTC_10x5_FLOAT
361 DXGI_FORMAT_UNKNOWN, // ASTC_10x6_FLOAT
362 DXGI_FORMAT_UNKNOWN, // ASTC_10x8_FLOAT
363 DXGI_FORMAT_UNKNOWN, // ASTC_10x10_FLOAT
364 DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT
365 DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT
366};
367SDL_COMPILE_TIME_ASSERT(SDLToD3D12_TextureFormat, SDL_arraysize(SDLToD3D12_TextureFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE);
368
369static DXGI_FORMAT SDLToD3D12_DepthFormat[] = {
370 DXGI_FORMAT_UNKNOWN, // INVALID
371 DXGI_FORMAT_UNKNOWN, // A8_UNORM
372 DXGI_FORMAT_UNKNOWN, // R8_UNORM
373 DXGI_FORMAT_UNKNOWN, // R8G8_UNORM
374 DXGI_FORMAT_UNKNOWN, // R8G8B8A8_UNORM
375 DXGI_FORMAT_UNKNOWN, // R16_UNORM
376 DXGI_FORMAT_UNKNOWN, // R16G16_UNORM
377 DXGI_FORMAT_UNKNOWN, // R16G16B16A16_UNORM
378 DXGI_FORMAT_UNKNOWN, // R10G10B10A2_UNORM
379 DXGI_FORMAT_UNKNOWN, // B5G6R5_UNORM
380 DXGI_FORMAT_UNKNOWN, // B5G5R5A1_UNORM
381 DXGI_FORMAT_UNKNOWN, // B4G4R4A4_UNORM
382 DXGI_FORMAT_UNKNOWN, // B8G8R8A8_UNORM
383 DXGI_FORMAT_UNKNOWN, // BC1_UNORM
384 DXGI_FORMAT_UNKNOWN, // BC2_UNORM
385 DXGI_FORMAT_UNKNOWN, // BC3_UNORM
386 DXGI_FORMAT_UNKNOWN, // BC4_UNORM
387 DXGI_FORMAT_UNKNOWN, // BC5_UNORM
388 DXGI_FORMAT_UNKNOWN, // BC7_UNORM
389 DXGI_FORMAT_UNKNOWN, // BC6H_FLOAT
390 DXGI_FORMAT_UNKNOWN, // BC6H_UFLOAT
391 DXGI_FORMAT_UNKNOWN, // R8_SNORM
392 DXGI_FORMAT_UNKNOWN, // R8G8_SNORM
393 DXGI_FORMAT_UNKNOWN, // R8G8B8A8_SNORM
394 DXGI_FORMAT_UNKNOWN, // R16_SNORM
395 DXGI_FORMAT_UNKNOWN, // R16G16_SNORM
396 DXGI_FORMAT_UNKNOWN, // R16G16B16A16_SNORM
397 DXGI_FORMAT_UNKNOWN, // R16_FLOAT
398 DXGI_FORMAT_UNKNOWN, // R16G16_FLOAT
399 DXGI_FORMAT_UNKNOWN, // R16G16B16A16_FLOAT
400 DXGI_FORMAT_UNKNOWN, // R32_FLOAT
401 DXGI_FORMAT_UNKNOWN, // R32G32_FLOAT
402 DXGI_FORMAT_UNKNOWN, // R32G32B32A32_FLOAT
403 DXGI_FORMAT_UNKNOWN, // R11G11B10_UFLOAT
404 DXGI_FORMAT_UNKNOWN, // R8_UINT
405 DXGI_FORMAT_UNKNOWN, // R8G8_UINT
406 DXGI_FORMAT_UNKNOWN, // R8G8B8A8_UINT
407 DXGI_FORMAT_UNKNOWN, // R16_UINT
408 DXGI_FORMAT_UNKNOWN, // R16G16_UINT
409 DXGI_FORMAT_UNKNOWN, // R16G16B16A16_UINT
410 DXGI_FORMAT_UNKNOWN, // R32_UINT
411 DXGI_FORMAT_UNKNOWN, // R32G32_UINT
412 DXGI_FORMAT_UNKNOWN, // R32G32B32A32_UINT
413 DXGI_FORMAT_UNKNOWN, // R8_INT
414 DXGI_FORMAT_UNKNOWN, // R8G8_INT
415 DXGI_FORMAT_UNKNOWN, // R8G8B8A8_INT
416 DXGI_FORMAT_UNKNOWN, // R16_INT
417 DXGI_FORMAT_UNKNOWN, // R16G16_INT
418 DXGI_FORMAT_UNKNOWN, // R16G16B16A16_INT
419 DXGI_FORMAT_UNKNOWN, // R32_INT
420 DXGI_FORMAT_UNKNOWN, // R32G32_INT
421 DXGI_FORMAT_UNKNOWN, // R32G32B32A32_INT
422 DXGI_FORMAT_UNKNOWN, // R8G8B8A8_UNORM_SRGB
423 DXGI_FORMAT_UNKNOWN, // B8G8R8A8_UNORM_SRGB
424 DXGI_FORMAT_UNKNOWN, // BC1_UNORM_SRGB
425 DXGI_FORMAT_UNKNOWN, // BC2_UNORM_SRGB
426 DXGI_FORMAT_UNKNOWN, // BC3_UNORM_SRGB
427 DXGI_FORMAT_UNKNOWN, // BC7_UNORM_SRGB
428 DXGI_FORMAT_D16_UNORM, // D16_UNORM
429 DXGI_FORMAT_D24_UNORM_S8_UINT, // D24_UNORM
430 DXGI_FORMAT_D32_FLOAT, // D32_FLOAT
431 DXGI_FORMAT_D24_UNORM_S8_UINT, // D24_UNORM_S8_UINT
432 DXGI_FORMAT_D32_FLOAT_S8X24_UINT, // D32_FLOAT_S8_UINT
433 DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM
434 DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM
435 DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM
436 DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM
437 DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM
438 DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM
439 DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM
440 DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM
441 DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM
442 DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM
443 DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM
444 DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM
445 DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM
446 DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM
447 DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM_SRGB
448 DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM_SRGB
449 DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM_SRGB
450 DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM_SRGB
451 DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM_SRGB
452 DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM_SRGB
453 DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM_SRGB
454 DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM_SRGB
455 DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM_SRGB
456 DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM_SRGB
457 DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM_SRGB
458 DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM_SRGB
459 DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM_SRGB
460 DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM_SRGB
461 DXGI_FORMAT_UNKNOWN, // ASTC_4x4_FLOAT
462 DXGI_FORMAT_UNKNOWN, // ASTC_5x4_FLOAT
463 DXGI_FORMAT_UNKNOWN, // ASTC_5x5_FLOAT
464 DXGI_FORMAT_UNKNOWN, // ASTC_6x5_FLOAT
465 DXGI_FORMAT_UNKNOWN, // ASTC_6x6_FLOAT
466 DXGI_FORMAT_UNKNOWN, // ASTC_8x5_FLOAT
467 DXGI_FORMAT_UNKNOWN, // ASTC_8x6_FLOAT
468 DXGI_FORMAT_UNKNOWN, // ASTC_8x8_FLOAT
469 DXGI_FORMAT_UNKNOWN, // ASTC_10x5_FLOAT
470 DXGI_FORMAT_UNKNOWN, // ASTC_10x6_FLOAT
471 DXGI_FORMAT_UNKNOWN, // ASTC_10x8_FLOAT
472 DXGI_FORMAT_UNKNOWN, // ASTC_10x10_FLOAT
473 DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT
474 DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT
475};
476SDL_COMPILE_TIME_ASSERT(SDLToD3D12_DepthFormat, SDL_arraysize(SDLToD3D12_DepthFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE);
477
478static D3D12_COMPARISON_FUNC SDLToD3D12_CompareOp[] = {
479 D3D12_COMPARISON_FUNC_NEVER, // INVALID
480 D3D12_COMPARISON_FUNC_NEVER, // NEVER
481 D3D12_COMPARISON_FUNC_LESS, // LESS
482 D3D12_COMPARISON_FUNC_EQUAL, // EQUAL
483 D3D12_COMPARISON_FUNC_LESS_EQUAL, // LESS_OR_EQUAL
484 D3D12_COMPARISON_FUNC_GREATER, // GREATER
485 D3D12_COMPARISON_FUNC_NOT_EQUAL, // NOT_EQUAL
486 D3D12_COMPARISON_FUNC_GREATER_EQUAL, // GREATER_OR_EQUAL
487 D3D12_COMPARISON_FUNC_ALWAYS // ALWAYS
488};
489SDL_COMPILE_TIME_ASSERT(SDLToD3D12_CompareOp, SDL_arraysize(SDLToD3D12_CompareOp) == SDL_GPU_COMPAREOP_MAX_ENUM_VALUE);
490
491static D3D12_STENCIL_OP SDLToD3D12_StencilOp[] = {
492 D3D12_STENCIL_OP_KEEP, // INVALID
493 D3D12_STENCIL_OP_KEEP, // KEEP
494 D3D12_STENCIL_OP_ZERO, // ZERO
495 D3D12_STENCIL_OP_REPLACE, // REPLACE
496 D3D12_STENCIL_OP_INCR_SAT, // INCREMENT_AND_CLAMP
497 D3D12_STENCIL_OP_DECR_SAT, // DECREMENT_AND_CLAMP
498 D3D12_STENCIL_OP_INVERT, // INVERT
499 D3D12_STENCIL_OP_INCR, // INCREMENT_AND_WRAP
500 D3D12_STENCIL_OP_DECR // DECREMENT_AND_WRAP
501};
502SDL_COMPILE_TIME_ASSERT(SDLToD3D12_StencilOp, SDL_arraysize(SDLToD3D12_StencilOp) == SDL_GPU_STENCILOP_MAX_ENUM_VALUE);
503
504static D3D12_CULL_MODE SDLToD3D12_CullMode[] = {
505 D3D12_CULL_MODE_NONE, // NONE
506 D3D12_CULL_MODE_FRONT, // FRONT
507 D3D12_CULL_MODE_BACK // BACK
508};
509
510static D3D12_FILL_MODE SDLToD3D12_FillMode[] = {
511 D3D12_FILL_MODE_SOLID, // FILL
512 D3D12_FILL_MODE_WIREFRAME // LINE
513};
514
515static D3D12_INPUT_CLASSIFICATION SDLToD3D12_InputRate[] = {
516 D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, // VERTEX
517 D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA // INSTANCE
518};
519
520static DXGI_FORMAT SDLToD3D12_VertexFormat[] = {
521 DXGI_FORMAT_UNKNOWN, // UNKNOWN
522 DXGI_FORMAT_R32_SINT, // INT
523 DXGI_FORMAT_R32G32_SINT, // INT2
524 DXGI_FORMAT_R32G32B32_SINT, // INT3
525 DXGI_FORMAT_R32G32B32A32_SINT, // INT4
526 DXGI_FORMAT_R32_UINT, // UINT
527 DXGI_FORMAT_R32G32_UINT, // UINT2
528 DXGI_FORMAT_R32G32B32_UINT, // UINT3
529 DXGI_FORMAT_R32G32B32A32_UINT, // UINT4
530 DXGI_FORMAT_R32_FLOAT, // FLOAT
531 DXGI_FORMAT_R32G32_FLOAT, // FLOAT2
532 DXGI_FORMAT_R32G32B32_FLOAT, // FLOAT3
533 DXGI_FORMAT_R32G32B32A32_FLOAT, // FLOAT4
534 DXGI_FORMAT_R8G8_SINT, // BYTE2
535 DXGI_FORMAT_R8G8B8A8_SINT, // BYTE4
536 DXGI_FORMAT_R8G8_UINT, // UBYTE2
537 DXGI_FORMAT_R8G8B8A8_UINT, // UBYTE4
538 DXGI_FORMAT_R8G8_SNORM, // BYTE2_NORM
539 DXGI_FORMAT_R8G8B8A8_SNORM, // BYTE4_NORM
540 DXGI_FORMAT_R8G8_UNORM, // UBYTE2_NORM
541 DXGI_FORMAT_R8G8B8A8_UNORM, // UBYTE4_NORM
542 DXGI_FORMAT_R16G16_SINT, // SHORT2
543 DXGI_FORMAT_R16G16B16A16_SINT, // SHORT4
544 DXGI_FORMAT_R16G16_UINT, // USHORT2
545 DXGI_FORMAT_R16G16B16A16_UINT, // USHORT4
546 DXGI_FORMAT_R16G16_SNORM, // SHORT2_NORM
547 DXGI_FORMAT_R16G16B16A16_SNORM, // SHORT4_NORM
548 DXGI_FORMAT_R16G16_UNORM, // USHORT2_NORM
549 DXGI_FORMAT_R16G16B16A16_UNORM, // USHORT4_NORM
550 DXGI_FORMAT_R16G16_FLOAT, // HALF2
551 DXGI_FORMAT_R16G16B16A16_FLOAT // HALF4
552};
553SDL_COMPILE_TIME_ASSERT(SDLToD3D12_VertexFormat, SDL_arraysize(SDLToD3D12_VertexFormat) == SDL_GPU_VERTEXELEMENTFORMAT_MAX_ENUM_VALUE);
554
555static Uint32 SDLToD3D12_SampleCount[] = {
556 1, // SDL_GPU_SAMPLECOUNT_1
557 2, // SDL_GPU_SAMPLECOUNT_2
558 4, // SDL_GPU_SAMPLECOUNT_4
559 8, // SDL_GPU_SAMPLECOUNT_8
560};
561
562static D3D12_PRIMITIVE_TOPOLOGY SDLToD3D12_PrimitiveType[] = {
563 D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, // TRIANGLELIST
564 D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, // TRIANGLESTRIP
565 D3D_PRIMITIVE_TOPOLOGY_LINELIST, // LINELIST
566 D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, // LINESTRIP
567 D3D_PRIMITIVE_TOPOLOGY_POINTLIST // POINTLIST
568};
569
570static D3D12_PRIMITIVE_TOPOLOGY_TYPE SDLToD3D12_PrimitiveTopologyType[] = {
571 D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, // TRIANGLELIST
572 D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, // TRIANGLESTRIP
573 D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE, // LINELIST
574 D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE, // LINESTRIP
575 D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT // POINTLIST
576};
577
578static D3D12_TEXTURE_ADDRESS_MODE SDLToD3D12_SamplerAddressMode[] = {
579 D3D12_TEXTURE_ADDRESS_MODE_WRAP, // REPEAT
580 D3D12_TEXTURE_ADDRESS_MODE_MIRROR, // MIRRORED_REPEAT
581 D3D12_TEXTURE_ADDRESS_MODE_CLAMP // CLAMP_TO_EDGE
582};
583
584static D3D12_FILTER SDLToD3D12_Filter(
585 SDL_GPUFilter minFilter,
586 SDL_GPUFilter magFilter,
587 SDL_GPUSamplerMipmapMode mipmapMode,
588 bool comparisonEnabled,
589 bool anisotropyEnabled)
590{
591 D3D12_FILTER result = D3D12_ENCODE_BASIC_FILTER(
592 (minFilter == SDL_GPU_FILTER_LINEAR) ? 1 : 0,
593 (magFilter == SDL_GPU_FILTER_LINEAR) ? 1 : 0,
594 (mipmapMode == SDL_GPU_SAMPLERMIPMAPMODE_LINEAR) ? 1 : 0,
595 comparisonEnabled ? 1 : 0);
596
597 if (anisotropyEnabled) {
598 result = (D3D12_FILTER)(result | D3D12_ANISOTROPIC_FILTERING_BIT);
599 }
600
601 return result;
602}
603
604// Structures
605typedef struct D3D12Renderer D3D12Renderer;
606typedef struct D3D12CommandBufferPool D3D12CommandBufferPool;
607typedef struct D3D12CommandBuffer D3D12CommandBuffer;
608typedef struct D3D12Texture D3D12Texture;
609typedef struct D3D12Shader D3D12Shader;
610typedef struct D3D12GraphicsPipeline D3D12GraphicsPipeline;
611typedef struct D3D12ComputePipeline D3D12ComputePipeline;
612typedef struct D3D12Buffer D3D12Buffer;
613typedef struct D3D12BufferContainer D3D12BufferContainer;
614typedef struct D3D12UniformBuffer D3D12UniformBuffer;
615typedef struct D3D12DescriptorHeap D3D12DescriptorHeap;
616typedef struct D3D12StagingDescriptor D3D12StagingDescriptor;
617typedef struct D3D12TextureDownload D3D12TextureDownload;
618
619typedef struct D3D12Fence
620{
621 ID3D12Fence *handle;
622 HANDLE event; // used for blocking
623 SDL_AtomicInt referenceCount;
624} D3D12Fence;
625
626struct D3D12DescriptorHeap
627{
628 ID3D12DescriptorHeap *handle;
629 D3D12_DESCRIPTOR_HEAP_TYPE heapType;
630 D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapCPUStart;
631 D3D12_GPU_DESCRIPTOR_HANDLE descriptorHeapGPUStart; // only used by GPU heaps
632 Uint32 maxDescriptors;
633 Uint32 descriptorSize;
634 bool staging;
635
636 Uint32 currentDescriptorIndex; // only used by GPU heaps
637};
638
639typedef struct D3D12GPUDescriptorHeapPool
640{
641 Uint32 capacity;
642 Uint32 count;
643 D3D12DescriptorHeap **heaps;
644 SDL_Mutex *lock;
645} D3D12GPUDescriptorHeapPool;
646
647// The only thing we care about with staging descriptors is being able to grab a free descriptor.
648typedef struct D3D12StagingDescriptorPool
649{
650 Uint32 heapCount;
651 D3D12DescriptorHeap **heaps;
652
653 // Descriptor handles are owned by resources, so these can be thought of as descriptions of a free index within a heap.
654 Uint32 freeDescriptorCapacity;
655 Uint32 freeDescriptorCount;
656 D3D12StagingDescriptor *freeDescriptors;
657
658 SDL_Mutex *lock;
659} D3D12StagingDescriptorPool;
660
661struct D3D12StagingDescriptor
662{
663 D3D12StagingDescriptorPool *pool;
664 D3D12DescriptorHeap *heap;
665 D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle;
666 Uint32 cpuHandleIndex;
667};
668
669typedef struct D3D12TextureContainer
670{
671 TextureCommonHeader header;
672
673 D3D12Texture *activeTexture;
674
675 D3D12Texture **textures;
676 Uint32 textureCapacity;
677 Uint32 textureCount;
678
679 // Swapchain images cannot be cycled
680 bool canBeCycled;
681
682 char *debugName;
683} D3D12TextureContainer;
684
685// Null views represent by heap = NULL
686typedef struct D3D12TextureSubresource
687{
688 D3D12Texture *parent;
689 Uint32 layer;
690 Uint32 level;
691 Uint32 depth;
692 Uint32 index;
693
694 // One per depth slice
695 D3D12StagingDescriptor *rtvHandles; // NULL if not a color target
696
697 D3D12StagingDescriptor uavHandle; // NULL if not a compute storage write texture
698 D3D12StagingDescriptor dsvHandle; // NULL if not a depth stencil target
699} D3D12TextureSubresource;
700
701struct D3D12Texture
702{
703 D3D12TextureContainer *container;
704 Uint32 containerIndex;
705
706 D3D12TextureSubresource *subresources;
707 Uint32 subresourceCount; /* layerCount * num_levels */
708
709 ID3D12Resource *resource;
710 D3D12StagingDescriptor srvHandle;
711
712 SDL_AtomicInt referenceCount;
713};
714
715typedef struct D3D12Sampler
716{
717 SDL_GPUSamplerCreateInfo createInfo;
718 D3D12StagingDescriptor handle;
719 SDL_AtomicInt referenceCount;
720} D3D12Sampler;
721
722typedef struct D3D12WindowData
723{
724 SDL_Window *window;
725#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
726 D3D12XBOX_FRAME_PIPELINE_TOKEN frameToken;
727#else
728 IDXGISwapChain3 *swapchain;
729#endif
730 SDL_GPUPresentMode present_mode;
731 SDL_GPUSwapchainComposition swapchainComposition;
732 DXGI_COLOR_SPACE_TYPE swapchainColorSpace;
733 Uint32 frameCounter;
734
735 D3D12TextureContainer textureContainers[MAX_FRAMES_IN_FLIGHT];
736 Uint32 swapchainTextureCount;
737
738 SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT];
739 Uint32 width;
740 Uint32 height;
741 bool needsSwapchainRecreate;
742} D3D12WindowData;
743
744typedef struct D3D12PresentData
745{
746 D3D12WindowData *windowData;
747 Uint32 swapchainImageIndex;
748} D3D12PresentData;
749
750struct D3D12Renderer
751{
752 // Reference to the parent device
753 SDL_GPUDevice *sdlGPUDevice;
754
755#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
756 IDXGIDebug *dxgiDebug;
757 IDXGIFactory4 *factory;
758#ifdef HAVE_IDXGIINFOQUEUE
759 IDXGIInfoQueue *dxgiInfoQueue;
760#endif
761 IDXGIAdapter1 *adapter;
762 SDL_SharedObject *dxgi_dll;
763 SDL_SharedObject *dxgidebug_dll;
764#endif
765 ID3D12Debug *d3d12Debug;
766 BOOL supportsTearing;
767 SDL_SharedObject *d3d12_dll;
768 ID3D12Device *device;
769 PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignature_func;
770 const char *semantic;
771 SDL_iconv_t iconv;
772
773 ID3D12CommandQueue *commandQueue;
774
775 bool debug_mode;
776 bool GPUUploadHeapSupported;
777 // FIXME: these might not be necessary since we're not using custom heaps
778 bool UMA;
779 bool UMACacheCoherent;
780 Uint32 allowedFramesInFlight;
781
782 // Indirect command signatures
783 ID3D12CommandSignature *indirectDrawCommandSignature;
784 ID3D12CommandSignature *indirectIndexedDrawCommandSignature;
785 ID3D12CommandSignature *indirectDispatchCommandSignature;
786
787 // Blit
788 SDL_GPUShader *blitVertexShader;
789 SDL_GPUShader *blitFrom2DShader;
790 SDL_GPUShader *blitFrom2DArrayShader;
791 SDL_GPUShader *blitFrom3DShader;
792 SDL_GPUShader *blitFromCubeShader;
793 SDL_GPUShader *blitFromCubeArrayShader;
794
795 SDL_GPUSampler *blitNearestSampler;
796 SDL_GPUSampler *blitLinearSampler;
797
798 BlitPipelineCacheEntry *blitPipelines;
799 Uint32 blitPipelineCount;
800 Uint32 blitPipelineCapacity;
801
802 // Resources
803
804 D3D12CommandBuffer **availableCommandBuffers;
805 Uint32 availableCommandBufferCount;
806 Uint32 availableCommandBufferCapacity;
807
808 D3D12CommandBuffer **submittedCommandBuffers;
809 Uint32 submittedCommandBufferCount;
810 Uint32 submittedCommandBufferCapacity;
811
812 D3D12UniformBuffer **uniformBufferPool;
813 Uint32 uniformBufferPoolCount;
814 Uint32 uniformBufferPoolCapacity;
815
816 D3D12WindowData **claimedWindows;
817 Uint32 claimedWindowCount;
818 Uint32 claimedWindowCapacity;
819
820 D3D12Fence **availableFences;
821 Uint32 availableFenceCount;
822 Uint32 availableFenceCapacity;
823
824 D3D12StagingDescriptorPool *stagingDescriptorPools[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
825 D3D12GPUDescriptorHeapPool gpuDescriptorHeapPools[2];
826
827 // Deferred resource releasing
828
829 D3D12Buffer **buffersToDestroy;
830 Uint32 buffersToDestroyCount;
831 Uint32 buffersToDestroyCapacity;
832
833 D3D12Texture **texturesToDestroy;
834 Uint32 texturesToDestroyCount;
835 Uint32 texturesToDestroyCapacity;
836
837 D3D12Sampler **samplersToDestroy;
838 Uint32 samplersToDestroyCount;
839 Uint32 samplersToDestroyCapacity;
840
841 D3D12GraphicsPipeline **graphicsPipelinesToDestroy;
842 Uint32 graphicsPipelinesToDestroyCount;
843 Uint32 graphicsPipelinesToDestroyCapacity;
844
845 D3D12ComputePipeline **computePipelinesToDestroy;
846 Uint32 computePipelinesToDestroyCount;
847 Uint32 computePipelinesToDestroyCapacity;
848
849 // Locks
850 SDL_Mutex *acquireCommandBufferLock;
851 SDL_Mutex *acquireUniformBufferLock;
852 SDL_Mutex *submitLock;
853 SDL_Mutex *windowLock;
854 SDL_Mutex *fenceLock;
855 SDL_Mutex *disposeLock;
856};
857
858struct D3D12CommandBuffer
859{
860 // reserved for SDL_gpu
861 CommandBufferCommonHeader common;
862
863 // non owning parent reference
864 D3D12Renderer *renderer;
865
866 ID3D12CommandAllocator *commandAllocator;
867 ID3D12GraphicsCommandList *graphicsCommandList;
868 D3D12Fence *inFlightFence;
869 bool autoReleaseFence;
870
871 // Presentation data
872 D3D12PresentData *presentDatas;
873 Uint32 presentDataCount;
874 Uint32 presentDataCapacity;
875
876 D3D12TextureSubresource *colorTargetSubresources[MAX_COLOR_TARGET_BINDINGS];
877 D3D12TextureSubresource *colorResolveSubresources[MAX_COLOR_TARGET_BINDINGS];
878 D3D12TextureSubresource *depthStencilTextureSubresource;
879 D3D12GraphicsPipeline *currentGraphicsPipeline;
880 D3D12ComputePipeline *currentComputePipeline;
881
882 // Set at acquire time
883 D3D12DescriptorHeap *gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + 1];
884
885 D3D12UniformBuffer **usedUniformBuffers;
886 Uint32 usedUniformBufferCount;
887 Uint32 usedUniformBufferCapacity;
888
889 // Resource slot state
890 bool needVertexBufferBind;
891 bool needVertexSamplerBind;
892 bool needVertexStorageTextureBind;
893 bool needVertexStorageBufferBind;
894 bool needVertexUniformBufferBind[MAX_UNIFORM_BUFFERS_PER_STAGE];
895 bool needFragmentSamplerBind;
896 bool needFragmentStorageTextureBind;
897 bool needFragmentStorageBufferBind;
898 bool needFragmentUniformBufferBind[MAX_UNIFORM_BUFFERS_PER_STAGE];
899
900 bool needComputeSamplerBind;
901 bool needComputeReadOnlyStorageTextureBind;
902 bool needComputeReadOnlyStorageBufferBind;
903 bool needComputeUniformBufferBind[MAX_UNIFORM_BUFFERS_PER_STAGE];
904
905 D3D12Buffer *vertexBuffers[MAX_VERTEX_BUFFERS];
906 Uint32 vertexBufferOffsets[MAX_VERTEX_BUFFERS];
907 Uint32 vertexBufferCount;
908
909 D3D12Texture *vertexSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
910 D3D12Sampler *vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
911 D3D12Texture *vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
912 D3D12Buffer *vertexStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
913 D3D12UniformBuffer *vertexUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
914
915 D3D12Texture *fragmentSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
916 D3D12Sampler *fragmentSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
917 D3D12Texture *fragmentStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
918 D3D12Buffer *fragmentStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
919 D3D12UniformBuffer *fragmentUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
920
921 D3D12Texture *computeSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
922 D3D12Sampler *computeSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
923 D3D12Texture *computeReadOnlyStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
924 D3D12Buffer *computeReadOnlyStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
925 D3D12TextureSubresource *computeReadWriteStorageTextureSubresources[MAX_COMPUTE_WRITE_TEXTURES];
926 Uint32 computeReadWriteStorageTextureSubresourceCount;
927 D3D12Buffer *computeReadWriteStorageBuffers[MAX_COMPUTE_WRITE_BUFFERS];
928 Uint32 computeReadWriteStorageBufferCount;
929 D3D12UniformBuffer *computeUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
930
931 // Resource tracking
932 D3D12Texture **usedTextures;
933 Uint32 usedTextureCount;
934 Uint32 usedTextureCapacity;
935
936 D3D12Buffer **usedBuffers;
937 Uint32 usedBufferCount;
938 Uint32 usedBufferCapacity;
939
940 D3D12Sampler **usedSamplers;
941 Uint32 usedSamplerCount;
942 Uint32 usedSamplerCapacity;
943
944 D3D12GraphicsPipeline **usedGraphicsPipelines;
945 Uint32 usedGraphicsPipelineCount;
946 Uint32 usedGraphicsPipelineCapacity;
947
948 D3D12ComputePipeline **usedComputePipelines;
949 Uint32 usedComputePipelineCount;
950 Uint32 usedComputePipelineCapacity;
951
952 // Used for texture pitch hack
953 D3D12TextureDownload **textureDownloads;
954 Uint32 textureDownloadCount;
955 Uint32 textureDownloadCapacity;
956};
957
958struct D3D12Shader
959{
960 // todo cleanup
961 void *bytecode;
962 size_t bytecodeSize;
963
964 SDL_GPUShaderStage stage;
965 Uint32 num_samplers;
966 Uint32 numUniformBuffers;
967 Uint32 numStorageBuffers;
968 Uint32 numStorageTextures;
969};
970
971typedef struct D3D12GraphicsRootSignature
972{
973 ID3D12RootSignature *handle;
974
975 Sint32 vertexSamplerRootIndex;
976 Sint32 vertexSamplerTextureRootIndex;
977 Sint32 vertexStorageTextureRootIndex;
978 Sint32 vertexStorageBufferRootIndex;
979
980 Sint32 vertexUniformBufferRootIndex[MAX_UNIFORM_BUFFERS_PER_STAGE];
981
982 Sint32 fragmentSamplerRootIndex;
983 Sint32 fragmentSamplerTextureRootIndex;
984 Sint32 fragmentStorageTextureRootIndex;
985 Sint32 fragmentStorageBufferRootIndex;
986
987 Sint32 fragmentUniformBufferRootIndex[MAX_UNIFORM_BUFFERS_PER_STAGE];
988} D3D12GraphicsRootSignature;
989
990struct D3D12GraphicsPipeline
991{
992 ID3D12PipelineState *pipelineState;
993 D3D12GraphicsRootSignature *rootSignature;
994 SDL_GPUPrimitiveType primitiveType;
995
996 Uint32 vertexStrides[MAX_VERTEX_BUFFERS];
997
998 Uint32 vertexSamplerCount;
999 Uint32 vertexUniformBufferCount;
1000 Uint32 vertexStorageBufferCount;
1001 Uint32 vertexStorageTextureCount;
1002
1003 Uint32 fragmentSamplerCount;
1004 Uint32 fragmentUniformBufferCount;
1005 Uint32 fragmentStorageBufferCount;
1006 Uint32 fragmentStorageTextureCount;
1007
1008 SDL_AtomicInt referenceCount;
1009};
1010
1011typedef struct D3D12ComputeRootSignature
1012{
1013 ID3D12RootSignature *handle;
1014
1015 Sint32 samplerRootIndex;
1016 Sint32 samplerTextureRootIndex;
1017 Sint32 readOnlyStorageTextureRootIndex;
1018 Sint32 readOnlyStorageBufferRootIndex;
1019 Sint32 readWriteStorageTextureRootIndex;
1020 Sint32 readWriteStorageBufferRootIndex;
1021 Sint32 uniformBufferRootIndex[MAX_UNIFORM_BUFFERS_PER_STAGE];
1022} D3D12ComputeRootSignature;
1023
1024struct D3D12ComputePipeline
1025{
1026 ID3D12PipelineState *pipelineState;
1027 D3D12ComputeRootSignature *rootSignature;
1028
1029 Uint32 numSamplers;
1030 Uint32 numReadOnlyStorageTextures;
1031 Uint32 numReadOnlyStorageBuffers;
1032 Uint32 numReadWriteStorageTextures;
1033 Uint32 numReadWriteStorageBuffers;
1034 Uint32 numUniformBuffers;
1035
1036 SDL_AtomicInt referenceCount;
1037};
1038
1039struct D3D12TextureDownload
1040{
1041 D3D12Buffer *destinationBuffer;
1042 D3D12Buffer *temporaryBuffer;
1043 Uint32 width;
1044 Uint32 height;
1045 Uint32 depth;
1046 Uint32 bufferOffset;
1047 Uint32 bytesPerRow;
1048 Uint32 bytesPerDepthSlice;
1049 Uint32 alignedBytesPerRow;
1050};
1051
1052struct D3D12Buffer
1053{
1054 D3D12BufferContainer *container;
1055 Uint32 containerIndex;
1056
1057 ID3D12Resource *handle;
1058 D3D12StagingDescriptor uavDescriptor;
1059 D3D12StagingDescriptor srvDescriptor;
1060 D3D12StagingDescriptor cbvDescriptor;
1061 D3D12_GPU_VIRTUAL_ADDRESS virtualAddress;
1062 Uint8 *mapPointer; // NULL except for upload buffers and fast uniform buffers
1063 SDL_AtomicInt referenceCount;
1064 bool transitioned; // used for initial resource barrier
1065};
1066
1067struct D3D12BufferContainer
1068{
1069 SDL_GPUBufferUsageFlags usage;
1070 Uint32 size;
1071 D3D12BufferType type;
1072
1073 D3D12Buffer *activeBuffer;
1074
1075 D3D12Buffer **buffers;
1076 Uint32 bufferCapacity;
1077 Uint32 bufferCount;
1078
1079 D3D12_RESOURCE_DESC bufferDesc;
1080
1081 char *debugName;
1082};
1083
1084struct D3D12UniformBuffer
1085{
1086 D3D12Buffer *buffer;
1087 Uint32 writeOffset;
1088 Uint32 drawOffset;
1089 Uint32 currentBlockSize;
1090};
1091
1092// Forward function declarations
1093
1094static void D3D12_ReleaseWindow(SDL_GPURenderer *driverData, SDL_Window *window);
1095static bool D3D12_Wait(SDL_GPURenderer *driverData);
1096static bool D3D12_WaitForFences(SDL_GPURenderer *driverData, bool waitAll, SDL_GPUFence *const *fences, Uint32 numFences);
1097static void D3D12_INTERNAL_ReleaseBlitPipelines(SDL_GPURenderer *driverData);
1098
1099// Helpers
1100
1101static Uint32 D3D12_INTERNAL_Align(Uint32 location, Uint32 alignment)
1102{
1103 return (location + (alignment - 1)) & ~(alignment - 1);
1104}
1105
1106// Xbox Hack
1107
1108#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
1109// FIXME: This is purely to work around a presentation bug when recreating the device/command queue.
1110static ID3D12Device *s_Device;
1111static ID3D12CommandQueue *s_CommandQueue;
1112#endif
1113
1114#if defined(SDL_PLATFORM_XBOXONE)
1115// These are not defined in d3d12_x.h.
1116typedef HRESULT (D3DAPI* PFN_D3D12_XBOX_CREATE_DEVICE)(_In_opt_ IGraphicsUnknown*, _In_ const D3D12XBOX_CREATE_DEVICE_PARAMETERS*, _In_ REFIID, _Outptr_opt_ void**);
1117#define D3D12_STANDARD_MULTISAMPLE_PATTERN DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN
1118#endif
1119
1120// Logging
1121
1122static void D3D12_INTERNAL_SetError(
1123 D3D12Renderer *renderer,
1124 const char *msg,
1125 HRESULT res)
1126{
1127 #define MAX_ERROR_LEN 1024 // FIXME: Arbitrary!
1128
1129 // Buffer for text, ensure space for \0 terminator after buffer
1130 char wszMsgBuff[MAX_ERROR_LEN + 1];
1131 DWORD dwChars; // Number of chars returned.
1132
1133 if (res == DXGI_ERROR_DEVICE_REMOVED) {
1134 if (renderer->device) {
1135 res = ID3D12Device_GetDeviceRemovedReason(renderer->device);
1136 }
1137 }
1138
1139 // Try to get the message from the system errors.
1140 dwChars = FormatMessageA(
1141 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1142 NULL,
1143 res,
1144 0,
1145 wszMsgBuff,
1146 MAX_ERROR_LEN,
1147 NULL);
1148
1149 // No message? Screw it, just post the code.
1150 if (dwChars == 0) {
1151 if (renderer->debug_mode) {
1152 SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s! Error Code: " HRESULT_FMT, msg, res);
1153 }
1154 SDL_SetError("%s! Error Code: " HRESULT_FMT, msg, res);
1155 return;
1156 }
1157
1158 // Ensure valid range
1159 dwChars = SDL_min(dwChars, MAX_ERROR_LEN);
1160
1161 // Trim whitespace from tail of message
1162 while (dwChars > 0) {
1163 if (wszMsgBuff[dwChars - 1] <= ' ') {
1164 dwChars--;
1165 } else {
1166 break;
1167 }
1168 }
1169
1170 // Ensure null-terminated string
1171 wszMsgBuff[dwChars] = '\0';
1172
1173 if (renderer->debug_mode) {
1174 SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s! Error Code: %s " HRESULT_FMT, msg, wszMsgBuff, res);
1175 }
1176 SDL_SetError("%s! Error Code: %s " HRESULT_FMT, msg, wszMsgBuff, res);
1177}
1178
1179// Release / Cleanup
1180
1181static void D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
1182 D3D12Renderer *renderer,
1183 D3D12StagingDescriptor *cpuDescriptor)
1184{
1185 D3D12StagingDescriptorPool *pool = cpuDescriptor->pool;
1186
1187 if (pool != NULL) {
1188 SDL_LockMutex(pool->lock);
1189 SDL_memcpy(&pool->freeDescriptors[pool->freeDescriptorCount], cpuDescriptor, sizeof(D3D12StagingDescriptor));
1190 pool->freeDescriptorCount += 1;
1191 SDL_UnlockMutex(pool->lock);
1192 }
1193}
1194
1195static void D3D12_INTERNAL_DestroyBuffer(
1196 D3D12Renderer *renderer,
1197 D3D12Buffer *buffer)
1198{
1199 if (!buffer) {
1200 return;
1201 }
1202
1203 if (buffer->mapPointer != NULL) {
1204 ID3D12Resource_Unmap(
1205 buffer->handle,
1206 0,
1207 NULL);
1208 }
1209 D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
1210 renderer,
1211 &buffer->srvDescriptor);
1212 D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
1213 renderer,
1214 &buffer->uavDescriptor);
1215 D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
1216 renderer,
1217 &buffer->cbvDescriptor);
1218
1219 if (buffer->handle) {
1220 ID3D12Resource_Release(buffer->handle);
1221 }
1222 SDL_free(buffer);
1223}
1224
1225static void D3D12_INTERNAL_ReleaseBuffer(
1226 D3D12Renderer *renderer,
1227 D3D12Buffer *buffer)
1228{
1229 SDL_LockMutex(renderer->disposeLock);
1230
1231 EXPAND_ARRAY_IF_NEEDED(
1232 renderer->buffersToDestroy,
1233 D3D12Buffer *,
1234 renderer->buffersToDestroyCount + 1,
1235 renderer->buffersToDestroyCapacity,
1236 renderer->buffersToDestroyCapacity * 2);
1237
1238 renderer->buffersToDestroy[renderer->buffersToDestroyCount] = buffer;
1239 renderer->buffersToDestroyCount += 1;
1240
1241 SDL_UnlockMutex(renderer->disposeLock);
1242}
1243
1244static void D3D12_INTERNAL_ReleaseBufferContainer(
1245 D3D12Renderer *renderer,
1246 D3D12BufferContainer *container)
1247{
1248 SDL_LockMutex(renderer->disposeLock);
1249
1250 for (Uint32 i = 0; i < container->bufferCount; i += 1) {
1251 D3D12_INTERNAL_ReleaseBuffer(
1252 renderer,
1253 container->buffers[i]);
1254 }
1255
1256 // Containers are just client handles, so we can free immediately
1257 if (container->debugName) {
1258 SDL_free(container->debugName);
1259 }
1260 SDL_free(container->buffers);
1261 SDL_free(container);
1262
1263 SDL_UnlockMutex(renderer->disposeLock);
1264}
1265
1266static void D3D12_INTERNAL_DestroyTexture(
1267 D3D12Renderer *renderer,
1268 D3D12Texture *texture)
1269{
1270 if (!texture) {
1271 return;
1272 }
1273 for (Uint32 i = 0; i < texture->subresourceCount; i += 1) {
1274 D3D12TextureSubresource *subresource = &texture->subresources[i];
1275 if (subresource->rtvHandles) {
1276 for (Uint32 depthIndex = 0; depthIndex < subresource->depth; depthIndex += 1) {
1277 D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
1278 renderer,
1279 &subresource->rtvHandles[depthIndex]);
1280 }
1281 SDL_free(subresource->rtvHandles);
1282 }
1283
1284 D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
1285 renderer,
1286 &subresource->uavHandle);
1287
1288 D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
1289 renderer,
1290 &subresource->dsvHandle);
1291 }
1292 SDL_free(texture->subresources);
1293
1294 D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
1295 renderer,
1296 &texture->srvHandle);
1297
1298 if (texture->resource) {
1299 ID3D12Resource_Release(texture->resource);
1300 }
1301
1302 SDL_free(texture);
1303}
1304
1305static void D3D12_INTERNAL_ReleaseTexture(
1306 D3D12Renderer *renderer,
1307 D3D12Texture *texture)
1308{
1309 SDL_LockMutex(renderer->disposeLock);
1310
1311 EXPAND_ARRAY_IF_NEEDED(
1312 renderer->texturesToDestroy,
1313 D3D12Texture *,
1314 renderer->texturesToDestroyCount + 1,
1315 renderer->texturesToDestroyCapacity,
1316 renderer->texturesToDestroyCapacity * 2);
1317
1318 renderer->texturesToDestroy[renderer->texturesToDestroyCount] = texture;
1319 renderer->texturesToDestroyCount += 1;
1320
1321 SDL_UnlockMutex(renderer->disposeLock);
1322}
1323
1324static void D3D12_INTERNAL_ReleaseTextureContainer(
1325 D3D12Renderer *renderer,
1326 D3D12TextureContainer *container)
1327{
1328 SDL_LockMutex(renderer->disposeLock);
1329
1330 for (Uint32 i = 0; i < container->textureCount; i += 1) {
1331 D3D12_INTERNAL_ReleaseTexture(
1332 renderer,
1333 container->textures[i]);
1334 }
1335
1336 // Containers are just client handles, so we can destroy immediately
1337 if (container->debugName) {
1338 SDL_free(container->debugName);
1339 }
1340 SDL_free(container->textures);
1341 SDL_free(container);
1342
1343 SDL_UnlockMutex(renderer->disposeLock);
1344}
1345
1346static void D3D12_INTERNAL_DestroySampler(
1347 D3D12Renderer *renderer,
1348 D3D12Sampler *sampler)
1349{
1350 D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
1351 renderer,
1352 &sampler->handle);
1353
1354 SDL_free(sampler);
1355}
1356
1357static void D3D12_INTERNAL_DestroyGraphicsRootSignature(
1358 D3D12GraphicsRootSignature *rootSignature)
1359{
1360 if (!rootSignature) {
1361 return;
1362 }
1363 if (rootSignature->handle) {
1364 ID3D12RootSignature_Release(rootSignature->handle);
1365 }
1366 SDL_free(rootSignature);
1367}
1368
1369static void D3D12_INTERNAL_DestroyGraphicsPipeline(
1370 D3D12GraphicsPipeline *graphicsPipeline)
1371{
1372 if (graphicsPipeline->pipelineState) {
1373 ID3D12PipelineState_Release(graphicsPipeline->pipelineState);
1374 }
1375 D3D12_INTERNAL_DestroyGraphicsRootSignature(graphicsPipeline->rootSignature);
1376 SDL_free(graphicsPipeline);
1377}
1378
1379static void D3D12_INTERNAL_DestroyComputeRootSignature(
1380 D3D12ComputeRootSignature *rootSignature)
1381{
1382 if (!rootSignature) {
1383 return;
1384 }
1385 if (rootSignature->handle) {
1386 ID3D12RootSignature_Release(rootSignature->handle);
1387 }
1388 SDL_free(rootSignature);
1389}
1390
1391static void D3D12_INTERNAL_DestroyComputePipeline(
1392 D3D12ComputePipeline *computePipeline)
1393{
1394 if (computePipeline->pipelineState) {
1395 ID3D12PipelineState_Release(computePipeline->pipelineState);
1396 }
1397 D3D12_INTERNAL_DestroyComputeRootSignature(computePipeline->rootSignature);
1398 SDL_free(computePipeline);
1399}
1400
1401static void D3D12_INTERNAL_ReleaseFenceToPool(
1402 D3D12Renderer *renderer,
1403 D3D12Fence *fence)
1404{
1405 SDL_LockMutex(renderer->fenceLock);
1406
1407 EXPAND_ARRAY_IF_NEEDED(
1408 renderer->availableFences,
1409 D3D12Fence *,
1410 renderer->availableFenceCount + 1,
1411 renderer->availableFenceCapacity,
1412 renderer->availableFenceCapacity * 2);
1413
1414 renderer->availableFences[renderer->availableFenceCount] = fence;
1415 renderer->availableFenceCount += 1;
1416
1417 SDL_UnlockMutex(renderer->fenceLock);
1418}
1419
1420static void D3D12_ReleaseFence(
1421 SDL_GPURenderer *driverData,
1422 SDL_GPUFence *fence)
1423{
1424 D3D12Fence *d3d12Fence = (D3D12Fence *)fence;
1425
1426 if (SDL_AtomicDecRef(&d3d12Fence->referenceCount)) {
1427 D3D12_INTERNAL_ReleaseFenceToPool(
1428 (D3D12Renderer *)driverData,
1429 d3d12Fence);
1430 }
1431}
1432
1433static bool D3D12_QueryFence(
1434 SDL_GPURenderer *driverData,
1435 SDL_GPUFence *fence)
1436{
1437 D3D12Fence *d3d12Fence = (D3D12Fence *)fence;
1438 return ID3D12Fence_GetCompletedValue(d3d12Fence->handle) == D3D12_FENCE_SIGNAL_VALUE;
1439}
1440
1441static void D3D12_INTERNAL_DestroyDescriptorHeap(D3D12DescriptorHeap *descriptorHeap)
1442{
1443 if (!descriptorHeap) {
1444 return;
1445 }
1446 if (descriptorHeap->handle) {
1447 ID3D12DescriptorHeap_Release(descriptorHeap->handle);
1448 }
1449 SDL_free(descriptorHeap);
1450}
1451
1452static void D3D12_INTERNAL_DestroyStagingDescriptorPool(
1453 D3D12StagingDescriptorPool *pool)
1454{
1455 for (Uint32 i = 0; i < pool->heapCount; i += 1) {
1456 D3D12_INTERNAL_DestroyDescriptorHeap(pool->heaps[i]);
1457 }
1458 SDL_free(pool->heaps);
1459 SDL_free(pool->freeDescriptors);
1460 SDL_DestroyMutex(pool->lock);
1461
1462 SDL_free(pool);
1463}
1464
1465static void D3D12_INTERNAL_DestroyCommandBuffer(D3D12CommandBuffer *commandBuffer)
1466{
1467 if (!commandBuffer) {
1468 return;
1469 }
1470 if (commandBuffer->graphicsCommandList) {
1471 ID3D12GraphicsCommandList_Release(commandBuffer->graphicsCommandList);
1472 }
1473 if (commandBuffer->commandAllocator) {
1474 ID3D12CommandAllocator_Release(commandBuffer->commandAllocator);
1475 }
1476 SDL_free(commandBuffer->presentDatas);
1477 SDL_free(commandBuffer->usedTextures);
1478 SDL_free(commandBuffer->usedBuffers);
1479 SDL_free(commandBuffer->usedSamplers);
1480 SDL_free(commandBuffer->usedGraphicsPipelines);
1481 SDL_free(commandBuffer->usedComputePipelines);
1482 SDL_free(commandBuffer->usedUniformBuffers);
1483 SDL_free(commandBuffer->textureDownloads);
1484 SDL_free(commandBuffer);
1485}
1486
1487static void D3D12_INTERNAL_DestroyFence(D3D12Fence *fence)
1488{
1489 if (!fence) {
1490 return;
1491 }
1492 if (fence->handle) {
1493 ID3D12Fence_Release(fence->handle);
1494 }
1495 if (fence->event) {
1496 CloseHandle(fence->event);
1497 }
1498 SDL_free(fence);
1499}
1500
1501static void D3D12_INTERNAL_DestroyRenderer(D3D12Renderer *renderer)
1502{
1503 // Release uniform buffers
1504 for (Uint32 i = 0; i < renderer->uniformBufferPoolCount; i += 1) {
1505 D3D12_INTERNAL_DestroyBuffer(
1506 renderer,
1507 renderer->uniformBufferPool[i]->buffer);
1508 SDL_free(renderer->uniformBufferPool[i]);
1509 }
1510
1511 // Clean up descriptor heaps
1512 for (Uint32 i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; i += 1) {
1513 if (renderer->stagingDescriptorPools[i]) {
1514 D3D12_INTERNAL_DestroyStagingDescriptorPool(renderer->stagingDescriptorPools[i]);
1515 renderer->stagingDescriptorPools[i] = NULL;
1516 }
1517 }
1518
1519 for (Uint32 i = 0; i < 2; i += 1) {
1520 if (renderer->gpuDescriptorHeapPools[i].heaps) {
1521 for (Uint32 j = 0; j < renderer->gpuDescriptorHeapPools[i].count; j += 1) {
1522 if (renderer->gpuDescriptorHeapPools[i].heaps[j]) {
1523 D3D12_INTERNAL_DestroyDescriptorHeap(renderer->gpuDescriptorHeapPools[i].heaps[j]);
1524 renderer->gpuDescriptorHeapPools[i].heaps[j] = NULL;
1525 }
1526 }
1527 SDL_free(renderer->gpuDescriptorHeapPools[i].heaps);
1528 }
1529 if (renderer->gpuDescriptorHeapPools[i].lock) {
1530 SDL_DestroyMutex(renderer->gpuDescriptorHeapPools[i].lock);
1531 renderer->gpuDescriptorHeapPools[i].lock = NULL;
1532 }
1533 }
1534
1535 // Release command buffers
1536 for (Uint32 i = 0; i < renderer->availableCommandBufferCount; i += 1) {
1537 if (renderer->availableCommandBuffers[i]) {
1538 D3D12_INTERNAL_DestroyCommandBuffer(renderer->availableCommandBuffers[i]);
1539 renderer->availableCommandBuffers[i] = NULL;
1540 }
1541 }
1542
1543 // Release fences
1544 for (Uint32 i = 0; i < renderer->availableFenceCount; i += 1) {
1545 if (renderer->availableFences[i]) {
1546 D3D12_INTERNAL_DestroyFence(renderer->availableFences[i]);
1547 renderer->availableFences[i] = NULL;
1548 }
1549 }
1550
1551 // Clean up allocations
1552 SDL_free(renderer->availableCommandBuffers);
1553 SDL_free(renderer->submittedCommandBuffers);
1554 SDL_free(renderer->uniformBufferPool);
1555 SDL_free(renderer->claimedWindows);
1556 SDL_free(renderer->availableFences);
1557 SDL_free(renderer->buffersToDestroy);
1558 SDL_free(renderer->texturesToDestroy);
1559 SDL_free(renderer->samplersToDestroy);
1560 SDL_free(renderer->graphicsPipelinesToDestroy);
1561 SDL_free(renderer->computePipelinesToDestroy);
1562
1563 // Tear down D3D12 objects
1564 if (renderer->indirectDrawCommandSignature) {
1565 ID3D12CommandSignature_Release(renderer->indirectDrawCommandSignature);
1566 renderer->indirectDrawCommandSignature = NULL;
1567 }
1568 if (renderer->indirectIndexedDrawCommandSignature) {
1569 ID3D12CommandSignature_Release(renderer->indirectIndexedDrawCommandSignature);
1570 renderer->indirectIndexedDrawCommandSignature = NULL;
1571 }
1572 if (renderer->indirectDispatchCommandSignature) {
1573 ID3D12CommandSignature_Release(renderer->indirectDispatchCommandSignature);
1574 renderer->indirectDispatchCommandSignature = NULL;
1575 }
1576#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
1577 if (renderer->commandQueue) {
1578 ID3D12CommandQueue_Release(renderer->commandQueue);
1579 renderer->commandQueue = NULL;
1580 }
1581 if (renderer->device) {
1582 ID3D12Device_Release(renderer->device);
1583 renderer->device = NULL;
1584 }
1585 if (renderer->adapter) {
1586 IDXGIAdapter1_Release(renderer->adapter);
1587 renderer->adapter = NULL;
1588 }
1589 if (renderer->factory) {
1590 IDXGIFactory4_Release(renderer->factory);
1591 renderer->factory = NULL;
1592 }
1593 if (renderer->dxgiDebug) {
1594 IDXGIDebug_ReportLiveObjects(
1595 renderer->dxgiDebug,
1596 D3D_IID_DXGI_DEBUG_ALL,
1597 (DXGI_DEBUG_RLO_FLAGS)(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_DETAIL));
1598 IDXGIDebug_Release(renderer->dxgiDebug);
1599 renderer->dxgiDebug = NULL;
1600 }
1601#endif
1602 if (renderer->d3d12_dll) {
1603 SDL_UnloadObject(renderer->d3d12_dll);
1604 renderer->d3d12_dll = NULL;
1605 }
1606#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
1607 if (renderer->dxgi_dll) {
1608 SDL_UnloadObject(renderer->dxgi_dll);
1609 renderer->dxgi_dll = NULL;
1610 }
1611 if (renderer->dxgidebug_dll) {
1612 SDL_UnloadObject(renderer->dxgidebug_dll);
1613 renderer->dxgidebug_dll = NULL;
1614 }
1615#endif
1616 renderer->D3D12SerializeRootSignature_func = NULL;
1617
1618 if (renderer->iconv) {
1619 SDL_iconv_close(renderer->iconv);
1620 }
1621
1622 SDL_DestroyMutex(renderer->acquireCommandBufferLock);
1623 SDL_DestroyMutex(renderer->acquireUniformBufferLock);
1624 SDL_DestroyMutex(renderer->submitLock);
1625 SDL_DestroyMutex(renderer->windowLock);
1626 SDL_DestroyMutex(renderer->fenceLock);
1627 SDL_DestroyMutex(renderer->disposeLock);
1628 SDL_free(renderer);
1629}
1630
1631static void D3D12_DestroyDevice(SDL_GPUDevice *device)
1632{
1633 D3D12Renderer *renderer = (D3D12Renderer *)device->driverData;
1634
1635 // Release blit pipeline structures
1636 D3D12_INTERNAL_ReleaseBlitPipelines((SDL_GPURenderer *)renderer);
1637
1638 // Flush any remaining GPU work...
1639 D3D12_Wait((SDL_GPURenderer *)renderer);
1640
1641 // Release window data
1642 for (Sint32 i = renderer->claimedWindowCount - 1; i >= 0; i -= 1) {
1643 D3D12_ReleaseWindow((SDL_GPURenderer *)renderer, renderer->claimedWindows[i]->window);
1644 }
1645
1646 D3D12_INTERNAL_DestroyRenderer(renderer);
1647 SDL_free(device);
1648}
1649
1650// Barriers
1651
1652static inline Uint32 D3D12_INTERNAL_CalcSubresource(
1653 Uint32 mipLevel,
1654 Uint32 layer,
1655 Uint32 numLevels)
1656{
1657 return mipLevel + (layer * numLevels);
1658}
1659
1660static void D3D12_INTERNAL_ResourceBarrier(
1661 D3D12CommandBuffer *commandBuffer,
1662 D3D12_RESOURCE_STATES sourceState,
1663 D3D12_RESOURCE_STATES destinationState,
1664 ID3D12Resource *resource,
1665 Uint32 subresourceIndex,
1666 bool needsUavBarrier)
1667{
1668 D3D12_RESOURCE_BARRIER barrierDesc[2];
1669 Uint32 numBarriers = 0;
1670
1671 // No transition barrier is needed if the state is not changing.
1672 if (sourceState != destinationState) {
1673 barrierDesc[numBarriers].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
1674 barrierDesc[numBarriers].Flags = (D3D12_RESOURCE_BARRIER_FLAGS)0;
1675 barrierDesc[numBarriers].Transition.StateBefore = sourceState;
1676 barrierDesc[numBarriers].Transition.StateAfter = destinationState;
1677 barrierDesc[numBarriers].Transition.pResource = resource;
1678 barrierDesc[numBarriers].Transition.Subresource = subresourceIndex;
1679
1680 numBarriers += 1;
1681 }
1682
1683 if (needsUavBarrier) {
1684 barrierDesc[numBarriers].Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
1685 barrierDesc[numBarriers].Flags = (D3D12_RESOURCE_BARRIER_FLAGS)0;
1686 barrierDesc[numBarriers].UAV.pResource = resource;
1687
1688 numBarriers += 1;
1689 }
1690
1691 if (numBarriers > 0) {
1692 ID3D12GraphicsCommandList_ResourceBarrier(
1693 commandBuffer->graphicsCommandList,
1694 numBarriers,
1695 barrierDesc);
1696 }
1697}
1698
1699static void D3D12_INTERNAL_TextureSubresourceBarrier(
1700 D3D12CommandBuffer *commandBuffer,
1701 D3D12_RESOURCE_STATES sourceState,
1702 D3D12_RESOURCE_STATES destinationState,
1703 D3D12TextureSubresource *textureSubresource)
1704{
1705 bool needsUAVBarrier =
1706 (textureSubresource->parent->container->header.info.usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) ||
1707 (textureSubresource->parent->container->header.info.usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE);
1708
1709 D3D12_INTERNAL_ResourceBarrier(
1710 commandBuffer,
1711 sourceState,
1712 destinationState,
1713 textureSubresource->parent->resource,
1714 textureSubresource->index,
1715 needsUAVBarrier);
1716}
1717
1718static D3D12_RESOURCE_STATES D3D12_INTERNAL_DefaultTextureResourceState(
1719 SDL_GPUTextureUsageFlags usageFlags)
1720{
1721 // NOTE: order matters here!
1722
1723 if (usageFlags & SDL_GPU_TEXTUREUSAGE_SAMPLER) {
1724 return D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE;
1725 } else if (usageFlags & SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ) {
1726 return D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE;
1727 } else if (usageFlags & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) {
1728 return D3D12_RESOURCE_STATE_RENDER_TARGET;
1729 } else if (usageFlags & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) {
1730 return D3D12_RESOURCE_STATE_DEPTH_WRITE;
1731 } else if (usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ) {
1732 return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
1733 } else if (usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) {
1734 return D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
1735 } else if (usageFlags & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE) {
1736 return D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
1737 } else {
1738 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Texture has no default usage mode!");
1739 return D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE;
1740 }
1741}
1742
1743static void D3D12_INTERNAL_TextureSubresourceTransitionFromDefaultUsage(
1744 D3D12CommandBuffer *commandBuffer,
1745 D3D12_RESOURCE_STATES destinationUsageMode,
1746 D3D12TextureSubresource *textureSubresource)
1747{
1748 D3D12_INTERNAL_TextureSubresourceBarrier(
1749 commandBuffer,
1750 D3D12_INTERNAL_DefaultTextureResourceState(textureSubresource->parent->container->header.info.usage),
1751 destinationUsageMode,
1752 textureSubresource);
1753}
1754
1755static void D3D12_INTERNAL_TextureTransitionFromDefaultUsage(
1756 D3D12CommandBuffer *commandBuffer,
1757 D3D12_RESOURCE_STATES destinationUsageMode,
1758 D3D12Texture *texture)
1759{
1760 for (Uint32 i = 0; i < texture->subresourceCount; i += 1) {
1761 D3D12_INTERNAL_TextureSubresourceTransitionFromDefaultUsage(
1762 commandBuffer,
1763 destinationUsageMode,
1764 &texture->subresources[i]);
1765 }
1766}
1767
1768static void D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
1769 D3D12CommandBuffer *commandBuffer,
1770 D3D12_RESOURCE_STATES sourceUsageMode,
1771 D3D12TextureSubresource *textureSubresource)
1772{
1773 D3D12_INTERNAL_TextureSubresourceBarrier(
1774 commandBuffer,
1775 sourceUsageMode,
1776 D3D12_INTERNAL_DefaultTextureResourceState(textureSubresource->parent->container->header.info.usage),
1777 textureSubresource);
1778}
1779
1780static void D3D12_INTERNAL_TextureTransitionToDefaultUsage(
1781 D3D12CommandBuffer *commandBuffer,
1782 D3D12_RESOURCE_STATES sourceUsageMode,
1783 D3D12Texture *texture)
1784{
1785 for (Uint32 i = 0; i < texture->subresourceCount; i += 1) {
1786 D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
1787 commandBuffer,
1788 sourceUsageMode,
1789 &texture->subresources[i]);
1790 }
1791}
1792
1793static D3D12_RESOURCE_STATES D3D12_INTERNAL_DefaultBufferResourceState(
1794 D3D12Buffer *buffer)
1795{
1796 if (buffer->container->usage & SDL_GPU_BUFFERUSAGE_VERTEX) {
1797 return D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
1798 } else if (buffer->container->usage & SDL_GPU_BUFFERUSAGE_INDEX) {
1799 return D3D12_RESOURCE_STATE_INDEX_BUFFER;
1800 } else if (buffer->container->usage & SDL_GPU_BUFFERUSAGE_INDIRECT) {
1801 return D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT;
1802 } else if (buffer->container->usage & SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ) {
1803 return D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE;
1804 } else if (buffer->container->usage & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_READ) {
1805 return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
1806 } else if (buffer->container->usage & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE) {
1807 return D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
1808 } else {
1809 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Buffer has no default usage mode!");
1810 return D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
1811 }
1812}
1813
1814static void D3D12_INTERNAL_BufferBarrier(
1815 D3D12CommandBuffer *commandBuffer,
1816 D3D12_RESOURCE_STATES sourceState,
1817 D3D12_RESOURCE_STATES destinationState,
1818 D3D12Buffer *buffer)
1819{
1820 D3D12_INTERNAL_ResourceBarrier(
1821 commandBuffer,
1822 buffer->transitioned ? sourceState : D3D12_RESOURCE_STATE_COMMON,
1823 destinationState,
1824 buffer->handle,
1825 0,
1826 buffer->container->usage & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE);
1827
1828 buffer->transitioned = true;
1829}
1830
1831static void D3D12_INTERNAL_BufferTransitionFromDefaultUsage(
1832 D3D12CommandBuffer *commandBuffer,
1833 D3D12_RESOURCE_STATES destinationState,
1834 D3D12Buffer *buffer)
1835{
1836 D3D12_INTERNAL_BufferBarrier(
1837 commandBuffer,
1838 D3D12_INTERNAL_DefaultBufferResourceState(buffer),
1839 destinationState,
1840 buffer);
1841}
1842
1843static void D3D12_INTERNAL_BufferTransitionToDefaultUsage(
1844 D3D12CommandBuffer *commandBuffer,
1845 D3D12_RESOURCE_STATES sourceState,
1846 D3D12Buffer *buffer)
1847{
1848 D3D12_INTERNAL_BufferBarrier(
1849 commandBuffer,
1850 sourceState,
1851 D3D12_INTERNAL_DefaultBufferResourceState(buffer),
1852 buffer);
1853}
1854
1855// Resource tracking
1856
1857#define TRACK_RESOURCE(resource, type, array, count, capacity) \
1858 Uint32 i; \
1859 \
1860 for (i = 0; i < commandBuffer->count; i += 1) { \
1861 if (commandBuffer->array[i] == resource) { \
1862 return; \
1863 } \
1864 } \
1865 \
1866 if (commandBuffer->count == commandBuffer->capacity) { \
1867 commandBuffer->capacity += 1; \
1868 commandBuffer->array = (type *)SDL_realloc( \
1869 commandBuffer->array, \
1870 commandBuffer->capacity * sizeof(type)); \
1871 } \
1872 commandBuffer->array[commandBuffer->count] = resource; \
1873 commandBuffer->count += 1; \
1874 SDL_AtomicIncRef(&resource->referenceCount);
1875
1876static void D3D12_INTERNAL_TrackTexture(
1877 D3D12CommandBuffer *commandBuffer,
1878 D3D12Texture *texture)
1879{
1880 TRACK_RESOURCE(
1881 texture,
1882 D3D12Texture *,
1883 usedTextures,
1884 usedTextureCount,
1885 usedTextureCapacity)
1886}
1887
1888static void D3D12_INTERNAL_TrackBuffer(
1889 D3D12CommandBuffer *commandBuffer,
1890 D3D12Buffer *buffer)
1891{
1892 TRACK_RESOURCE(
1893 buffer,
1894 D3D12Buffer *,
1895 usedBuffers,
1896 usedBufferCount,
1897 usedBufferCapacity)
1898}
1899
1900static void D3D12_INTERNAL_TrackSampler(
1901 D3D12CommandBuffer *commandBuffer,
1902 D3D12Sampler *sampler)
1903{
1904 TRACK_RESOURCE(
1905 sampler,
1906 D3D12Sampler *,
1907 usedSamplers,
1908 usedSamplerCount,
1909 usedSamplerCapacity)
1910}
1911
1912static void D3D12_INTERNAL_TrackGraphicsPipeline(
1913 D3D12CommandBuffer *commandBuffer,
1914 D3D12GraphicsPipeline *graphicsPipeline)
1915{
1916 TRACK_RESOURCE(
1917 graphicsPipeline,
1918 D3D12GraphicsPipeline *,
1919 usedGraphicsPipelines,
1920 usedGraphicsPipelineCount,
1921 usedGraphicsPipelineCapacity)
1922}
1923
1924static void D3D12_INTERNAL_TrackComputePipeline(
1925 D3D12CommandBuffer *commandBuffer,
1926 D3D12ComputePipeline *computePipeline)
1927{
1928 TRACK_RESOURCE(
1929 computePipeline,
1930 D3D12ComputePipeline *,
1931 usedComputePipelines,
1932 usedComputePipelineCount,
1933 usedComputePipelineCapacity)
1934}
1935
1936#undef TRACK_RESOURCE
1937
1938// Debug Naming
1939
1940static void D3D12_INTERNAL_SetPipelineStateName(
1941 D3D12Renderer *renderer,
1942 ID3D12PipelineState *pipelineState,
1943 const char *text
1944) {
1945 if (renderer->debug_mode && text != NULL) {
1946 WCHAR *wchar_text = WIN_UTF8ToStringW(text);
1947 ID3D12PipelineState_SetName(
1948 pipelineState,
1949 wchar_text);
1950 SDL_free(wchar_text);
1951 }
1952}
1953
1954static void D3D12_INTERNAL_SetResourceName(
1955 D3D12Renderer *renderer,
1956 ID3D12Resource *resource,
1957 const char *text
1958) {
1959 if (renderer->debug_mode && text != NULL) {
1960 WCHAR *wchar_text = WIN_UTF8ToStringW(text);
1961 ID3D12Resource_SetName(
1962 resource,
1963 wchar_text);
1964 SDL_free(wchar_text);
1965 }
1966}
1967
1968static void D3D12_SetBufferName(
1969 SDL_GPURenderer *driverData,
1970 SDL_GPUBuffer *buffer,
1971 const char *text)
1972{
1973 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
1974 D3D12BufferContainer *container = (D3D12BufferContainer *)buffer;
1975
1976 if (renderer->debug_mode && text != NULL) {
1977 if (container->debugName != NULL) {
1978 SDL_free(container->debugName);
1979 }
1980
1981 container->debugName = SDL_strdup(text);
1982
1983 for (Uint32 i = 0; i < container->bufferCount; i += 1) {
1984 D3D12_INTERNAL_SetResourceName(
1985 renderer,
1986 container->buffers[i]->handle,
1987 text);
1988 }
1989 }
1990}
1991
1992static void D3D12_SetTextureName(
1993 SDL_GPURenderer *driverData,
1994 SDL_GPUTexture *texture,
1995 const char *text)
1996{
1997 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
1998 D3D12TextureContainer *container = (D3D12TextureContainer *)texture;
1999
2000 if (renderer->debug_mode && text != NULL) {
2001 if (container->debugName != NULL) {
2002 SDL_free(container->debugName);
2003 }
2004
2005 container->debugName = SDL_strdup(text);
2006
2007 for (Uint32 i = 0; i < container->textureCount; i += 1) {
2008 D3D12_INTERNAL_SetResourceName(
2009 renderer,
2010 container->textures[i]->resource,
2011 text);
2012 }
2013 }
2014}
2015
2016/* These debug functions are all marked as "for internal usage only"
2017 * on D3D12... works on renderdoc!
2018 */
2019
2020static void D3D12_InsertDebugLabel(
2021 SDL_GPUCommandBuffer *commandBuffer,
2022 const char *text)
2023{
2024 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
2025 WCHAR *wchar_text = WIN_UTF8ToStringW(text);
2026
2027 ID3D12GraphicsCommandList_SetMarker(
2028 d3d12CommandBuffer->graphicsCommandList,
2029 0,
2030 wchar_text,
2031 (UINT)SDL_wcslen(wchar_text) * sizeof(WCHAR));
2032
2033 SDL_free(wchar_text);
2034}
2035
2036static void D3D12_PushDebugGroup(
2037 SDL_GPUCommandBuffer *commandBuffer,
2038 const char *name)
2039{
2040 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
2041 WCHAR *wchar_text = WIN_UTF8ToStringW(name);
2042
2043 ID3D12GraphicsCommandList_BeginEvent(
2044 d3d12CommandBuffer->graphicsCommandList,
2045 0,
2046 wchar_text,
2047 (UINT)SDL_wcslen(wchar_text) * sizeof(WCHAR));
2048
2049 SDL_free(wchar_text);
2050}
2051
2052static void D3D12_PopDebugGroup(
2053 SDL_GPUCommandBuffer *commandBuffer)
2054{
2055 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
2056 ID3D12GraphicsCommandList_EndEvent(d3d12CommandBuffer->graphicsCommandList);
2057}
2058
2059// State Creation
2060
2061static D3D12DescriptorHeap *D3D12_INTERNAL_CreateDescriptorHeap(
2062 D3D12Renderer *renderer,
2063 D3D12_DESCRIPTOR_HEAP_TYPE type,
2064 Uint32 descriptorCount,
2065 bool staging)
2066{
2067 D3D12DescriptorHeap *heap;
2068 ID3D12DescriptorHeap *handle;
2069 D3D12_DESCRIPTOR_HEAP_DESC heapDesc;
2070 HRESULT res;
2071
2072 heap = (D3D12DescriptorHeap *)SDL_calloc(1, sizeof(D3D12DescriptorHeap));
2073 if (!heap) {
2074 return NULL;
2075 }
2076
2077 heap->currentDescriptorIndex = 0;
2078
2079 heapDesc.NumDescriptors = descriptorCount;
2080 heapDesc.Type = type;
2081 heapDesc.Flags = staging ? D3D12_DESCRIPTOR_HEAP_FLAG_NONE : D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
2082 heapDesc.NodeMask = 0;
2083
2084 res = ID3D12Device_CreateDescriptorHeap(
2085 renderer->device,
2086 &heapDesc,
2087 D3D_GUID(D3D_IID_ID3D12DescriptorHeap),
2088 (void **)&handle);
2089
2090 if (FAILED(res)) {
2091 D3D12_INTERNAL_SetError(renderer, "Failed to create descriptor heap!", res);
2092 D3D12_INTERNAL_DestroyDescriptorHeap(heap);
2093 return NULL;
2094 }
2095
2096 heap->handle = handle;
2097 heap->heapType = type;
2098 heap->maxDescriptors = descriptorCount;
2099 heap->staging = staging;
2100 heap->descriptorSize = ID3D12Device_GetDescriptorHandleIncrementSize(renderer->device, type);
2101 D3D_CALL_RET(handle, GetCPUDescriptorHandleForHeapStart, &heap->descriptorHeapCPUStart);
2102 if (!staging) {
2103 D3D_CALL_RET(handle, GetGPUDescriptorHandleForHeapStart, &heap->descriptorHeapGPUStart);
2104 }
2105
2106 return heap;
2107}
2108
2109static D3D12StagingDescriptorPool *D3D12_INTERNAL_CreateStagingDescriptorPool(
2110 D3D12Renderer *renderer,
2111 D3D12_DESCRIPTOR_HEAP_TYPE heapType
2112) {
2113 D3D12DescriptorHeap *heap = D3D12_INTERNAL_CreateDescriptorHeap(
2114 renderer,
2115 heapType,
2116 STAGING_HEAP_DESCRIPTOR_COUNT,
2117 true);
2118
2119 if (!heap) {
2120 return NULL;
2121 }
2122
2123 D3D12StagingDescriptorPool *pool = (D3D12StagingDescriptorPool*) SDL_calloc(1, sizeof(D3D12StagingDescriptorPool));
2124
2125 pool->heapCount = 1;
2126 pool->heaps = (D3D12DescriptorHeap**) SDL_malloc(sizeof(D3D12DescriptorHeap*));
2127 pool->heaps[0] = heap;
2128
2129 pool->freeDescriptorCapacity = STAGING_HEAP_DESCRIPTOR_COUNT;
2130 pool->freeDescriptorCount = STAGING_HEAP_DESCRIPTOR_COUNT;
2131 pool->freeDescriptors = (D3D12StagingDescriptor*) SDL_malloc(STAGING_HEAP_DESCRIPTOR_COUNT * sizeof(D3D12StagingDescriptor));
2132
2133 for (Uint32 i = 0; i < STAGING_HEAP_DESCRIPTOR_COUNT; i += 1) {
2134 pool->freeDescriptors[i].pool = pool;
2135 pool->freeDescriptors[i].heap = heap;
2136 pool->freeDescriptors[i].cpuHandleIndex = i;
2137 pool->freeDescriptors[i].cpuHandle.ptr = heap->descriptorHeapCPUStart.ptr + (i * heap->descriptorSize);
2138 }
2139
2140 pool->lock = SDL_CreateMutex();
2141
2142 return pool;
2143}
2144
2145/* If the pool is empty, we need to refill it! */
2146static bool D3D12_INTERNAL_ExpandStagingDescriptorPool(
2147 D3D12Renderer *renderer,
2148 D3D12StagingDescriptorPool *pool
2149) {
2150 D3D12DescriptorHeap *heap = D3D12_INTERNAL_CreateDescriptorHeap(
2151 renderer,
2152 pool->heaps[0]->heapType,
2153 STAGING_HEAP_DESCRIPTOR_COUNT,
2154 true);
2155
2156 if (!heap) {
2157 return false;
2158 }
2159
2160 pool->heapCount += 1;
2161 pool->heaps = (D3D12DescriptorHeap**) SDL_realloc(pool->heaps, pool->heapCount * sizeof(D3D12DescriptorHeap*));
2162 pool->heaps[pool->heapCount - 1] = heap;
2163
2164 pool->freeDescriptorCapacity += STAGING_HEAP_DESCRIPTOR_COUNT;
2165 pool->freeDescriptorCount += STAGING_HEAP_DESCRIPTOR_COUNT;
2166 pool->freeDescriptors = (D3D12StagingDescriptor*) SDL_realloc(pool->freeDescriptors, pool->freeDescriptorCapacity * sizeof(D3D12StagingDescriptor));
2167
2168 for (Uint32 i = 0; i < STAGING_HEAP_DESCRIPTOR_COUNT; i += 1) {
2169 pool->freeDescriptors[i].pool = pool;
2170 pool->freeDescriptors[i].heap = heap;
2171 pool->freeDescriptors[i].cpuHandleIndex = i;
2172 pool->freeDescriptors[i].cpuHandle.ptr = heap->descriptorHeapCPUStart.ptr + (i * heap->descriptorSize);
2173 }
2174
2175 return true;
2176}
2177
2178static D3D12DescriptorHeap *D3D12_INTERNAL_AcquireGPUDescriptorHeapFromPool(
2179 D3D12CommandBuffer *commandBuffer,
2180 D3D12_DESCRIPTOR_HEAP_TYPE descriptorHeapType)
2181{
2182 D3D12DescriptorHeap *result;
2183 D3D12Renderer *renderer = commandBuffer->renderer;
2184 D3D12GPUDescriptorHeapPool *pool = &renderer->gpuDescriptorHeapPools[descriptorHeapType];
2185
2186 SDL_LockMutex(pool->lock);
2187 if (pool->count > 0) {
2188 result = pool->heaps[pool->count - 1];
2189 pool->count -= 1;
2190 } else {
2191 result = D3D12_INTERNAL_CreateDescriptorHeap(
2192 renderer,
2193 descriptorHeapType,
2194 descriptorHeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV ? VIEW_GPU_DESCRIPTOR_COUNT : SAMPLER_GPU_DESCRIPTOR_COUNT,
2195 false);
2196 }
2197 SDL_UnlockMutex(pool->lock);
2198
2199 return result;
2200}
2201
2202static void D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(
2203 D3D12Renderer *renderer,
2204 D3D12DescriptorHeap *heap)
2205{
2206 if (heap == NULL) {
2207 return;
2208 }
2209
2210 D3D12GPUDescriptorHeapPool *pool = &renderer->gpuDescriptorHeapPools[heap->heapType];
2211
2212 heap->currentDescriptorIndex = 0;
2213
2214 SDL_LockMutex(pool->lock);
2215 if (pool->count >= pool->capacity) {
2216 pool->capacity *= 2;
2217 pool->heaps = (D3D12DescriptorHeap **)SDL_realloc(
2218 pool->heaps,
2219 pool->capacity * sizeof(D3D12DescriptorHeap *));
2220 }
2221
2222 pool->heaps[pool->count] = heap;
2223 pool->count += 1;
2224 SDL_UnlockMutex(pool->lock);
2225}
2226
2227/*
2228 * The root signature lets us define "root parameters" which are essentially bind points for resources.
2229 * These let us define the register ranges as well as the register "space".
2230 * The register space is akin to the descriptor set index in Vulkan, which allows us to group resources
2231 * by stage so that the registers from the vertex and fragment shaders don't clobber each other.
2232 *
2233 * Most of our root parameters are implemented as "descriptor tables" so we can
2234 * copy and then point to contiguous descriptor regions.
2235 * Uniform buffers are the exception - these have to be implemented as raw "root descriptors" so
2236 * that we can dynamically update the address that the constant buffer view points to.
2237 *
2238 * The root signature has a maximum size of 64 DWORDs.
2239 * A descriptor table uses 1 DWORD.
2240 * A root descriptor uses 2 DWORDS.
2241 * This means our biggest root signature uses 24 DWORDs total, well under the limit.
2242 *
2243 * The root parameter indices are created dynamically and stored in the D3D12GraphicsRootSignature struct.
2244 */
2245static D3D12GraphicsRootSignature *D3D12_INTERNAL_CreateGraphicsRootSignature(
2246 D3D12Renderer *renderer,
2247 D3D12Shader *vertexShader,
2248 D3D12Shader *fragmentShader)
2249{
2250 // FIXME: I think the max can be smaller...
2251 D3D12_ROOT_PARAMETER rootParameters[MAX_ROOT_SIGNATURE_PARAMETERS];
2252 D3D12_DESCRIPTOR_RANGE descriptorRanges[MAX_ROOT_SIGNATURE_PARAMETERS];
2253 Uint32 parameterCount = 0;
2254 Uint32 rangeCount = 0;
2255 D3D12_DESCRIPTOR_RANGE descriptorRange;
2256 D3D12_ROOT_PARAMETER rootParameter;
2257 D3D12GraphicsRootSignature *d3d12GraphicsRootSignature =
2258 (D3D12GraphicsRootSignature *)SDL_calloc(1, sizeof(D3D12GraphicsRootSignature));
2259 if (!d3d12GraphicsRootSignature) {
2260 return NULL;
2261 }
2262
2263 SDL_zeroa(rootParameters);
2264 SDL_zeroa(descriptorRanges);
2265 SDL_zero(rootParameter);
2266
2267 d3d12GraphicsRootSignature->vertexSamplerRootIndex = -1;
2268 d3d12GraphicsRootSignature->vertexSamplerTextureRootIndex = -1;
2269 d3d12GraphicsRootSignature->vertexStorageTextureRootIndex = -1;
2270 d3d12GraphicsRootSignature->vertexStorageBufferRootIndex = -1;
2271
2272 d3d12GraphicsRootSignature->fragmentSamplerRootIndex = -1;
2273 d3d12GraphicsRootSignature->fragmentSamplerTextureRootIndex = -1;
2274 d3d12GraphicsRootSignature->fragmentStorageTextureRootIndex = -1;
2275 d3d12GraphicsRootSignature->fragmentStorageBufferRootIndex = -1;
2276
2277 for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
2278 d3d12GraphicsRootSignature->vertexUniformBufferRootIndex[i] = -1;
2279 d3d12GraphicsRootSignature->fragmentUniformBufferRootIndex[i] = -1;
2280 }
2281
2282 if (vertexShader->num_samplers > 0) {
2283 // Vertex Samplers
2284 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
2285 descriptorRange.NumDescriptors = vertexShader->num_samplers;
2286 descriptorRange.BaseShaderRegister = 0;
2287 descriptorRange.RegisterSpace = 0;
2288 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2289 descriptorRanges[rangeCount] = descriptorRange;
2290
2291 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2292 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2293 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2294 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
2295 rootParameters[parameterCount] = rootParameter;
2296 d3d12GraphicsRootSignature->vertexSamplerRootIndex = parameterCount;
2297 rangeCount += 1;
2298 parameterCount += 1;
2299
2300 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
2301 descriptorRange.NumDescriptors = vertexShader->num_samplers;
2302 descriptorRange.BaseShaderRegister = 0;
2303 descriptorRange.RegisterSpace = 0;
2304 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2305 descriptorRanges[rangeCount] = descriptorRange;
2306
2307 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2308 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2309 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2310 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
2311 rootParameters[parameterCount] = rootParameter;
2312 d3d12GraphicsRootSignature->vertexSamplerTextureRootIndex = parameterCount;
2313 rangeCount += 1;
2314 parameterCount += 1;
2315 }
2316
2317 if (vertexShader->numStorageTextures) {
2318 // Vertex storage textures
2319 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
2320 descriptorRange.NumDescriptors = vertexShader->numStorageTextures;
2321 descriptorRange.BaseShaderRegister = vertexShader->num_samplers;
2322 descriptorRange.RegisterSpace = 0;
2323 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2324 descriptorRanges[rangeCount] = descriptorRange;
2325
2326 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2327 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2328 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2329 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
2330 rootParameters[parameterCount] = rootParameter;
2331 d3d12GraphicsRootSignature->vertexStorageTextureRootIndex = parameterCount;
2332 rangeCount += 1;
2333 parameterCount += 1;
2334 }
2335
2336 if (vertexShader->numStorageBuffers) {
2337
2338 // Vertex storage buffers
2339 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
2340 descriptorRange.NumDescriptors = vertexShader->numStorageBuffers;
2341 descriptorRange.BaseShaderRegister = vertexShader->num_samplers + vertexShader->numStorageTextures;
2342 descriptorRange.RegisterSpace = 0;
2343 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2344 descriptorRanges[rangeCount] = descriptorRange;
2345
2346 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2347 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2348 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2349 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
2350 rootParameters[parameterCount] = rootParameter;
2351 d3d12GraphicsRootSignature->vertexStorageBufferRootIndex = parameterCount;
2352 rangeCount += 1;
2353 parameterCount += 1;
2354 }
2355
2356 // Vertex Uniforms
2357 for (Uint32 i = 0; i < vertexShader->numUniformBuffers; i += 1) {
2358 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
2359 rootParameter.Descriptor.ShaderRegister = i;
2360 rootParameter.Descriptor.RegisterSpace = 1;
2361 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
2362 rootParameters[parameterCount] = rootParameter;
2363 d3d12GraphicsRootSignature->vertexUniformBufferRootIndex[i] = parameterCount;
2364 parameterCount += 1;
2365 }
2366
2367 if (fragmentShader->num_samplers) {
2368 // Fragment Samplers
2369 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
2370 descriptorRange.NumDescriptors = fragmentShader->num_samplers;
2371 descriptorRange.BaseShaderRegister = 0;
2372 descriptorRange.RegisterSpace = 2;
2373 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2374 descriptorRanges[rangeCount] = descriptorRange;
2375
2376 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2377 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2378 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2379 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
2380 rootParameters[parameterCount] = rootParameter;
2381 d3d12GraphicsRootSignature->fragmentSamplerRootIndex = parameterCount;
2382 rangeCount += 1;
2383 parameterCount += 1;
2384
2385 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
2386 descriptorRange.NumDescriptors = fragmentShader->num_samplers;
2387 descriptorRange.BaseShaderRegister = 0;
2388 descriptorRange.RegisterSpace = 2;
2389 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2390 descriptorRanges[rangeCount] = descriptorRange;
2391
2392 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2393 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2394 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2395 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
2396 rootParameters[parameterCount] = rootParameter;
2397 d3d12GraphicsRootSignature->fragmentSamplerTextureRootIndex = parameterCount;
2398 rangeCount += 1;
2399 parameterCount += 1;
2400 }
2401
2402 if (fragmentShader->numStorageTextures) {
2403 // Fragment Storage Textures
2404 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
2405 descriptorRange.NumDescriptors = fragmentShader->numStorageTextures;
2406 descriptorRange.BaseShaderRegister = fragmentShader->num_samplers;
2407 descriptorRange.RegisterSpace = 2;
2408 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2409 descriptorRanges[rangeCount] = descriptorRange;
2410
2411 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2412 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2413 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2414 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
2415 rootParameters[parameterCount] = rootParameter;
2416 d3d12GraphicsRootSignature->fragmentStorageTextureRootIndex = parameterCount;
2417 rangeCount += 1;
2418 parameterCount += 1;
2419 }
2420
2421 if (fragmentShader->numStorageBuffers) {
2422 // Fragment Storage Buffers
2423 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
2424 descriptorRange.NumDescriptors = fragmentShader->numStorageBuffers;
2425 descriptorRange.BaseShaderRegister = fragmentShader->num_samplers + fragmentShader->numStorageTextures;
2426 descriptorRange.RegisterSpace = 2;
2427 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2428 descriptorRanges[rangeCount] = descriptorRange;
2429
2430 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2431 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2432 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2433 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
2434 rootParameters[parameterCount] = rootParameter;
2435 d3d12GraphicsRootSignature->fragmentStorageBufferRootIndex = parameterCount;
2436 rangeCount += 1;
2437 parameterCount += 1;
2438 }
2439
2440 // Fragment Uniforms
2441 for (Uint32 i = 0; i < fragmentShader->numUniformBuffers; i += 1) {
2442 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
2443 rootParameter.Descriptor.ShaderRegister = i;
2444 rootParameter.Descriptor.RegisterSpace = 3;
2445 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
2446 rootParameters[parameterCount] = rootParameter;
2447 d3d12GraphicsRootSignature->fragmentUniformBufferRootIndex[i] = parameterCount;
2448 parameterCount += 1;
2449 }
2450
2451 // FIXME: shouldn't have to assert here
2452 SDL_assert(parameterCount <= MAX_ROOT_SIGNATURE_PARAMETERS);
2453 SDL_assert(rangeCount <= MAX_ROOT_SIGNATURE_PARAMETERS);
2454
2455 // Create the root signature description
2456 D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc;
2457 rootSignatureDesc.NumParameters = parameterCount;
2458 rootSignatureDesc.pParameters = rootParameters;
2459 rootSignatureDesc.NumStaticSamplers = 0;
2460 rootSignatureDesc.pStaticSamplers = NULL;
2461 rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
2462
2463 // Serialize the root signature
2464 ID3DBlob *serializedRootSignature;
2465 ID3DBlob *errorBlob;
2466 HRESULT res = renderer->D3D12SerializeRootSignature_func(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &serializedRootSignature, &errorBlob);
2467
2468 if (FAILED(res)) {
2469 if (errorBlob) {
2470 SET_ERROR("Failed to serialize RootSignature: %s", (const char *)ID3D10Blob_GetBufferPointer(errorBlob));
2471 ID3D10Blob_Release(errorBlob);
2472 }
2473 D3D12_INTERNAL_DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
2474 return NULL;
2475 }
2476
2477 // Create the root signature
2478 ID3D12RootSignature *rootSignature;
2479
2480 res = ID3D12Device_CreateRootSignature(
2481 renderer->device,
2482 0,
2483 ID3D10Blob_GetBufferPointer(serializedRootSignature),
2484 ID3D10Blob_GetBufferSize(serializedRootSignature),
2485 D3D_GUID(D3D_IID_ID3D12RootSignature),
2486 (void **)&rootSignature);
2487
2488 if (FAILED(res)) {
2489 if (errorBlob) {
2490 SET_ERROR("Failed to create RootSignature: %s", (const char *)ID3D10Blob_GetBufferPointer(errorBlob));
2491 ID3D10Blob_Release(errorBlob);
2492 }
2493 D3D12_INTERNAL_DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
2494 return NULL;
2495 }
2496
2497 d3d12GraphicsRootSignature->handle = rootSignature;
2498 return d3d12GraphicsRootSignature;
2499}
2500
2501static bool D3D12_INTERNAL_CreateShaderBytecode(
2502 D3D12Renderer *renderer,
2503 Uint32 stage,
2504 SDL_GPUShaderFormat format,
2505 const Uint8 *code,
2506 size_t codeSize,
2507 const char *entrypointName,
2508 void **pBytecode,
2509 size_t *pBytecodeSize)
2510{
2511 if (pBytecode != NULL) {
2512 *pBytecode = SDL_malloc(codeSize);
2513 if (!*pBytecode) {
2514 return false;
2515 }
2516 SDL_memcpy(*pBytecode, code, codeSize);
2517 *pBytecodeSize = codeSize;
2518 }
2519
2520 return true;
2521}
2522
2523static D3D12ComputeRootSignature *D3D12_INTERNAL_CreateComputeRootSignature(
2524 D3D12Renderer *renderer,
2525 const SDL_GPUComputePipelineCreateInfo *createInfo)
2526{
2527 // FIXME: I think the max can be smaller...
2528 D3D12_ROOT_PARAMETER rootParameters[MAX_ROOT_SIGNATURE_PARAMETERS];
2529 D3D12_DESCRIPTOR_RANGE descriptorRanges[MAX_ROOT_SIGNATURE_PARAMETERS];
2530 Uint32 parameterCount = 0;
2531 Uint32 rangeCount = 0;
2532 D3D12_DESCRIPTOR_RANGE descriptorRange;
2533 D3D12_ROOT_PARAMETER rootParameter;
2534 D3D12ComputeRootSignature *d3d12ComputeRootSignature =
2535 (D3D12ComputeRootSignature *)SDL_calloc(1, sizeof(D3D12ComputeRootSignature));
2536 if (!d3d12ComputeRootSignature) {
2537 return NULL;
2538 }
2539
2540 SDL_zeroa(rootParameters);
2541 SDL_zeroa(descriptorRanges);
2542 SDL_zero(rootParameter);
2543
2544 d3d12ComputeRootSignature->samplerRootIndex = -1;
2545 d3d12ComputeRootSignature->samplerTextureRootIndex = -1;
2546 d3d12ComputeRootSignature->readOnlyStorageTextureRootIndex = -1;
2547 d3d12ComputeRootSignature->readOnlyStorageBufferRootIndex = -1;
2548 d3d12ComputeRootSignature->readWriteStorageTextureRootIndex = -1;
2549 d3d12ComputeRootSignature->readWriteStorageBufferRootIndex = -1;
2550
2551 for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
2552 d3d12ComputeRootSignature->uniformBufferRootIndex[i] = -1;
2553 }
2554
2555 if (createInfo->num_samplers) {
2556 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
2557 descriptorRange.NumDescriptors = createInfo->num_samplers;
2558 descriptorRange.BaseShaderRegister = 0;
2559 descriptorRange.RegisterSpace = 0;
2560 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2561 descriptorRanges[rangeCount] = descriptorRange;
2562
2563 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2564 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2565 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2566 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; // ALL is used for compute
2567 rootParameters[parameterCount] = rootParameter;
2568 d3d12ComputeRootSignature->samplerRootIndex = parameterCount;
2569 rangeCount += 1;
2570 parameterCount += 1;
2571
2572 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
2573 descriptorRange.NumDescriptors = createInfo->num_samplers;
2574 descriptorRange.BaseShaderRegister = 0;
2575 descriptorRange.RegisterSpace = 0;
2576 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2577 descriptorRanges[rangeCount] = descriptorRange;
2578
2579 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2580 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2581 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2582 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; // ALL is used for compute
2583 rootParameters[parameterCount] = rootParameter;
2584 d3d12ComputeRootSignature->samplerTextureRootIndex = parameterCount;
2585 rangeCount += 1;
2586 parameterCount += 1;
2587 }
2588
2589 if (createInfo->num_readonly_storage_textures) {
2590 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
2591 descriptorRange.NumDescriptors = createInfo->num_readonly_storage_textures;
2592 descriptorRange.BaseShaderRegister = createInfo->num_samplers;
2593 descriptorRange.RegisterSpace = 0;
2594 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2595 descriptorRanges[rangeCount] = descriptorRange;
2596
2597 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2598 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2599 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2600 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; // ALL is used for compute
2601 rootParameters[parameterCount] = rootParameter;
2602 d3d12ComputeRootSignature->readOnlyStorageTextureRootIndex = parameterCount;
2603 rangeCount += 1;
2604 parameterCount += 1;
2605 }
2606
2607 if (createInfo->num_readonly_storage_buffers) {
2608 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
2609 descriptorRange.NumDescriptors = createInfo->num_readonly_storage_buffers;
2610 descriptorRange.BaseShaderRegister = createInfo->num_samplers + createInfo->num_readonly_storage_textures;
2611 descriptorRange.RegisterSpace = 0;
2612 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2613 descriptorRanges[rangeCount] = descriptorRange;
2614
2615 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2616 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2617 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2618 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; // ALL is used for compute
2619 rootParameters[parameterCount] = rootParameter;
2620 d3d12ComputeRootSignature->readOnlyStorageBufferRootIndex = parameterCount;
2621 rangeCount += 1;
2622 parameterCount += 1;
2623 }
2624
2625 if (createInfo->num_readwrite_storage_textures) {
2626 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
2627 descriptorRange.NumDescriptors = createInfo->num_readwrite_storage_textures;
2628 descriptorRange.BaseShaderRegister = 0;
2629 descriptorRange.RegisterSpace = 1;
2630 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2631 descriptorRanges[rangeCount] = descriptorRange;
2632
2633 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2634 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2635 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2636 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; // ALL is used for compute
2637 rootParameters[parameterCount] = rootParameter;
2638 d3d12ComputeRootSignature->readWriteStorageTextureRootIndex = parameterCount;
2639 rangeCount += 1;
2640 parameterCount += 1;
2641 }
2642
2643 if (createInfo->num_readwrite_storage_buffers) {
2644 descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
2645 descriptorRange.NumDescriptors = createInfo->num_readwrite_storage_buffers;
2646 descriptorRange.BaseShaderRegister = createInfo->num_readwrite_storage_textures;
2647 descriptorRange.RegisterSpace = 1;
2648 descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
2649 descriptorRanges[rangeCount] = descriptorRange;
2650
2651 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2652 rootParameter.DescriptorTable.NumDescriptorRanges = 1;
2653 rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
2654 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; // ALL is used for compute
2655 rootParameters[parameterCount] = rootParameter;
2656 d3d12ComputeRootSignature->readWriteStorageBufferRootIndex = parameterCount;
2657 rangeCount += 1;
2658 parameterCount += 1;
2659 }
2660
2661 for (Uint32 i = 0; i < createInfo->num_uniform_buffers; i += 1) {
2662 rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
2663 rootParameter.Descriptor.ShaderRegister = i;
2664 rootParameter.Descriptor.RegisterSpace = 2;
2665 rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; // ALL is used for compute
2666 rootParameters[parameterCount] = rootParameter;
2667 d3d12ComputeRootSignature->uniformBufferRootIndex[i] = parameterCount;
2668 parameterCount += 1;
2669 }
2670
2671 D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc;
2672 rootSignatureDesc.NumParameters = parameterCount;
2673 rootSignatureDesc.pParameters = rootParameters;
2674 rootSignatureDesc.NumStaticSamplers = 0;
2675 rootSignatureDesc.pStaticSamplers = NULL;
2676 rootSignatureDesc.Flags = (D3D12_ROOT_SIGNATURE_FLAGS)0;
2677
2678 ID3DBlob *serializedRootSignature;
2679 ID3DBlob *errorBlob;
2680 HRESULT res = renderer->D3D12SerializeRootSignature_func(
2681 &rootSignatureDesc,
2682 D3D_ROOT_SIGNATURE_VERSION_1,
2683 &serializedRootSignature,
2684 &errorBlob);
2685
2686 if (FAILED(res)) {
2687 if (errorBlob) {
2688 SET_ERROR("Failed to serialize RootSignature: %s", (const char *)ID3D10Blob_GetBufferPointer(errorBlob));
2689 ID3D10Blob_Release(errorBlob);
2690 }
2691 D3D12_INTERNAL_DestroyComputeRootSignature(d3d12ComputeRootSignature);
2692 return NULL;
2693 }
2694
2695 ID3D12RootSignature *rootSignature;
2696
2697 res = ID3D12Device_CreateRootSignature(
2698 renderer->device,
2699 0,
2700 ID3D10Blob_GetBufferPointer(serializedRootSignature),
2701 ID3D10Blob_GetBufferSize(serializedRootSignature),
2702 D3D_GUID(D3D_IID_ID3D12RootSignature),
2703 (void **)&rootSignature);
2704
2705 if (FAILED(res)) {
2706 if (errorBlob) {
2707 SET_ERROR("Failed to create RootSignature: %s", (const char *)ID3D10Blob_GetBufferPointer(errorBlob));
2708 ID3D10Blob_Release(errorBlob);
2709 }
2710 D3D12_INTERNAL_DestroyComputeRootSignature(d3d12ComputeRootSignature);
2711 return NULL;
2712 }
2713
2714 d3d12ComputeRootSignature->handle = rootSignature;
2715 return d3d12ComputeRootSignature;
2716}
2717
2718static SDL_GPUComputePipeline *D3D12_CreateComputePipeline(
2719 SDL_GPURenderer *driverData,
2720 const SDL_GPUComputePipelineCreateInfo *createinfo)
2721{
2722 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
2723 void *bytecode;
2724 size_t bytecodeSize;
2725 ID3D12PipelineState *pipelineState;
2726
2727 if (!D3D12_INTERNAL_CreateShaderBytecode(
2728 renderer,
2729 SDL_GPU_SHADERSTAGE_COMPUTE,
2730 createinfo->format,
2731 createinfo->code,
2732 createinfo->code_size,
2733 createinfo->entrypoint,
2734 &bytecode,
2735 &bytecodeSize)) {
2736 return NULL;
2737 }
2738
2739 D3D12ComputeRootSignature *rootSignature = D3D12_INTERNAL_CreateComputeRootSignature(
2740 renderer,
2741 createinfo);
2742
2743 if (rootSignature == NULL) {
2744 SDL_free(bytecode);
2745 SET_STRING_ERROR_AND_RETURN("Could not create root signature!", NULL);
2746 }
2747
2748 D3D12_COMPUTE_PIPELINE_STATE_DESC pipelineDesc;
2749 pipelineDesc.CS.pShaderBytecode = bytecode;
2750 pipelineDesc.CS.BytecodeLength = bytecodeSize;
2751 pipelineDesc.pRootSignature = rootSignature->handle;
2752 pipelineDesc.CachedPSO.CachedBlobSizeInBytes = 0;
2753 pipelineDesc.CachedPSO.pCachedBlob = NULL;
2754 pipelineDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
2755 pipelineDesc.NodeMask = 0;
2756
2757 HRESULT res = ID3D12Device_CreateComputePipelineState(
2758 renderer->device,
2759 &pipelineDesc,
2760 D3D_GUID(D3D_IID_ID3D12PipelineState),
2761 (void **)&pipelineState);
2762
2763 if (FAILED(res)) {
2764 D3D12_INTERNAL_SetError(renderer, "Could not create compute pipeline state", res);
2765 SDL_free(bytecode);
2766 return NULL;
2767 }
2768
2769 D3D12ComputePipeline *computePipeline =
2770 (D3D12ComputePipeline *)SDL_calloc(1, sizeof(D3D12ComputePipeline));
2771
2772 if (!computePipeline) {
2773 ID3D12PipelineState_Release(pipelineState);
2774 SDL_free(bytecode);
2775 return NULL;
2776 }
2777
2778 computePipeline->pipelineState = pipelineState;
2779 computePipeline->rootSignature = rootSignature;
2780 computePipeline->numSamplers = createinfo->num_samplers;
2781 computePipeline->numReadOnlyStorageTextures = createinfo->num_readonly_storage_textures;
2782 computePipeline->numReadOnlyStorageBuffers = createinfo->num_readonly_storage_buffers;
2783 computePipeline->numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures;
2784 computePipeline->numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers;
2785 computePipeline->numUniformBuffers = createinfo->num_uniform_buffers;
2786 SDL_SetAtomicInt(&computePipeline->referenceCount, 0);
2787
2788 if (renderer->debug_mode && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING)) {
2789 D3D12_INTERNAL_SetPipelineStateName(
2790 renderer,
2791 computePipeline->pipelineState,
2792 SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING, NULL));
2793 }
2794
2795 return (SDL_GPUComputePipeline *)computePipeline;
2796}
2797
2798static bool D3D12_INTERNAL_ConvertRasterizerState(SDL_GPURasterizerState rasterizerState, D3D12_RASTERIZER_DESC *desc)
2799{
2800 if (!desc) {
2801 return false;
2802 }
2803
2804 desc->FillMode = SDLToD3D12_FillMode[rasterizerState.fill_mode];
2805 desc->CullMode = SDLToD3D12_CullMode[rasterizerState.cull_mode];
2806
2807 switch (rasterizerState.front_face) {
2808 case SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE:
2809 desc->FrontCounterClockwise = TRUE;
2810 break;
2811 case SDL_GPU_FRONTFACE_CLOCKWISE:
2812 desc->FrontCounterClockwise = FALSE;
2813 break;
2814 default:
2815 return false;
2816 }
2817
2818 if (rasterizerState.enable_depth_bias) {
2819 desc->DepthBias = SDL_lroundf(rasterizerState.depth_bias_constant_factor);
2820 desc->DepthBiasClamp = rasterizerState.depth_bias_clamp;
2821 desc->SlopeScaledDepthBias = rasterizerState.depth_bias_slope_factor;
2822 } else {
2823 desc->DepthBias = 0;
2824 desc->DepthBiasClamp = 0.0f;
2825 desc->SlopeScaledDepthBias = 0.0f;
2826 }
2827
2828 desc->DepthClipEnable = rasterizerState.enable_depth_clip;
2829 desc->MultisampleEnable = FALSE;
2830 desc->AntialiasedLineEnable = FALSE;
2831 desc->ForcedSampleCount = 0;
2832 desc->ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
2833
2834 return true;
2835}
2836
2837static bool D3D12_INTERNAL_ConvertBlendState(
2838 const SDL_GPUGraphicsPipelineCreateInfo *pipelineInfo,
2839 D3D12_BLEND_DESC *blendDesc)
2840{
2841 if (!blendDesc) {
2842 return false;
2843 }
2844
2845 SDL_zerop(blendDesc);
2846 blendDesc->AlphaToCoverageEnable = FALSE;
2847 blendDesc->IndependentBlendEnable = FALSE;
2848
2849 for (UINT i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1) {
2850 D3D12_RENDER_TARGET_BLEND_DESC rtBlendDesc;
2851 rtBlendDesc.BlendEnable = FALSE;
2852 rtBlendDesc.LogicOpEnable = FALSE;
2853 rtBlendDesc.SrcBlend = D3D12_BLEND_ONE;
2854 rtBlendDesc.DestBlend = D3D12_BLEND_ZERO;
2855 rtBlendDesc.BlendOp = D3D12_BLEND_OP_ADD;
2856 rtBlendDesc.SrcBlendAlpha = D3D12_BLEND_ONE;
2857 rtBlendDesc.DestBlendAlpha = D3D12_BLEND_ZERO;
2858 rtBlendDesc.BlendOpAlpha = D3D12_BLEND_OP_ADD;
2859 rtBlendDesc.LogicOp = D3D12_LOGIC_OP_NOOP;
2860 rtBlendDesc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
2861
2862 // If target_info has more blend states, you can set IndependentBlendEnable to TRUE and assign different blend states to each render target slot
2863 if (i < pipelineInfo->target_info.num_color_targets) {
2864 SDL_GPUColorTargetBlendState sdlBlendState = pipelineInfo->target_info.color_target_descriptions[i].blend_state;
2865 SDL_GPUColorComponentFlags colorWriteMask = sdlBlendState.enable_color_write_mask ?
2866 sdlBlendState.color_write_mask :
2867 0xF;
2868
2869 rtBlendDesc.BlendEnable = sdlBlendState.enable_blend;
2870 rtBlendDesc.SrcBlend = SDLToD3D12_BlendFactor[sdlBlendState.src_color_blendfactor];
2871 rtBlendDesc.DestBlend = SDLToD3D12_BlendFactor[sdlBlendState.dst_color_blendfactor];
2872 rtBlendDesc.BlendOp = SDLToD3D12_BlendOp[sdlBlendState.color_blend_op];
2873 rtBlendDesc.SrcBlendAlpha = SDLToD3D12_BlendFactorAlpha[sdlBlendState.src_alpha_blendfactor];
2874 rtBlendDesc.DestBlendAlpha = SDLToD3D12_BlendFactorAlpha[sdlBlendState.dst_alpha_blendfactor];
2875 rtBlendDesc.BlendOpAlpha = SDLToD3D12_BlendOp[sdlBlendState.alpha_blend_op];
2876 rtBlendDesc.RenderTargetWriteMask = colorWriteMask;
2877
2878 if (i > 0) {
2879 blendDesc->IndependentBlendEnable = TRUE;
2880 }
2881 }
2882
2883 blendDesc->RenderTarget[i] = rtBlendDesc;
2884 }
2885
2886 return true;
2887}
2888
2889static bool D3D12_INTERNAL_ConvertDepthStencilState(SDL_GPUDepthStencilState depthStencilState, D3D12_DEPTH_STENCIL_DESC *desc)
2890{
2891 if (desc == NULL) {
2892 return false;
2893 }
2894
2895 desc->DepthEnable = depthStencilState.enable_depth_test == true ? TRUE : FALSE;
2896 desc->DepthWriteMask = depthStencilState.enable_depth_write == true ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
2897 desc->DepthFunc = SDLToD3D12_CompareOp[depthStencilState.compare_op];
2898 desc->StencilEnable = depthStencilState.enable_stencil_test == true ? TRUE : FALSE;
2899 desc->StencilReadMask = depthStencilState.compare_mask;
2900 desc->StencilWriteMask = depthStencilState.write_mask;
2901
2902 desc->FrontFace.StencilFailOp = SDLToD3D12_StencilOp[depthStencilState.front_stencil_state.fail_op];
2903 desc->FrontFace.StencilDepthFailOp = SDLToD3D12_StencilOp[depthStencilState.front_stencil_state.depth_fail_op];
2904 desc->FrontFace.StencilPassOp = SDLToD3D12_StencilOp[depthStencilState.front_stencil_state.pass_op];
2905 desc->FrontFace.StencilFunc = SDLToD3D12_CompareOp[depthStencilState.front_stencil_state.compare_op];
2906
2907 desc->BackFace.StencilFailOp = SDLToD3D12_StencilOp[depthStencilState.back_stencil_state.fail_op];
2908 desc->BackFace.StencilDepthFailOp = SDLToD3D12_StencilOp[depthStencilState.back_stencil_state.depth_fail_op];
2909 desc->BackFace.StencilPassOp = SDLToD3D12_StencilOp[depthStencilState.back_stencil_state.pass_op];
2910 desc->BackFace.StencilFunc = SDLToD3D12_CompareOp[depthStencilState.back_stencil_state.compare_op];
2911
2912 return true;
2913}
2914
2915static bool D3D12_INTERNAL_ConvertVertexInputState(SDL_GPUVertexInputState vertexInputState, D3D12_INPUT_ELEMENT_DESC *desc, const char *semantic)
2916{
2917 if (desc == NULL || vertexInputState.num_vertex_attributes == 0) {
2918 return false;
2919 }
2920
2921 for (Uint32 i = 0; i < vertexInputState.num_vertex_attributes; i += 1) {
2922 SDL_GPUVertexAttribute attribute = vertexInputState.vertex_attributes[i];
2923
2924 desc[i].SemanticName = semantic;
2925 desc[i].SemanticIndex = attribute.location;
2926 desc[i].Format = SDLToD3D12_VertexFormat[attribute.format];
2927 desc[i].InputSlot = attribute.buffer_slot;
2928 desc[i].AlignedByteOffset = attribute.offset;
2929 desc[i].InputSlotClass = SDLToD3D12_InputRate[vertexInputState.vertex_buffer_descriptions[attribute.buffer_slot].input_rate];
2930 desc[i].InstanceDataStepRate = (vertexInputState.vertex_buffer_descriptions[attribute.buffer_slot].input_rate == SDL_GPU_VERTEXINPUTRATE_INSTANCE)
2931 ? 1
2932 : 0;
2933 }
2934
2935 return true;
2936}
2937
2938static bool D3D12_INTERNAL_AssignStagingDescriptorHandle(
2939 D3D12Renderer *renderer,
2940 D3D12_DESCRIPTOR_HEAP_TYPE heapType,
2941 D3D12StagingDescriptor *cpuDescriptor)
2942{
2943 D3D12StagingDescriptor *descriptor;
2944 D3D12StagingDescriptorPool *pool = renderer->stagingDescriptorPools[heapType];
2945
2946 SDL_LockMutex(pool->lock);
2947
2948 if (pool->freeDescriptorCount == 0) {
2949 if (!D3D12_INTERNAL_ExpandStagingDescriptorPool(renderer, pool))
2950 {
2951 SDL_UnlockMutex(pool->lock);
2952 return false;
2953 }
2954 }
2955
2956 descriptor = &pool->freeDescriptors[pool->freeDescriptorCount - 1];
2957 SDL_memcpy(cpuDescriptor, descriptor, sizeof(D3D12StagingDescriptor));
2958 pool->freeDescriptorCount -= 1;
2959
2960 SDL_UnlockMutex(pool->lock);
2961
2962 return true;
2963}
2964
2965static SDL_GPUGraphicsPipeline *D3D12_CreateGraphicsPipeline(
2966 SDL_GPURenderer *driverData,
2967 const SDL_GPUGraphicsPipelineCreateInfo *createinfo)
2968{
2969 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
2970 D3D12Shader *vertShader = (D3D12Shader *)createinfo->vertex_shader;
2971 D3D12Shader *fragShader = (D3D12Shader *)createinfo->fragment_shader;
2972
2973 if (renderer->debug_mode) {
2974 if (vertShader->stage != SDL_GPU_SHADERSTAGE_VERTEX) {
2975 SDL_assert_release(!"CreateGraphicsPipeline was passed a fragment shader for the vertex stage");
2976 }
2977 if (fragShader->stage != SDL_GPU_SHADERSTAGE_FRAGMENT) {
2978 SDL_assert_release(!"CreateGraphicsPipeline was passed a vertex shader for the fragment stage");
2979 }
2980 }
2981
2982 D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc;
2983 SDL_zero(psoDesc);
2984 psoDesc.VS.pShaderBytecode = vertShader->bytecode;
2985 psoDesc.VS.BytecodeLength = vertShader->bytecodeSize;
2986 psoDesc.PS.pShaderBytecode = fragShader->bytecode;
2987 psoDesc.PS.BytecodeLength = fragShader->bytecodeSize;
2988
2989 D3D12_INPUT_ELEMENT_DESC inputElementDescs[D3D12_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT];
2990 if (createinfo->vertex_input_state.num_vertex_attributes > 0) {
2991 psoDesc.InputLayout.pInputElementDescs = inputElementDescs;
2992 psoDesc.InputLayout.NumElements = createinfo->vertex_input_state.num_vertex_attributes;
2993 D3D12_INTERNAL_ConvertVertexInputState(createinfo->vertex_input_state, inputElementDescs, renderer->semantic);
2994 }
2995
2996 psoDesc.PrimitiveTopologyType = SDLToD3D12_PrimitiveTopologyType[createinfo->primitive_type];
2997
2998 if (!D3D12_INTERNAL_ConvertRasterizerState(createinfo->rasterizer_state, &psoDesc.RasterizerState)) {
2999 return NULL;
3000 }
3001 if (!D3D12_INTERNAL_ConvertBlendState(createinfo, &psoDesc.BlendState)) {
3002 return NULL;
3003 }
3004 if (!D3D12_INTERNAL_ConvertDepthStencilState(createinfo->depth_stencil_state, &psoDesc.DepthStencilState)) {
3005 return NULL;
3006 }
3007
3008 D3D12GraphicsPipeline *pipeline = (D3D12GraphicsPipeline *)SDL_calloc(1, sizeof(D3D12GraphicsPipeline));
3009 if (!pipeline) {
3010 return NULL;
3011 }
3012
3013 psoDesc.SampleMask = 0xFFFFFFFF;
3014 psoDesc.SampleDesc.Count = SDLToD3D12_SampleCount[createinfo->multisample_state.sample_count];
3015 psoDesc.SampleDesc.Quality = (createinfo->multisample_state.sample_count > SDL_GPU_SAMPLECOUNT_1) ? D3D12_STANDARD_MULTISAMPLE_PATTERN : 0;
3016
3017 if (createinfo->target_info.has_depth_stencil_target) {
3018 psoDesc.DSVFormat = SDLToD3D12_DepthFormat[createinfo->target_info.depth_stencil_format];
3019 }
3020 psoDesc.NumRenderTargets = createinfo->target_info.num_color_targets;
3021 for (uint32_t i = 0; i < createinfo->target_info.num_color_targets; i += 1) {
3022 psoDesc.RTVFormats[i] = SDLToD3D12_TextureFormat[createinfo->target_info.color_target_descriptions[i].format];
3023 }
3024
3025 // Assuming some default values or further initialization
3026 psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
3027 psoDesc.CachedPSO.CachedBlobSizeInBytes = 0;
3028 psoDesc.CachedPSO.pCachedBlob = NULL;
3029
3030 psoDesc.NodeMask = 0;
3031
3032 D3D12GraphicsRootSignature *rootSignature = D3D12_INTERNAL_CreateGraphicsRootSignature(
3033 renderer,
3034 vertShader,
3035 fragShader);
3036
3037 if (rootSignature == NULL) {
3038 D3D12_INTERNAL_DestroyGraphicsPipeline(pipeline);
3039 return NULL;
3040 }
3041 pipeline->rootSignature = rootSignature;
3042
3043 psoDesc.pRootSignature = rootSignature->handle;
3044 ID3D12PipelineState *pipelineState;
3045
3046 HRESULT res = ID3D12Device_CreateGraphicsPipelineState(
3047 renderer->device,
3048 &psoDesc,
3049 D3D_GUID(D3D_IID_ID3D12PipelineState),
3050 (void **)&pipelineState);
3051 if (FAILED(res)) {
3052 D3D12_INTERNAL_SetError(renderer, "Could not create graphics pipeline state", res);
3053 D3D12_INTERNAL_DestroyGraphicsPipeline(pipeline);
3054 return NULL;
3055 }
3056
3057 pipeline->pipelineState = pipelineState;
3058
3059 for (Uint32 i = 0; i < createinfo->vertex_input_state.num_vertex_buffers; i += 1) {
3060 pipeline->vertexStrides[createinfo->vertex_input_state.vertex_buffer_descriptions[i].slot] =
3061 createinfo->vertex_input_state.vertex_buffer_descriptions[i].pitch;
3062 }
3063
3064 pipeline->primitiveType = createinfo->primitive_type;
3065
3066 pipeline->vertexSamplerCount = vertShader->num_samplers;
3067 pipeline->vertexStorageTextureCount = vertShader->numStorageTextures;
3068 pipeline->vertexStorageBufferCount = vertShader->numStorageBuffers;
3069 pipeline->vertexUniformBufferCount = vertShader->numUniformBuffers;
3070
3071 pipeline->fragmentSamplerCount = fragShader->num_samplers;
3072 pipeline->fragmentStorageTextureCount = fragShader->numStorageTextures;
3073 pipeline->fragmentStorageBufferCount = fragShader->numStorageBuffers;
3074 pipeline->fragmentUniformBufferCount = fragShader->numUniformBuffers;
3075
3076 SDL_SetAtomicInt(&pipeline->referenceCount, 0);
3077
3078 if (renderer->debug_mode && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING)) {
3079 D3D12_INTERNAL_SetPipelineStateName(
3080 renderer,
3081 pipeline->pipelineState,
3082 SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING, NULL));
3083 }
3084
3085 return (SDL_GPUGraphicsPipeline *)pipeline;
3086}
3087
3088static SDL_GPUSampler *D3D12_CreateSampler(
3089 SDL_GPURenderer *driverData,
3090 const SDL_GPUSamplerCreateInfo *createinfo)
3091{
3092 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3093 D3D12Sampler *sampler = (D3D12Sampler *)SDL_calloc(1, sizeof(D3D12Sampler));
3094 if (!sampler) {
3095 return NULL;
3096 }
3097 D3D12_SAMPLER_DESC samplerDesc;
3098
3099 samplerDesc.Filter = SDLToD3D12_Filter(
3100 createinfo->min_filter,
3101 createinfo->mag_filter,
3102 createinfo->mipmap_mode,
3103 createinfo->enable_compare,
3104 createinfo->enable_anisotropy);
3105 samplerDesc.AddressU = SDLToD3D12_SamplerAddressMode[createinfo->address_mode_u];
3106 samplerDesc.AddressV = SDLToD3D12_SamplerAddressMode[createinfo->address_mode_v];
3107 samplerDesc.AddressW = SDLToD3D12_SamplerAddressMode[createinfo->address_mode_w];
3108 samplerDesc.MaxAnisotropy = (Uint32)createinfo->max_anisotropy;
3109 samplerDesc.ComparisonFunc = SDLToD3D12_CompareOp[createinfo->compare_op];
3110 samplerDesc.MinLOD = createinfo->min_lod;
3111 samplerDesc.MaxLOD = createinfo->max_lod;
3112 samplerDesc.MipLODBias = createinfo->mip_lod_bias;
3113 samplerDesc.BorderColor[0] = 0;
3114 samplerDesc.BorderColor[1] = 0;
3115 samplerDesc.BorderColor[2] = 0;
3116 samplerDesc.BorderColor[3] = 0;
3117
3118 D3D12_INTERNAL_AssignStagingDescriptorHandle(
3119 renderer,
3120 D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
3121 &sampler->handle);
3122
3123 ID3D12Device_CreateSampler(
3124 renderer->device,
3125 &samplerDesc,
3126 sampler->handle.cpuHandle);
3127
3128 sampler->createInfo = *createinfo;
3129 SDL_SetAtomicInt(&sampler->referenceCount, 0);
3130
3131 // Ignore name property because it is not applicable to D3D12.
3132
3133 return (SDL_GPUSampler *)sampler;
3134}
3135
3136static SDL_GPUShader *D3D12_CreateShader(
3137 SDL_GPURenderer *driverData,
3138 const SDL_GPUShaderCreateInfo *createinfo)
3139{
3140 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3141 void *bytecode;
3142 size_t bytecodeSize;
3143 D3D12Shader *shader;
3144
3145 if (!D3D12_INTERNAL_CreateShaderBytecode(
3146 renderer,
3147 createinfo->stage,
3148 createinfo->format,
3149 createinfo->code,
3150 createinfo->code_size,
3151 createinfo->entrypoint,
3152 &bytecode,
3153 &bytecodeSize)) {
3154 return NULL;
3155 }
3156 shader = (D3D12Shader *)SDL_calloc(1, sizeof(D3D12Shader));
3157 if (!shader) {
3158 SDL_free(bytecode);
3159 return NULL;
3160 }
3161 shader->stage = createinfo->stage;
3162 shader->num_samplers = createinfo->num_samplers;
3163 shader->numStorageBuffers = createinfo->num_storage_buffers;
3164 shader->numStorageTextures = createinfo->num_storage_textures;
3165 shader->numUniformBuffers = createinfo->num_uniform_buffers;
3166
3167 shader->bytecode = bytecode;
3168 shader->bytecodeSize = bytecodeSize;
3169
3170 // Ignore name property because it is not applicable to D3D12.
3171
3172 return (SDL_GPUShader *)shader;
3173}
3174
3175static D3D12Texture *D3D12_INTERNAL_CreateTexture(
3176 D3D12Renderer *renderer,
3177 const SDL_GPUTextureCreateInfo *createinfo,
3178 bool isSwapchainTexture,
3179 const char *debugName)
3180{
3181 D3D12Texture *texture;
3182 ID3D12Resource *handle;
3183 D3D12_HEAP_PROPERTIES heapProperties;
3184 D3D12_HEAP_FLAGS heapFlags = (D3D12_HEAP_FLAGS)0;
3185 D3D12_RESOURCE_DESC desc;
3186 D3D12_RESOURCE_FLAGS resourceFlags = (D3D12_RESOURCE_FLAGS)0;
3187 D3D12_RESOURCE_STATES initialState = (D3D12_RESOURCE_STATES)0;
3188 D3D12_CLEAR_VALUE clearValue;
3189 DXGI_FORMAT format;
3190 bool useClearValue = false;
3191 bool needsUAV =
3192 (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) ||
3193 (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE);
3194 HRESULT res;
3195
3196 texture = (D3D12Texture *)SDL_calloc(1, sizeof(D3D12Texture));
3197 if (!texture) {
3198 return NULL;
3199 }
3200
3201 Uint32 layerCount = createinfo->type == SDL_GPU_TEXTURETYPE_3D ? 1 : createinfo->layer_count_or_depth;
3202 Uint32 depth = createinfo->type == SDL_GPU_TEXTURETYPE_3D ? createinfo->layer_count_or_depth : 1;
3203 bool isMultisample = createinfo->sample_count > SDL_GPU_SAMPLECOUNT_1;
3204
3205 format = SDLToD3D12_TextureFormat[createinfo->format];
3206
3207 if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) {
3208 resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
3209 useClearValue = true;
3210 clearValue.Color[0] = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_R_FLOAT, 0);
3211 clearValue.Color[1] = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_G_FLOAT, 0);
3212 clearValue.Color[2] = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_B_FLOAT, 0);
3213 clearValue.Color[3] = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_A_FLOAT, 0);
3214 }
3215
3216 if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) {
3217 resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
3218 useClearValue = true;
3219 clearValue.DepthStencil.Depth = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_DEPTH_FLOAT, 0);
3220 clearValue.DepthStencil.Stencil = (UINT8)SDL_GetNumberProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_UINT8, 0);
3221 format = SDLToD3D12_DepthFormat[createinfo->format];
3222 }
3223
3224 if (needsUAV) {
3225 resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
3226 }
3227
3228 heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
3229 heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
3230 heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
3231 heapProperties.CreationNodeMask = 0; // We don't do multi-adapter operation
3232 heapProperties.VisibleNodeMask = 0; // We don't do multi-adapter operation
3233
3234 heapFlags = isSwapchainTexture ? D3D12_HEAP_FLAG_ALLOW_DISPLAY : D3D12_HEAP_FLAG_NONE;
3235
3236 if (createinfo->type != SDL_GPU_TEXTURETYPE_3D) {
3237 desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
3238 desc.Alignment = isSwapchainTexture ? 0 : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
3239 desc.Width = createinfo->width;
3240 desc.Height = createinfo->height;
3241 desc.DepthOrArraySize = (UINT16)createinfo->layer_count_or_depth;
3242 desc.MipLevels = (UINT16)createinfo->num_levels;
3243 desc.Format = format;
3244 desc.SampleDesc.Count = SDLToD3D12_SampleCount[createinfo->sample_count];
3245 desc.SampleDesc.Quality = isMultisample ? D3D12_STANDARD_MULTISAMPLE_PATTERN : 0;
3246 desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; // Apparently this is the most efficient choice
3247 desc.Flags = resourceFlags;
3248 } else {
3249 desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D;
3250 desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
3251 desc.Width = createinfo->width;
3252 desc.Height = createinfo->height;
3253 desc.DepthOrArraySize = (UINT16)createinfo->layer_count_or_depth;
3254 desc.MipLevels = (UINT16)createinfo->num_levels;
3255 desc.Format = format;
3256 desc.SampleDesc.Count = 1;
3257 desc.SampleDesc.Quality = 0;
3258 desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
3259 desc.Flags = resourceFlags;
3260 }
3261
3262 initialState = isSwapchainTexture ? D3D12_RESOURCE_STATE_PRESENT : D3D12_INTERNAL_DefaultTextureResourceState(createinfo->usage);
3263 clearValue.Format = desc.Format;
3264
3265 res = ID3D12Device_CreateCommittedResource(
3266 renderer->device,
3267 &heapProperties,
3268 heapFlags,
3269 &desc,
3270 initialState,
3271 useClearValue ? &clearValue : NULL,
3272 D3D_GUID(D3D_IID_ID3D12Resource),
3273 (void **)&handle);
3274 if (FAILED(res)) {
3275 D3D12_INTERNAL_SetError(renderer, "Failed to create texture!", res);
3276 D3D12_INTERNAL_DestroyTexture(renderer, texture);
3277 return NULL;
3278 }
3279
3280 texture->resource = handle;
3281
3282 // Create the SRV if applicable
3283 if ((createinfo->usage & SDL_GPU_TEXTUREUSAGE_SAMPLER) ||
3284 (createinfo->usage & SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ) ||
3285 (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ)) {
3286 D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
3287
3288 D3D12_INTERNAL_AssignStagingDescriptorHandle(
3289 renderer,
3290 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
3291 &texture->srvHandle);
3292
3293 srvDesc.Format = SDLToD3D12_TextureFormat[createinfo->format];
3294 srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
3295
3296 if (createinfo->type == SDL_GPU_TEXTURETYPE_CUBE) {
3297 srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
3298 srvDesc.TextureCube.MipLevels = createinfo->num_levels;
3299 srvDesc.TextureCube.MostDetailedMip = 0;
3300 srvDesc.TextureCube.ResourceMinLODClamp = 0;
3301 } else if (createinfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
3302 srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
3303 srvDesc.TextureCubeArray.MipLevels = createinfo->num_levels;
3304 srvDesc.TextureCubeArray.MostDetailedMip = 0;
3305 srvDesc.TextureCubeArray.First2DArrayFace = 0;
3306 srvDesc.TextureCubeArray.NumCubes = createinfo->layer_count_or_depth / 6;
3307 srvDesc.TextureCubeArray.ResourceMinLODClamp = 0;
3308 } else if (createinfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY) {
3309 srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
3310 srvDesc.Texture2DArray.MipLevels = createinfo->num_levels;
3311 srvDesc.Texture2DArray.MostDetailedMip = 0;
3312 srvDesc.Texture2DArray.FirstArraySlice = 0;
3313 srvDesc.Texture2DArray.ArraySize = layerCount;
3314 srvDesc.Texture2DArray.ResourceMinLODClamp = 0;
3315 srvDesc.Texture2DArray.PlaneSlice = 0;
3316 } else if (createinfo->type == SDL_GPU_TEXTURETYPE_3D) {
3317 srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
3318 srvDesc.Texture3D.MipLevels = createinfo->num_levels;
3319 srvDesc.Texture3D.MostDetailedMip = 0;
3320 srvDesc.Texture3D.ResourceMinLODClamp = 0; // default behavior
3321 } else {
3322 srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
3323 srvDesc.Texture2D.MipLevels = createinfo->num_levels;
3324 srvDesc.Texture2D.MostDetailedMip = 0;
3325 srvDesc.Texture2D.PlaneSlice = 0;
3326 srvDesc.Texture2D.ResourceMinLODClamp = 0; // default behavior
3327 }
3328
3329 ID3D12Device_CreateShaderResourceView(
3330 renderer->device,
3331 handle,
3332 &srvDesc,
3333 texture->srvHandle.cpuHandle);
3334 }
3335
3336 SDL_SetAtomicInt(&texture->referenceCount, 0);
3337
3338 texture->subresourceCount = createinfo->num_levels * layerCount;
3339 texture->subresources = (D3D12TextureSubresource *)SDL_calloc(
3340 texture->subresourceCount, sizeof(D3D12TextureSubresource));
3341 if (!texture->subresources) {
3342 D3D12_INTERNAL_DestroyTexture(renderer, texture);
3343 return NULL;
3344 }
3345 for (Uint32 layerIndex = 0; layerIndex < layerCount; layerIndex += 1) {
3346 for (Uint32 levelIndex = 0; levelIndex < createinfo->num_levels; levelIndex += 1) {
3347 Uint32 subresourceIndex = D3D12_INTERNAL_CalcSubresource(
3348 levelIndex,
3349 layerIndex,
3350 createinfo->num_levels);
3351
3352 texture->subresources[subresourceIndex].parent = texture;
3353 texture->subresources[subresourceIndex].layer = layerIndex;
3354 texture->subresources[subresourceIndex].level = levelIndex;
3355 texture->subresources[subresourceIndex].depth = depth;
3356 texture->subresources[subresourceIndex].index = subresourceIndex;
3357
3358 texture->subresources[subresourceIndex].rtvHandles = NULL;
3359 texture->subresources[subresourceIndex].uavHandle.heap = NULL;
3360 texture->subresources[subresourceIndex].dsvHandle.heap = NULL;
3361
3362 // Create RTV if needed
3363 if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) {
3364 texture->subresources[subresourceIndex].rtvHandles = (D3D12StagingDescriptor *)SDL_calloc(depth, sizeof(D3D12StagingDescriptor));
3365
3366 for (Uint32 depthIndex = 0; depthIndex < depth; depthIndex += 1) {
3367 D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
3368
3369 D3D12_INTERNAL_AssignStagingDescriptorHandle(
3370 renderer,
3371 D3D12_DESCRIPTOR_HEAP_TYPE_RTV,
3372 &texture->subresources[subresourceIndex].rtvHandles[depthIndex]);
3373
3374 rtvDesc.Format = SDLToD3D12_TextureFormat[createinfo->format];
3375
3376 if (createinfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || createinfo->type == SDL_GPU_TEXTURETYPE_CUBE || createinfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
3377 rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
3378 rtvDesc.Texture2DArray.MipSlice = levelIndex;
3379 rtvDesc.Texture2DArray.FirstArraySlice = layerIndex;
3380 rtvDesc.Texture2DArray.ArraySize = 1;
3381 rtvDesc.Texture2DArray.PlaneSlice = 0;
3382 } else if (createinfo->type == SDL_GPU_TEXTURETYPE_3D) {
3383 rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D;
3384 rtvDesc.Texture3D.MipSlice = levelIndex;
3385 rtvDesc.Texture3D.FirstWSlice = depthIndex;
3386 rtvDesc.Texture3D.WSize = 1;
3387 } else if (isMultisample) {
3388 rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS;
3389 } else {
3390 rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
3391 rtvDesc.Texture2D.MipSlice = levelIndex;
3392 rtvDesc.Texture2D.PlaneSlice = 0;
3393 }
3394
3395 ID3D12Device_CreateRenderTargetView(
3396 renderer->device,
3397 texture->resource,
3398 &rtvDesc,
3399 texture->subresources[subresourceIndex].rtvHandles[depthIndex].cpuHandle);
3400 }
3401 }
3402
3403 // Create DSV if needed
3404 if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) {
3405 D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc;
3406
3407 D3D12_INTERNAL_AssignStagingDescriptorHandle(
3408 renderer,
3409 D3D12_DESCRIPTOR_HEAP_TYPE_DSV,
3410 &texture->subresources[subresourceIndex].dsvHandle);
3411
3412 dsvDesc.Format = SDLToD3D12_DepthFormat[createinfo->format];
3413 dsvDesc.Flags = (D3D12_DSV_FLAGS)0;
3414
3415 if (isMultisample) {
3416 dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMS;
3417 } else {
3418 dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
3419 dsvDesc.Texture2D.MipSlice = levelIndex;
3420 }
3421
3422 ID3D12Device_CreateDepthStencilView(
3423 renderer->device,
3424 texture->resource,
3425 &dsvDesc,
3426 texture->subresources[subresourceIndex].dsvHandle.cpuHandle);
3427 }
3428
3429 // Create subresource UAV if necessary
3430 if (needsUAV) {
3431 D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc;
3432
3433 D3D12_INTERNAL_AssignStagingDescriptorHandle(
3434 renderer,
3435 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
3436 &texture->subresources[subresourceIndex].uavHandle);
3437
3438 uavDesc.Format = SDLToD3D12_TextureFormat[createinfo->format];
3439
3440 if (createinfo->type == SDL_GPU_TEXTURETYPE_2D_ARRAY || createinfo->type == SDL_GPU_TEXTURETYPE_CUBE || createinfo->type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY) {
3441 uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY;
3442 uavDesc.Texture2DArray.MipSlice = levelIndex;
3443 uavDesc.Texture2DArray.FirstArraySlice = layerIndex;
3444 uavDesc.Texture2DArray.ArraySize = 1;
3445 } else if (createinfo->type == SDL_GPU_TEXTURETYPE_3D) {
3446 uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D;
3447 uavDesc.Texture3D.MipSlice = levelIndex;
3448 uavDesc.Texture3D.FirstWSlice = 0;
3449 uavDesc.Texture3D.WSize = depth;
3450 } else {
3451 uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
3452 uavDesc.Texture2D.MipSlice = levelIndex;
3453 uavDesc.Texture2D.PlaneSlice = 0;
3454 }
3455
3456 ID3D12Device_CreateUnorderedAccessView(
3457 renderer->device,
3458 texture->resource,
3459 NULL,
3460 &uavDesc,
3461 texture->subresources[subresourceIndex].uavHandle.cpuHandle);
3462 }
3463 }
3464 }
3465
3466 D3D12_INTERNAL_SetResourceName(
3467 renderer,
3468 texture->resource,
3469 debugName);
3470
3471 return texture;
3472}
3473
3474static SDL_GPUTexture *D3D12_CreateTexture(
3475 SDL_GPURenderer *driverData,
3476 const SDL_GPUTextureCreateInfo *createinfo)
3477{
3478 D3D12TextureContainer *container = (D3D12TextureContainer *)SDL_calloc(1, sizeof(D3D12TextureContainer));
3479 if (!container) {
3480 return NULL;
3481 }
3482
3483 // Copy properties so we don't lose information when the client destroys them
3484 container->header.info = *createinfo;
3485 container->header.info.props = SDL_CreateProperties();
3486 SDL_CopyProperties(createinfo->props, container->header.info.props);
3487
3488 container->textureCapacity = 1;
3489 container->textureCount = 1;
3490 container->textures = (D3D12Texture **)SDL_calloc(
3491 container->textureCapacity, sizeof(D3D12Texture *));
3492
3493 if (!container->textures) {
3494 SDL_free(container);
3495 return NULL;
3496 }
3497
3498 container->debugName = NULL;
3499 if (SDL_HasProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING)) {
3500 container->debugName = SDL_strdup(SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING, NULL));
3501 }
3502
3503 container->canBeCycled = true;
3504
3505 D3D12Texture *texture = D3D12_INTERNAL_CreateTexture(
3506 (D3D12Renderer *)driverData,
3507 createinfo,
3508 false,
3509 container->debugName);
3510
3511 if (!texture) {
3512 SDL_free(container->textures);
3513 SDL_free(container);
3514 return NULL;
3515 }
3516
3517 container->textures[0] = texture;
3518 container->activeTexture = texture;
3519
3520 texture->container = container;
3521 texture->containerIndex = 0;
3522
3523 return (SDL_GPUTexture *)container;
3524}
3525
3526static D3D12Buffer *D3D12_INTERNAL_CreateBuffer(
3527 D3D12Renderer *renderer,
3528 SDL_GPUBufferUsageFlags usageFlags,
3529 Uint32 size,
3530 D3D12BufferType type,
3531 const char *debugName)
3532{
3533 D3D12Buffer *buffer;
3534 ID3D12Resource *handle;
3535 D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc;
3536 D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
3537 D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc;
3538 D3D12_HEAP_PROPERTIES heapProperties;
3539 D3D12_RESOURCE_DESC desc;
3540 D3D12_HEAP_FLAGS heapFlags = (D3D12_HEAP_FLAGS)0;
3541 D3D12_RESOURCE_FLAGS resourceFlags = (D3D12_RESOURCE_FLAGS)0;
3542 D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_COMMON;
3543 HRESULT res;
3544
3545 buffer = (D3D12Buffer *)SDL_calloc(1, sizeof(D3D12Buffer));
3546
3547 if (!buffer) {
3548 return NULL;
3549 }
3550
3551 if (usageFlags & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE) {
3552 resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
3553 }
3554#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
3555 if (usageFlags & SDL_GPU_BUFFERUSAGE_INDIRECT) {
3556 resourceFlags |= D3D12XBOX_RESOURCE_FLAG_ALLOW_INDIRECT_BUFFER;
3557 }
3558#endif
3559
3560 heapProperties.CreationNodeMask = 0; // We don't do multi-adapter operation
3561 heapProperties.VisibleNodeMask = 0; // We don't do multi-adapter operation
3562
3563 if (type == D3D12_BUFFER_TYPE_GPU) {
3564 heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
3565 heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
3566 heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
3567 heapFlags = D3D12_HEAP_FLAG_NONE;
3568 } else if (type == D3D12_BUFFER_TYPE_UPLOAD) {
3569 heapProperties.Type = D3D12_HEAP_TYPE_UPLOAD;
3570 heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
3571 heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
3572 heapFlags = D3D12_HEAP_FLAG_NONE;
3573 initialState = D3D12_RESOURCE_STATE_GENERIC_READ;
3574 } else if (type == D3D12_BUFFER_TYPE_DOWNLOAD) {
3575 heapProperties.Type = D3D12_HEAP_TYPE_READBACK;
3576 heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
3577 heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
3578 heapFlags = D3D12_HEAP_FLAG_NONE;
3579 initialState = D3D12_RESOURCE_STATE_COPY_DEST;
3580 } else if (type == D3D12_BUFFER_TYPE_UNIFORM) {
3581 // D3D12 is badly designed, so we have to check if the fast path for uniform buffers is enabled
3582 if (renderer->GPUUploadHeapSupported) {
3583 heapProperties.Type = D3D12_HEAP_TYPE_GPU_UPLOAD;
3584 heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
3585 heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
3586 } else {
3587 heapProperties.Type = D3D12_HEAP_TYPE_UPLOAD;
3588 heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
3589 heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
3590 initialState = D3D12_RESOURCE_STATE_GENERIC_READ;
3591 }
3592 heapFlags = D3D12_HEAP_FLAG_NONE;
3593 } else {
3594 SET_STRING_ERROR_AND_RETURN("Unrecognized buffer type!", NULL);
3595 }
3596
3597 desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
3598 desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
3599 desc.Width = size;
3600 desc.Height = 1;
3601 desc.DepthOrArraySize = 1;
3602 desc.MipLevels = 1;
3603 desc.Format = DXGI_FORMAT_UNKNOWN;
3604 desc.SampleDesc.Count = 1;
3605 desc.SampleDesc.Quality = 0;
3606 desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
3607 desc.Flags = resourceFlags;
3608
3609 res = ID3D12Device_CreateCommittedResource(
3610 renderer->device,
3611 &heapProperties,
3612 heapFlags,
3613 &desc,
3614 initialState,
3615 NULL,
3616 D3D_GUID(D3D_IID_ID3D12Resource),
3617 (void **)&handle);
3618 if (FAILED(res)) {
3619 D3D12_INTERNAL_SetError(renderer, "Could not create buffer!", res);
3620 D3D12_INTERNAL_DestroyBuffer(renderer, buffer);
3621 return NULL;
3622 }
3623
3624 buffer->handle = handle;
3625 SDL_SetAtomicInt(&buffer->referenceCount, 0);
3626
3627 buffer->uavDescriptor.heap = NULL;
3628 buffer->srvDescriptor.heap = NULL;
3629 buffer->cbvDescriptor.heap = NULL;
3630
3631 if (usageFlags & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE) {
3632 D3D12_INTERNAL_AssignStagingDescriptorHandle(
3633 renderer,
3634 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
3635 &buffer->uavDescriptor);
3636
3637 uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
3638 uavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
3639 uavDesc.Buffer.FirstElement = 0;
3640 uavDesc.Buffer.NumElements = size / sizeof(Uint32);
3641 uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
3642 uavDesc.Buffer.CounterOffsetInBytes = 0; // TODO: support counters?
3643 uavDesc.Buffer.StructureByteStride = 0;
3644
3645 // Create UAV
3646 ID3D12Device_CreateUnorderedAccessView(
3647 renderer->device,
3648 handle,
3649 NULL, // TODO: support counters?
3650 &uavDesc,
3651 buffer->uavDescriptor.cpuHandle);
3652 }
3653
3654 if (
3655 (usageFlags & SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ) ||
3656 (usageFlags & SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_READ)) {
3657 D3D12_INTERNAL_AssignStagingDescriptorHandle(
3658 renderer,
3659 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
3660 &buffer->srvDescriptor);
3661
3662 srvDesc.Format = DXGI_FORMAT_R32_TYPELESS;
3663 srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
3664 srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
3665 srvDesc.Buffer.FirstElement = 0;
3666 srvDesc.Buffer.NumElements = size / sizeof(Uint32);
3667 srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
3668 srvDesc.Buffer.StructureByteStride = 0;
3669
3670 // Create SRV
3671 ID3D12Device_CreateShaderResourceView(
3672 renderer->device,
3673 handle,
3674 &srvDesc,
3675 buffer->srvDescriptor.cpuHandle);
3676 }
3677
3678 // FIXME: we may not need a CBV since we use root descriptors
3679 if (type == D3D12_BUFFER_TYPE_UNIFORM) {
3680 D3D12_INTERNAL_AssignStagingDescriptorHandle(
3681 renderer,
3682 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
3683 &buffer->cbvDescriptor);
3684
3685 cbvDesc.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(handle);
3686 cbvDesc.SizeInBytes = size;
3687
3688 // Create CBV
3689 ID3D12Device_CreateConstantBufferView(
3690 renderer->device,
3691 &cbvDesc,
3692 buffer->cbvDescriptor.cpuHandle);
3693 }
3694
3695 buffer->virtualAddress = 0;
3696 if (type == D3D12_BUFFER_TYPE_GPU || type == D3D12_BUFFER_TYPE_UNIFORM) {
3697 buffer->virtualAddress = ID3D12Resource_GetGPUVirtualAddress(buffer->handle);
3698 }
3699
3700 buffer->mapPointer = NULL;
3701 // Persistently map upload buffers
3702 if (type == D3D12_BUFFER_TYPE_UPLOAD) {
3703 res = ID3D12Resource_Map(
3704 buffer->handle,
3705 0,
3706 NULL,
3707 (void **)&buffer->mapPointer);
3708 if (FAILED(res)) {
3709 D3D12_INTERNAL_SetError(renderer, "Failed to map upload buffer!", res);
3710 D3D12_INTERNAL_DestroyBuffer(renderer, buffer);
3711 return NULL;
3712 }
3713 }
3714
3715 buffer->container = NULL;
3716 buffer->containerIndex = 0;
3717
3718 buffer->transitioned = initialState != D3D12_RESOURCE_STATE_COMMON;
3719 SDL_SetAtomicInt(&buffer->referenceCount, 0);
3720
3721 D3D12_INTERNAL_SetResourceName(
3722 renderer,
3723 buffer->handle,
3724 debugName);
3725
3726 return buffer;
3727}
3728
3729static D3D12BufferContainer *D3D12_INTERNAL_CreateBufferContainer(
3730 D3D12Renderer *renderer,
3731 SDL_GPUBufferUsageFlags usageFlags,
3732 Uint32 size,
3733 D3D12BufferType type,
3734 const char *debugName)
3735{
3736 D3D12BufferContainer *container;
3737 D3D12Buffer *buffer;
3738
3739 container = (D3D12BufferContainer *)SDL_calloc(1, sizeof(D3D12BufferContainer));
3740 if (!container) {
3741 return NULL;
3742 }
3743
3744 container->usage = usageFlags;
3745 container->size = size;
3746 container->type = type;
3747
3748 container->bufferCapacity = 1;
3749 container->bufferCount = 1;
3750 container->buffers = (D3D12Buffer **)SDL_calloc(
3751 container->bufferCapacity, sizeof(D3D12Buffer *));
3752 if (!container->buffers) {
3753 SDL_free(container);
3754 return NULL;
3755 }
3756 container->debugName = NULL;
3757
3758 buffer = D3D12_INTERNAL_CreateBuffer(
3759 renderer,
3760 usageFlags,
3761 size,
3762 type,
3763 debugName);
3764
3765 if (buffer == NULL) {
3766 SDL_free(container->buffers);
3767 SDL_free(container);
3768 return NULL;
3769 }
3770
3771 container->activeBuffer = buffer;
3772 container->buffers[0] = buffer;
3773 buffer->container = container;
3774 buffer->containerIndex = 0;
3775
3776 if (debugName != NULL) {
3777 container->debugName = SDL_strdup(debugName);
3778 }
3779
3780 return container;
3781}
3782
3783static SDL_GPUBuffer *D3D12_CreateBuffer(
3784 SDL_GPURenderer *driverData,
3785 SDL_GPUBufferUsageFlags usageFlags,
3786 Uint32 size,
3787 const char *debugName)
3788{
3789 return (SDL_GPUBuffer *)D3D12_INTERNAL_CreateBufferContainer(
3790 (D3D12Renderer *)driverData,
3791 usageFlags,
3792 size,
3793 D3D12_BUFFER_TYPE_GPU,
3794 debugName);
3795}
3796
3797static SDL_GPUTransferBuffer *D3D12_CreateTransferBuffer(
3798 SDL_GPURenderer *driverData,
3799 SDL_GPUTransferBufferUsage usage,
3800 Uint32 size,
3801 const char *debugName)
3802{
3803 return (SDL_GPUTransferBuffer *)D3D12_INTERNAL_CreateBufferContainer(
3804 (D3D12Renderer *)driverData,
3805 0,
3806 size,
3807 usage == SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD ? D3D12_BUFFER_TYPE_UPLOAD : D3D12_BUFFER_TYPE_DOWNLOAD,
3808 debugName);
3809}
3810
3811// Disposal
3812
3813static void D3D12_ReleaseTexture(
3814 SDL_GPURenderer *driverData,
3815 SDL_GPUTexture *texture)
3816{
3817 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3818 D3D12TextureContainer *container = (D3D12TextureContainer *)texture;
3819
3820 D3D12_INTERNAL_ReleaseTextureContainer(
3821 renderer,
3822 container);
3823}
3824
3825static void D3D12_ReleaseSampler(
3826 SDL_GPURenderer *driverData,
3827 SDL_GPUSampler *sampler)
3828{
3829 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3830 D3D12Sampler *d3d12Sampler = (D3D12Sampler *)sampler;
3831
3832 SDL_LockMutex(renderer->disposeLock);
3833
3834 EXPAND_ARRAY_IF_NEEDED(
3835 renderer->samplersToDestroy,
3836 D3D12Sampler *,
3837 renderer->samplersToDestroyCount + 1,
3838 renderer->samplersToDestroyCapacity,
3839 renderer->samplersToDestroyCapacity * 2);
3840
3841 renderer->samplersToDestroy[renderer->samplersToDestroyCount] = d3d12Sampler;
3842 renderer->samplersToDestroyCount += 1;
3843
3844 SDL_UnlockMutex(renderer->disposeLock);
3845}
3846
3847static void D3D12_ReleaseBuffer(
3848 SDL_GPURenderer *driverData,
3849 SDL_GPUBuffer *buffer)
3850{
3851 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3852 D3D12BufferContainer *bufferContainer = (D3D12BufferContainer *)buffer;
3853
3854 D3D12_INTERNAL_ReleaseBufferContainer(
3855 renderer,
3856 bufferContainer);
3857}
3858
3859static void D3D12_ReleaseTransferBuffer(
3860 SDL_GPURenderer *driverData,
3861 SDL_GPUTransferBuffer *transferBuffer)
3862{
3863 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3864 D3D12BufferContainer *transferBufferContainer = (D3D12BufferContainer *)transferBuffer;
3865
3866 D3D12_INTERNAL_ReleaseBufferContainer(
3867 renderer,
3868 transferBufferContainer);
3869}
3870
3871static void D3D12_ReleaseShader(
3872 SDL_GPURenderer *driverData,
3873 SDL_GPUShader *shader)
3874{
3875 /* D3D12Renderer *renderer = (D3D12Renderer *)driverData; */
3876 D3D12Shader *d3d12shader = (D3D12Shader *)shader;
3877
3878 if (d3d12shader->bytecode) {
3879 SDL_free(d3d12shader->bytecode);
3880 d3d12shader->bytecode = NULL;
3881 }
3882 SDL_free(d3d12shader);
3883}
3884
3885static void D3D12_ReleaseComputePipeline(
3886 SDL_GPURenderer *driverData,
3887 SDL_GPUComputePipeline *computePipeline)
3888{
3889 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3890 D3D12ComputePipeline *d3d12ComputePipeline = (D3D12ComputePipeline *)computePipeline;
3891
3892 SDL_LockMutex(renderer->disposeLock);
3893
3894 EXPAND_ARRAY_IF_NEEDED(
3895 renderer->computePipelinesToDestroy,
3896 D3D12ComputePipeline *,
3897 renderer->computePipelinesToDestroyCount + 1,
3898 renderer->computePipelinesToDestroyCapacity,
3899 renderer->computePipelinesToDestroyCapacity * 2);
3900
3901 renderer->computePipelinesToDestroy[renderer->computePipelinesToDestroyCount] = d3d12ComputePipeline;
3902 renderer->computePipelinesToDestroyCount += 1;
3903
3904 SDL_UnlockMutex(renderer->disposeLock);
3905}
3906
3907static void D3D12_ReleaseGraphicsPipeline(
3908 SDL_GPURenderer *driverData,
3909 SDL_GPUGraphicsPipeline *graphicsPipeline)
3910{
3911 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3912 D3D12GraphicsPipeline *d3d12GraphicsPipeline = (D3D12GraphicsPipeline *)graphicsPipeline;
3913
3914 SDL_LockMutex(renderer->disposeLock);
3915
3916 EXPAND_ARRAY_IF_NEEDED(
3917 renderer->graphicsPipelinesToDestroy,
3918 D3D12GraphicsPipeline *,
3919 renderer->graphicsPipelinesToDestroyCount + 1,
3920 renderer->graphicsPipelinesToDestroyCapacity,
3921 renderer->graphicsPipelinesToDestroyCapacity * 2);
3922
3923 renderer->graphicsPipelinesToDestroy[renderer->graphicsPipelinesToDestroyCount] = d3d12GraphicsPipeline;
3924 renderer->graphicsPipelinesToDestroyCount += 1;
3925
3926 SDL_UnlockMutex(renderer->disposeLock);
3927}
3928
3929static void D3D12_INTERNAL_ReleaseBlitPipelines(SDL_GPURenderer *driverData)
3930{
3931 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
3932 D3D12_ReleaseSampler(driverData, renderer->blitLinearSampler);
3933 D3D12_ReleaseSampler(driverData, renderer->blitNearestSampler);
3934 D3D12_ReleaseShader(driverData, renderer->blitVertexShader);
3935 D3D12_ReleaseShader(driverData, renderer->blitFrom2DShader);
3936 D3D12_ReleaseShader(driverData, renderer->blitFrom2DArrayShader);
3937 D3D12_ReleaseShader(driverData, renderer->blitFrom3DShader);
3938 D3D12_ReleaseShader(driverData, renderer->blitFromCubeShader);
3939 D3D12_ReleaseShader(driverData, renderer->blitFromCubeArrayShader);
3940
3941 for (Uint32 i = 0; i < renderer->blitPipelineCount; i += 1) {
3942 D3D12_ReleaseGraphicsPipeline(driverData, renderer->blitPipelines[i].pipeline);
3943 }
3944 SDL_free(renderer->blitPipelines);
3945}
3946
3947// Render Pass
3948
3949static void D3D12_SetViewport(
3950 SDL_GPUCommandBuffer *commandBuffer,
3951 const SDL_GPUViewport *viewport)
3952{
3953 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
3954 D3D12_VIEWPORT d3d12Viewport;
3955 d3d12Viewport.TopLeftX = viewport->x;
3956 d3d12Viewport.TopLeftY = viewport->y;
3957 d3d12Viewport.Width = viewport->w;
3958 d3d12Viewport.Height = viewport->h;
3959 d3d12Viewport.MinDepth = viewport->min_depth;
3960 d3d12Viewport.MaxDepth = viewport->max_depth;
3961 ID3D12GraphicsCommandList_RSSetViewports(d3d12CommandBuffer->graphicsCommandList, 1, &d3d12Viewport);
3962}
3963
3964static void D3D12_SetScissor(
3965 SDL_GPUCommandBuffer *commandBuffer,
3966 const SDL_Rect *scissor)
3967{
3968 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
3969 D3D12_RECT scissorRect;
3970 scissorRect.left = scissor->x;
3971 scissorRect.top = scissor->y;
3972 scissorRect.right = scissor->x + scissor->w;
3973 scissorRect.bottom = scissor->y + scissor->h;
3974 ID3D12GraphicsCommandList_RSSetScissorRects(d3d12CommandBuffer->graphicsCommandList, 1, &scissorRect);
3975}
3976
3977static void D3D12_SetBlendConstants(
3978 SDL_GPUCommandBuffer *commandBuffer,
3979 SDL_FColor blendConstants)
3980{
3981 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
3982 FLOAT blendFactor[4] = { blendConstants.r, blendConstants.g, blendConstants.b, blendConstants.a };
3983 ID3D12GraphicsCommandList_OMSetBlendFactor(d3d12CommandBuffer->graphicsCommandList, blendFactor);
3984}
3985
3986static void D3D12_SetStencilReference(
3987 SDL_GPUCommandBuffer *commandBuffer,
3988 Uint8 reference
3989) {
3990 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
3991 ID3D12GraphicsCommandList_OMSetStencilRef(d3d12CommandBuffer->graphicsCommandList, reference);
3992}
3993
3994static D3D12TextureSubresource *D3D12_INTERNAL_FetchTextureSubresource(
3995 D3D12TextureContainer *container,
3996 Uint32 layer,
3997 Uint32 level)
3998{
3999 Uint32 index = D3D12_INTERNAL_CalcSubresource(
4000 level,
4001 layer,
4002 container->header.info.num_levels);
4003 return &container->activeTexture->subresources[index];
4004}
4005
4006static void D3D12_INTERNAL_CycleActiveTexture(
4007 D3D12Renderer *renderer,
4008 D3D12TextureContainer *container)
4009{
4010 D3D12Texture *texture;
4011
4012 // If a previously-cycled texture is available, we can use that.
4013 for (Uint32 i = 0; i < container->textureCount; i += 1) {
4014 texture = container->textures[i];
4015
4016 if (SDL_GetAtomicInt(&texture->referenceCount) == 0) {
4017 container->activeTexture = texture;
4018 return;
4019 }
4020 }
4021
4022 // No texture is available, generate a new one.
4023 texture = D3D12_INTERNAL_CreateTexture(
4024 renderer,
4025 &container->header.info,
4026 false,
4027 container->debugName);
4028
4029 if (!texture) {
4030 return;
4031 }
4032
4033 EXPAND_ARRAY_IF_NEEDED(
4034 container->textures,
4035 D3D12Texture *,
4036 container->textureCount + 1,
4037 container->textureCapacity,
4038 container->textureCapacity * 2);
4039
4040 container->textures[container->textureCount] = texture;
4041 texture->container = container;
4042 texture->containerIndex = container->textureCount;
4043 container->textureCount += 1;
4044
4045 container->activeTexture = texture;
4046}
4047
4048static D3D12TextureSubresource *D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
4049 D3D12CommandBuffer *commandBuffer,
4050 D3D12TextureContainer *container,
4051 Uint32 layer,
4052 Uint32 level,
4053 bool cycle,
4054 D3D12_RESOURCE_STATES destinationUsageMode)
4055{
4056 D3D12TextureSubresource *subresource = D3D12_INTERNAL_FetchTextureSubresource(
4057 container,
4058 layer,
4059 level);
4060
4061 if (
4062 container->canBeCycled &&
4063 cycle &&
4064 SDL_GetAtomicInt(&subresource->parent->referenceCount) > 0) {
4065 D3D12_INTERNAL_CycleActiveTexture(
4066 commandBuffer->renderer,
4067 container);
4068
4069 subresource = D3D12_INTERNAL_FetchTextureSubresource(
4070 container,
4071 layer,
4072 level);
4073 }
4074
4075 D3D12_INTERNAL_TextureSubresourceTransitionFromDefaultUsage(
4076 commandBuffer,
4077 destinationUsageMode,
4078 subresource);
4079
4080 return subresource;
4081}
4082
4083static void D3D12_INTERNAL_CycleActiveBuffer(
4084 D3D12Renderer *renderer,
4085 D3D12BufferContainer *container)
4086{
4087 // If a previously-cycled buffer is available, we can use that.
4088 for (Uint32 i = 0; i < container->bufferCount; i += 1) {
4089 D3D12Buffer *buffer = container->buffers[i];
4090 if (SDL_GetAtomicInt(&buffer->referenceCount) == 0) {
4091 container->activeBuffer = buffer;
4092 return;
4093 }
4094 }
4095
4096 // No buffer handle is available, create a new one.
4097 D3D12Buffer *buffer = D3D12_INTERNAL_CreateBuffer(
4098 renderer,
4099 container->usage,
4100 container->size,
4101 container->type,
4102 container->debugName);
4103
4104 if (!buffer) {
4105 return;
4106 }
4107
4108 EXPAND_ARRAY_IF_NEEDED(
4109 container->buffers,
4110 D3D12Buffer *,
4111 container->bufferCount + 1,
4112 container->bufferCapacity,
4113 container->bufferCapacity * 2);
4114
4115 container->buffers[container->bufferCount] = buffer;
4116 buffer->container = container;
4117 buffer->containerIndex = container->bufferCount;
4118 container->bufferCount += 1;
4119
4120 container->activeBuffer = buffer;
4121
4122 if (renderer->debug_mode && container->debugName != NULL) {
4123 D3D12_INTERNAL_SetResourceName(
4124 renderer,
4125 container->activeBuffer->handle,
4126 container->debugName);
4127 }
4128}
4129
4130static D3D12Buffer *D3D12_INTERNAL_PrepareBufferForWrite(
4131 D3D12CommandBuffer *commandBuffer,
4132 D3D12BufferContainer *container,
4133 bool cycle,
4134 D3D12_RESOURCE_STATES destinationState)
4135{
4136 if (
4137 cycle &&
4138 SDL_GetAtomicInt(&container->activeBuffer->referenceCount) > 0) {
4139 D3D12_INTERNAL_CycleActiveBuffer(
4140 commandBuffer->renderer,
4141 container);
4142 }
4143
4144 D3D12_INTERNAL_BufferTransitionFromDefaultUsage(
4145 commandBuffer,
4146 destinationState,
4147 container->activeBuffer);
4148
4149 return container->activeBuffer;
4150}
4151
4152static void D3D12_BeginRenderPass(
4153 SDL_GPUCommandBuffer *commandBuffer,
4154 const SDL_GPUColorTargetInfo *colorTargetInfos,
4155 Uint32 numColorTargets,
4156 const SDL_GPUDepthStencilTargetInfo *depthStencilTargetInfo)
4157{
4158 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4159
4160 Uint32 framebufferWidth = SDL_MAX_UINT32;
4161 Uint32 framebufferHeight = SDL_MAX_UINT32;
4162
4163 for (Uint32 i = 0; i < numColorTargets; i += 1) {
4164 D3D12TextureContainer *container = (D3D12TextureContainer *)colorTargetInfos[i].texture;
4165 Uint32 h = container->header.info.height >> colorTargetInfos[i].mip_level;
4166 Uint32 w = container->header.info.width >> colorTargetInfos[i].mip_level;
4167
4168 // The framebuffer cannot be larger than the smallest target.
4169
4170 if (w < framebufferWidth) {
4171 framebufferWidth = w;
4172 }
4173
4174 if (h < framebufferHeight) {
4175 framebufferHeight = h;
4176 }
4177 }
4178
4179 if (depthStencilTargetInfo != NULL) {
4180 D3D12TextureContainer *container = (D3D12TextureContainer *)depthStencilTargetInfo->texture;
4181
4182 Uint32 h = container->header.info.height;
4183 Uint32 w = container->header.info.width;
4184
4185 // The framebuffer cannot be larger than the smallest target.
4186
4187 if (w < framebufferWidth) {
4188 framebufferWidth = w;
4189 }
4190
4191 if (h < framebufferHeight) {
4192 framebufferHeight = h;
4193 }
4194 }
4195
4196 D3D12_CPU_DESCRIPTOR_HANDLE rtvs[MAX_COLOR_TARGET_BINDINGS];
4197
4198 for (Uint32 i = 0; i < numColorTargets; i += 1) {
4199 D3D12TextureContainer *container = (D3D12TextureContainer *)colorTargetInfos[i].texture;
4200 D3D12TextureSubresource *subresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
4201 d3d12CommandBuffer,
4202 container,
4203 container->header.info.type == SDL_GPU_TEXTURETYPE_3D ? 0 : colorTargetInfos[i].layer_or_depth_plane,
4204 colorTargetInfos[i].mip_level,
4205 colorTargetInfos[i].cycle,
4206 D3D12_RESOURCE_STATE_RENDER_TARGET);
4207
4208 Uint32 rtvIndex = container->header.info.type == SDL_GPU_TEXTURETYPE_3D ? colorTargetInfos[i].layer_or_depth_plane : 0;
4209 D3D12_CPU_DESCRIPTOR_HANDLE rtv = subresource->rtvHandles[rtvIndex].cpuHandle;
4210
4211 if (colorTargetInfos[i].load_op == SDL_GPU_LOADOP_CLEAR) {
4212 float clearColor[4];
4213 clearColor[0] = colorTargetInfos[i].clear_color.r;
4214 clearColor[1] = colorTargetInfos[i].clear_color.g;
4215 clearColor[2] = colorTargetInfos[i].clear_color.b;
4216 clearColor[3] = colorTargetInfos[i].clear_color.a;
4217
4218 ID3D12GraphicsCommandList_ClearRenderTargetView(
4219 d3d12CommandBuffer->graphicsCommandList,
4220 rtv,
4221 clearColor,
4222 0,
4223 NULL);
4224 }
4225
4226 rtvs[i] = rtv;
4227 d3d12CommandBuffer->colorTargetSubresources[i] = subresource;
4228
4229 D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, subresource->parent);
4230
4231 if (colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE || colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) {
4232 D3D12TextureContainer *resolveContainer = (D3D12TextureContainer *)colorTargetInfos[i].resolve_texture;
4233 D3D12TextureSubresource *resolveSubresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
4234 d3d12CommandBuffer,
4235 resolveContainer,
4236 colorTargetInfos[i].resolve_layer,
4237 colorTargetInfos[i].resolve_mip_level,
4238 colorTargetInfos[i].cycle_resolve_texture,
4239 D3D12_RESOURCE_STATE_RESOLVE_DEST);
4240
4241 d3d12CommandBuffer->colorResolveSubresources[i] = resolveSubresource;
4242 D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, resolveSubresource->parent);
4243 }
4244 }
4245
4246 D3D12_CPU_DESCRIPTOR_HANDLE dsv;
4247 if (depthStencilTargetInfo != NULL) {
4248 D3D12TextureContainer *container = (D3D12TextureContainer *)depthStencilTargetInfo->texture;
4249 D3D12TextureSubresource *subresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
4250 d3d12CommandBuffer,
4251 container,
4252 0,
4253 0,
4254 depthStencilTargetInfo->cycle,
4255 D3D12_RESOURCE_STATE_DEPTH_WRITE);
4256
4257 if (
4258 depthStencilTargetInfo->load_op == SDL_GPU_LOADOP_CLEAR ||
4259 depthStencilTargetInfo->stencil_load_op == SDL_GPU_LOADOP_CLEAR) {
4260 D3D12_CLEAR_FLAGS clearFlags = (D3D12_CLEAR_FLAGS)0;
4261 if (depthStencilTargetInfo->load_op == SDL_GPU_LOADOP_CLEAR) {
4262 clearFlags |= D3D12_CLEAR_FLAG_DEPTH;
4263 }
4264 if (depthStencilTargetInfo->stencil_load_op == SDL_GPU_LOADOP_CLEAR) {
4265 clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
4266 }
4267
4268 ID3D12GraphicsCommandList_ClearDepthStencilView(
4269 d3d12CommandBuffer->graphicsCommandList,
4270 subresource->dsvHandle.cpuHandle,
4271 clearFlags,
4272 depthStencilTargetInfo->clear_depth,
4273 depthStencilTargetInfo->clear_stencil,
4274 0,
4275 NULL);
4276 }
4277
4278 dsv = subresource->dsvHandle.cpuHandle;
4279 d3d12CommandBuffer->depthStencilTextureSubresource = subresource;
4280 D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, subresource->parent);
4281 }
4282
4283 ID3D12GraphicsCommandList_OMSetRenderTargets(
4284 d3d12CommandBuffer->graphicsCommandList,
4285 numColorTargets,
4286 rtvs,
4287 false,
4288 (depthStencilTargetInfo == NULL) ? NULL : &dsv);
4289
4290 // Set sensible default states
4291 SDL_GPUViewport defaultViewport;
4292 defaultViewport.x = 0;
4293 defaultViewport.y = 0;
4294 defaultViewport.w = (float)framebufferWidth;
4295 defaultViewport.h = (float)framebufferHeight;
4296 defaultViewport.min_depth = 0;
4297 defaultViewport.max_depth = 1;
4298
4299 D3D12_SetViewport(
4300 commandBuffer,
4301 &defaultViewport);
4302
4303 SDL_Rect defaultScissor;
4304 defaultScissor.x = 0;
4305 defaultScissor.y = 0;
4306 defaultScissor.w = (Sint32)framebufferWidth;
4307 defaultScissor.h = (Sint32)framebufferHeight;
4308
4309 D3D12_SetScissor(
4310 commandBuffer,
4311 &defaultScissor);
4312
4313 D3D12_SetStencilReference(
4314 commandBuffer,
4315 0);
4316
4317 SDL_FColor blendConstants;
4318 blendConstants.r = 1.0f;
4319 blendConstants.g = 1.0f;
4320 blendConstants.b = 1.0f;
4321 blendConstants.a = 1.0f;
4322
4323 D3D12_SetBlendConstants(
4324 commandBuffer,
4325 blendConstants);
4326}
4327
4328static void D3D12_INTERNAL_TrackUniformBuffer(
4329 D3D12CommandBuffer *commandBuffer,
4330 D3D12UniformBuffer *uniformBuffer)
4331{
4332 Uint32 i;
4333 for (i = 0; i < commandBuffer->usedUniformBufferCount; i += 1) {
4334 if (commandBuffer->usedUniformBuffers[i] == uniformBuffer) {
4335 return;
4336 }
4337 }
4338
4339 if (commandBuffer->usedUniformBufferCount == commandBuffer->usedUniformBufferCapacity) {
4340 commandBuffer->usedUniformBufferCapacity += 1;
4341 commandBuffer->usedUniformBuffers = (D3D12UniformBuffer **)SDL_realloc(
4342 commandBuffer->usedUniformBuffers,
4343 commandBuffer->usedUniformBufferCapacity * sizeof(D3D12UniformBuffer *));
4344 }
4345
4346 commandBuffer->usedUniformBuffers[commandBuffer->usedUniformBufferCount] = uniformBuffer;
4347 commandBuffer->usedUniformBufferCount += 1;
4348
4349 D3D12_INTERNAL_TrackBuffer(
4350 commandBuffer,
4351 uniformBuffer->buffer);
4352}
4353
4354static D3D12UniformBuffer *D3D12_INTERNAL_AcquireUniformBufferFromPool(
4355 D3D12CommandBuffer *commandBuffer)
4356{
4357 D3D12Renderer *renderer = commandBuffer->renderer;
4358 D3D12UniformBuffer *uniformBuffer;
4359
4360 SDL_LockMutex(renderer->acquireUniformBufferLock);
4361
4362 if (renderer->uniformBufferPoolCount > 0) {
4363 uniformBuffer = renderer->uniformBufferPool[renderer->uniformBufferPoolCount - 1];
4364 renderer->uniformBufferPoolCount -= 1;
4365 } else {
4366 uniformBuffer = (D3D12UniformBuffer *)SDL_calloc(1, sizeof(D3D12UniformBuffer));
4367 if (!uniformBuffer) {
4368 SDL_UnlockMutex(renderer->acquireUniformBufferLock);
4369 return NULL;
4370 }
4371
4372 uniformBuffer->buffer = D3D12_INTERNAL_CreateBuffer(
4373 renderer,
4374 0,
4375 UNIFORM_BUFFER_SIZE,
4376 D3D12_BUFFER_TYPE_UNIFORM,
4377 NULL);
4378 if (!uniformBuffer->buffer) {
4379 SDL_UnlockMutex(renderer->acquireUniformBufferLock);
4380 return NULL;
4381 }
4382 }
4383
4384 SDL_UnlockMutex(renderer->acquireUniformBufferLock);
4385
4386 uniformBuffer->currentBlockSize = 0;
4387 uniformBuffer->drawOffset = 0;
4388 uniformBuffer->writeOffset = 0;
4389
4390 HRESULT res = ID3D12Resource_Map(
4391 uniformBuffer->buffer->handle,
4392 0,
4393 NULL,
4394 (void **)&uniformBuffer->buffer->mapPointer);
4395 CHECK_D3D12_ERROR_AND_RETURN("Failed to map buffer pool!", NULL);
4396
4397 D3D12_INTERNAL_TrackUniformBuffer(commandBuffer, uniformBuffer);
4398
4399 return uniformBuffer;
4400}
4401
4402static void D3D12_INTERNAL_ReturnUniformBufferToPool(
4403 D3D12Renderer *renderer,
4404 D3D12UniformBuffer *uniformBuffer)
4405{
4406 if (renderer->uniformBufferPoolCount >= renderer->uniformBufferPoolCapacity) {
4407 renderer->uniformBufferPoolCapacity *= 2;
4408 renderer->uniformBufferPool = (D3D12UniformBuffer **)SDL_realloc(
4409 renderer->uniformBufferPool,
4410 renderer->uniformBufferPoolCapacity * sizeof(D3D12UniformBuffer *));
4411 }
4412
4413 renderer->uniformBufferPool[renderer->uniformBufferPoolCount] = uniformBuffer;
4414 renderer->uniformBufferPoolCount += 1;
4415}
4416
4417static void D3D12_INTERNAL_PushUniformData(
4418 D3D12CommandBuffer *commandBuffer,
4419 SDL_GPUShaderStage shaderStage,
4420 Uint32 slotIndex,
4421 const void *data,
4422 Uint32 length)
4423{
4424 D3D12UniformBuffer *uniformBuffer;
4425
4426 if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
4427 if (commandBuffer->vertexUniformBuffers[slotIndex] == NULL) {
4428 commandBuffer->vertexUniformBuffers[slotIndex] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
4429 commandBuffer);
4430 }
4431 uniformBuffer = commandBuffer->vertexUniformBuffers[slotIndex];
4432 } else if (shaderStage == SDL_GPU_SHADERSTAGE_FRAGMENT) {
4433 if (commandBuffer->fragmentUniformBuffers[slotIndex] == NULL) {
4434 commandBuffer->fragmentUniformBuffers[slotIndex] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
4435 commandBuffer);
4436 }
4437 uniformBuffer = commandBuffer->fragmentUniformBuffers[slotIndex];
4438 } else if (shaderStage == SDL_GPU_SHADERSTAGE_COMPUTE) {
4439 if (commandBuffer->computeUniformBuffers[slotIndex] == NULL) {
4440 commandBuffer->computeUniformBuffers[slotIndex] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
4441 commandBuffer);
4442 }
4443 uniformBuffer = commandBuffer->computeUniformBuffers[slotIndex];
4444 } else {
4445 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Unrecognized shader stage!");
4446 return;
4447 }
4448
4449 uniformBuffer->currentBlockSize =
4450 D3D12_INTERNAL_Align(
4451 length,
4452 256);
4453
4454 // If there is no more room, acquire a new uniform buffer
4455 if (uniformBuffer->writeOffset + uniformBuffer->currentBlockSize >= UNIFORM_BUFFER_SIZE) {
4456 ID3D12Resource_Unmap(
4457 uniformBuffer->buffer->handle,
4458 0,
4459 NULL);
4460 uniformBuffer->buffer->mapPointer = NULL;
4461
4462 uniformBuffer = D3D12_INTERNAL_AcquireUniformBufferFromPool(commandBuffer);
4463
4464 uniformBuffer->drawOffset = 0;
4465 uniformBuffer->writeOffset = 0;
4466
4467 if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
4468 commandBuffer->vertexUniformBuffers[slotIndex] = uniformBuffer;
4469 } else if (shaderStage == SDL_GPU_SHADERSTAGE_FRAGMENT) {
4470 commandBuffer->fragmentUniformBuffers[slotIndex] = uniformBuffer;
4471 } else if (shaderStage == SDL_GPU_SHADERSTAGE_COMPUTE) {
4472 commandBuffer->computeUniformBuffers[slotIndex] = uniformBuffer;
4473 } else {
4474 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Unrecognized shader stage!");
4475 }
4476 }
4477
4478 uniformBuffer->drawOffset = uniformBuffer->writeOffset;
4479
4480 SDL_memcpy(
4481 (Uint8 *)uniformBuffer->buffer->mapPointer + uniformBuffer->writeOffset,
4482 data,
4483 length);
4484
4485 uniformBuffer->writeOffset += uniformBuffer->currentBlockSize;
4486
4487 if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
4488 commandBuffer->needVertexUniformBufferBind[slotIndex] = true;
4489 } else if (shaderStage == SDL_GPU_SHADERSTAGE_FRAGMENT) {
4490 commandBuffer->needFragmentUniformBufferBind[slotIndex] = true;
4491 } else if (shaderStage == SDL_GPU_SHADERSTAGE_COMPUTE) {
4492 commandBuffer->needComputeUniformBufferBind[slotIndex] = true;
4493 } else {
4494 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Unrecognized shader stage!");
4495 }
4496}
4497
4498static void D3D12_BindGraphicsPipeline(
4499 SDL_GPUCommandBuffer *commandBuffer,
4500 SDL_GPUGraphicsPipeline *graphicsPipeline)
4501{
4502 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4503 D3D12GraphicsPipeline *pipeline = (D3D12GraphicsPipeline *)graphicsPipeline;
4504 Uint32 i;
4505
4506 d3d12CommandBuffer->currentGraphicsPipeline = pipeline;
4507
4508 // Set the pipeline state
4509 ID3D12GraphicsCommandList_SetPipelineState(d3d12CommandBuffer->graphicsCommandList, pipeline->pipelineState);
4510 ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d12CommandBuffer->graphicsCommandList, pipeline->rootSignature->handle);
4511 ID3D12GraphicsCommandList_IASetPrimitiveTopology(d3d12CommandBuffer->graphicsCommandList, SDLToD3D12_PrimitiveType[pipeline->primitiveType]);
4512
4513 // Mark that bindings are needed
4514 d3d12CommandBuffer->needVertexSamplerBind = true;
4515 d3d12CommandBuffer->needVertexStorageTextureBind = true;
4516 d3d12CommandBuffer->needVertexStorageBufferBind = true;
4517 d3d12CommandBuffer->needFragmentSamplerBind = true;
4518 d3d12CommandBuffer->needFragmentStorageTextureBind = true;
4519 d3d12CommandBuffer->needFragmentStorageBufferBind = true;
4520
4521 for (i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
4522 d3d12CommandBuffer->needVertexUniformBufferBind[i] = true;
4523 d3d12CommandBuffer->needFragmentUniformBufferBind[i] = true;
4524 }
4525
4526 for (i = 0; i < pipeline->vertexUniformBufferCount; i += 1) {
4527 if (d3d12CommandBuffer->vertexUniformBuffers[i] == NULL) {
4528 d3d12CommandBuffer->vertexUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
4529 d3d12CommandBuffer);
4530 }
4531 }
4532
4533 for (i = 0; i < pipeline->fragmentUniformBufferCount; i += 1) {
4534 if (d3d12CommandBuffer->fragmentUniformBuffers[i] == NULL) {
4535 d3d12CommandBuffer->fragmentUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
4536 d3d12CommandBuffer);
4537 }
4538 }
4539
4540 D3D12_INTERNAL_TrackGraphicsPipeline(d3d12CommandBuffer, pipeline);
4541}
4542
4543static void D3D12_BindVertexBuffers(
4544 SDL_GPUCommandBuffer *commandBuffer,
4545 Uint32 firstSlot,
4546 const SDL_GPUBufferBinding *bindings,
4547 Uint32 numBindings)
4548{
4549 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4550
4551 for (Uint32 i = 0; i < numBindings; i += 1) {
4552 D3D12Buffer *currentBuffer = ((D3D12BufferContainer *)bindings[i].buffer)->activeBuffer;
4553
4554 if (d3d12CommandBuffer->vertexBuffers[firstSlot + i] != currentBuffer || d3d12CommandBuffer->vertexBufferOffsets[firstSlot + i] != bindings[i].offset) {
4555 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, currentBuffer);
4556
4557 d3d12CommandBuffer->vertexBuffers[firstSlot + i] = currentBuffer;
4558 d3d12CommandBuffer->vertexBufferOffsets[firstSlot + i] = bindings[i].offset;
4559 d3d12CommandBuffer->needVertexBufferBind = true;
4560 }
4561 }
4562
4563 d3d12CommandBuffer->vertexBufferCount =
4564 SDL_max(d3d12CommandBuffer->vertexBufferCount, firstSlot + numBindings);
4565}
4566
4567static void D3D12_BindIndexBuffer(
4568 SDL_GPUCommandBuffer *commandBuffer,
4569 const SDL_GPUBufferBinding *binding,
4570 SDL_GPUIndexElementSize indexElementSize)
4571{
4572 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4573 D3D12Buffer *buffer = ((D3D12BufferContainer *)binding->buffer)->activeBuffer;
4574 D3D12_INDEX_BUFFER_VIEW view;
4575
4576 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, buffer);
4577
4578 view.BufferLocation = buffer->virtualAddress + binding->offset;
4579 view.SizeInBytes = buffer->container->size - binding->offset;
4580 view.Format =
4581 indexElementSize == SDL_GPU_INDEXELEMENTSIZE_16BIT ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
4582
4583 ID3D12GraphicsCommandList_IASetIndexBuffer(
4584 d3d12CommandBuffer->graphicsCommandList,
4585 &view);
4586}
4587
4588static void D3D12_BindVertexSamplers(
4589 SDL_GPUCommandBuffer *commandBuffer,
4590 Uint32 firstSlot,
4591 const SDL_GPUTextureSamplerBinding *textureSamplerBindings,
4592 Uint32 numBindings)
4593{
4594 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4595
4596 for (Uint32 i = 0; i < numBindings; i += 1) {
4597 D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture;
4598 D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler;
4599
4600 if (d3d12CommandBuffer->vertexSamplers[firstSlot + i] != sampler) {
4601 D3D12_INTERNAL_TrackSampler(
4602 d3d12CommandBuffer,
4603 sampler);
4604
4605 d3d12CommandBuffer->vertexSamplers[firstSlot + i] = sampler;
4606 d3d12CommandBuffer->needVertexSamplerBind = true;
4607 }
4608
4609 if (d3d12CommandBuffer->vertexSamplerTextures[firstSlot + i] != container->activeTexture) {
4610 D3D12_INTERNAL_TrackTexture(
4611 d3d12CommandBuffer,
4612 container->activeTexture);
4613
4614 d3d12CommandBuffer->vertexSamplerTextures[firstSlot + i] = container->activeTexture;
4615 d3d12CommandBuffer->needVertexSamplerBind = true;
4616 }
4617 }
4618}
4619
4620static void D3D12_BindVertexStorageTextures(
4621 SDL_GPUCommandBuffer *commandBuffer,
4622 Uint32 firstSlot,
4623 SDL_GPUTexture *const *storageTextures,
4624 Uint32 numBindings)
4625{
4626 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4627
4628 for (Uint32 i = 0; i < numBindings; i += 1) {
4629 D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i];
4630 D3D12Texture *texture = container->activeTexture;
4631
4632 if (d3d12CommandBuffer->vertexStorageTextures[firstSlot + i] != texture) {
4633 D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture);
4634
4635 d3d12CommandBuffer->vertexStorageTextures[firstSlot + i] = texture;
4636 d3d12CommandBuffer->needVertexStorageTextureBind = true;
4637 }
4638 }
4639}
4640
4641static void D3D12_BindVertexStorageBuffers(
4642 SDL_GPUCommandBuffer *commandBuffer,
4643 Uint32 firstSlot,
4644 SDL_GPUBuffer *const *storageBuffers,
4645 Uint32 numBindings)
4646{
4647 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4648
4649 for (Uint32 i = 0; i < numBindings; i += 1) {
4650 D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i];
4651 if (d3d12CommandBuffer->vertexStorageBuffers[firstSlot + i] != container->activeBuffer) {
4652 D3D12_INTERNAL_TrackBuffer(
4653 d3d12CommandBuffer,
4654 container->activeBuffer);
4655
4656 d3d12CommandBuffer->vertexStorageBuffers[firstSlot + i] = container->activeBuffer;
4657 d3d12CommandBuffer->needVertexStorageBufferBind = true;
4658 }
4659 }
4660}
4661
4662static void D3D12_BindFragmentSamplers(
4663 SDL_GPUCommandBuffer *commandBuffer,
4664 Uint32 firstSlot,
4665 const SDL_GPUTextureSamplerBinding *textureSamplerBindings,
4666 Uint32 numBindings)
4667{
4668 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4669
4670 for (Uint32 i = 0; i < numBindings; i += 1) {
4671 D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture;
4672 D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler;
4673
4674 if (d3d12CommandBuffer->fragmentSamplers[firstSlot + i] != sampler) {
4675 D3D12_INTERNAL_TrackSampler(
4676 d3d12CommandBuffer,
4677 sampler);
4678
4679 d3d12CommandBuffer->fragmentSamplers[firstSlot + i] = sampler;
4680 d3d12CommandBuffer->needFragmentSamplerBind = true;
4681 }
4682
4683 if (d3d12CommandBuffer->fragmentSamplerTextures[firstSlot + i] != container->activeTexture) {
4684 D3D12_INTERNAL_TrackTexture(
4685 d3d12CommandBuffer,
4686 container->activeTexture);
4687
4688 d3d12CommandBuffer->fragmentSamplerTextures[firstSlot + i] = container->activeTexture;
4689 d3d12CommandBuffer->needFragmentSamplerBind = true;
4690 }
4691 }
4692}
4693
4694static void D3D12_BindFragmentStorageTextures(
4695 SDL_GPUCommandBuffer *commandBuffer,
4696 Uint32 firstSlot,
4697 SDL_GPUTexture *const *storageTextures,
4698 Uint32 numBindings)
4699{
4700 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4701
4702 for (Uint32 i = 0; i < numBindings; i += 1) {
4703 D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i];
4704 D3D12Texture *texture = container->activeTexture;
4705
4706 if (d3d12CommandBuffer->fragmentStorageTextures[firstSlot + i] != texture) {
4707 D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture);
4708
4709 d3d12CommandBuffer->fragmentStorageTextures[firstSlot + i] = texture;
4710 d3d12CommandBuffer->needFragmentStorageTextureBind = true;
4711 }
4712 }
4713}
4714
4715static void D3D12_BindFragmentStorageBuffers(
4716 SDL_GPUCommandBuffer *commandBuffer,
4717 Uint32 firstSlot,
4718 SDL_GPUBuffer *const *storageBuffers,
4719 Uint32 numBindings)
4720{
4721 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4722
4723 for (Uint32 i = 0; i < numBindings; i += 1) {
4724 D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i];
4725
4726 if (d3d12CommandBuffer->fragmentStorageBuffers[firstSlot + i] != container->activeBuffer) {
4727 D3D12_INTERNAL_TrackBuffer(
4728 d3d12CommandBuffer,
4729 container->activeBuffer);
4730
4731 d3d12CommandBuffer->fragmentStorageBuffers[firstSlot + i] = container->activeBuffer;
4732 d3d12CommandBuffer->needFragmentStorageBufferBind = true;
4733 }
4734 }
4735}
4736
4737static void D3D12_PushVertexUniformData(
4738 SDL_GPUCommandBuffer *commandBuffer,
4739 Uint32 slotIndex,
4740 const void *data,
4741 Uint32 length)
4742{
4743 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4744
4745 D3D12_INTERNAL_PushUniformData(
4746 d3d12CommandBuffer,
4747 SDL_GPU_SHADERSTAGE_VERTEX,
4748 slotIndex,
4749 data,
4750 length);
4751}
4752
4753static void D3D12_PushFragmentUniformData(
4754 SDL_GPUCommandBuffer *commandBuffer,
4755 Uint32 slotIndex,
4756 const void *data,
4757 Uint32 length)
4758{
4759 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
4760
4761 D3D12_INTERNAL_PushUniformData(
4762 d3d12CommandBuffer,
4763 SDL_GPU_SHADERSTAGE_FRAGMENT,
4764 slotIndex,
4765 data,
4766 length);
4767}
4768
4769static void D3D12_INTERNAL_SetGPUDescriptorHeaps(D3D12CommandBuffer *commandBuffer)
4770{
4771 ID3D12DescriptorHeap *heaps[2];
4772 D3D12DescriptorHeap *viewHeap;
4773 D3D12DescriptorHeap *samplerHeap;
4774
4775 viewHeap = D3D12_INTERNAL_AcquireGPUDescriptorHeapFromPool(commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
4776 samplerHeap = D3D12_INTERNAL_AcquireGPUDescriptorHeapFromPool(commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
4777
4778 commandBuffer->gpuDescriptorHeaps[0] = viewHeap;
4779 commandBuffer->gpuDescriptorHeaps[1] = samplerHeap;
4780
4781 heaps[0] = viewHeap->handle;
4782 heaps[1] = samplerHeap->handle;
4783
4784 ID3D12GraphicsCommandList_SetDescriptorHeaps(
4785 commandBuffer->graphicsCommandList,
4786 2,
4787 heaps);
4788}
4789
4790static void D3D12_INTERNAL_WriteGPUDescriptors(
4791 D3D12CommandBuffer *commandBuffer,
4792 D3D12_DESCRIPTOR_HEAP_TYPE heapType,
4793 D3D12_CPU_DESCRIPTOR_HANDLE *resourceDescriptorHandles,
4794 Uint32 resourceHandleCount,
4795 D3D12_GPU_DESCRIPTOR_HANDLE *gpuBaseDescriptor)
4796{
4797 D3D12DescriptorHeap *heap;
4798 D3D12_CPU_DESCRIPTOR_HANDLE gpuHeapCpuHandle;
4799
4800 /* Descriptor overflow, acquire new heaps */
4801 if (commandBuffer->gpuDescriptorHeaps[heapType]->currentDescriptorIndex >= commandBuffer->gpuDescriptorHeaps[heapType]->maxDescriptors) {
4802 D3D12_INTERNAL_SetGPUDescriptorHeaps(commandBuffer);
4803 }
4804
4805 heap = commandBuffer->gpuDescriptorHeaps[heapType];
4806
4807 // FIXME: need to error on overflow
4808 gpuHeapCpuHandle.ptr = heap->descriptorHeapCPUStart.ptr + (heap->currentDescriptorIndex * heap->descriptorSize);
4809 gpuBaseDescriptor->ptr = heap->descriptorHeapGPUStart.ptr + (heap->currentDescriptorIndex * heap->descriptorSize);
4810
4811 for (Uint32 i = 0; i < resourceHandleCount; i += 1) {
4812 ID3D12Device_CopyDescriptorsSimple(
4813 commandBuffer->renderer->device,
4814 1,
4815 gpuHeapCpuHandle,
4816 resourceDescriptorHandles[i],
4817 heapType);
4818
4819 heap->currentDescriptorIndex += 1;
4820 gpuHeapCpuHandle.ptr += heap->descriptorSize;
4821 }
4822}
4823
4824static void D3D12_INTERNAL_BindGraphicsResources(
4825 D3D12CommandBuffer *commandBuffer)
4826{
4827 D3D12GraphicsPipeline *graphicsPipeline = commandBuffer->currentGraphicsPipeline;
4828
4829 /* Acquire GPU descriptor heaps if we haven't yet */
4830 if (commandBuffer->gpuDescriptorHeaps[0] == NULL) {
4831 D3D12_INTERNAL_SetGPUDescriptorHeaps(commandBuffer);
4832 }
4833
4834 D3D12_CPU_DESCRIPTOR_HANDLE cpuHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE];
4835 D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle;
4836 D3D12_VERTEX_BUFFER_VIEW vertexBufferViews[MAX_VERTEX_BUFFERS];
4837
4838 if (commandBuffer->needVertexBufferBind) {
4839 for (Uint32 i = 0; i < commandBuffer->vertexBufferCount; i += 1) {
4840 vertexBufferViews[i].BufferLocation = commandBuffer->vertexBuffers[i]->virtualAddress + commandBuffer->vertexBufferOffsets[i];
4841 vertexBufferViews[i].SizeInBytes = commandBuffer->vertexBuffers[i]->container->size - commandBuffer->vertexBufferOffsets[i];
4842 vertexBufferViews[i].StrideInBytes = graphicsPipeline->vertexStrides[i];
4843 }
4844
4845 ID3D12GraphicsCommandList_IASetVertexBuffers(
4846 commandBuffer->graphicsCommandList,
4847 0,
4848 commandBuffer->vertexBufferCount,
4849 vertexBufferViews);
4850 }
4851
4852 if (commandBuffer->needVertexSamplerBind) {
4853 if (graphicsPipeline->vertexSamplerCount > 0) {
4854 for (Uint32 i = 0; i < graphicsPipeline->vertexSamplerCount; i += 1) {
4855 cpuHandles[i] = commandBuffer->vertexSamplers[i]->handle.cpuHandle;
4856 }
4857
4858 D3D12_INTERNAL_WriteGPUDescriptors(
4859 commandBuffer,
4860 D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
4861 cpuHandles,
4862 graphicsPipeline->vertexSamplerCount,
4863 &gpuDescriptorHandle);
4864
4865 ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4866 commandBuffer->graphicsCommandList,
4867 graphicsPipeline->rootSignature->vertexSamplerRootIndex,
4868 gpuDescriptorHandle);
4869
4870 for (Uint32 i = 0; i < graphicsPipeline->vertexSamplerCount; i += 1) {
4871 cpuHandles[i] = commandBuffer->vertexSamplerTextures[i]->srvHandle.cpuHandle;
4872 }
4873
4874 D3D12_INTERNAL_WriteGPUDescriptors(
4875 commandBuffer,
4876 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4877 cpuHandles,
4878 graphicsPipeline->vertexSamplerCount,
4879 &gpuDescriptorHandle);
4880
4881 ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4882 commandBuffer->graphicsCommandList,
4883 graphicsPipeline->rootSignature->vertexSamplerTextureRootIndex,
4884 gpuDescriptorHandle);
4885 }
4886 commandBuffer->needVertexSamplerBind = false;
4887 }
4888
4889 if (commandBuffer->needVertexStorageTextureBind) {
4890 if (graphicsPipeline->vertexStorageTextureCount > 0) {
4891 for (Uint32 i = 0; i < graphicsPipeline->vertexStorageTextureCount; i += 1) {
4892 cpuHandles[i] = commandBuffer->vertexStorageTextures[i]->srvHandle.cpuHandle;
4893 }
4894
4895 D3D12_INTERNAL_WriteGPUDescriptors(
4896 commandBuffer,
4897 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4898 cpuHandles,
4899 graphicsPipeline->vertexStorageTextureCount,
4900 &gpuDescriptorHandle);
4901
4902 ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4903 commandBuffer->graphicsCommandList,
4904 graphicsPipeline->rootSignature->vertexStorageTextureRootIndex,
4905 gpuDescriptorHandle);
4906 }
4907 commandBuffer->needVertexStorageTextureBind = false;
4908 }
4909
4910 if (commandBuffer->needVertexStorageBufferBind) {
4911 if (graphicsPipeline->vertexStorageBufferCount > 0) {
4912 for (Uint32 i = 0; i < graphicsPipeline->vertexStorageBufferCount; i += 1) {
4913 cpuHandles[i] = commandBuffer->vertexStorageBuffers[i]->srvDescriptor.cpuHandle;
4914 }
4915
4916 D3D12_INTERNAL_WriteGPUDescriptors(
4917 commandBuffer,
4918 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4919 cpuHandles,
4920 graphicsPipeline->vertexStorageBufferCount,
4921 &gpuDescriptorHandle);
4922
4923 ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4924 commandBuffer->graphicsCommandList,
4925 graphicsPipeline->rootSignature->vertexStorageBufferRootIndex,
4926 gpuDescriptorHandle);
4927 }
4928 commandBuffer->needVertexStorageBufferBind = false;
4929 }
4930
4931 for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
4932 if (commandBuffer->needVertexUniformBufferBind[i]) {
4933 if (graphicsPipeline->vertexUniformBufferCount > i) {
4934 ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(
4935 commandBuffer->graphicsCommandList,
4936 graphicsPipeline->rootSignature->vertexUniformBufferRootIndex[i],
4937 commandBuffer->vertexUniformBuffers[i]->buffer->virtualAddress + commandBuffer->vertexUniformBuffers[i]->drawOffset);
4938 }
4939 commandBuffer->needVertexUniformBufferBind[i] = false;
4940 }
4941 }
4942
4943 if (commandBuffer->needFragmentSamplerBind) {
4944 if (graphicsPipeline->fragmentSamplerCount > 0) {
4945 for (Uint32 i = 0; i < graphicsPipeline->fragmentSamplerCount; i += 1) {
4946 cpuHandles[i] = commandBuffer->fragmentSamplers[i]->handle.cpuHandle;
4947 }
4948
4949 D3D12_INTERNAL_WriteGPUDescriptors(
4950 commandBuffer,
4951 D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
4952 cpuHandles,
4953 graphicsPipeline->fragmentSamplerCount,
4954 &gpuDescriptorHandle);
4955
4956 ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4957 commandBuffer->graphicsCommandList,
4958 graphicsPipeline->rootSignature->fragmentSamplerRootIndex,
4959 gpuDescriptorHandle);
4960
4961 for (Uint32 i = 0; i < graphicsPipeline->fragmentSamplerCount; i += 1) {
4962 cpuHandles[i] = commandBuffer->fragmentSamplerTextures[i]->srvHandle.cpuHandle;
4963 }
4964
4965 D3D12_INTERNAL_WriteGPUDescriptors(
4966 commandBuffer,
4967 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4968 cpuHandles,
4969 graphicsPipeline->fragmentSamplerCount,
4970 &gpuDescriptorHandle);
4971
4972 ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4973 commandBuffer->graphicsCommandList,
4974 graphicsPipeline->rootSignature->fragmentSamplerTextureRootIndex,
4975 gpuDescriptorHandle);
4976 }
4977 commandBuffer->needFragmentSamplerBind = false;
4978 }
4979
4980 if (commandBuffer->needFragmentStorageTextureBind) {
4981 if (graphicsPipeline->fragmentStorageTextureCount > 0) {
4982 for (Uint32 i = 0; i < graphicsPipeline->fragmentStorageTextureCount; i += 1) {
4983 cpuHandles[i] = commandBuffer->fragmentStorageTextures[i]->srvHandle.cpuHandle;
4984 }
4985
4986 D3D12_INTERNAL_WriteGPUDescriptors(
4987 commandBuffer,
4988 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
4989 cpuHandles,
4990 graphicsPipeline->fragmentStorageTextureCount,
4991 &gpuDescriptorHandle);
4992
4993 ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
4994 commandBuffer->graphicsCommandList,
4995 graphicsPipeline->rootSignature->fragmentStorageTextureRootIndex,
4996 gpuDescriptorHandle);
4997 }
4998 commandBuffer->needFragmentStorageTextureBind = false;
4999 }
5000
5001 if (commandBuffer->needFragmentStorageBufferBind) {
5002 if (graphicsPipeline->fragmentStorageBufferCount > 0) {
5003 for (Uint32 i = 0; i < graphicsPipeline->fragmentStorageBufferCount; i += 1) {
5004 cpuHandles[i] = commandBuffer->fragmentStorageBuffers[i]->srvDescriptor.cpuHandle;
5005 }
5006
5007 D3D12_INTERNAL_WriteGPUDescriptors(
5008 commandBuffer,
5009 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
5010 cpuHandles,
5011 graphicsPipeline->fragmentStorageBufferCount,
5012 &gpuDescriptorHandle);
5013
5014 ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
5015 commandBuffer->graphicsCommandList,
5016 graphicsPipeline->rootSignature->fragmentStorageBufferRootIndex,
5017 gpuDescriptorHandle);
5018 }
5019 commandBuffer->needFragmentStorageBufferBind = false;
5020 }
5021
5022 for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
5023 if (commandBuffer->needFragmentUniformBufferBind[i]) {
5024 if (graphicsPipeline->fragmentUniformBufferCount > i) {
5025 ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(
5026 commandBuffer->graphicsCommandList,
5027 graphicsPipeline->rootSignature->fragmentUniformBufferRootIndex[i],
5028 commandBuffer->fragmentUniformBuffers[i]->buffer->virtualAddress + commandBuffer->fragmentUniformBuffers[i]->drawOffset);
5029 }
5030 commandBuffer->needFragmentUniformBufferBind[i] = false;
5031 }
5032 }
5033}
5034
5035static void D3D12_DrawIndexedPrimitives(
5036 SDL_GPUCommandBuffer *commandBuffer,
5037 Uint32 numIndices,
5038 Uint32 numInstances,
5039 Uint32 firstIndex,
5040 Sint32 vertexOffset,
5041 Uint32 firstInstance)
5042{
5043 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5044 D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer);
5045
5046 ID3D12GraphicsCommandList_DrawIndexedInstanced(
5047 d3d12CommandBuffer->graphicsCommandList,
5048 numIndices,
5049 numInstances,
5050 firstIndex,
5051 vertexOffset,
5052 firstInstance);
5053}
5054
5055static void D3D12_DrawPrimitives(
5056 SDL_GPUCommandBuffer *commandBuffer,
5057 Uint32 numVertices,
5058 Uint32 numInstances,
5059 Uint32 firstVertex,
5060 Uint32 firstInstance)
5061{
5062 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5063 D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer);
5064
5065 ID3D12GraphicsCommandList_DrawInstanced(
5066 d3d12CommandBuffer->graphicsCommandList,
5067 numVertices,
5068 numInstances,
5069 firstVertex,
5070 firstInstance);
5071}
5072
5073static void D3D12_DrawPrimitivesIndirect(
5074 SDL_GPUCommandBuffer *commandBuffer,
5075 SDL_GPUBuffer *buffer,
5076 Uint32 offset,
5077 Uint32 drawCount)
5078{
5079 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5080 D3D12Buffer *d3d12Buffer = ((D3D12BufferContainer *)buffer)->activeBuffer;
5081
5082 D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer);
5083
5084 ID3D12GraphicsCommandList_ExecuteIndirect(
5085 d3d12CommandBuffer->graphicsCommandList,
5086 d3d12CommandBuffer->renderer->indirectDrawCommandSignature,
5087 drawCount,
5088 d3d12Buffer->handle,
5089 offset,
5090 NULL,
5091 0);
5092
5093 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, d3d12Buffer);
5094}
5095
5096static void D3D12_DrawIndexedPrimitivesIndirect(
5097 SDL_GPUCommandBuffer *commandBuffer,
5098 SDL_GPUBuffer *buffer,
5099 Uint32 offset,
5100 Uint32 drawCount)
5101{
5102 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5103 D3D12Buffer *d3d12Buffer = ((D3D12BufferContainer *)buffer)->activeBuffer;
5104
5105 D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer);
5106
5107 ID3D12GraphicsCommandList_ExecuteIndirect(
5108 d3d12CommandBuffer->graphicsCommandList,
5109 d3d12CommandBuffer->renderer->indirectIndexedDrawCommandSignature,
5110 drawCount,
5111 d3d12Buffer->handle,
5112 offset,
5113 NULL,
5114 0);
5115
5116 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, d3d12Buffer);
5117}
5118
5119static void D3D12_EndRenderPass(
5120 SDL_GPUCommandBuffer *commandBuffer)
5121{
5122 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5123 Uint32 i;
5124
5125 for (i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1) {
5126 if (d3d12CommandBuffer->colorTargetSubresources[i] != NULL) {
5127 if (d3d12CommandBuffer->colorResolveSubresources[i] != NULL) {
5128 // Resolving requires some extra barriers
5129 D3D12_INTERNAL_TextureSubresourceBarrier(
5130 d3d12CommandBuffer,
5131 D3D12_RESOURCE_STATE_RENDER_TARGET,
5132 D3D12_RESOURCE_STATE_RESOLVE_SOURCE,
5133 d3d12CommandBuffer->colorTargetSubresources[i]
5134 );
5135
5136 ID3D12GraphicsCommandList_ResolveSubresource(
5137 d3d12CommandBuffer->graphicsCommandList,
5138 d3d12CommandBuffer->colorResolveSubresources[i]->parent->resource,
5139 d3d12CommandBuffer->colorResolveSubresources[i]->index,
5140 d3d12CommandBuffer->colorTargetSubresources[i]->parent->resource,
5141 d3d12CommandBuffer->colorTargetSubresources[i]->index,
5142 SDLToD3D12_TextureFormat[d3d12CommandBuffer->colorTargetSubresources[i]->parent->container->header.info.format]);
5143
5144 D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5145 d3d12CommandBuffer,
5146 D3D12_RESOURCE_STATE_RESOLVE_SOURCE,
5147 d3d12CommandBuffer->colorTargetSubresources[i]);
5148
5149 D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5150 d3d12CommandBuffer,
5151 D3D12_RESOURCE_STATE_RESOLVE_DEST,
5152 d3d12CommandBuffer->colorResolveSubresources[i]);
5153 } else {
5154 D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5155 d3d12CommandBuffer,
5156 D3D12_RESOURCE_STATE_RENDER_TARGET,
5157 d3d12CommandBuffer->colorTargetSubresources[i]);
5158 }
5159 }
5160 }
5161
5162 if (d3d12CommandBuffer->depthStencilTextureSubresource != NULL) {
5163 D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5164 d3d12CommandBuffer,
5165 D3D12_RESOURCE_STATE_DEPTH_WRITE,
5166 d3d12CommandBuffer->depthStencilTextureSubresource);
5167
5168 d3d12CommandBuffer->depthStencilTextureSubresource = NULL;
5169 }
5170
5171 d3d12CommandBuffer->currentGraphicsPipeline = NULL;
5172
5173 ID3D12GraphicsCommandList_OMSetRenderTargets(
5174 d3d12CommandBuffer->graphicsCommandList,
5175 0,
5176 NULL,
5177 false,
5178 NULL);
5179
5180 // Reset bind state
5181 SDL_zeroa(d3d12CommandBuffer->colorTargetSubresources);
5182 SDL_zeroa(d3d12CommandBuffer->colorResolveSubresources);
5183 d3d12CommandBuffer->depthStencilTextureSubresource = NULL;
5184
5185 SDL_zeroa(d3d12CommandBuffer->vertexBuffers);
5186 SDL_zeroa(d3d12CommandBuffer->vertexBufferOffsets);
5187 d3d12CommandBuffer->vertexBufferCount = 0;
5188
5189 SDL_zeroa(d3d12CommandBuffer->vertexSamplerTextures);
5190 SDL_zeroa(d3d12CommandBuffer->vertexSamplers);
5191 SDL_zeroa(d3d12CommandBuffer->vertexStorageTextures);
5192 SDL_zeroa(d3d12CommandBuffer->vertexStorageBuffers);
5193
5194 SDL_zeroa(d3d12CommandBuffer->fragmentSamplerTextures);
5195 SDL_zeroa(d3d12CommandBuffer->fragmentSamplers);
5196 SDL_zeroa(d3d12CommandBuffer->fragmentStorageTextures);
5197 SDL_zeroa(d3d12CommandBuffer->fragmentStorageBuffers);
5198}
5199
5200// Compute Pass
5201
5202static void D3D12_BeginComputePass(
5203 SDL_GPUCommandBuffer *commandBuffer,
5204 const SDL_GPUStorageTextureReadWriteBinding *storageTextureBindings,
5205 Uint32 numStorageTextureBindings,
5206 const SDL_GPUStorageBufferReadWriteBinding *storageBufferBindings,
5207 Uint32 numStorageBufferBindings)
5208{
5209 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5210
5211 d3d12CommandBuffer->computeReadWriteStorageTextureSubresourceCount = numStorageTextureBindings;
5212 d3d12CommandBuffer->computeReadWriteStorageBufferCount = numStorageBufferBindings;
5213
5214 /* Read-write resources will be actually bound in BindComputePipeline
5215 * after the root signature is set.
5216 * We also have to scan to see which barriers we actually need because depth slices aren't separate subresources
5217 */
5218 if (numStorageTextureBindings > 0) {
5219 for (Uint32 i = 0; i < numStorageTextureBindings; i += 1) {
5220 D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextureBindings[i].texture;
5221
5222 D3D12TextureSubresource *subresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
5223 d3d12CommandBuffer,
5224 container,
5225 storageTextureBindings[i].layer,
5226 storageTextureBindings[i].mip_level,
5227 storageTextureBindings[i].cycle,
5228 D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
5229
5230 d3d12CommandBuffer->computeReadWriteStorageTextureSubresources[i] = subresource;
5231
5232 D3D12_INTERNAL_TrackTexture(
5233 d3d12CommandBuffer,
5234 subresource->parent);
5235 }
5236 }
5237
5238 if (numStorageBufferBindings > 0) {
5239 for (Uint32 i = 0; i < numStorageBufferBindings; i += 1) {
5240 D3D12BufferContainer *container = (D3D12BufferContainer *)storageBufferBindings[i].buffer;
5241
5242 D3D12Buffer *buffer = D3D12_INTERNAL_PrepareBufferForWrite(
5243 d3d12CommandBuffer,
5244 container,
5245 storageBufferBindings[i].cycle,
5246 D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
5247
5248 d3d12CommandBuffer->computeReadWriteStorageBuffers[i] = buffer;
5249
5250 D3D12_INTERNAL_TrackBuffer(
5251 d3d12CommandBuffer,
5252 buffer);
5253 }
5254 }
5255}
5256
5257static void D3D12_BindComputePipeline(
5258 SDL_GPUCommandBuffer *commandBuffer,
5259 SDL_GPUComputePipeline *computePipeline)
5260{
5261 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5262
5263 /* Acquire GPU descriptor heaps if we haven't yet */
5264 if (d3d12CommandBuffer->gpuDescriptorHeaps[0] == NULL) {
5265 D3D12_INTERNAL_SetGPUDescriptorHeaps(d3d12CommandBuffer);
5266 }
5267
5268 D3D12ComputePipeline *pipeline = (D3D12ComputePipeline *)computePipeline;
5269 D3D12_CPU_DESCRIPTOR_HANDLE cpuHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE];
5270 D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle;
5271
5272 ID3D12GraphicsCommandList_SetPipelineState(
5273 d3d12CommandBuffer->graphicsCommandList,
5274 pipeline->pipelineState);
5275
5276 ID3D12GraphicsCommandList_SetComputeRootSignature(
5277 d3d12CommandBuffer->graphicsCommandList,
5278 pipeline->rootSignature->handle);
5279
5280 d3d12CommandBuffer->currentComputePipeline = pipeline;
5281
5282 d3d12CommandBuffer->needComputeSamplerBind = true;
5283 d3d12CommandBuffer->needComputeReadOnlyStorageTextureBind = true;
5284 d3d12CommandBuffer->needComputeReadOnlyStorageBufferBind = true;
5285
5286 for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
5287 d3d12CommandBuffer->needComputeUniformBufferBind[i] = true;
5288 }
5289
5290 for (Uint32 i = 0; i < pipeline->numUniformBuffers; i += 1) {
5291 if (d3d12CommandBuffer->computeUniformBuffers[i] == NULL) {
5292 d3d12CommandBuffer->computeUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
5293 d3d12CommandBuffer);
5294 }
5295 }
5296
5297 D3D12_INTERNAL_TrackComputePipeline(d3d12CommandBuffer, pipeline);
5298
5299 // Bind write-only resources after setting root signature
5300 if (pipeline->numReadWriteStorageTextures > 0) {
5301 for (Uint32 i = 0; i < pipeline->numReadWriteStorageTextures; i += 1) {
5302 cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageTextureSubresources[i]->uavHandle.cpuHandle;
5303 }
5304
5305 D3D12_INTERNAL_WriteGPUDescriptors(
5306 d3d12CommandBuffer,
5307 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
5308 cpuHandles,
5309 d3d12CommandBuffer->computeReadWriteStorageTextureSubresourceCount,
5310 &gpuDescriptorHandle);
5311
5312 ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
5313 d3d12CommandBuffer->graphicsCommandList,
5314 d3d12CommandBuffer->currentComputePipeline->rootSignature->readWriteStorageTextureRootIndex,
5315 gpuDescriptorHandle);
5316 }
5317
5318 if (pipeline->numReadWriteStorageBuffers > 0) {
5319 for (Uint32 i = 0; i < pipeline->numReadWriteStorageBuffers; i += 1) {
5320 cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageBuffers[i]->uavDescriptor.cpuHandle;
5321 }
5322
5323 D3D12_INTERNAL_WriteGPUDescriptors(
5324 d3d12CommandBuffer,
5325 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
5326 cpuHandles,
5327 d3d12CommandBuffer->computeReadWriteStorageBufferCount,
5328 &gpuDescriptorHandle);
5329
5330 ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
5331 d3d12CommandBuffer->graphicsCommandList,
5332 d3d12CommandBuffer->currentComputePipeline->rootSignature->readWriteStorageBufferRootIndex,
5333 gpuDescriptorHandle);
5334 }
5335}
5336
5337static void D3D12_BindComputeSamplers(
5338 SDL_GPUCommandBuffer *commandBuffer,
5339 Uint32 firstSlot,
5340 const SDL_GPUTextureSamplerBinding *textureSamplerBindings,
5341 Uint32 numBindings)
5342{
5343 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5344
5345 for (Uint32 i = 0; i < numBindings; i += 1) {
5346 D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture;
5347 D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler;
5348
5349 if (d3d12CommandBuffer->computeSamplers[firstSlot + i] != sampler) {
5350 D3D12_INTERNAL_TrackSampler(
5351 d3d12CommandBuffer,
5352 (D3D12Sampler *)textureSamplerBindings[i].sampler);
5353
5354 d3d12CommandBuffer->computeSamplers[firstSlot + i] = (D3D12Sampler *)textureSamplerBindings[i].sampler;
5355 d3d12CommandBuffer->needComputeSamplerBind = true;
5356 }
5357
5358 if (d3d12CommandBuffer->computeSamplerTextures[firstSlot + i] != container->activeTexture) {
5359 D3D12_INTERNAL_TrackTexture(
5360 d3d12CommandBuffer,
5361 container->activeTexture);
5362
5363 d3d12CommandBuffer->computeSamplerTextures[firstSlot + i] = container->activeTexture;
5364 d3d12CommandBuffer->needComputeSamplerBind = true;
5365 }
5366 }
5367}
5368
5369static void D3D12_BindComputeStorageTextures(
5370 SDL_GPUCommandBuffer *commandBuffer,
5371 Uint32 firstSlot,
5372 SDL_GPUTexture *const *storageTextures,
5373 Uint32 numBindings)
5374{
5375 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5376
5377 for (Uint32 i = 0; i < numBindings; i += 1) {
5378 D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i];
5379
5380 if (d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] != container->activeTexture) {
5381 /* If a different texture was in this slot, transition it back to its default usage */
5382 if (d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] != NULL) {
5383 D3D12_INTERNAL_TextureTransitionToDefaultUsage(
5384 d3d12CommandBuffer,
5385 D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
5386 d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i]);
5387 }
5388
5389 /* Then transition the new texture and prepare it for binding */
5390 D3D12_INTERNAL_TextureTransitionFromDefaultUsage(
5391 d3d12CommandBuffer,
5392 D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
5393 container->activeTexture);
5394
5395 D3D12_INTERNAL_TrackTexture(
5396 d3d12CommandBuffer,
5397 container->activeTexture);
5398
5399 d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] = container->activeTexture;
5400 d3d12CommandBuffer->needComputeReadOnlyStorageTextureBind = true;
5401 }
5402 }
5403}
5404
5405static void D3D12_BindComputeStorageBuffers(
5406 SDL_GPUCommandBuffer *commandBuffer,
5407 Uint32 firstSlot,
5408 SDL_GPUBuffer *const *storageBuffers,
5409 Uint32 numBindings)
5410{
5411 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5412
5413 for (Uint32 i = 0; i < numBindings; i += 1) {
5414 D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i];
5415 D3D12Buffer *buffer = container->activeBuffer;
5416
5417 if (d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] != buffer) {
5418 /* If a different buffer was in this slot, transition it back to its default usage */
5419 if (d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] != NULL) {
5420 D3D12_INTERNAL_BufferTransitionToDefaultUsage(
5421 d3d12CommandBuffer,
5422 D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
5423 d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i]);
5424 }
5425
5426 /* Then transition the new buffer and prepare it for binding */
5427 D3D12_INTERNAL_BufferTransitionFromDefaultUsage(
5428 d3d12CommandBuffer,
5429 D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
5430 buffer);
5431
5432 D3D12_INTERNAL_TrackBuffer(
5433 d3d12CommandBuffer,
5434 buffer);
5435
5436 d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] = buffer;
5437 d3d12CommandBuffer->needComputeReadOnlyStorageBufferBind = true;
5438 }
5439 }
5440}
5441
5442static void D3D12_PushComputeUniformData(
5443 SDL_GPUCommandBuffer *commandBuffer,
5444 Uint32 slotIndex,
5445 const void *data,
5446 Uint32 length)
5447{
5448 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5449
5450 D3D12_INTERNAL_PushUniformData(
5451 d3d12CommandBuffer,
5452 SDL_GPU_SHADERSTAGE_COMPUTE,
5453 slotIndex,
5454 data,
5455 length);
5456}
5457
5458static void D3D12_INTERNAL_BindComputeResources(
5459 D3D12CommandBuffer *commandBuffer)
5460{
5461 D3D12ComputePipeline *computePipeline = commandBuffer->currentComputePipeline;
5462
5463 /* Acquire GPU descriptor heaps if we haven't yet */
5464 if (commandBuffer->gpuDescriptorHeaps[0] == NULL) {
5465 D3D12_INTERNAL_SetGPUDescriptorHeaps(commandBuffer);
5466 }
5467
5468 D3D12_CPU_DESCRIPTOR_HANDLE cpuHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE];
5469 D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle;
5470
5471 if (commandBuffer->needComputeSamplerBind) {
5472 if (computePipeline->numSamplers > 0) {
5473 for (Uint32 i = 0; i < computePipeline->numSamplers; i += 1) {
5474 cpuHandles[i] = commandBuffer->computeSamplers[i]->handle.cpuHandle;
5475 }
5476
5477 D3D12_INTERNAL_WriteGPUDescriptors(
5478 commandBuffer,
5479 D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
5480 cpuHandles,
5481 computePipeline->numSamplers,
5482 &gpuDescriptorHandle);
5483
5484 ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
5485 commandBuffer->graphicsCommandList,
5486 computePipeline->rootSignature->samplerRootIndex,
5487 gpuDescriptorHandle);
5488
5489 for (Uint32 i = 0; i < computePipeline->numSamplers; i += 1) {
5490 cpuHandles[i] = commandBuffer->computeSamplerTextures[i]->srvHandle.cpuHandle;
5491 }
5492
5493 D3D12_INTERNAL_WriteGPUDescriptors(
5494 commandBuffer,
5495 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
5496 cpuHandles,
5497 computePipeline->numSamplers,
5498 &gpuDescriptorHandle);
5499
5500 ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
5501 commandBuffer->graphicsCommandList,
5502 computePipeline->rootSignature->samplerTextureRootIndex,
5503 gpuDescriptorHandle);
5504 }
5505 commandBuffer->needComputeSamplerBind = false;
5506 }
5507
5508 if (commandBuffer->needComputeReadOnlyStorageTextureBind) {
5509 if (computePipeline->numReadOnlyStorageTextures > 0) {
5510 for (Uint32 i = 0; i < computePipeline->numReadOnlyStorageTextures; i += 1) {
5511 cpuHandles[i] = commandBuffer->computeReadOnlyStorageTextures[i]->srvHandle.cpuHandle;
5512 }
5513
5514 D3D12_INTERNAL_WriteGPUDescriptors(
5515 commandBuffer,
5516 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
5517 cpuHandles,
5518 computePipeline->numReadOnlyStorageTextures,
5519 &gpuDescriptorHandle);
5520
5521 ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
5522 commandBuffer->graphicsCommandList,
5523 computePipeline->rootSignature->readOnlyStorageTextureRootIndex,
5524 gpuDescriptorHandle);
5525 }
5526 commandBuffer->needComputeReadOnlyStorageTextureBind = false;
5527 }
5528
5529 if (commandBuffer->needComputeReadOnlyStorageBufferBind) {
5530 if (computePipeline->numReadOnlyStorageBuffers > 0) {
5531 for (Uint32 i = 0; i < computePipeline->numReadOnlyStorageBuffers; i += 1) {
5532 cpuHandles[i] = commandBuffer->computeReadOnlyStorageBuffers[i]->srvDescriptor.cpuHandle;
5533 }
5534
5535 D3D12_INTERNAL_WriteGPUDescriptors(
5536 commandBuffer,
5537 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
5538 cpuHandles,
5539 computePipeline->numReadOnlyStorageBuffers,
5540 &gpuDescriptorHandle);
5541
5542 ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
5543 commandBuffer->graphicsCommandList,
5544 computePipeline->rootSignature->readOnlyStorageBufferRootIndex,
5545 gpuDescriptorHandle);
5546 }
5547 commandBuffer->needComputeReadOnlyStorageBufferBind = false;
5548 }
5549
5550 for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
5551 if (commandBuffer->needComputeUniformBufferBind[i]) {
5552 if (computePipeline->numUniformBuffers > i) {
5553 ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(
5554 commandBuffer->graphicsCommandList,
5555 computePipeline->rootSignature->uniformBufferRootIndex[i],
5556 commandBuffer->computeUniformBuffers[i]->buffer->virtualAddress + commandBuffer->computeUniformBuffers[i]->drawOffset);
5557 }
5558 }
5559 commandBuffer->needComputeUniformBufferBind[i] = false;
5560 }
5561}
5562
5563static void D3D12_DispatchCompute(
5564 SDL_GPUCommandBuffer *commandBuffer,
5565 Uint32 groupcountX,
5566 Uint32 groupcountY,
5567 Uint32 groupcountZ)
5568{
5569 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5570
5571 D3D12_INTERNAL_BindComputeResources(d3d12CommandBuffer);
5572 ID3D12GraphicsCommandList_Dispatch(
5573 d3d12CommandBuffer->graphicsCommandList,
5574 groupcountX,
5575 groupcountY,
5576 groupcountZ);
5577}
5578
5579static void D3D12_DispatchComputeIndirect(
5580 SDL_GPUCommandBuffer *commandBuffer,
5581 SDL_GPUBuffer *buffer,
5582 Uint32 offset)
5583{
5584 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5585 D3D12Buffer *d3d12Buffer = ((D3D12BufferContainer *)buffer)->activeBuffer;
5586
5587 D3D12_INTERNAL_BindComputeResources(d3d12CommandBuffer);
5588 ID3D12GraphicsCommandList_ExecuteIndirect(
5589 d3d12CommandBuffer->graphicsCommandList,
5590 d3d12CommandBuffer->renderer->indirectDispatchCommandSignature,
5591 1,
5592 d3d12Buffer->handle,
5593 offset,
5594 NULL,
5595 0);
5596
5597 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, d3d12Buffer);
5598}
5599
5600static void D3D12_EndComputePass(
5601 SDL_GPUCommandBuffer *commandBuffer)
5602{
5603 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5604
5605 for (Uint32 i = 0; i < d3d12CommandBuffer->computeReadWriteStorageTextureSubresourceCount; i += 1) {
5606 if (d3d12CommandBuffer->computeReadWriteStorageTextureSubresources[i]) {
5607 D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5608 d3d12CommandBuffer,
5609 D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
5610 d3d12CommandBuffer->computeReadWriteStorageTextureSubresources[i]);
5611
5612 d3d12CommandBuffer->computeReadWriteStorageTextureSubresources[i] = NULL;
5613 }
5614 }
5615 d3d12CommandBuffer->computeReadWriteStorageTextureSubresourceCount = 0;
5616
5617 for (Uint32 i = 0; i < d3d12CommandBuffer->computeReadWriteStorageBufferCount; i += 1) {
5618 if (d3d12CommandBuffer->computeReadWriteStorageBuffers[i]) {
5619 D3D12_INTERNAL_BufferTransitionToDefaultUsage(
5620 d3d12CommandBuffer,
5621 D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
5622 d3d12CommandBuffer->computeReadWriteStorageBuffers[i]);
5623
5624 d3d12CommandBuffer->computeReadWriteStorageBuffers[i] = NULL;
5625 }
5626 }
5627 d3d12CommandBuffer->computeReadWriteStorageBufferCount = 0;
5628
5629 for (Uint32 i = 0; i < MAX_STORAGE_TEXTURES_PER_STAGE; i += 1) {
5630 if (d3d12CommandBuffer->computeReadOnlyStorageTextures[i]) {
5631 D3D12_INTERNAL_TextureTransitionToDefaultUsage(
5632 d3d12CommandBuffer,
5633 D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
5634 d3d12CommandBuffer->computeReadOnlyStorageTextures[i]);
5635
5636 d3d12CommandBuffer->computeReadOnlyStorageTextures[i] = NULL;
5637 }
5638 }
5639
5640 for (Uint32 i = 0; i < MAX_STORAGE_BUFFERS_PER_STAGE; i += 1) {
5641 if (d3d12CommandBuffer->computeReadOnlyStorageBuffers[i]) {
5642 D3D12_INTERNAL_BufferTransitionToDefaultUsage(
5643 d3d12CommandBuffer,
5644 D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
5645 d3d12CommandBuffer->computeReadOnlyStorageBuffers[i]);
5646
5647 d3d12CommandBuffer->computeReadOnlyStorageBuffers[i] = NULL;
5648 }
5649 }
5650
5651 SDL_zeroa(d3d12CommandBuffer->computeSamplerTextures);
5652 SDL_zeroa(d3d12CommandBuffer->computeSamplers);
5653
5654 d3d12CommandBuffer->currentComputePipeline = NULL;
5655}
5656
5657// TransferBuffer Data
5658
5659static void *D3D12_MapTransferBuffer(
5660 SDL_GPURenderer *driverData,
5661 SDL_GPUTransferBuffer *transferBuffer,
5662 bool cycle)
5663{
5664 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
5665 D3D12BufferContainer *container = (D3D12BufferContainer *)transferBuffer;
5666 void *dataPointer;
5667
5668 if (
5669 cycle &&
5670 SDL_GetAtomicInt(&container->activeBuffer->referenceCount) > 0) {
5671 D3D12_INTERNAL_CycleActiveBuffer(
5672 renderer,
5673 container);
5674 }
5675
5676 // Upload buffers are persistently mapped, download buffers are not
5677 if (container->type == D3D12_BUFFER_TYPE_UPLOAD) {
5678 dataPointer = container->activeBuffer->mapPointer;
5679 } else {
5680 ID3D12Resource_Map(
5681 container->activeBuffer->handle,
5682 0,
5683 NULL,
5684 (void **)&dataPointer);
5685 }
5686
5687 return dataPointer;
5688}
5689
5690static void D3D12_UnmapTransferBuffer(
5691 SDL_GPURenderer *driverData,
5692 SDL_GPUTransferBuffer *transferBuffer)
5693{
5694 (void)driverData;
5695 D3D12BufferContainer *container = (D3D12BufferContainer *)transferBuffer;
5696
5697 // Upload buffers are persistently mapped, download buffers are not
5698 if (container->type == D3D12_BUFFER_TYPE_DOWNLOAD) {
5699 ID3D12Resource_Unmap(
5700 container->activeBuffer->handle,
5701 0,
5702 NULL);
5703 }
5704}
5705
5706// Copy Pass
5707
5708static void D3D12_BeginCopyPass(
5709 SDL_GPUCommandBuffer *commandBuffer)
5710{
5711 // no-op
5712 (void)commandBuffer;
5713}
5714
5715static void D3D12_UploadToTexture(
5716 SDL_GPUCommandBuffer *commandBuffer,
5717 const SDL_GPUTextureTransferInfo *source,
5718 const SDL_GPUTextureRegion *destination,
5719 bool cycle)
5720{
5721 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5722 D3D12BufferContainer *transferBufferContainer = (D3D12BufferContainer *)source->transfer_buffer;
5723 D3D12Buffer *temporaryBuffer = NULL;
5724 D3D12_TEXTURE_COPY_LOCATION sourceLocation;
5725 D3D12_TEXTURE_COPY_LOCATION destinationLocation;
5726 Uint32 pixelsPerRow = source->pixels_per_row;
5727 Uint32 rowPitch;
5728 Uint32 alignedRowPitch;
5729 Uint32 rowsPerSlice = source->rows_per_layer;
5730 Uint32 bytesPerSlice;
5731 bool needsRealignment;
5732 bool needsPlacementCopy;
5733
5734 // Note that the transfer buffer does not need a barrier, as it is synced by the client.
5735
5736 D3D12TextureContainer *textureContainer = (D3D12TextureContainer *)destination->texture;
5737 D3D12TextureSubresource *textureSubresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
5738 d3d12CommandBuffer,
5739 textureContainer,
5740 destination->layer,
5741 destination->mip_level,
5742 cycle,
5743 D3D12_RESOURCE_STATE_COPY_DEST);
5744
5745 /* D3D12 requires texture data row pitch to be 256 byte aligned, which is obviously insane.
5746 * Instead of exposing that restriction to the client, which is a huge rake to step on,
5747 * and a restriction that no other backend requires, we're going to copy data to a temporary buffer,
5748 * copy THAT data to the texture, and then get rid of the temporary buffer ASAP.
5749 * If we're lucky and the row pitch and depth pitch are already aligned, we can skip all of that.
5750 *
5751 * D3D12 also requires offsets to be 512 byte aligned. We'll fix that for the client and warn them as well.
5752 *
5753 * And just for some extra fun, D3D12 doesn't actually support depth pitch, so we have to realign that too!
5754 */
5755
5756 if (pixelsPerRow == 0) {
5757 pixelsPerRow = destination->w;
5758 }
5759
5760 rowPitch = BytesPerRow(pixelsPerRow, textureContainer->header.info.format);
5761
5762 if (rowsPerSlice == 0) {
5763 rowsPerSlice = destination->h;
5764 }
5765
5766 bytesPerSlice = rowsPerSlice * rowPitch;
5767
5768 alignedRowPitch = D3D12_INTERNAL_Align(rowPitch, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
5769 needsRealignment = rowsPerSlice != destination->h || rowPitch != alignedRowPitch;
5770 needsPlacementCopy = source->offset % D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT != 0;
5771
5772 sourceLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
5773 sourceLocation.PlacedFootprint.Footprint.Format = SDLToD3D12_TextureFormat[textureContainer->header.info.format];
5774 sourceLocation.PlacedFootprint.Footprint.RowPitch = alignedRowPitch;
5775
5776 destinationLocation.pResource = textureContainer->activeTexture->resource;
5777 destinationLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
5778 destinationLocation.SubresourceIndex = textureSubresource->index;
5779
5780 if (needsRealignment) {
5781 temporaryBuffer = D3D12_INTERNAL_CreateBuffer(
5782 d3d12CommandBuffer->renderer,
5783 0,
5784 alignedRowPitch * destination->h * destination->d,
5785 D3D12_BUFFER_TYPE_UPLOAD,
5786 NULL);
5787
5788 if (!temporaryBuffer) {
5789 return;
5790 }
5791
5792 sourceLocation.pResource = temporaryBuffer->handle;
5793
5794 for (Uint32 sliceIndex = 0; sliceIndex < destination->d; sliceIndex += 1) {
5795 // copy row count minus one to avoid overread
5796 for (Uint32 rowIndex = 0; rowIndex < rowsPerSlice - 1; rowIndex += 1) {
5797 SDL_memcpy(
5798 temporaryBuffer->mapPointer + (sliceIndex * rowsPerSlice) + (rowIndex * alignedRowPitch),
5799 transferBufferContainer->activeBuffer->mapPointer + source->offset + (sliceIndex * bytesPerSlice) + (rowIndex * rowPitch),
5800 alignedRowPitch);
5801 }
5802 Uint32 offset = source->offset + (sliceIndex * bytesPerSlice) + ((rowsPerSlice - 1) * rowPitch);
5803 SDL_memcpy(
5804 temporaryBuffer->mapPointer + (sliceIndex * rowsPerSlice) + ((rowsPerSlice - 1) * alignedRowPitch),
5805 transferBufferContainer->activeBuffer->mapPointer + offset,
5806 SDL_min(alignedRowPitch, transferBufferContainer->size - offset));
5807
5808 sourceLocation.PlacedFootprint.Footprint.Width = destination->w;
5809 sourceLocation.PlacedFootprint.Footprint.Height = rowsPerSlice;
5810 sourceLocation.PlacedFootprint.Footprint.Depth = 1;
5811 sourceLocation.PlacedFootprint.Offset = (sliceIndex * bytesPerSlice);
5812
5813 ID3D12GraphicsCommandList_CopyTextureRegion(
5814 d3d12CommandBuffer->graphicsCommandList,
5815 &destinationLocation,
5816 destination->x,
5817 destination->y,
5818 sliceIndex,
5819 &sourceLocation,
5820 NULL);
5821 }
5822
5823 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, temporaryBuffer);
5824 D3D12_INTERNAL_ReleaseBuffer(
5825 d3d12CommandBuffer->renderer,
5826 temporaryBuffer);
5827 } else if (needsPlacementCopy) {
5828 temporaryBuffer = D3D12_INTERNAL_CreateBuffer(
5829 d3d12CommandBuffer->renderer,
5830 0,
5831 alignedRowPitch * destination->h * destination->d,
5832 D3D12_BUFFER_TYPE_UPLOAD,
5833 NULL);
5834
5835 if (!temporaryBuffer) {
5836 return;
5837 }
5838
5839 SDL_memcpy(
5840 temporaryBuffer->mapPointer,
5841 transferBufferContainer->activeBuffer->mapPointer + source->offset,
5842 alignedRowPitch * destination->h * destination->d);
5843
5844 sourceLocation.pResource = temporaryBuffer->handle;
5845 sourceLocation.PlacedFootprint.Offset = 0;
5846 sourceLocation.PlacedFootprint.Footprint.Width = destination->w;
5847 sourceLocation.PlacedFootprint.Footprint.Height = destination->h;
5848 sourceLocation.PlacedFootprint.Footprint.Depth = 1;
5849
5850 ID3D12GraphicsCommandList_CopyTextureRegion(
5851 d3d12CommandBuffer->graphicsCommandList,
5852 &destinationLocation,
5853 destination->x,
5854 destination->y,
5855 destination->z,
5856 &sourceLocation,
5857 NULL);
5858
5859 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, temporaryBuffer);
5860 D3D12_INTERNAL_ReleaseBuffer(
5861 d3d12CommandBuffer->renderer,
5862 temporaryBuffer);
5863
5864 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Texture upload offset not aligned to 512 bytes! This is suboptimal on D3D12!");
5865 } else {
5866 sourceLocation.pResource = transferBufferContainer->activeBuffer->handle;
5867 sourceLocation.PlacedFootprint.Offset = source->offset;
5868 sourceLocation.PlacedFootprint.Footprint.Width = destination->w;
5869 sourceLocation.PlacedFootprint.Footprint.Height = destination->h;
5870 sourceLocation.PlacedFootprint.Footprint.Depth = destination->d;
5871
5872 ID3D12GraphicsCommandList_CopyTextureRegion(
5873 d3d12CommandBuffer->graphicsCommandList,
5874 &destinationLocation,
5875 destination->x,
5876 destination->y,
5877 destination->z,
5878 &sourceLocation,
5879 NULL);
5880 }
5881
5882 D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5883 d3d12CommandBuffer,
5884 D3D12_RESOURCE_STATE_COPY_DEST,
5885 textureSubresource);
5886
5887 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, transferBufferContainer->activeBuffer);
5888 D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, textureSubresource->parent);
5889}
5890
5891static void D3D12_UploadToBuffer(
5892 SDL_GPUCommandBuffer *commandBuffer,
5893 const SDL_GPUTransferBufferLocation *source,
5894 const SDL_GPUBufferRegion *destination,
5895 bool cycle)
5896{
5897 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5898 D3D12BufferContainer *transferBufferContainer = (D3D12BufferContainer *)source->transfer_buffer;
5899 D3D12BufferContainer *bufferContainer = (D3D12BufferContainer *)destination->buffer;
5900
5901 // The transfer buffer does not need a barrier, it is synced by the client.
5902
5903 D3D12Buffer *buffer = D3D12_INTERNAL_PrepareBufferForWrite(
5904 d3d12CommandBuffer,
5905 bufferContainer,
5906 cycle,
5907 D3D12_RESOURCE_STATE_COPY_DEST);
5908
5909 ID3D12GraphicsCommandList_CopyBufferRegion(
5910 d3d12CommandBuffer->graphicsCommandList,
5911 buffer->handle,
5912 destination->offset,
5913 transferBufferContainer->activeBuffer->handle,
5914 source->offset,
5915 destination->size);
5916
5917 D3D12_INTERNAL_BufferTransitionToDefaultUsage(
5918 d3d12CommandBuffer,
5919 D3D12_RESOURCE_STATE_COPY_DEST,
5920 buffer);
5921
5922 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, transferBufferContainer->activeBuffer);
5923 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, buffer);
5924}
5925
5926static void D3D12_CopyTextureToTexture(
5927 SDL_GPUCommandBuffer *commandBuffer,
5928 const SDL_GPUTextureLocation *source,
5929 const SDL_GPUTextureLocation *destination,
5930 Uint32 w,
5931 Uint32 h,
5932 Uint32 d,
5933 bool cycle)
5934{
5935 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
5936 D3D12_TEXTURE_COPY_LOCATION sourceLocation;
5937 D3D12_TEXTURE_COPY_LOCATION destinationLocation;
5938
5939 D3D12TextureSubresource *sourceSubresource = D3D12_INTERNAL_FetchTextureSubresource(
5940 (D3D12TextureContainer *)source->texture,
5941 source->layer,
5942 source->mip_level);
5943
5944 D3D12TextureSubresource *destinationSubresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
5945 d3d12CommandBuffer,
5946 (D3D12TextureContainer *)destination->texture,
5947 destination->layer,
5948 destination->mip_level,
5949 cycle,
5950 D3D12_RESOURCE_STATE_COPY_DEST);
5951
5952 D3D12_INTERNAL_TextureSubresourceTransitionFromDefaultUsage(
5953 d3d12CommandBuffer,
5954 D3D12_RESOURCE_STATE_COPY_SOURCE,
5955 sourceSubresource);
5956
5957 sourceLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
5958 sourceLocation.SubresourceIndex = sourceSubresource->index;
5959 sourceLocation.pResource = sourceSubresource->parent->resource;
5960
5961 destinationLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
5962 destinationLocation.SubresourceIndex = destinationSubresource->index;
5963 destinationLocation.pResource = destinationSubresource->parent->resource;
5964
5965 D3D12_BOX sourceBox = { source->x, source->y, source->z, source->x + w, source->y + h, source->z + d };
5966
5967 ID3D12GraphicsCommandList_CopyTextureRegion(
5968 d3d12CommandBuffer->graphicsCommandList,
5969 &destinationLocation,
5970 destination->x,
5971 destination->y,
5972 destination->z,
5973 &sourceLocation,
5974 &sourceBox);
5975
5976 D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5977 d3d12CommandBuffer,
5978 D3D12_RESOURCE_STATE_COPY_SOURCE,
5979 sourceSubresource);
5980
5981 D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
5982 d3d12CommandBuffer,
5983 D3D12_RESOURCE_STATE_COPY_DEST,
5984 destinationSubresource);
5985
5986 D3D12_INTERNAL_TrackTexture(
5987 d3d12CommandBuffer,
5988 sourceSubresource->parent);
5989
5990 D3D12_INTERNAL_TrackTexture(
5991 d3d12CommandBuffer,
5992 destinationSubresource->parent);
5993}
5994
5995static void D3D12_CopyBufferToBuffer(
5996 SDL_GPUCommandBuffer *commandBuffer,
5997 const SDL_GPUBufferLocation *source,
5998 const SDL_GPUBufferLocation *destination,
5999 Uint32 size,
6000 bool cycle)
6001{
6002 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
6003 D3D12BufferContainer *sourceContainer = (D3D12BufferContainer *)source->buffer;
6004 D3D12BufferContainer *destinationContainer = (D3D12BufferContainer *)destination->buffer;
6005
6006 D3D12Buffer *sourceBuffer = sourceContainer->activeBuffer;
6007 D3D12Buffer *destinationBuffer = D3D12_INTERNAL_PrepareBufferForWrite(
6008 d3d12CommandBuffer,
6009 destinationContainer,
6010 cycle,
6011 D3D12_RESOURCE_STATE_COPY_DEST);
6012
6013 D3D12_INTERNAL_BufferTransitionFromDefaultUsage(
6014 d3d12CommandBuffer,
6015 D3D12_RESOURCE_STATE_COPY_SOURCE,
6016 sourceBuffer);
6017
6018 ID3D12GraphicsCommandList_CopyBufferRegion(
6019 d3d12CommandBuffer->graphicsCommandList,
6020 destinationBuffer->handle,
6021 destination->offset,
6022 sourceBuffer->handle,
6023 source->offset,
6024 size);
6025
6026 D3D12_INTERNAL_BufferTransitionToDefaultUsage(
6027 d3d12CommandBuffer,
6028 D3D12_RESOURCE_STATE_COPY_SOURCE,
6029 sourceBuffer);
6030
6031 D3D12_INTERNAL_BufferTransitionToDefaultUsage(
6032 d3d12CommandBuffer,
6033 D3D12_RESOURCE_STATE_COPY_DEST,
6034 destinationBuffer);
6035
6036 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, sourceBuffer);
6037 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, destinationBuffer);
6038}
6039
6040static void D3D12_DownloadFromTexture(
6041 SDL_GPUCommandBuffer *commandBuffer,
6042 const SDL_GPUTextureRegion *source,
6043 const SDL_GPUTextureTransferInfo *destination)
6044{
6045 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
6046 D3D12_TEXTURE_COPY_LOCATION sourceLocation;
6047 D3D12_TEXTURE_COPY_LOCATION destinationLocation;
6048 Uint32 pixelsPerRow = destination->pixels_per_row;
6049 Uint32 rowPitch;
6050 Uint32 alignedRowPitch;
6051 Uint32 rowsPerSlice = destination->rows_per_layer;
6052 bool needsRealignment;
6053 bool needsPlacementCopy;
6054 D3D12TextureDownload *textureDownload = NULL;
6055 D3D12TextureContainer *sourceContainer = (D3D12TextureContainer *)source->texture;
6056 D3D12TextureSubresource *sourceSubresource = D3D12_INTERNAL_FetchTextureSubresource(
6057 sourceContainer,
6058 source->layer,
6059 source->mip_level);
6060 D3D12BufferContainer *destinationContainer = (D3D12BufferContainer *)destination->transfer_buffer;
6061 D3D12Buffer *destinationBuffer = destinationContainer->activeBuffer;
6062
6063 /* D3D12 requires texture data row pitch to be 256 byte aligned, which is obviously insane.
6064 * Instead of exposing that restriction to the client, which is a huge rake to step on,
6065 * and a restriction that no other backend requires, we're going to copy data to a temporary buffer,
6066 * copy THAT data to the texture, and then get rid of the temporary buffer ASAP.
6067 * If we're lucky and the row pitch and depth pitch are already aligned, we can skip all of that.
6068 *
6069 * D3D12 also requires offsets to be 512 byte aligned. We'll fix that for the client and warn them as well.
6070 *
6071 * And just for some extra fun, D3D12 doesn't actually support depth pitch, so we have to realign that too!
6072 *
6073 * Since this is an async download we have to do all these fixups after the command is finished,
6074 * so we'll cache the metadata and map and copy it when the command buffer is cleaned.
6075 */
6076
6077 if (pixelsPerRow == 0) {
6078 pixelsPerRow = source->w;
6079 }
6080
6081 rowPitch = BytesPerRow(pixelsPerRow, sourceContainer->header.info.format);
6082
6083 if (rowsPerSlice == 0) {
6084 rowsPerSlice = source->h;
6085 }
6086
6087 alignedRowPitch = D3D12_INTERNAL_Align(rowPitch, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
6088 needsRealignment = rowsPerSlice != source->h || rowPitch != alignedRowPitch;
6089 needsPlacementCopy = destination->offset % D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT != 0;
6090
6091 sourceLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
6092 sourceLocation.SubresourceIndex = sourceSubresource->index;
6093 sourceLocation.pResource = sourceSubresource->parent->resource;
6094
6095 D3D12_BOX sourceBox = { source->x, source->y, source->z, source->x + source->w, source->y + rowsPerSlice, source->z + source->d };
6096
6097 destinationLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
6098 destinationLocation.PlacedFootprint.Footprint.Format = SDLToD3D12_TextureFormat[sourceContainer->header.info.format];
6099 destinationLocation.PlacedFootprint.Footprint.Width = source->w;
6100 destinationLocation.PlacedFootprint.Footprint.Height = rowsPerSlice;
6101 destinationLocation.PlacedFootprint.Footprint.Depth = source->d;
6102 destinationLocation.PlacedFootprint.Footprint.RowPitch = alignedRowPitch;
6103
6104 if (needsRealignment || needsPlacementCopy) {
6105 textureDownload = (D3D12TextureDownload *)SDL_malloc(sizeof(D3D12TextureDownload));
6106
6107 if (!textureDownload) {
6108 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create texture download structure!");
6109 return;
6110 }
6111
6112 textureDownload->temporaryBuffer = D3D12_INTERNAL_CreateBuffer(
6113 d3d12CommandBuffer->renderer,
6114 0,
6115 alignedRowPitch * rowsPerSlice * source->d,
6116 D3D12_BUFFER_TYPE_DOWNLOAD,
6117 NULL);
6118
6119 if (!textureDownload->temporaryBuffer) {
6120 SDL_free(textureDownload);
6121 return;
6122 }
6123
6124 textureDownload->destinationBuffer = destinationBuffer;
6125 textureDownload->bufferOffset = destination->offset;
6126 textureDownload->width = source->w;
6127 textureDownload->height = rowsPerSlice;
6128 textureDownload->depth = source->d;
6129 textureDownload->bytesPerRow = rowPitch;
6130 textureDownload->bytesPerDepthSlice = rowPitch * rowsPerSlice;
6131 textureDownload->alignedBytesPerRow = alignedRowPitch;
6132
6133 destinationLocation.pResource = textureDownload->temporaryBuffer->handle;
6134 destinationLocation.PlacedFootprint.Offset = 0;
6135 } else {
6136 destinationLocation.pResource = destinationBuffer->handle;
6137 destinationLocation.PlacedFootprint.Offset = destination->offset;
6138 }
6139
6140 D3D12_INTERNAL_TextureSubresourceTransitionFromDefaultUsage(
6141 d3d12CommandBuffer,
6142 D3D12_RESOURCE_STATE_COPY_SOURCE,
6143 sourceSubresource);
6144
6145 ID3D12GraphicsCommandList_CopyTextureRegion(
6146 d3d12CommandBuffer->graphicsCommandList,
6147 &destinationLocation,
6148 0,
6149 0,
6150 0,
6151 &sourceLocation,
6152 &sourceBox);
6153
6154 D3D12_INTERNAL_TextureSubresourceTransitionToDefaultUsage(
6155 d3d12CommandBuffer,
6156 D3D12_RESOURCE_STATE_COPY_SOURCE,
6157 sourceSubresource);
6158
6159 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, destinationBuffer);
6160 D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, sourceSubresource->parent);
6161
6162 if (textureDownload != NULL) {
6163 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, textureDownload->temporaryBuffer);
6164
6165 if (d3d12CommandBuffer->textureDownloadCount >= d3d12CommandBuffer->textureDownloadCapacity) {
6166 d3d12CommandBuffer->textureDownloadCapacity *= 2;
6167 d3d12CommandBuffer->textureDownloads = (D3D12TextureDownload **)SDL_realloc(
6168 d3d12CommandBuffer->textureDownloads,
6169 d3d12CommandBuffer->textureDownloadCapacity * sizeof(D3D12TextureDownload *));
6170 }
6171
6172 d3d12CommandBuffer->textureDownloads[d3d12CommandBuffer->textureDownloadCount] = textureDownload;
6173 d3d12CommandBuffer->textureDownloadCount += 1;
6174
6175 D3D12_INTERNAL_ReleaseBuffer(d3d12CommandBuffer->renderer, textureDownload->temporaryBuffer);
6176 }
6177}
6178
6179static void D3D12_DownloadFromBuffer(
6180 SDL_GPUCommandBuffer *commandBuffer,
6181 const SDL_GPUBufferRegion *source,
6182 const SDL_GPUTransferBufferLocation *destination)
6183{
6184 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
6185 D3D12BufferContainer *sourceContainer = (D3D12BufferContainer *)source->buffer;
6186 D3D12BufferContainer *destinationContainer = (D3D12BufferContainer *)destination->transfer_buffer;
6187
6188 D3D12Buffer *sourceBuffer = sourceContainer->activeBuffer;
6189 D3D12_INTERNAL_BufferTransitionFromDefaultUsage(
6190 d3d12CommandBuffer,
6191 D3D12_RESOURCE_STATE_COPY_SOURCE,
6192 sourceBuffer);
6193
6194 D3D12Buffer *destinationBuffer = destinationContainer->activeBuffer;
6195
6196 ID3D12GraphicsCommandList_CopyBufferRegion(
6197 d3d12CommandBuffer->graphicsCommandList,
6198 destinationBuffer->handle,
6199 destination->offset,
6200 sourceBuffer->handle,
6201 source->offset,
6202 source->size);
6203
6204 D3D12_INTERNAL_BufferTransitionToDefaultUsage(
6205 d3d12CommandBuffer,
6206 D3D12_RESOURCE_STATE_COPY_SOURCE,
6207 sourceBuffer);
6208
6209 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, sourceBuffer);
6210 D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, destinationBuffer);
6211}
6212
6213static void D3D12_EndCopyPass(
6214 SDL_GPUCommandBuffer *commandBuffer)
6215{
6216 // no-op
6217 (void)commandBuffer;
6218}
6219
6220static void D3D12_GenerateMipmaps(
6221 SDL_GPUCommandBuffer *commandBuffer,
6222 SDL_GPUTexture *texture)
6223{
6224 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
6225 D3D12Renderer *renderer = d3d12CommandBuffer->renderer;
6226 D3D12TextureContainer *container = (D3D12TextureContainer *)texture;
6227 SDL_GPUGraphicsPipeline *blitPipeline;
6228
6229 blitPipeline = SDL_GPU_FetchBlitPipeline(
6230 renderer->sdlGPUDevice,
6231 container->header.info.type,
6232 container->header.info.format,
6233 renderer->blitVertexShader,
6234 renderer->blitFrom2DShader,
6235 renderer->blitFrom2DArrayShader,
6236 renderer->blitFrom3DShader,
6237 renderer->blitFromCubeShader,
6238 renderer->blitFromCubeArrayShader,
6239 &renderer->blitPipelines,
6240 &renderer->blitPipelineCount,
6241 &renderer->blitPipelineCapacity);
6242
6243 if (blitPipeline == NULL) {
6244 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not fetch blit pipeline");
6245 return;
6246 }
6247
6248 // We have to do this one subresource at a time
6249 for (Uint32 layerOrDepthIndex = 0; layerOrDepthIndex < container->header.info.layer_count_or_depth; layerOrDepthIndex += 1) {
6250 for (Uint32 levelIndex = 1; levelIndex < container->header.info.num_levels; levelIndex += 1) {
6251 SDL_GPUBlitInfo blitInfo;
6252 SDL_zero(blitInfo);
6253
6254 blitInfo.source.texture = texture;
6255 blitInfo.source.mip_level = levelIndex - 1;
6256 blitInfo.source.layer_or_depth_plane = layerOrDepthIndex;
6257 blitInfo.source.x = 0;
6258 blitInfo.source.y = 0;
6259 blitInfo.source.w = SDL_max(container->header.info.width >> (levelIndex - 1), 1);
6260 blitInfo.source.h = SDL_max(container->header.info.height >> (levelIndex - 1), 1);
6261
6262 blitInfo.destination.texture = texture;
6263 blitInfo.destination.mip_level = levelIndex;
6264 blitInfo.destination.layer_or_depth_plane = layerOrDepthIndex;
6265 blitInfo.destination.x = 0;
6266 blitInfo.destination.y = 0;
6267 blitInfo.destination.w = SDL_max(container->header.info.width >> levelIndex, 1);
6268 blitInfo.destination.h = SDL_max(container->header.info.height >> levelIndex, 1);
6269
6270 blitInfo.load_op = SDL_GPU_LOADOP_DONT_CARE;
6271 blitInfo.filter = SDL_GPU_FILTER_LINEAR;
6272
6273 SDL_BlitGPUTexture(
6274 commandBuffer,
6275 &blitInfo);
6276 }
6277 }
6278
6279 D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, container->activeTexture);
6280}
6281
6282static void D3D12_Blit(
6283 SDL_GPUCommandBuffer *commandBuffer,
6284 const SDL_GPUBlitInfo *info)
6285{
6286 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
6287 D3D12Renderer *renderer = (D3D12Renderer *)d3d12CommandBuffer->renderer;
6288
6289 SDL_GPU_BlitCommon(
6290 commandBuffer,
6291 info,
6292 renderer->blitLinearSampler,
6293 renderer->blitNearestSampler,
6294 renderer->blitVertexShader,
6295 renderer->blitFrom2DShader,
6296 renderer->blitFrom2DArrayShader,
6297 renderer->blitFrom3DShader,
6298 renderer->blitFromCubeShader,
6299 renderer->blitFromCubeArrayShader,
6300 &renderer->blitPipelines,
6301 &renderer->blitPipelineCount,
6302 &renderer->blitPipelineCapacity);
6303}
6304
6305// Submission/Presentation
6306
6307static D3D12WindowData *D3D12_INTERNAL_FetchWindowData(
6308 SDL_Window *window)
6309{
6310 SDL_PropertiesID properties = SDL_GetWindowProperties(window);
6311 return (D3D12WindowData *)SDL_GetPointerProperty(properties, WINDOW_PROPERTY_DATA, NULL);
6312}
6313
6314static bool D3D12_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e)
6315{
6316 SDL_Window *w = (SDL_Window *)userdata;
6317 D3D12WindowData *data;
6318 if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED && e->window.windowID == SDL_GetWindowID(w)) {
6319 data = D3D12_INTERNAL_FetchWindowData(w);
6320 data->needsSwapchainRecreate = true;
6321 }
6322
6323 return true;
6324}
6325
6326static bool D3D12_SupportsSwapchainComposition(
6327 SDL_GPURenderer *driverData,
6328 SDL_Window *window,
6329 SDL_GPUSwapchainComposition swapchainComposition)
6330{
6331#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
6332 // FIXME: HDR support would be nice to add, but it seems complicated...
6333 return swapchainComposition == SDL_GPU_SWAPCHAINCOMPOSITION_SDR ||
6334 swapchainComposition == SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR;
6335#else
6336 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
6337 DXGI_FORMAT format;
6338 D3D12_FEATURE_DATA_FORMAT_SUPPORT formatSupport;
6339 Uint32 colorSpaceSupport;
6340 HRESULT res;
6341
6342 format = SwapchainCompositionToTextureFormat[swapchainComposition];
6343
6344 formatSupport.Format = format;
6345 res = ID3D12Device_CheckFeatureSupport(
6346 renderer->device,
6347 D3D12_FEATURE_FORMAT_SUPPORT,
6348 &formatSupport,
6349 sizeof(formatSupport));
6350 if (FAILED(res)) {
6351 // Format is apparently unknown
6352 return false;
6353 }
6354
6355 if (!(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_DISPLAY)) {
6356 return false;
6357 }
6358
6359 D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
6360 if (windowData == NULL) {
6361 SET_STRING_ERROR_AND_RETURN("Must claim window before querying swapchain composition support!", false);
6362 }
6363
6364 // Check the color space support if necessary
6365 if (swapchainComposition != SDL_GPU_SWAPCHAINCOMPOSITION_SDR) {
6366 IDXGISwapChain3_CheckColorSpaceSupport(
6367 windowData->swapchain,
6368 SwapchainCompositionToColorSpace[swapchainComposition],
6369 &colorSpaceSupport);
6370
6371 if (!(colorSpaceSupport & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT)) {
6372 return false;
6373 }
6374 }
6375#endif
6376
6377 return true;
6378}
6379
6380static bool D3D12_SupportsPresentMode(
6381 SDL_GPURenderer *driverData,
6382 SDL_Window *window,
6383 SDL_GPUPresentMode presentMode)
6384{
6385 (void)driverData;
6386 (void)window;
6387
6388 switch (presentMode) {
6389 case SDL_GPU_PRESENTMODE_IMMEDIATE:
6390 case SDL_GPU_PRESENTMODE_VSYNC:
6391 return true;
6392 case SDL_GPU_PRESENTMODE_MAILBOX:
6393#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
6394 return false;
6395#else
6396 return true;
6397#endif
6398 default:
6399 SDL_assert(!"Unrecognized present mode");
6400 return false;
6401 }
6402}
6403
6404#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
6405static bool D3D12_INTERNAL_CreateSwapchain(
6406 D3D12Renderer *renderer,
6407 D3D12WindowData *windowData,
6408 SDL_GPUSwapchainComposition swapchain_composition,
6409 SDL_GPUPresentMode present_mode)
6410{
6411 int width, height;
6412 SDL_GPUTextureCreateInfo createInfo;
6413 D3D12Texture *texture;
6414
6415 // Get the swapchain size
6416 SDL_SyncWindow(windowData->window);
6417 SDL_GetWindowSizeInPixels(windowData->window, &width, &height);
6418
6419 // Min swapchain image count is 2
6420 windowData->swapchainTextureCount = SDL_clamp(renderer->allowedFramesInFlight, 2, 3);
6421
6422 // Create the swapchain textures
6423 SDL_zero(createInfo);
6424 createInfo.type = SDL_GPU_TEXTURETYPE_2D;
6425 createInfo.width = width;
6426 createInfo.height = height;
6427 createInfo.format = SwapchainCompositionToSDLTextureFormat[swapchain_composition];
6428 createInfo.usage = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
6429 createInfo.layer_count_or_depth = 1;
6430 createInfo.num_levels = 1;
6431
6432 for (Uint32 i = 0; i < windowData->swapchainTextureCount; i += 1) {
6433 texture = D3D12_INTERNAL_CreateTexture(renderer, &createInfo, true, "Swapchain");
6434 texture->container = &windowData->textureContainers[i];
6435 windowData->textureContainers[i].activeTexture = texture;
6436 windowData->textureContainers[i].canBeCycled = false;
6437 windowData->textureContainers[i].header.info = createInfo;
6438 windowData->textureContainers[i].textureCapacity = 1;
6439 windowData->textureContainers[i].textureCount = 1;
6440 windowData->textureContainers[i].textures = &windowData->textureContainers[i].activeTexture;
6441 }
6442
6443 // Initialize the swapchain data
6444 windowData->present_mode = present_mode;
6445 windowData->swapchainComposition = swapchain_composition;
6446 windowData->swapchainColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
6447 windowData->frameCounter = 0;
6448 windowData->width = width;
6449 windowData->height = height;
6450
6451 // Precache blit pipelines for the swapchain format
6452 for (Uint32 i = 0; i < 5; i += 1) {
6453 SDL_GPU_FetchBlitPipeline(
6454 renderer->sdlGPUDevice,
6455 (SDL_GPUTextureType)i,
6456 createInfo.format,
6457 renderer->blitVertexShader,
6458 renderer->blitFrom2DShader,
6459 renderer->blitFrom2DArrayShader,
6460 renderer->blitFrom3DShader,
6461 renderer->blitFromCubeShader,
6462 renderer->blitFromCubeArrayShader,
6463 &renderer->blitPipelines,
6464 &renderer->blitPipelineCount,
6465 &renderer->blitPipelineCapacity);
6466 }
6467
6468 return true;
6469}
6470
6471static void D3D12_INTERNAL_DestroySwapchain(
6472 D3D12Renderer *renderer,
6473 D3D12WindowData *windowData)
6474{
6475 renderer->commandQueue->PresentX(0, NULL, NULL);
6476 for (Uint32 i = 0; i < windowData->swapchainTextureCount; i += 1) {
6477 D3D12_INTERNAL_DestroyTexture(
6478 renderer,
6479 windowData->textureContainers[i].activeTexture);
6480 }
6481}
6482
6483static bool D3D12_INTERNAL_ResizeSwapchain(
6484 D3D12Renderer *renderer,
6485 D3D12WindowData *windowData)
6486{
6487 // Wait so we don't release in-flight views
6488 D3D12_Wait((SDL_GPURenderer *)renderer);
6489
6490 // Present a black screen
6491 renderer->commandQueue->PresentX(0, NULL, NULL);
6492
6493 // Clean up the previous swapchain textures
6494 for (Uint32 i = 0; i < windowData->swapchainTextureCount; i += 1) {
6495 D3D12_INTERNAL_DestroyTexture(
6496 renderer,
6497 windowData->textureContainers[i].activeTexture);
6498 }
6499
6500 // Create a new swapchain
6501 D3D12_INTERNAL_CreateSwapchain(
6502 renderer,
6503 windowData,
6504 windowData->swapchainComposition,
6505 windowData->present_mode);
6506
6507 windowData->needsSwapchainRecreate = false;
6508 return true;
6509}
6510#else
6511static bool D3D12_INTERNAL_InitializeSwapchainTexture(
6512 D3D12Renderer *renderer,
6513 IDXGISwapChain3 *swapchain,
6514 SDL_GPUSwapchainComposition composition,
6515 Uint32 index,
6516 D3D12TextureContainer *pTextureContainer)
6517{
6518 D3D12Texture *pTexture;
6519 ID3D12Resource *swapchainTexture;
6520 D3D12_RESOURCE_DESC textureDesc;
6521 D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
6522 D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
6523 DXGI_FORMAT swapchainFormat = SwapchainCompositionToTextureFormat[composition];
6524 HRESULT res;
6525
6526 res = IDXGISwapChain_GetBuffer(
6527 swapchain,
6528 index,
6529 D3D_GUID(D3D_IID_ID3D12Resource),
6530 (void **)&swapchainTexture);
6531 CHECK_D3D12_ERROR_AND_RETURN("Could not get buffer from swapchain!", false);
6532
6533 pTexture = (D3D12Texture *)SDL_calloc(1, sizeof(D3D12Texture));
6534 if (!pTexture) {
6535 ID3D12Resource_Release(swapchainTexture);
6536 return false;
6537 }
6538 pTexture->resource = NULL; // This will be set in AcquireSwapchainTexture
6539 SDL_SetAtomicInt(&pTexture->referenceCount, 0);
6540 pTexture->subresourceCount = 1;
6541 pTexture->subresources = (D3D12TextureSubresource *)SDL_calloc(1, sizeof(D3D12TextureSubresource));
6542 if (!pTexture->subresources) {
6543 SDL_free(pTexture);
6544 ID3D12Resource_Release(swapchainTexture);
6545 return false;
6546 }
6547 pTexture->subresources[0].rtvHandles = SDL_calloc(1, sizeof(D3D12StagingDescriptor));
6548 pTexture->subresources[0].uavHandle.heap = NULL;
6549 pTexture->subresources[0].dsvHandle.heap = NULL;
6550 pTexture->subresources[0].parent = pTexture;
6551 pTexture->subresources[0].index = 0;
6552 pTexture->subresources[0].layer = 0;
6553 pTexture->subresources[0].depth = 1;
6554 pTexture->subresources[0].level = 0;
6555
6556 ID3D12Resource_GetDesc(swapchainTexture, &textureDesc);
6557 pTextureContainer->header.info.width = (Uint32)textureDesc.Width;
6558 pTextureContainer->header.info.height = (Uint32)textureDesc.Height;
6559 pTextureContainer->header.info.layer_count_or_depth = 1;
6560 pTextureContainer->header.info.num_levels = 1;
6561 pTextureContainer->header.info.type = SDL_GPU_TEXTURETYPE_2D;
6562 pTextureContainer->header.info.usage = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
6563 pTextureContainer->header.info.sample_count = SDL_GPU_SAMPLECOUNT_1;
6564 pTextureContainer->header.info.format = SwapchainCompositionToSDLTextureFormat[composition];
6565
6566 pTextureContainer->debugName = NULL;
6567 pTextureContainer->textures = (D3D12Texture **)SDL_calloc(1, sizeof(D3D12Texture *));
6568 if (!pTextureContainer->textures) {
6569 SDL_free(pTexture->subresources);
6570 SDL_free(pTexture);
6571 ID3D12Resource_Release(swapchainTexture);
6572 return false;
6573 }
6574
6575 pTextureContainer->textureCapacity = 1;
6576 pTextureContainer->textureCount = 1;
6577 pTextureContainer->textures[0] = pTexture;
6578 pTextureContainer->activeTexture = pTexture;
6579 pTextureContainer->canBeCycled = false;
6580
6581 pTexture->container = pTextureContainer;
6582 pTexture->containerIndex = 0;
6583
6584 // Create the SRV for the swapchain
6585 D3D12_INTERNAL_AssignStagingDescriptorHandle(
6586 renderer,
6587 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
6588 &pTexture->srvHandle);
6589
6590 srvDesc.Format = SwapchainCompositionToTextureFormat[composition];
6591 srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
6592 srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
6593 srvDesc.Texture2D.MipLevels = 1;
6594 srvDesc.Texture2D.MostDetailedMip = 0;
6595 srvDesc.Texture2D.ResourceMinLODClamp = 0;
6596 srvDesc.Texture2D.PlaneSlice = 0;
6597
6598 ID3D12Device_CreateShaderResourceView(
6599 renderer->device,
6600 swapchainTexture,
6601 &srvDesc,
6602 pTexture->srvHandle.cpuHandle);
6603
6604 // Create the RTV for the swapchain
6605 D3D12_INTERNAL_AssignStagingDescriptorHandle(
6606 renderer,
6607 D3D12_DESCRIPTOR_HEAP_TYPE_RTV,
6608 &pTexture->subresources[0].rtvHandles[0]);
6609
6610 rtvDesc.Format = (composition == SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR) ? DXGI_FORMAT_B8G8R8A8_UNORM_SRGB : swapchainFormat;
6611 rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
6612 rtvDesc.Texture2D.MipSlice = 0;
6613 rtvDesc.Texture2D.PlaneSlice = 0;
6614
6615 ID3D12Device_CreateRenderTargetView(
6616 renderer->device,
6617 swapchainTexture,
6618 &rtvDesc,
6619 pTexture->subresources[0].rtvHandles[0].cpuHandle);
6620
6621 ID3D12Resource_Release(swapchainTexture);
6622
6623 return true;
6624}
6625
6626static bool D3D12_INTERNAL_ResizeSwapchain(
6627 D3D12Renderer *renderer,
6628 D3D12WindowData *windowData)
6629{
6630 // Wait so we don't release in-flight views
6631 D3D12_Wait((SDL_GPURenderer *)renderer);
6632
6633 // Release views and clean up
6634 for (Uint32 i = 0; i < windowData->swapchainTextureCount; i += 1) {
6635 D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
6636 renderer,
6637 &windowData->textureContainers[i].activeTexture->srvHandle);
6638 D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
6639 renderer,
6640 &windowData->textureContainers[i].activeTexture->subresources[0].rtvHandles[0]);
6641
6642 SDL_free(windowData->textureContainers[i].activeTexture->subresources[0].rtvHandles);
6643 SDL_free(windowData->textureContainers[i].activeTexture->subresources);
6644 SDL_free(windowData->textureContainers[i].activeTexture);
6645 SDL_free(windowData->textureContainers[i].textures);
6646 }
6647
6648 // Resize the swapchain
6649 HRESULT res = IDXGISwapChain_ResizeBuffers(
6650 windowData->swapchain,
6651 0, // Keep buffer count the same
6652 0, // use client window width
6653 0, // use client window height
6654 DXGI_FORMAT_UNKNOWN, // Keep the old format
6655 renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0);
6656 CHECK_D3D12_ERROR_AND_RETURN("Could not resize swapchain buffers", false);
6657
6658 // Create texture object for the swapchain
6659 for (Uint32 i = 0; i < windowData->swapchainTextureCount; i += 1) {
6660 if (!D3D12_INTERNAL_InitializeSwapchainTexture(
6661 renderer,
6662 windowData->swapchain,
6663 windowData->swapchainComposition,
6664 i,
6665 &windowData->textureContainers[i])) {
6666 return false;
6667 }
6668 }
6669
6670 DXGI_SWAP_CHAIN_DESC1 swapchainDesc;
6671 IDXGISwapChain3_GetDesc1(windowData->swapchain, &swapchainDesc);
6672 CHECK_D3D12_ERROR_AND_RETURN("Failed to retrieve swapchain descriptor!", false);
6673
6674 windowData->width = swapchainDesc.Width;
6675 windowData->height = swapchainDesc.Height;
6676 windowData->needsSwapchainRecreate = false;
6677 return true;
6678}
6679
6680static void D3D12_INTERNAL_DestroySwapchain(
6681 D3D12Renderer *renderer,
6682 D3D12WindowData *windowData)
6683{
6684 // Release views and clean up
6685 for (Uint32 i = 0; i < windowData->swapchainTextureCount; i += 1) {
6686 D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
6687 renderer,
6688 &windowData->textureContainers[i].activeTexture->srvHandle);
6689 D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
6690 renderer,
6691 &windowData->textureContainers[i].activeTexture->subresources[0].rtvHandles[0]);
6692
6693 SDL_free(windowData->textureContainers[i].activeTexture->subresources[0].rtvHandles);
6694 SDL_free(windowData->textureContainers[i].activeTexture->subresources);
6695 SDL_free(windowData->textureContainers[i].activeTexture);
6696 SDL_free(windowData->textureContainers[i].textures);
6697 }
6698
6699 IDXGISwapChain_Release(windowData->swapchain);
6700 windowData->swapchain = NULL;
6701}
6702
6703static bool D3D12_INTERNAL_CreateSwapchain(
6704 D3D12Renderer *renderer,
6705 D3D12WindowData *windowData,
6706 SDL_GPUSwapchainComposition swapchainComposition,
6707 SDL_GPUPresentMode presentMode)
6708{
6709 HWND dxgiHandle;
6710 DXGI_SWAP_CHAIN_DESC1 swapchainDesc;
6711 DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreenDesc;
6712 DXGI_FORMAT swapchainFormat;
6713 IDXGIFactory1 *pParent;
6714 IDXGISwapChain1 *swapchain;
6715 IDXGISwapChain3 *swapchain3;
6716 HRESULT res;
6717
6718 // Get the DXGI handle
6719#ifdef _WIN32
6720 dxgiHandle = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(windowData->window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
6721#else
6722 dxgiHandle = (HWND)windowData->window;
6723#endif
6724
6725 swapchainFormat = SwapchainCompositionToTextureFormat[swapchainComposition];
6726
6727 // Min swapchain image count is 2
6728 windowData->swapchainTextureCount = SDL_clamp(renderer->allowedFramesInFlight, 2, 3);
6729
6730 // Initialize the swapchain buffer descriptor
6731 swapchainDesc.Width = 0; // use client window width
6732 swapchainDesc.Height = 0; // use client window height
6733 swapchainDesc.Format = swapchainFormat;
6734 swapchainDesc.SampleDesc.Count = 1;
6735 swapchainDesc.SampleDesc.Quality = 0;
6736 swapchainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
6737 swapchainDesc.BufferCount = windowData->swapchainTextureCount;
6738 swapchainDesc.Scaling = DXGI_SCALING_NONE;
6739 swapchainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
6740 swapchainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
6741 swapchainDesc.Flags = 0;
6742 swapchainDesc.Stereo = 0;
6743
6744 // Initialize the fullscreen descriptor (if needed)
6745 fullscreenDesc.RefreshRate.Numerator = 0;
6746 fullscreenDesc.RefreshRate.Denominator = 0;
6747 fullscreenDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
6748 fullscreenDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
6749 fullscreenDesc.Windowed = true;
6750
6751 if (renderer->supportsTearing) {
6752 swapchainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
6753 } else {
6754 swapchainDesc.Flags = 0;
6755 }
6756
6757 if (!IsWindow(dxgiHandle)) {
6758 return false;
6759 }
6760
6761 // Create the swapchain!
6762 res = IDXGIFactory4_CreateSwapChainForHwnd(
6763 renderer->factory,
6764 (IUnknown *)renderer->commandQueue,
6765 dxgiHandle,
6766 &swapchainDesc,
6767 &fullscreenDesc,
6768 NULL,
6769 &swapchain);
6770 CHECK_D3D12_ERROR_AND_RETURN("Could not create swapchain", false);
6771
6772 res = IDXGISwapChain1_QueryInterface(
6773 swapchain,
6774 D3D_GUID(D3D_IID_IDXGISwapChain3),
6775 (void **)&swapchain3);
6776 IDXGISwapChain1_Release(swapchain);
6777 CHECK_D3D12_ERROR_AND_RETURN("Could not create IDXGISwapChain3", false);
6778
6779 if (swapchainComposition != SDL_GPU_SWAPCHAINCOMPOSITION_SDR) {
6780 // Support already verified if we hit this block
6781 IDXGISwapChain3_SetColorSpace1(
6782 swapchain3,
6783 SwapchainCompositionToColorSpace[swapchainComposition]);
6784 }
6785
6786 /*
6787 * The swapchain's parent is a separate factory from the factory that
6788 * we used to create the swapchain, and only that parent can be used to
6789 * set the window association. Trying to set an association on our factory
6790 * will silently fail and doesn't even verify arguments or return errors.
6791 * See https://gamedev.net/forums/topic/634235-dxgidisabling-altenter/4999955/
6792 */
6793 res = IDXGISwapChain3_GetParent(
6794 swapchain3,
6795 D3D_GUID(D3D_IID_IDXGIFactory1),
6796 (void **)&pParent);
6797 if (FAILED(res)) {
6798 SDL_LogWarn(
6799 SDL_LOG_CATEGORY_GPU,
6800 "Could not get swapchain parent! Error Code: " HRESULT_FMT,
6801 res);
6802 } else {
6803 // Disable DXGI window crap
6804 res = IDXGIFactory1_MakeWindowAssociation(
6805 pParent,
6806 dxgiHandle,
6807 DXGI_MWA_NO_WINDOW_CHANGES);
6808 if (FAILED(res)) {
6809 SDL_LogWarn(
6810 SDL_LOG_CATEGORY_GPU,
6811 "MakeWindowAssociation failed! Error Code: " HRESULT_FMT,
6812 res);
6813 }
6814
6815 // We're done with the parent now
6816 IDXGIFactory1_Release(pParent);
6817 }
6818
6819 IDXGISwapChain3_GetDesc1(swapchain3, &swapchainDesc);
6820 CHECK_D3D12_ERROR_AND_RETURN("Failed to retrieve swapchain descriptor!", false);
6821
6822 // Initialize the swapchain data
6823 windowData->swapchain = swapchain3;
6824 windowData->present_mode = presentMode;
6825 windowData->swapchainComposition = swapchainComposition;
6826 windowData->swapchainColorSpace = SwapchainCompositionToColorSpace[swapchainComposition];
6827 windowData->frameCounter = 0;
6828 windowData->width = swapchainDesc.Width;
6829 windowData->height = swapchainDesc.Height;
6830
6831 // Precache blit pipelines for the swapchain format
6832 for (Uint32 i = 0; i < 5; i += 1) {
6833 SDL_GPU_FetchBlitPipeline(
6834 renderer->sdlGPUDevice,
6835 (SDL_GPUTextureType)i,
6836 SwapchainCompositionToSDLTextureFormat[swapchainComposition],
6837 renderer->blitVertexShader,
6838 renderer->blitFrom2DShader,
6839 renderer->blitFrom2DArrayShader,
6840 renderer->blitFrom3DShader,
6841 renderer->blitFromCubeShader,
6842 renderer->blitFromCubeArrayShader,
6843 &renderer->blitPipelines,
6844 &renderer->blitPipelineCount,
6845 &renderer->blitPipelineCapacity);
6846 }
6847
6848 /* If a you are using a FLIP model format you can't create the swapchain as DXGI_FORMAT_B8G8R8A8_UNORM_SRGB.
6849 * You have to create the swapchain as DXGI_FORMAT_B8G8R8A8_UNORM and then set the render target view's format to DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
6850 */
6851 for (Uint32 i = 0; i < windowData->swapchainTextureCount; i += 1) {
6852 if (!D3D12_INTERNAL_InitializeSwapchainTexture(
6853 renderer,
6854 swapchain3,
6855 swapchainComposition,
6856 i,
6857 &windowData->textureContainers[i])) {
6858 IDXGISwapChain3_Release(swapchain3);
6859 return false;
6860 }
6861 }
6862
6863 return true;
6864}
6865#endif
6866
6867static bool D3D12_ClaimWindow(
6868 SDL_GPURenderer *driverData,
6869 SDL_Window *window)
6870{
6871 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
6872 D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
6873
6874 if (windowData == NULL) {
6875 windowData = (D3D12WindowData *)SDL_calloc(1, sizeof(D3D12WindowData));
6876 if (!windowData) {
6877 return false;
6878 }
6879 windowData->window = window;
6880
6881 if (D3D12_INTERNAL_CreateSwapchain(renderer, windowData, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_VSYNC)) {
6882 SDL_SetPointerProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData);
6883
6884 SDL_LockMutex(renderer->windowLock);
6885 if (renderer->claimedWindowCount >= renderer->claimedWindowCapacity) {
6886 renderer->claimedWindowCapacity *= 2;
6887 renderer->claimedWindows = (D3D12WindowData **)SDL_realloc(
6888 renderer->claimedWindows,
6889 renderer->claimedWindowCapacity * sizeof(D3D12WindowData *));
6890 }
6891 renderer->claimedWindows[renderer->claimedWindowCount] = windowData;
6892 renderer->claimedWindowCount += 1;
6893 SDL_UnlockMutex(renderer->windowLock);
6894
6895 SDL_AddEventWatch(D3D12_INTERNAL_OnWindowResize, window);
6896
6897 return true;
6898 } else {
6899 SDL_free(windowData);
6900 SET_STRING_ERROR_AND_RETURN("Could not create swapchain, failed to claim window!", false);
6901 }
6902 } else {
6903 SET_STRING_ERROR_AND_RETURN("Window already claimed", false);
6904 }
6905}
6906
6907static void D3D12_ReleaseWindow(
6908 SDL_GPURenderer *driverData,
6909 SDL_Window *window)
6910{
6911 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
6912 D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
6913
6914 if (windowData == NULL) {
6915 SET_STRING_ERROR_AND_RETURN("Window already unclaimed!", );
6916 }
6917
6918 D3D12_Wait(driverData);
6919
6920 for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) {
6921 if (windowData->inFlightFences[i] != NULL) {
6922 D3D12_ReleaseFence(
6923 driverData,
6924 windowData->inFlightFences[i]);
6925 windowData->inFlightFences[i] = NULL;
6926 }
6927 }
6928
6929 D3D12_INTERNAL_DestroySwapchain(renderer, windowData);
6930
6931 SDL_LockMutex(renderer->windowLock);
6932 for (Uint32 i = 0; i < renderer->claimedWindowCount; i += 1) {
6933 if (renderer->claimedWindows[i]->window == window) {
6934 renderer->claimedWindows[i] = renderer->claimedWindows[renderer->claimedWindowCount - 1];
6935 renderer->claimedWindowCount -= 1;
6936 break;
6937 }
6938 }
6939 SDL_UnlockMutex(renderer->windowLock);
6940
6941 SDL_free(windowData);
6942 SDL_ClearProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA);
6943 SDL_RemoveEventWatch(D3D12_INTERNAL_OnWindowResize, window);
6944}
6945
6946static bool D3D12_SetSwapchainParameters(
6947 SDL_GPURenderer *driverData,
6948 SDL_Window *window,
6949 SDL_GPUSwapchainComposition swapchainComposition,
6950 SDL_GPUPresentMode presentMode)
6951{
6952 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
6953 D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
6954
6955 if (windowData == NULL) {
6956 SET_STRING_ERROR_AND_RETURN("Cannot set swapchain parameters on unclaimed window!", false);
6957 }
6958
6959 if (!D3D12_SupportsSwapchainComposition(driverData, window, swapchainComposition)) {
6960 SET_STRING_ERROR_AND_RETURN("Swapchain composition not supported!", false);
6961 }
6962
6963 if (!D3D12_SupportsPresentMode(driverData, window, presentMode)) {
6964 SET_STRING_ERROR_AND_RETURN("Present mode not supported!", false);
6965 }
6966
6967 if (
6968 swapchainComposition != windowData->swapchainComposition ||
6969 presentMode != windowData->present_mode) {
6970 D3D12_Wait(driverData);
6971
6972 // Recreate the swapchain
6973 D3D12_INTERNAL_DestroySwapchain(
6974 renderer,
6975 windowData);
6976
6977 return D3D12_INTERNAL_CreateSwapchain(
6978 renderer,
6979 windowData,
6980 swapchainComposition,
6981 presentMode);
6982 }
6983
6984 return true;
6985}
6986
6987static bool D3D12_SetAllowedFramesInFlight(
6988 SDL_GPURenderer *driverData,
6989 Uint32 allowedFramesInFlight)
6990{
6991 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
6992
6993 if (!D3D12_Wait(driverData)) {
6994 return false;
6995 }
6996
6997 // Destroy all swapchains
6998 for (Uint32 i = 0; i < renderer->claimedWindowCount; i += 1) {
6999 D3D12WindowData *windowData = renderer->claimedWindows[i];
7000
7001 D3D12_INTERNAL_DestroySwapchain(renderer, windowData);
7002 }
7003
7004 // Set the frames in flight value
7005 renderer->allowedFramesInFlight = allowedFramesInFlight;
7006
7007 // Recreate all swapchains
7008 for (Uint32 i = 0; i < renderer->claimedWindowCount; i += 1) {
7009 D3D12WindowData *windowData = renderer->claimedWindows[i];
7010
7011 if (!D3D12_INTERNAL_CreateSwapchain(
7012 renderer,
7013 windowData,
7014 windowData->swapchainComposition,
7015 windowData->present_mode)) {
7016 return false;
7017 }
7018 }
7019
7020 return true;
7021}
7022
7023static SDL_GPUTextureFormat D3D12_GetSwapchainTextureFormat(
7024 SDL_GPURenderer *driverData,
7025 SDL_Window *window)
7026{
7027 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
7028 D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
7029
7030 if (windowData == NULL) {
7031 SET_STRING_ERROR_AND_RETURN("Cannot get swapchain format, window has not been claimed!", SDL_GPU_TEXTUREFORMAT_INVALID);
7032 }
7033
7034 return windowData->textureContainers[windowData->frameCounter].header.info.format;
7035}
7036
7037static D3D12Fence *D3D12_INTERNAL_AcquireFence(
7038 D3D12Renderer *renderer)
7039{
7040 D3D12Fence *fence;
7041 ID3D12Fence *handle;
7042 HRESULT res;
7043
7044 SDL_LockMutex(renderer->fenceLock);
7045
7046 if (renderer->availableFenceCount == 0) {
7047 res = ID3D12Device_CreateFence(
7048 renderer->device,
7049 D3D12_FENCE_UNSIGNALED_VALUE,
7050 D3D12_FENCE_FLAG_NONE,
7051 D3D_GUID(D3D_IID_ID3D12Fence),
7052 (void **)&handle);
7053 if (FAILED(res)) {
7054 D3D12_INTERNAL_SetError(renderer, "Failed to create fence!", res);
7055 SDL_UnlockMutex(renderer->fenceLock);
7056 return NULL;
7057 }
7058
7059 fence = (D3D12Fence *)SDL_calloc(1, sizeof(D3D12Fence));
7060 if (!fence) {
7061 ID3D12Fence_Release(handle);
7062 SDL_UnlockMutex(renderer->fenceLock);
7063 return NULL;
7064 }
7065 fence->handle = handle;
7066 fence->event = CreateEvent(NULL, FALSE, FALSE, NULL);
7067 SDL_SetAtomicInt(&fence->referenceCount, 0);
7068 } else {
7069 fence = renderer->availableFences[renderer->availableFenceCount - 1];
7070 renderer->availableFenceCount -= 1;
7071 ID3D12Fence_Signal(fence->handle, D3D12_FENCE_UNSIGNALED_VALUE);
7072 }
7073
7074 SDL_UnlockMutex(renderer->fenceLock);
7075
7076 (void)SDL_AtomicIncRef(&fence->referenceCount);
7077 return fence;
7078}
7079
7080static bool D3D12_INTERNAL_AllocateCommandBuffer(
7081 D3D12Renderer *renderer)
7082{
7083 D3D12CommandBuffer *commandBuffer;
7084 HRESULT res;
7085 ID3D12CommandAllocator *commandAllocator;
7086 ID3D12GraphicsCommandList *commandList;
7087
7088 commandBuffer = (D3D12CommandBuffer *)SDL_calloc(1, sizeof(D3D12CommandBuffer));
7089 if (!commandBuffer) {
7090 SET_STRING_ERROR_AND_RETURN("Failed to create ID3D12CommandList. Out of Memory", false);
7091 }
7092
7093 res = ID3D12Device_CreateCommandAllocator(
7094 renderer->device,
7095 D3D12_COMMAND_LIST_TYPE_DIRECT,
7096 D3D_GUID(D3D_IID_ID3D12CommandAllocator),
7097 (void **)&commandAllocator);
7098 if (FAILED(res)) {
7099 D3D12_INTERNAL_SetError(renderer, "Failed to create ID3D12CommandAllocator", res);
7100 D3D12_INTERNAL_DestroyCommandBuffer(commandBuffer);
7101 return false;
7102 }
7103 commandBuffer->commandAllocator = commandAllocator;
7104
7105 res = ID3D12Device_CreateCommandList(
7106 renderer->device,
7107 0,
7108 D3D12_COMMAND_LIST_TYPE_DIRECT,
7109 commandAllocator,
7110 NULL,
7111 D3D_GUID(D3D_IID_ID3D12GraphicsCommandList),
7112 (void **)&commandList);
7113
7114 if (FAILED(res)) {
7115 D3D12_INTERNAL_SetError(renderer, "Failed to create ID3D12CommandList", res);
7116 D3D12_INTERNAL_DestroyCommandBuffer(commandBuffer);
7117 return false;
7118 }
7119 commandBuffer->graphicsCommandList = commandList;
7120
7121 commandBuffer->renderer = renderer;
7122 commandBuffer->inFlightFence = NULL;
7123
7124 // Window handling
7125 commandBuffer->presentDataCapacity = 1;
7126 commandBuffer->presentDataCount = 0;
7127 commandBuffer->presentDatas = (D3D12PresentData *)SDL_calloc(
7128 commandBuffer->presentDataCapacity, sizeof(D3D12PresentData));
7129
7130 // Resource tracking
7131 commandBuffer->usedTextureCapacity = 4;
7132 commandBuffer->usedTextureCount = 0;
7133 commandBuffer->usedTextures = (D3D12Texture **)SDL_calloc(
7134 commandBuffer->usedTextureCapacity, sizeof(D3D12Texture *));
7135
7136 commandBuffer->usedBufferCapacity = 4;
7137 commandBuffer->usedBufferCount = 0;
7138 commandBuffer->usedBuffers = (D3D12Buffer **)SDL_calloc(
7139 commandBuffer->usedBufferCapacity, sizeof(D3D12Buffer *));
7140
7141 commandBuffer->usedSamplerCapacity = 4;
7142 commandBuffer->usedSamplerCount = 0;
7143 commandBuffer->usedSamplers = (D3D12Sampler **)SDL_calloc(
7144 commandBuffer->usedSamplerCapacity, sizeof(D3D12Sampler *));
7145
7146 commandBuffer->usedGraphicsPipelineCapacity = 4;
7147 commandBuffer->usedGraphicsPipelineCount = 0;
7148 commandBuffer->usedGraphicsPipelines = (D3D12GraphicsPipeline **)SDL_calloc(
7149 commandBuffer->usedGraphicsPipelineCapacity, sizeof(D3D12GraphicsPipeline *));
7150
7151 commandBuffer->usedComputePipelineCapacity = 4;
7152 commandBuffer->usedComputePipelineCount = 0;
7153 commandBuffer->usedComputePipelines = (D3D12ComputePipeline **)SDL_calloc(
7154 commandBuffer->usedComputePipelineCapacity, sizeof(D3D12ComputePipeline *));
7155
7156 commandBuffer->usedUniformBufferCapacity = 4;
7157 commandBuffer->usedUniformBufferCount = 0;
7158 commandBuffer->usedUniformBuffers = (D3D12UniformBuffer **)SDL_calloc(
7159 commandBuffer->usedUniformBufferCapacity, sizeof(D3D12UniformBuffer *));
7160
7161 commandBuffer->textureDownloadCapacity = 4;
7162 commandBuffer->textureDownloadCount = 0;
7163 commandBuffer->textureDownloads = (D3D12TextureDownload **)SDL_calloc(
7164 commandBuffer->textureDownloadCapacity, sizeof(D3D12TextureDownload *));
7165
7166 if (
7167 (!commandBuffer->presentDatas) ||
7168 (!commandBuffer->usedTextures) ||
7169 (!commandBuffer->usedBuffers) ||
7170 (!commandBuffer->usedSamplers) ||
7171 (!commandBuffer->usedGraphicsPipelines) ||
7172 (!commandBuffer->usedComputePipelines) ||
7173 (!commandBuffer->usedUniformBuffers) ||
7174 (!commandBuffer->textureDownloads)) {
7175 D3D12_INTERNAL_DestroyCommandBuffer(commandBuffer);
7176 SET_STRING_ERROR_AND_RETURN("Failed to create ID3D12CommandList. Out of Memory", false);
7177 }
7178
7179 D3D12CommandBuffer **resizedAvailableCommandBuffers = (D3D12CommandBuffer **)SDL_realloc(
7180 renderer->availableCommandBuffers,
7181 sizeof(D3D12CommandBuffer *) * (renderer->availableCommandBufferCapacity + 1));
7182
7183 if (!resizedAvailableCommandBuffers) {
7184 D3D12_INTERNAL_DestroyCommandBuffer(commandBuffer);
7185 SET_STRING_ERROR_AND_RETURN("Failed to create ID3D12CommandList. Out of Memory", false);
7186 }
7187 // Add to inactive command buffer array
7188 renderer->availableCommandBufferCapacity += 1;
7189 renderer->availableCommandBuffers = resizedAvailableCommandBuffers;
7190
7191 renderer->availableCommandBuffers[renderer->availableCommandBufferCount] = commandBuffer;
7192 renderer->availableCommandBufferCount += 1;
7193
7194 return true;
7195}
7196
7197static D3D12CommandBuffer *D3D12_INTERNAL_AcquireCommandBufferFromPool(
7198 D3D12Renderer *renderer)
7199{
7200 D3D12CommandBuffer *commandBuffer;
7201
7202 if (renderer->availableCommandBufferCount == 0) {
7203 if (!D3D12_INTERNAL_AllocateCommandBuffer(renderer)) {
7204 return NULL;
7205 }
7206 }
7207
7208 commandBuffer = renderer->availableCommandBuffers[renderer->availableCommandBufferCount - 1];
7209 renderer->availableCommandBufferCount -= 1;
7210
7211 return commandBuffer;
7212}
7213
7214static SDL_GPUCommandBuffer *D3D12_AcquireCommandBuffer(
7215 SDL_GPURenderer *driverData)
7216{
7217 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
7218 D3D12CommandBuffer *commandBuffer;
7219 ID3D12DescriptorHeap *heaps[2];
7220 SDL_zeroa(heaps);
7221
7222 SDL_LockMutex(renderer->acquireCommandBufferLock);
7223 commandBuffer = D3D12_INTERNAL_AcquireCommandBufferFromPool(renderer);
7224 SDL_UnlockMutex(renderer->acquireCommandBufferLock);
7225
7226 if (commandBuffer == NULL) {
7227 return NULL;
7228 }
7229
7230 // Set the bind state
7231 commandBuffer->currentGraphicsPipeline = NULL;
7232
7233 SDL_zeroa(commandBuffer->colorTargetSubresources);
7234 SDL_zeroa(commandBuffer->colorResolveSubresources);
7235 commandBuffer->depthStencilTextureSubresource = NULL;
7236
7237 SDL_zeroa(commandBuffer->vertexBuffers);
7238 SDL_zeroa(commandBuffer->vertexBufferOffsets);
7239 commandBuffer->vertexBufferCount = 0;
7240
7241 SDL_zeroa(commandBuffer->vertexSamplerTextures);
7242 SDL_zeroa(commandBuffer->vertexSamplers);
7243 SDL_zeroa(commandBuffer->vertexStorageTextures);
7244 SDL_zeroa(commandBuffer->vertexStorageBuffers);
7245 SDL_zeroa(commandBuffer->vertexUniformBuffers);
7246
7247 SDL_zeroa(commandBuffer->fragmentSamplerTextures);
7248 SDL_zeroa(commandBuffer->fragmentSamplers);
7249 SDL_zeroa(commandBuffer->fragmentStorageTextures);
7250 SDL_zeroa(commandBuffer->fragmentStorageBuffers);
7251 SDL_zeroa(commandBuffer->fragmentUniformBuffers);
7252
7253 SDL_zeroa(commandBuffer->computeSamplerTextures);
7254 SDL_zeroa(commandBuffer->computeSamplers);
7255 SDL_zeroa(commandBuffer->computeReadOnlyStorageTextures);
7256 SDL_zeroa(commandBuffer->computeReadOnlyStorageBuffers);
7257 SDL_zeroa(commandBuffer->computeReadWriteStorageTextureSubresources);
7258 SDL_zeroa(commandBuffer->computeReadWriteStorageBuffers);
7259 SDL_zeroa(commandBuffer->computeUniformBuffers);
7260
7261 commandBuffer->autoReleaseFence = true;
7262
7263 return (SDL_GPUCommandBuffer *)commandBuffer;
7264}
7265
7266static bool D3D12_WaitForSwapchain(
7267 SDL_GPURenderer *driverData,
7268 SDL_Window *window)
7269{
7270 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
7271 D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
7272
7273 if (windowData == NULL) {
7274 SET_STRING_ERROR_AND_RETURN("Cannot wait for a swapchain from an unclaimed window!", false);
7275 }
7276
7277 if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
7278 if (!D3D12_WaitForFences(
7279 driverData,
7280 true,
7281 &windowData->inFlightFences[windowData->frameCounter],
7282 1)) {
7283 return false;
7284 }
7285 }
7286
7287 return true;
7288}
7289
7290static bool D3D12_INTERNAL_AcquireSwapchainTexture(
7291 bool block,
7292 SDL_GPUCommandBuffer *commandBuffer,
7293 SDL_Window *window,
7294 SDL_GPUTexture **swapchainTexture,
7295 Uint32 *swapchainTextureWidth,
7296 Uint32 *swapchainTextureHeight)
7297{
7298 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
7299 D3D12Renderer *renderer = d3d12CommandBuffer->renderer;
7300 D3D12WindowData *windowData;
7301 Uint32 swapchainIndex;
7302 HRESULT res;
7303
7304 *swapchainTexture = NULL;
7305 if (swapchainTextureWidth) {
7306 *swapchainTextureWidth = 0;
7307 }
7308 if (swapchainTextureHeight) {
7309 *swapchainTextureHeight = 0;
7310 }
7311
7312 windowData = D3D12_INTERNAL_FetchWindowData(window);
7313 if (windowData == NULL) {
7314 SET_STRING_ERROR_AND_RETURN("Cannot acquire swapchain texture from an unclaimed window!", false);
7315 }
7316
7317 if (windowData->needsSwapchainRecreate) {
7318 if (!D3D12_INTERNAL_ResizeSwapchain(renderer, windowData)) {
7319 return false;
7320 }
7321 }
7322
7323 if (swapchainTextureWidth) {
7324 *swapchainTextureWidth = windowData->width;
7325 }
7326 if (swapchainTextureHeight) {
7327 *swapchainTextureHeight = windowData->height;
7328 }
7329
7330 if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
7331 if (block) {
7332 // In VSYNC mode, block until the least recent presented frame is done
7333 if (!D3D12_WaitForFences(
7334 (SDL_GPURenderer *)renderer,
7335 true,
7336 &windowData->inFlightFences[windowData->frameCounter],
7337 1)) {
7338 return false;
7339 }
7340 } else {
7341 // If we are not blocking and the least recent fence is not signaled,
7342 // return true to indicate that there is no error but rendering should be skipped.
7343 if (!D3D12_QueryFence(
7344 (SDL_GPURenderer *)renderer,
7345 windowData->inFlightFences[windowData->frameCounter])) {
7346 return true;
7347 }
7348 }
7349
7350 D3D12_ReleaseFence(
7351 (SDL_GPURenderer *)renderer,
7352 windowData->inFlightFences[windowData->frameCounter]);
7353
7354 windowData->inFlightFences[windowData->frameCounter] = NULL;
7355 }
7356
7357#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
7358 // FIXME: Should this happen before the inFlightFences stuff above?
7359 windowData->frameToken = D3D12XBOX_FRAME_PIPELINE_TOKEN_NULL;
7360 renderer->device->WaitFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, INFINITE, NULL, D3D12XBOX_WAIT_FRAME_EVENT_FLAG_NONE, &windowData->frameToken);
7361 swapchainIndex = windowData->frameCounter;
7362#else
7363 swapchainIndex = IDXGISwapChain3_GetCurrentBackBufferIndex(windowData->swapchain);
7364
7365 // Set the handle on the windowData texture data.
7366 res = IDXGISwapChain_GetBuffer(
7367 windowData->swapchain,
7368 swapchainIndex,
7369 D3D_GUID(D3D_IID_ID3D12Resource),
7370 (void **)&windowData->textureContainers[swapchainIndex].activeTexture->resource);
7371 CHECK_D3D12_ERROR_AND_RETURN("Could not acquire swapchain!", false);
7372#endif
7373
7374 // Set up presentation
7375 if (d3d12CommandBuffer->presentDataCount == d3d12CommandBuffer->presentDataCapacity) {
7376 d3d12CommandBuffer->presentDataCapacity += 1;
7377 d3d12CommandBuffer->presentDatas = (D3D12PresentData *)SDL_realloc(
7378 d3d12CommandBuffer->presentDatas,
7379 d3d12CommandBuffer->presentDataCapacity * sizeof(D3D12PresentData));
7380 }
7381 d3d12CommandBuffer->presentDatas[d3d12CommandBuffer->presentDataCount].windowData = windowData;
7382 d3d12CommandBuffer->presentDatas[d3d12CommandBuffer->presentDataCount].swapchainImageIndex = swapchainIndex;
7383 d3d12CommandBuffer->presentDataCount += 1;
7384
7385 // Set up resource barrier
7386 D3D12_RESOURCE_BARRIER barrierDesc;
7387 barrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
7388 barrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
7389 barrierDesc.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
7390 barrierDesc.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
7391 barrierDesc.Transition.pResource = windowData->textureContainers[swapchainIndex].activeTexture->resource;
7392 barrierDesc.Transition.Subresource = 0;
7393
7394 ID3D12GraphicsCommandList_ResourceBarrier(
7395 d3d12CommandBuffer->graphicsCommandList,
7396 1,
7397 &barrierDesc);
7398
7399 *swapchainTexture = (SDL_GPUTexture*)&windowData->textureContainers[swapchainIndex];
7400 return true;
7401}
7402
7403static bool D3D12_AcquireSwapchainTexture(
7404 SDL_GPUCommandBuffer *command_buffer,
7405 SDL_Window *window,
7406 SDL_GPUTexture **swapchain_texture,
7407 Uint32 *swapchain_texture_width,
7408 Uint32 *swapchain_texture_height
7409) {
7410 return D3D12_INTERNAL_AcquireSwapchainTexture(
7411 false,
7412 command_buffer,
7413 window,
7414 swapchain_texture,
7415 swapchain_texture_width,
7416 swapchain_texture_height);
7417}
7418
7419static bool D3D12_WaitAndAcquireSwapchainTexture(
7420 SDL_GPUCommandBuffer *command_buffer,
7421 SDL_Window *window,
7422 SDL_GPUTexture **swapchain_texture,
7423 Uint32 *swapchain_texture_width,
7424 Uint32 *swapchain_texture_height
7425) {
7426 return D3D12_INTERNAL_AcquireSwapchainTexture(
7427 true,
7428 command_buffer,
7429 window,
7430 swapchain_texture,
7431 swapchain_texture_width,
7432 swapchain_texture_height);
7433}
7434
7435static void D3D12_INTERNAL_PerformPendingDestroys(D3D12Renderer *renderer)
7436{
7437 SDL_LockMutex(renderer->disposeLock);
7438
7439 for (Sint32 i = renderer->buffersToDestroyCount - 1; i >= 0; i -= 1) {
7440 if (SDL_GetAtomicInt(&renderer->buffersToDestroy[i]->referenceCount) == 0) {
7441 D3D12_INTERNAL_DestroyBuffer(
7442 renderer,
7443 renderer->buffersToDestroy[i]);
7444
7445 renderer->buffersToDestroy[i] = renderer->buffersToDestroy[renderer->buffersToDestroyCount - 1];
7446 renderer->buffersToDestroyCount -= 1;
7447 }
7448 }
7449
7450 for (Sint32 i = renderer->texturesToDestroyCount - 1; i >= 0; i -= 1) {
7451 if (SDL_GetAtomicInt(&renderer->texturesToDestroy[i]->referenceCount) == 0) {
7452 D3D12_INTERNAL_DestroyTexture(
7453 renderer,
7454 renderer->texturesToDestroy[i]);
7455
7456 renderer->texturesToDestroy[i] = renderer->texturesToDestroy[renderer->texturesToDestroyCount - 1];
7457 renderer->texturesToDestroyCount -= 1;
7458 }
7459 }
7460
7461 for (Sint32 i = renderer->samplersToDestroyCount - 1; i >= 0; i -= 1) {
7462 if (SDL_GetAtomicInt(&renderer->samplersToDestroy[i]->referenceCount) == 0) {
7463 D3D12_INTERNAL_DestroySampler(
7464 renderer,
7465 renderer->samplersToDestroy[i]);
7466
7467 renderer->samplersToDestroy[i] = renderer->samplersToDestroy[renderer->samplersToDestroyCount - 1];
7468 renderer->samplersToDestroyCount -= 1;
7469 }
7470 }
7471
7472 for (Sint32 i = renderer->graphicsPipelinesToDestroyCount - 1; i >= 0; i -= 1) {
7473 if (SDL_GetAtomicInt(&renderer->graphicsPipelinesToDestroy[i]->referenceCount) == 0) {
7474 D3D12_INTERNAL_DestroyGraphicsPipeline(
7475 renderer->graphicsPipelinesToDestroy[i]);
7476
7477 renderer->graphicsPipelinesToDestroy[i] = renderer->graphicsPipelinesToDestroy[renderer->graphicsPipelinesToDestroyCount - 1];
7478 renderer->graphicsPipelinesToDestroyCount -= 1;
7479 }
7480 }
7481
7482 for (Sint32 i = renderer->computePipelinesToDestroyCount - 1; i >= 0; i -= 1) {
7483 if (SDL_GetAtomicInt(&renderer->computePipelinesToDestroy[i]->referenceCount) == 0) {
7484 D3D12_INTERNAL_DestroyComputePipeline(
7485 renderer->computePipelinesToDestroy[i]);
7486
7487 renderer->computePipelinesToDestroy[i] = renderer->computePipelinesToDestroy[renderer->computePipelinesToDestroyCount - 1];
7488 renderer->computePipelinesToDestroyCount -= 1;
7489 }
7490 }
7491
7492 SDL_UnlockMutex(renderer->disposeLock);
7493}
7494
7495static bool D3D12_INTERNAL_CopyTextureDownload(
7496 D3D12CommandBuffer *commandBuffer,
7497 D3D12TextureDownload *download)
7498{
7499 D3D12Renderer *renderer = commandBuffer->renderer;
7500 Uint8 *sourcePtr;
7501 Uint8 *destPtr;
7502 HRESULT res;
7503
7504 res = ID3D12Resource_Map(
7505 download->temporaryBuffer->handle,
7506 0,
7507 NULL,
7508 (void **)&sourcePtr);
7509
7510 CHECK_D3D12_ERROR_AND_RETURN("Failed to map temporary buffer", false);
7511
7512 res = ID3D12Resource_Map(
7513 download->destinationBuffer->handle,
7514 0,
7515 NULL,
7516 (void **)&destPtr);
7517
7518 CHECK_D3D12_ERROR_AND_RETURN("Failed to map destination buffer", false);
7519
7520 for (Uint32 sliceIndex = 0; sliceIndex < download->depth; sliceIndex += 1) {
7521 for (Uint32 rowIndex = 0; rowIndex < download->height; rowIndex += 1) {
7522 SDL_memcpy(
7523 destPtr + download->bufferOffset + (sliceIndex * download->bytesPerDepthSlice) + (rowIndex * download->bytesPerRow),
7524 sourcePtr + (sliceIndex * download->height) + (rowIndex * download->alignedBytesPerRow),
7525 download->bytesPerRow);
7526 }
7527 }
7528
7529 ID3D12Resource_Unmap(
7530 download->temporaryBuffer->handle,
7531 0,
7532 NULL);
7533
7534 ID3D12Resource_Unmap(
7535 download->destinationBuffer->handle,
7536 0,
7537 NULL);
7538
7539 return true;
7540}
7541
7542static bool D3D12_INTERNAL_CleanCommandBuffer(
7543 D3D12Renderer *renderer,
7544 D3D12CommandBuffer *commandBuffer,
7545 bool cancel)
7546{
7547 Uint32 i;
7548 HRESULT res;
7549 bool result = true;
7550
7551 // Perform deferred texture data copies
7552 for (i = 0; i < commandBuffer->textureDownloadCount; i += 1) {
7553 if (!cancel) {
7554 result &= D3D12_INTERNAL_CopyTextureDownload(
7555 commandBuffer,
7556 commandBuffer->textureDownloads[i]);
7557 }
7558 SDL_free(commandBuffer->textureDownloads[i]);
7559 }
7560 commandBuffer->textureDownloadCount = 0;
7561
7562 if (!result) {
7563 return false;
7564 }
7565
7566 res = ID3D12CommandAllocator_Reset(commandBuffer->commandAllocator);
7567 CHECK_D3D12_ERROR_AND_RETURN("Could not reset command allocator", false);
7568
7569 res = ID3D12GraphicsCommandList_Reset(
7570 commandBuffer->graphicsCommandList,
7571 commandBuffer->commandAllocator,
7572 NULL);
7573 CHECK_D3D12_ERROR_AND_RETURN("Could not reset command list", false);
7574
7575 // Return descriptor heaps to pool
7576 D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(
7577 renderer,
7578 commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]);
7579 D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(
7580 renderer,
7581 commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER]);
7582
7583 commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] = NULL;
7584 commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] = NULL;
7585
7586 // Uniform buffers are now available
7587 SDL_LockMutex(renderer->acquireUniformBufferLock);
7588
7589 for (i = 0; i < commandBuffer->usedUniformBufferCount; i += 1) {
7590 D3D12_INTERNAL_ReturnUniformBufferToPool(
7591 renderer,
7592 commandBuffer->usedUniformBuffers[i]);
7593 }
7594 commandBuffer->usedUniformBufferCount = 0;
7595
7596 SDL_UnlockMutex(renderer->acquireUniformBufferLock);
7597
7598 // TODO: More reference counting
7599
7600 for (i = 0; i < commandBuffer->usedTextureCount; i += 1) {
7601 (void)SDL_AtomicDecRef(&commandBuffer->usedTextures[i]->referenceCount);
7602 }
7603 commandBuffer->usedTextureCount = 0;
7604
7605 for (i = 0; i < commandBuffer->usedBufferCount; i += 1) {
7606 (void)SDL_AtomicDecRef(&commandBuffer->usedBuffers[i]->referenceCount);
7607 }
7608 commandBuffer->usedBufferCount = 0;
7609
7610 for (i = 0; i < commandBuffer->usedSamplerCount; i += 1) {
7611 (void)SDL_AtomicDecRef(&commandBuffer->usedSamplers[i]->referenceCount);
7612 }
7613 commandBuffer->usedSamplerCount = 0;
7614
7615 for (i = 0; i < commandBuffer->usedGraphicsPipelineCount; i += 1) {
7616 (void)SDL_AtomicDecRef(&commandBuffer->usedGraphicsPipelines[i]->referenceCount);
7617 }
7618 commandBuffer->usedGraphicsPipelineCount = 0;
7619
7620 for (i = 0; i < commandBuffer->usedComputePipelineCount; i += 1) {
7621 (void)SDL_AtomicDecRef(&commandBuffer->usedComputePipelines[i]->referenceCount);
7622 }
7623 commandBuffer->usedComputePipelineCount = 0;
7624
7625 // Reset presentation
7626 commandBuffer->presentDataCount = 0;
7627
7628 // The fence is now available (unless SubmitAndAcquireFence was called)
7629 if (commandBuffer->autoReleaseFence) {
7630 D3D12_ReleaseFence(
7631 (SDL_GPURenderer *)renderer,
7632 (SDL_GPUFence *)commandBuffer->inFlightFence);
7633
7634 commandBuffer->inFlightFence = NULL;
7635 }
7636
7637 // Return command buffer to pool
7638 SDL_LockMutex(renderer->acquireCommandBufferLock);
7639
7640 if (renderer->availableCommandBufferCount == renderer->availableCommandBufferCapacity) {
7641 renderer->availableCommandBufferCapacity += 1;
7642 renderer->availableCommandBuffers = (D3D12CommandBuffer **)SDL_realloc(
7643 renderer->availableCommandBuffers,
7644 renderer->availableCommandBufferCapacity * sizeof(D3D12CommandBuffer *));
7645 }
7646
7647 renderer->availableCommandBuffers[renderer->availableCommandBufferCount] = commandBuffer;
7648 renderer->availableCommandBufferCount += 1;
7649
7650 SDL_UnlockMutex(renderer->acquireCommandBufferLock);
7651
7652 // Remove this command buffer from the submitted list
7653 if (!cancel) {
7654 for (i = 0; i < renderer->submittedCommandBufferCount; i += 1) {
7655 if (renderer->submittedCommandBuffers[i] == commandBuffer) {
7656 renderer->submittedCommandBuffers[i] = renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount - 1];
7657 renderer->submittedCommandBufferCount -= 1;
7658 }
7659 }
7660 }
7661
7662 return true;
7663}
7664
7665static bool D3D12_Submit(
7666 SDL_GPUCommandBuffer *commandBuffer)
7667{
7668 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
7669 D3D12Renderer *renderer = d3d12CommandBuffer->renderer;
7670 ID3D12CommandList *commandLists[1];
7671 HRESULT res;
7672
7673 SDL_LockMutex(renderer->submitLock);
7674
7675 // Unmap uniform buffers
7676 for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
7677 if (d3d12CommandBuffer->vertexUniformBuffers[i] != NULL) {
7678 ID3D12Resource_Unmap(
7679 d3d12CommandBuffer->vertexUniformBuffers[i]->buffer->handle,
7680 0,
7681 NULL);
7682 d3d12CommandBuffer->vertexUniformBuffers[i]->buffer->mapPointer = NULL;
7683 }
7684
7685 if (d3d12CommandBuffer->fragmentUniformBuffers[i] != NULL) {
7686 ID3D12Resource_Unmap(
7687 d3d12CommandBuffer->fragmentUniformBuffers[i]->buffer->handle,
7688 0,
7689 NULL);
7690 d3d12CommandBuffer->fragmentUniformBuffers[i]->buffer->mapPointer = NULL;
7691 }
7692
7693 // TODO: compute uniforms
7694 }
7695
7696 // Transition present textures to present mode
7697 for (Uint32 i = 0; i < d3d12CommandBuffer->presentDataCount; i += 1) {
7698 Uint32 swapchainIndex = d3d12CommandBuffer->presentDatas[i].swapchainImageIndex;
7699 D3D12TextureContainer *container = &d3d12CommandBuffer->presentDatas[i].windowData->textureContainers[swapchainIndex];
7700 D3D12TextureSubresource *subresource = D3D12_INTERNAL_FetchTextureSubresource(container, 0, 0);
7701
7702 D3D12_RESOURCE_BARRIER barrierDesc;
7703 barrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
7704 barrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
7705 barrierDesc.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
7706 barrierDesc.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
7707 barrierDesc.Transition.pResource = subresource->parent->resource;
7708 barrierDesc.Transition.Subresource = subresource->index;
7709
7710 ID3D12GraphicsCommandList_ResourceBarrier(
7711 d3d12CommandBuffer->graphicsCommandList,
7712 1,
7713 &barrierDesc);
7714 }
7715
7716 // Notify the command buffer that we have completed recording
7717 res = ID3D12GraphicsCommandList_Close(d3d12CommandBuffer->graphicsCommandList);
7718 CHECK_D3D12_ERROR_AND_RETURN("Failed to close command list!", false);
7719
7720 res = ID3D12GraphicsCommandList_QueryInterface(
7721 d3d12CommandBuffer->graphicsCommandList,
7722 D3D_GUID(D3D_IID_ID3D12CommandList),
7723 (void **)&commandLists[0]);
7724 if (FAILED(res)) {
7725 SDL_UnlockMutex(renderer->submitLock);
7726 CHECK_D3D12_ERROR_AND_RETURN("Failed to convert command list!", false);
7727 }
7728
7729 // Submit the command list to the queue
7730 ID3D12CommandQueue_ExecuteCommandLists(
7731 renderer->commandQueue,
7732 1,
7733 commandLists);
7734
7735 ID3D12CommandList_Release(commandLists[0]);
7736
7737 // Acquire a fence and set it to the in-flight fence
7738 d3d12CommandBuffer->inFlightFence = D3D12_INTERNAL_AcquireFence(renderer);
7739 if (!d3d12CommandBuffer->inFlightFence) {
7740 SDL_UnlockMutex(renderer->submitLock);
7741 return false;
7742 }
7743
7744 // Mark that a fence should be signaled after command list execution
7745 res = ID3D12CommandQueue_Signal(
7746 renderer->commandQueue,
7747 d3d12CommandBuffer->inFlightFence->handle,
7748 D3D12_FENCE_SIGNAL_VALUE);
7749 if (FAILED(res)) {
7750 SDL_UnlockMutex(renderer->submitLock);
7751 CHECK_D3D12_ERROR_AND_RETURN("Failed to enqueue fence signal!", false);
7752 }
7753
7754 // Mark the command buffer as submitted
7755 if (renderer->submittedCommandBufferCount + 1 >= renderer->submittedCommandBufferCapacity) {
7756 renderer->submittedCommandBufferCapacity = renderer->submittedCommandBufferCount + 1;
7757
7758 renderer->submittedCommandBuffers = (D3D12CommandBuffer **)SDL_realloc(
7759 renderer->submittedCommandBuffers,
7760 sizeof(D3D12CommandBuffer *) * renderer->submittedCommandBufferCapacity);
7761 }
7762
7763 renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount] = d3d12CommandBuffer;
7764 renderer->submittedCommandBufferCount += 1;
7765
7766 bool result = true;
7767
7768 // Present, if applicable
7769 for (Uint32 i = 0; i < d3d12CommandBuffer->presentDataCount; i += 1) {
7770 D3D12PresentData *presentData = &d3d12CommandBuffer->presentDatas[i];
7771 D3D12WindowData *windowData = presentData->windowData;
7772
7773#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
7774 D3D12XBOX_PRESENT_PLANE_PARAMETERS planeParams;
7775 SDL_zero(planeParams);
7776 planeParams.Token = windowData->frameToken;
7777 planeParams.ResourceCount = 1;
7778 planeParams.ppResources = &windowData->textureContainers[windowData->frameCounter].activeTexture->resource;
7779 planeParams.ColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; // FIXME
7780
7781 D3D12XBOX_PRESENT_PARAMETERS presentParams;
7782 SDL_zero(presentParams);
7783 presentParams.Flags = (windowData->present_mode == SDL_GPU_PRESENTMODE_IMMEDIATE) ? D3D12XBOX_PRESENT_FLAG_IMMEDIATE : D3D12XBOX_PRESENT_FLAG_NONE;
7784
7785 renderer->commandQueue->PresentX(1, &planeParams, &presentParams);
7786 if (FAILED(res)) {
7787 result = false;
7788 }
7789#else
7790 // NOTE: flip discard always supported since DXGI 1.4 is required
7791 Uint32 syncInterval = 1;
7792 if (windowData->present_mode == SDL_GPU_PRESENTMODE_IMMEDIATE ||
7793 windowData->present_mode == SDL_GPU_PRESENTMODE_MAILBOX) {
7794 syncInterval = 0;
7795 }
7796
7797 Uint32 presentFlags = 0;
7798 if (renderer->supportsTearing &&
7799 windowData->present_mode == SDL_GPU_PRESENTMODE_IMMEDIATE) {
7800 presentFlags = DXGI_PRESENT_ALLOW_TEARING;
7801 }
7802
7803 res = IDXGISwapChain_Present(
7804 windowData->swapchain,
7805 syncInterval,
7806 presentFlags);
7807 if (FAILED(res)) {
7808 result = false;
7809 }
7810
7811 ID3D12Resource_Release(windowData->textureContainers[presentData->swapchainImageIndex].activeTexture->resource);
7812#endif
7813
7814 windowData->inFlightFences[windowData->frameCounter] = (SDL_GPUFence*)d3d12CommandBuffer->inFlightFence;
7815 (void)SDL_AtomicIncRef(&d3d12CommandBuffer->inFlightFence->referenceCount);
7816 windowData->frameCounter = (windowData->frameCounter + 1) % renderer->allowedFramesInFlight;
7817 }
7818
7819 // Check for cleanups
7820 for (Sint32 i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) {
7821 Uint64 fenceValue = ID3D12Fence_GetCompletedValue(
7822 renderer->submittedCommandBuffers[i]->inFlightFence->handle);
7823
7824 if (fenceValue == D3D12_FENCE_SIGNAL_VALUE) {
7825 result &= D3D12_INTERNAL_CleanCommandBuffer(
7826 renderer,
7827 renderer->submittedCommandBuffers[i],
7828 false);
7829 }
7830 }
7831
7832 D3D12_INTERNAL_PerformPendingDestroys(renderer);
7833
7834 SDL_UnlockMutex(renderer->submitLock);
7835
7836 return result;
7837}
7838
7839static SDL_GPUFence *D3D12_SubmitAndAcquireFence(
7840 SDL_GPUCommandBuffer *commandBuffer)
7841{
7842 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
7843 d3d12CommandBuffer->autoReleaseFence = false;
7844 if (!D3D12_Submit(commandBuffer)) {
7845 return NULL;
7846 }
7847 return (SDL_GPUFence *)d3d12CommandBuffer->inFlightFence;
7848}
7849
7850static bool D3D12_Cancel(
7851 SDL_GPUCommandBuffer *commandBuffer)
7852{
7853 D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
7854 D3D12Renderer *renderer = d3d12CommandBuffer->renderer;
7855 bool result;
7856 HRESULT res;
7857
7858 // Notify the command buffer that we have completed recording
7859 res = ID3D12GraphicsCommandList_Close(d3d12CommandBuffer->graphicsCommandList);
7860 CHECK_D3D12_ERROR_AND_RETURN("Failed to close command list!", false);
7861
7862 d3d12CommandBuffer->autoReleaseFence = false;
7863 SDL_LockMutex(renderer->submitLock);
7864 result = D3D12_INTERNAL_CleanCommandBuffer(renderer, d3d12CommandBuffer, true);
7865 SDL_UnlockMutex(renderer->submitLock);
7866
7867 return result;
7868}
7869
7870static bool D3D12_Wait(
7871 SDL_GPURenderer *driverData)
7872{
7873 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
7874 D3D12Fence *fence = D3D12_INTERNAL_AcquireFence(renderer);
7875 if (!fence) {
7876 return false;
7877 }
7878 HRESULT res;
7879
7880 SDL_LockMutex(renderer->submitLock);
7881
7882 if (renderer->commandQueue) {
7883 // Insert a signal into the end of the command queue...
7884 ID3D12CommandQueue_Signal(
7885 renderer->commandQueue,
7886 fence->handle,
7887 D3D12_FENCE_SIGNAL_VALUE);
7888
7889 // ...and then block on it.
7890 if (ID3D12Fence_GetCompletedValue(fence->handle) != D3D12_FENCE_SIGNAL_VALUE) {
7891 res = ID3D12Fence_SetEventOnCompletion(
7892 fence->handle,
7893 D3D12_FENCE_SIGNAL_VALUE,
7894 fence->event);
7895 CHECK_D3D12_ERROR_AND_RETURN("Setting fence event failed", false);
7896
7897 DWORD waitResult = WaitForSingleObject(fence->event, INFINITE);
7898 if (waitResult == WAIT_FAILED) {
7899 SDL_UnlockMutex(renderer->submitLock);
7900 SET_STRING_ERROR_AND_RETURN("Wait failed", false); // TODO: is there a better way to report this?
7901 }
7902 }
7903 }
7904
7905 D3D12_ReleaseFence(
7906 (SDL_GPURenderer *)renderer,
7907 (SDL_GPUFence *)fence);
7908
7909 bool result = true;
7910
7911 // Clean up
7912 for (Sint32 i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) {
7913 result &= D3D12_INTERNAL_CleanCommandBuffer(renderer, renderer->submittedCommandBuffers[i], false);
7914 }
7915
7916 D3D12_INTERNAL_PerformPendingDestroys(renderer);
7917
7918 SDL_UnlockMutex(renderer->submitLock);
7919
7920 return result;
7921}
7922
7923static bool D3D12_WaitForFences(
7924 SDL_GPURenderer *driverData,
7925 bool waitAll,
7926 SDL_GPUFence *const *fences,
7927 Uint32 numFences)
7928{
7929 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
7930 D3D12Fence *fence;
7931 HANDLE *events = SDL_stack_alloc(HANDLE, numFences);
7932 HRESULT res;
7933
7934 SDL_LockMutex(renderer->submitLock);
7935
7936 for (Uint32 i = 0; i < numFences; i += 1) {
7937 fence = (D3D12Fence *)fences[i];
7938
7939 res = ID3D12Fence_SetEventOnCompletion(
7940 fence->handle,
7941 D3D12_FENCE_SIGNAL_VALUE,
7942 fence->event);
7943 CHECK_D3D12_ERROR_AND_RETURN("Setting fence event failed", false);
7944
7945 events[i] = fence->event;
7946 }
7947
7948 DWORD waitResult = WaitForMultipleObjects(
7949 numFences,
7950 events,
7951 waitAll,
7952 INFINITE);
7953
7954 if (waitResult == WAIT_FAILED) {
7955 SDL_UnlockMutex(renderer->submitLock);
7956 SET_STRING_ERROR_AND_RETURN("Wait failed", false); // TODO: is there a better way to report this?
7957 }
7958
7959 bool result = true;
7960
7961 // Check for cleanups
7962 for (Sint32 i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) {
7963 Uint64 fenceValue = ID3D12Fence_GetCompletedValue(
7964 renderer->submittedCommandBuffers[i]->inFlightFence->handle);
7965
7966 if (fenceValue == D3D12_FENCE_SIGNAL_VALUE) {
7967 result &= D3D12_INTERNAL_CleanCommandBuffer(
7968 renderer,
7969 renderer->submittedCommandBuffers[i],
7970 false);
7971 }
7972 }
7973
7974 D3D12_INTERNAL_PerformPendingDestroys(renderer);
7975
7976 SDL_stack_free(events);
7977
7978 SDL_UnlockMutex(renderer->submitLock);
7979
7980 return result;
7981}
7982
7983// Feature Queries
7984
7985static bool D3D12_SupportsTextureFormat(
7986 SDL_GPURenderer *driverData,
7987 SDL_GPUTextureFormat format,
7988 SDL_GPUTextureType type,
7989 SDL_GPUTextureUsageFlags usage)
7990{
7991 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
7992 DXGI_FORMAT dxgiFormat = SDLToD3D12_TextureFormat[format];
7993 D3D12_FEATURE_DATA_FORMAT_SUPPORT formatSupport = { dxgiFormat, D3D12_FORMAT_SUPPORT1_NONE, D3D12_FORMAT_SUPPORT2_NONE };
7994 HRESULT res;
7995
7996 res = ID3D12Device_CheckFeatureSupport(
7997 renderer->device,
7998 D3D12_FEATURE_FORMAT_SUPPORT,
7999 &formatSupport,
8000 sizeof(formatSupport));
8001 if (FAILED(res)) {
8002 // Format is apparently unknown
8003 return false;
8004 }
8005
8006 // Is the texture type supported?
8007 if (type == SDL_GPU_TEXTURETYPE_2D && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D)) {
8008 return false;
8009 }
8010 if (type == SDL_GPU_TEXTURETYPE_2D_ARRAY && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D)) {
8011 return false;
8012 }
8013 if (type == SDL_GPU_TEXTURETYPE_3D && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE3D)) {
8014 return false;
8015 }
8016 if (type == SDL_GPU_TEXTURETYPE_CUBE && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURECUBE)) {
8017 return false;
8018 }
8019 if (type == SDL_GPU_TEXTURETYPE_CUBE_ARRAY && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURECUBE)) {
8020 return false;
8021 }
8022
8023 // Are the usage flags supported?
8024 if ((usage & SDL_GPU_TEXTUREUSAGE_SAMPLER) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE)) {
8025 return false;
8026 }
8027 if ((usage & (SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ | SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ)) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_LOAD)) {
8028 return false;
8029 }
8030 if ((usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) && !(formatSupport.Support2 & D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE)) {
8031 return false;
8032 }
8033 if ((usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE) && !(formatSupport.Support2 & D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD)) {
8034 return false;
8035 }
8036 if ((usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_RENDER_TARGET)) {
8037 return false;
8038 }
8039
8040 // Special case check for depth, because D3D12 is great.
8041 formatSupport.Format = SDLToD3D12_DepthFormat[format];
8042 formatSupport.Support1 = D3D12_FORMAT_SUPPORT1_NONE;
8043 formatSupport.Support2 = D3D12_FORMAT_SUPPORT2_NONE;
8044
8045 res = ID3D12Device_CheckFeatureSupport(
8046 renderer->device,
8047 D3D12_FEATURE_FORMAT_SUPPORT,
8048 &formatSupport,
8049 sizeof(formatSupport));
8050 if (FAILED(res)) {
8051 // Format is apparently unknown
8052 return false;
8053 }
8054
8055 if ((usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) && !(formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL)) {
8056 return false;
8057 }
8058
8059 return true;
8060}
8061
8062static bool D3D12_SupportsSampleCount(
8063 SDL_GPURenderer *driverData,
8064 SDL_GPUTextureFormat format,
8065 SDL_GPUSampleCount sampleCount)
8066{
8067 D3D12Renderer *renderer = (D3D12Renderer *)driverData;
8068 D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS featureData;
8069 HRESULT res;
8070
8071#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
8072 featureData.Flags = (D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG)0;
8073#else
8074 featureData.Flags = (D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS)0;
8075#endif
8076 featureData.Format = SDLToD3D12_TextureFormat[format];
8077 featureData.SampleCount = SDLToD3D12_SampleCount[sampleCount];
8078 res = ID3D12Device_CheckFeatureSupport(
8079 renderer->device,
8080 D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
8081 &featureData,
8082 sizeof(featureData));
8083
8084 return SUCCEEDED(res) && featureData.NumQualityLevels > 0;
8085}
8086
8087static void D3D12_INTERNAL_InitBlitResources(
8088 D3D12Renderer *renderer)
8089{
8090 SDL_GPUShaderCreateInfo shaderCreateInfo;
8091 SDL_GPUSamplerCreateInfo samplerCreateInfo;
8092
8093 renderer->blitPipelineCapacity = 2;
8094 renderer->blitPipelineCount = 0;
8095 renderer->blitPipelines = (BlitPipelineCacheEntry *)SDL_malloc(
8096 renderer->blitPipelineCapacity * sizeof(BlitPipelineCacheEntry));
8097
8098 // Fullscreen vertex shader
8099 SDL_zero(shaderCreateInfo);
8100 shaderCreateInfo.code = (Uint8 *)D3D12_FullscreenVert;
8101 shaderCreateInfo.code_size = sizeof(D3D12_FullscreenVert);
8102 shaderCreateInfo.stage = SDL_GPU_SHADERSTAGE_VERTEX;
8103 shaderCreateInfo.format = SDL_GPU_SHADERFORMAT_DXBC;
8104 shaderCreateInfo.entrypoint = "main";
8105
8106 renderer->blitVertexShader = D3D12_CreateShader(
8107 (SDL_GPURenderer *)renderer,
8108 &shaderCreateInfo);
8109
8110 if (renderer->blitVertexShader == NULL) {
8111 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile vertex shader for blit!");
8112 }
8113
8114 // BlitFrom2D pixel shader
8115 shaderCreateInfo.code = (Uint8 *)D3D12_BlitFrom2D;
8116 shaderCreateInfo.code_size = sizeof(D3D12_BlitFrom2D);
8117 shaderCreateInfo.stage = SDL_GPU_SHADERSTAGE_FRAGMENT;
8118 shaderCreateInfo.num_samplers = 1;
8119 shaderCreateInfo.num_uniform_buffers = 1;
8120
8121 renderer->blitFrom2DShader = D3D12_CreateShader(
8122 (SDL_GPURenderer *)renderer,
8123 &shaderCreateInfo);
8124
8125 if (renderer->blitFrom2DShader == NULL) {
8126 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFrom2D pixel shader!");
8127 }
8128
8129 // BlitFrom2DArray pixel shader
8130 shaderCreateInfo.code = (Uint8 *)D3D12_BlitFrom2DArray;
8131 shaderCreateInfo.code_size = sizeof(D3D12_BlitFrom2DArray);
8132
8133 renderer->blitFrom2DArrayShader = D3D12_CreateShader(
8134 (SDL_GPURenderer *)renderer,
8135 &shaderCreateInfo);
8136
8137 if (renderer->blitFrom2DArrayShader == NULL) {
8138 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFrom2DArray pixel shader!");
8139 }
8140
8141 // BlitFrom3D pixel shader
8142 shaderCreateInfo.code = (Uint8 *)D3D12_BlitFrom3D;
8143 shaderCreateInfo.code_size = sizeof(D3D12_BlitFrom3D);
8144
8145 renderer->blitFrom3DShader = D3D12_CreateShader(
8146 (SDL_GPURenderer *)renderer,
8147 &shaderCreateInfo);
8148
8149 if (renderer->blitFrom3DShader == NULL) {
8150 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFrom3D pixel shader!");
8151 }
8152
8153 // BlitFromCube pixel shader
8154 shaderCreateInfo.code = (Uint8 *)D3D12_BlitFromCube;
8155 shaderCreateInfo.code_size = sizeof(D3D12_BlitFromCube);
8156
8157 renderer->blitFromCubeShader = D3D12_CreateShader(
8158 (SDL_GPURenderer *)renderer,
8159 &shaderCreateInfo);
8160
8161 if (renderer->blitFromCubeShader == NULL) {
8162 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFromCube pixel shader!");
8163 }
8164
8165 // BlitFromCubeArray pixel shader
8166 shaderCreateInfo.code = (Uint8 *)D3D12_BlitFromCubeArray;
8167 shaderCreateInfo.code_size = sizeof(D3D12_BlitFromCubeArray);
8168
8169 renderer->blitFromCubeArrayShader = D3D12_CreateShader(
8170 (SDL_GPURenderer *)renderer,
8171 &shaderCreateInfo);
8172
8173 if (renderer->blitFromCubeArrayShader == NULL) {
8174 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to compile BlitFromCubeArray pixel shader!");
8175 }
8176
8177 // Create samplers
8178 samplerCreateInfo.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
8179 samplerCreateInfo.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
8180 samplerCreateInfo.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
8181 samplerCreateInfo.enable_anisotropy = 0;
8182 samplerCreateInfo.enable_compare = 0;
8183 samplerCreateInfo.mag_filter = SDL_GPU_FILTER_NEAREST;
8184 samplerCreateInfo.min_filter = SDL_GPU_FILTER_NEAREST;
8185 samplerCreateInfo.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_NEAREST;
8186 samplerCreateInfo.mip_lod_bias = 0.0f;
8187 samplerCreateInfo.min_lod = 0;
8188 samplerCreateInfo.max_lod = 1000;
8189 samplerCreateInfo.max_anisotropy = 1.0f;
8190 samplerCreateInfo.compare_op = SDL_GPU_COMPAREOP_NEVER;
8191
8192 renderer->blitNearestSampler = D3D12_CreateSampler(
8193 (SDL_GPURenderer *)renderer,
8194 &samplerCreateInfo);
8195
8196 if (renderer->blitNearestSampler == NULL) {
8197 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create blit nearest sampler!");
8198 }
8199
8200 samplerCreateInfo.mag_filter = SDL_GPU_FILTER_LINEAR;
8201 samplerCreateInfo.min_filter = SDL_GPU_FILTER_LINEAR;
8202 samplerCreateInfo.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR;
8203
8204 renderer->blitLinearSampler = D3D12_CreateSampler(
8205 (SDL_GPURenderer *)renderer,
8206 &samplerCreateInfo);
8207
8208 if (renderer->blitLinearSampler == NULL) {
8209 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create blit linear sampler!");
8210 }
8211}
8212
8213static bool D3D12_PrepareDriver(SDL_VideoDevice *_this)
8214{
8215#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
8216 return true;
8217#else
8218 SDL_SharedObject *d3d12Dll;
8219 SDL_SharedObject *dxgiDll;
8220 PFN_D3D12_CREATE_DEVICE D3D12CreateDeviceFunc;
8221 PFN_CREATE_DXGI_FACTORY1 CreateDXGIFactoryFunc;
8222 HRESULT res;
8223 ID3D12Device *device;
8224 IDXGIFactory1 *factory;
8225 IDXGIFactory4 *factory4;
8226 IDXGIFactory6 *factory6;
8227 IDXGIAdapter1 *adapter;
8228
8229 // Can we load D3D12?
8230
8231 d3d12Dll = SDL_LoadObject(D3D12_DLL);
8232 if (d3d12Dll == NULL) {
8233 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Could not find " D3D12_DLL);
8234 return false;
8235 }
8236
8237 D3D12CreateDeviceFunc = (PFN_D3D12_CREATE_DEVICE)SDL_LoadFunction(
8238 d3d12Dll,
8239 D3D12_CREATE_DEVICE_FUNC);
8240 if (D3D12CreateDeviceFunc == NULL) {
8241 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Could not find function " D3D12_CREATE_DEVICE_FUNC " in " D3D12_DLL);
8242 SDL_UnloadObject(d3d12Dll);
8243 return false;
8244 }
8245
8246 // Can we load DXGI?
8247
8248 dxgiDll = SDL_LoadObject(DXGI_DLL);
8249 if (dxgiDll == NULL) {
8250 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Could not find " DXGI_DLL);
8251 return false;
8252 }
8253
8254 CreateDXGIFactoryFunc = (PFN_CREATE_DXGI_FACTORY1)SDL_LoadFunction(
8255 dxgiDll,
8256 CREATE_DXGI_FACTORY1_FUNC);
8257 if (CreateDXGIFactoryFunc == NULL) {
8258 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Could not find function " CREATE_DXGI_FACTORY1_FUNC " in " DXGI_DLL);
8259 SDL_UnloadObject(dxgiDll);
8260 return false;
8261 }
8262
8263 // Can we create a device?
8264
8265 // Create the DXGI factory
8266 res = CreateDXGIFactoryFunc(
8267 &D3D_IID_IDXGIFactory1,
8268 (void **)&factory);
8269 if (FAILED(res)) {
8270 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Could not create DXGIFactory");
8271 SDL_UnloadObject(d3d12Dll);
8272 SDL_UnloadObject(dxgiDll);
8273 return false;
8274 }
8275
8276 // Check for DXGI 1.4 support
8277 res = IDXGIFactory1_QueryInterface(
8278 factory,
8279 D3D_GUID(D3D_IID_IDXGIFactory4),
8280 (void **)&factory4);
8281 if (FAILED(res)) {
8282 IDXGIFactory1_Release(factory);
8283 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Failed to find DXGI1.4 support, required for DX12");
8284 SDL_UnloadObject(d3d12Dll);
8285 SDL_UnloadObject(dxgiDll);
8286 return false;
8287 }
8288 IDXGIFactory4_Release(factory4);
8289
8290 res = IDXGIFactory1_QueryInterface(
8291 factory,
8292 D3D_GUID(D3D_IID_IDXGIFactory6),
8293 (void **)&factory6);
8294 if (SUCCEEDED(res)) {
8295 res = IDXGIFactory6_EnumAdapterByGpuPreference(
8296 factory6,
8297 0,
8298 DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
8299 D3D_GUID(D3D_IID_IDXGIAdapter1),
8300 (void **)&adapter);
8301 IDXGIFactory6_Release(factory6);
8302 } else {
8303 res = IDXGIFactory1_EnumAdapters1(
8304 factory,
8305 0,
8306 &adapter);
8307 }
8308 if (FAILED(res)) {
8309 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Failed to find adapter for D3D12Device");
8310 IDXGIFactory1_Release(factory);
8311 SDL_UnloadObject(d3d12Dll);
8312 SDL_UnloadObject(dxgiDll);
8313 return false;
8314 }
8315
8316 res = D3D12CreateDeviceFunc(
8317 (IUnknown *)adapter,
8318 D3D_FEATURE_LEVEL_CHOICE,
8319 D3D_GUID(D3D_IID_ID3D12Device),
8320 (void **)&device);
8321
8322 if (SUCCEEDED(res)) {
8323 ID3D12Device_Release(device);
8324 }
8325 IDXGIAdapter1_Release(adapter);
8326 IDXGIFactory1_Release(factory);
8327
8328 SDL_UnloadObject(d3d12Dll);
8329 SDL_UnloadObject(dxgiDll);
8330
8331 if (FAILED(res)) {
8332 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Could not create D3D12Device with feature level " D3D_FEATURE_LEVEL_CHOICE_STR);
8333 return false;
8334 }
8335
8336 return true;
8337#endif
8338}
8339
8340#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)) && defined(HAVE_IDXGIINFOQUEUE)
8341static void D3D12_INTERNAL_TryInitializeDXGIDebug(D3D12Renderer *renderer)
8342{
8343 PFN_DXGI_GET_DEBUG_INTERFACE DXGIGetDebugInterfaceFunc;
8344 HRESULT res;
8345
8346 renderer->dxgidebug_dll = SDL_LoadObject(DXGIDEBUG_DLL);
8347 if (renderer->dxgidebug_dll == NULL) {
8348 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not find " DXGIDEBUG_DLL);
8349 return;
8350 }
8351
8352 DXGIGetDebugInterfaceFunc = (PFN_DXGI_GET_DEBUG_INTERFACE)SDL_LoadFunction(
8353 renderer->dxgidebug_dll,
8354 DXGI_GET_DEBUG_INTERFACE_FUNC);
8355 if (DXGIGetDebugInterfaceFunc == NULL) {
8356 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not load function: " DXGI_GET_DEBUG_INTERFACE_FUNC);
8357 return;
8358 }
8359
8360 res = DXGIGetDebugInterfaceFunc(&D3D_IID_IDXGIDebug, (void **)&renderer->dxgiDebug);
8361 if (FAILED(res)) {
8362 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not get IDXGIDebug interface");
8363 }
8364
8365 res = DXGIGetDebugInterfaceFunc(&D3D_IID_IDXGIInfoQueue, (void **)&renderer->dxgiInfoQueue);
8366 if (FAILED(res)) {
8367 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not get IDXGIInfoQueue interface");
8368 }
8369}
8370#endif
8371
8372static void D3D12_INTERNAL_TryInitializeD3D12Debug(D3D12Renderer *renderer)
8373{
8374 PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterfaceFunc;
8375 HRESULT res;
8376
8377 D3D12GetDebugInterfaceFunc = (PFN_D3D12_GET_DEBUG_INTERFACE)SDL_LoadFunction(
8378 renderer->d3d12_dll,
8379 D3D12_GET_DEBUG_INTERFACE_FUNC);
8380 if (D3D12GetDebugInterfaceFunc == NULL) {
8381 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not load function: " D3D12_GET_DEBUG_INTERFACE_FUNC);
8382 return;
8383 }
8384
8385 res = D3D12GetDebugInterfaceFunc(D3D_GUID(D3D_IID_ID3D12Debug), (void **)&renderer->d3d12Debug);
8386 if (FAILED(res)) {
8387 SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not get ID3D12Debug interface");
8388 return;
8389 }
8390
8391 ID3D12Debug_EnableDebugLayer(renderer->d3d12Debug);
8392}
8393
8394#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
8395static bool D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(D3D12Renderer *renderer)
8396{
8397 ID3D12InfoQueue *infoQueue = NULL;
8398 D3D12_MESSAGE_SEVERITY severities[] = { D3D12_MESSAGE_SEVERITY_INFO };
8399 D3D12_INFO_QUEUE_FILTER filter;
8400 HRESULT res;
8401
8402 res = ID3D12Device_QueryInterface(
8403 renderer->device,
8404 D3D_GUID(D3D_IID_ID3D12InfoQueue),
8405 (void **)&infoQueue);
8406 if (FAILED(res)) {
8407 CHECK_D3D12_ERROR_AND_RETURN("Failed to convert ID3D12Device to ID3D12InfoQueue", false);
8408 }
8409
8410 SDL_zero(filter);
8411 filter.DenyList.NumSeverities = 1;
8412 filter.DenyList.pSeverityList = severities;
8413 ID3D12InfoQueue_PushStorageFilter(
8414 infoQueue,
8415 &filter);
8416
8417 ID3D12InfoQueue_SetBreakOnSeverity(
8418 infoQueue,
8419 D3D12_MESSAGE_SEVERITY_CORRUPTION,
8420 true);
8421
8422 ID3D12InfoQueue_Release(infoQueue);
8423
8424 return true;
8425}
8426
8427static void WINAPI D3D12_INTERNAL_OnD3D12DebugInfoMsg(
8428 D3D12_MESSAGE_CATEGORY category,
8429 D3D12_MESSAGE_SEVERITY severity,
8430 D3D12_MESSAGE_ID id,
8431 LPCSTR description,
8432 void *context)
8433{
8434 char *catStr;
8435 char *sevStr;
8436
8437 switch (category) {
8438 case D3D12_MESSAGE_CATEGORY_APPLICATION_DEFINED:
8439 catStr = "APPLICATION_DEFINED";
8440 break;
8441 case D3D12_MESSAGE_CATEGORY_MISCELLANEOUS:
8442 catStr = "MISCELLANEOUS";
8443 break;
8444 case D3D12_MESSAGE_CATEGORY_INITIALIZATION:
8445 catStr = "INITIALIZATION";
8446 break;
8447 case D3D12_MESSAGE_CATEGORY_CLEANUP:
8448 catStr = "CLEANUP";
8449 break;
8450 case D3D12_MESSAGE_CATEGORY_COMPILATION:
8451 catStr = "COMPILATION";
8452 break;
8453 case D3D12_MESSAGE_CATEGORY_STATE_CREATION:
8454 catStr = "STATE_CREATION";
8455 break;
8456 case D3D12_MESSAGE_CATEGORY_STATE_SETTING:
8457 catStr = "STATE_SETTING";
8458 break;
8459 case D3D12_MESSAGE_CATEGORY_STATE_GETTING:
8460 catStr = "STATE_GETTING";
8461 break;
8462 case D3D12_MESSAGE_CATEGORY_RESOURCE_MANIPULATION:
8463 catStr = "RESOURCE_MANIPULATION";
8464 break;
8465 case D3D12_MESSAGE_CATEGORY_EXECUTION:
8466 catStr = "EXECUTION";
8467 break;
8468 case D3D12_MESSAGE_CATEGORY_SHADER:
8469 catStr = "SHADER";
8470 break;
8471 default:
8472 catStr = "UNKNOWN";
8473 break;
8474 }
8475
8476 switch (severity) {
8477 case D3D12_MESSAGE_SEVERITY_CORRUPTION:
8478 sevStr = "CORRUPTION";
8479 break;
8480 case D3D12_MESSAGE_SEVERITY_ERROR:
8481 sevStr = "ERROR";
8482 break;
8483 case D3D12_MESSAGE_SEVERITY_WARNING:
8484 sevStr = "WARNING";
8485 break;
8486 case D3D12_MESSAGE_SEVERITY_INFO:
8487 sevStr = "INFO";
8488 break;
8489 case D3D12_MESSAGE_SEVERITY_MESSAGE:
8490 sevStr = "MESSAGE";
8491 break;
8492 default:
8493 sevStr = "UNKNOWN";
8494 break;
8495 }
8496
8497 if (severity <= D3D12_MESSAGE_SEVERITY_ERROR) {
8498 SDL_LogError(
8499 SDL_LOG_CATEGORY_GPU,
8500 "D3D12 ERROR: %s [%s %s #%d]",
8501 description,
8502 catStr,
8503 sevStr,
8504 id);
8505 } else {
8506 SDL_LogWarn(
8507 SDL_LOG_CATEGORY_GPU,
8508 "D3D12 WARNING: %s [%s %s #%d]",
8509 description,
8510 catStr,
8511 sevStr,
8512 id);
8513 }
8514}
8515
8516static void D3D12_INTERNAL_TryInitializeD3D12DebugInfoLogger(D3D12Renderer *renderer)
8517{
8518 ID3D12InfoQueue1 *infoQueue = NULL;
8519 HRESULT res;
8520
8521 res = ID3D12Device_QueryInterface(
8522 renderer->device,
8523 D3D_GUID(D3D_IID_ID3D12InfoQueue1),
8524 (void **)&infoQueue);
8525 if (FAILED(res)) {
8526 return;
8527 }
8528
8529 ID3D12InfoQueue1_RegisterMessageCallback(
8530 infoQueue,
8531 D3D12_INTERNAL_OnD3D12DebugInfoMsg,
8532 D3D12_MESSAGE_CALLBACK_FLAG_NONE,
8533 NULL,
8534 NULL);
8535
8536 ID3D12InfoQueue1_Release(infoQueue);
8537}
8538#endif
8539
8540static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SDL_PropertiesID props)
8541{
8542 SDL_GPUDevice *result;
8543 D3D12Renderer *renderer;
8544 HRESULT res;
8545
8546#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
8547 PFN_D3D12_XBOX_CREATE_DEVICE D3D12XboxCreateDeviceFunc;
8548 D3D12XBOX_CREATE_DEVICE_PARAMETERS createDeviceParams;
8549#else
8550 PFN_CREATE_DXGI_FACTORY1 CreateDXGIFactoryFunc;
8551 IDXGIFactory1 *factory1;
8552 IDXGIFactory5 *factory5;
8553 IDXGIFactory6 *factory6;
8554 DXGI_ADAPTER_DESC1 adapterDesc;
8555 LARGE_INTEGER umdVersion;
8556 PFN_D3D12_CREATE_DEVICE D3D12CreateDeviceFunc;
8557#endif
8558 D3D12_FEATURE_DATA_ARCHITECTURE architecture;
8559 D3D12_COMMAND_QUEUE_DESC queueDesc;
8560
8561 renderer = (D3D12Renderer *)SDL_calloc(1, sizeof(D3D12Renderer));
8562
8563#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
8564 // Load the DXGI library
8565 renderer->dxgi_dll = SDL_LoadObject(DXGI_DLL);
8566 if (renderer->dxgi_dll == NULL) {
8567 D3D12_INTERNAL_DestroyRenderer(renderer);
8568 SET_STRING_ERROR_AND_RETURN("Could not find " DXGI_DLL, NULL);
8569 }
8570
8571#ifdef HAVE_IDXGIINFOQUEUE
8572 // Initialize the DXGI debug layer, if applicable
8573 if (debugMode) {
8574 D3D12_INTERNAL_TryInitializeDXGIDebug(renderer);
8575 }
8576#endif
8577
8578 // Load the CreateDXGIFactory1 function
8579 CreateDXGIFactoryFunc = (PFN_CREATE_DXGI_FACTORY1)SDL_LoadFunction(
8580 renderer->dxgi_dll,
8581 CREATE_DXGI_FACTORY1_FUNC);
8582 if (CreateDXGIFactoryFunc == NULL) {
8583 D3D12_INTERNAL_DestroyRenderer(renderer);
8584 SET_STRING_ERROR_AND_RETURN("Could not load function: " CREATE_DXGI_FACTORY1_FUNC, NULL);
8585 }
8586
8587 // Create the DXGI factory
8588 res = CreateDXGIFactoryFunc(
8589 &D3D_IID_IDXGIFactory1,
8590 (void **)&factory1);
8591 if (FAILED(res)) {
8592 D3D12_INTERNAL_DestroyRenderer(renderer);
8593 CHECK_D3D12_ERROR_AND_RETURN("Could not create DXGIFactory", NULL);
8594 }
8595
8596 // Check for DXGI 1.4 support
8597 res = IDXGIFactory1_QueryInterface(
8598 factory1,
8599 D3D_GUID(D3D_IID_IDXGIFactory4),
8600 (void **)&renderer->factory);
8601 if (FAILED(res)) {
8602 D3D12_INTERNAL_DestroyRenderer(renderer);
8603 CHECK_D3D12_ERROR_AND_RETURN("DXGI1.4 support not found, required for DX12", NULL);
8604 }
8605 IDXGIFactory1_Release(factory1);
8606
8607 // Check for explicit tearing support
8608 res = IDXGIFactory4_QueryInterface(
8609 renderer->factory,
8610 D3D_GUID(D3D_IID_IDXGIFactory5),
8611 (void **)&factory5);
8612 if (SUCCEEDED(res)) {
8613 res = IDXGIFactory5_CheckFeatureSupport(
8614 factory5,
8615 DXGI_FEATURE_PRESENT_ALLOW_TEARING,
8616 &renderer->supportsTearing,
8617 sizeof(renderer->supportsTearing));
8618 if (FAILED(res)) {
8619 renderer->supportsTearing = false;
8620 }
8621 IDXGIFactory5_Release(factory5);
8622 }
8623
8624 // Select the appropriate device for rendering
8625 res = IDXGIFactory4_QueryInterface(
8626 renderer->factory,
8627 D3D_GUID(D3D_IID_IDXGIFactory6),
8628 (void **)&factory6);
8629 if (SUCCEEDED(res)) {
8630 res = IDXGIFactory6_EnumAdapterByGpuPreference(
8631 factory6,
8632 0,
8633 preferLowPower ? DXGI_GPU_PREFERENCE_MINIMUM_POWER : DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
8634 D3D_GUID(D3D_IID_IDXGIAdapter1),
8635 (void **)&renderer->adapter);
8636 IDXGIFactory6_Release(factory6);
8637 } else {
8638 res = IDXGIFactory4_EnumAdapters1(
8639 renderer->factory,
8640 0,
8641 &renderer->adapter);
8642 }
8643
8644 if (FAILED(res)) {
8645 D3D12_INTERNAL_DestroyRenderer(renderer);
8646 CHECK_D3D12_ERROR_AND_RETURN("Could not find adapter for D3D12Device", NULL);
8647 }
8648
8649 // Get information about the selected adapter. Used for logging info.
8650 res = IDXGIAdapter1_GetDesc1(renderer->adapter, &adapterDesc);
8651 if (FAILED(res)) {
8652 D3D12_INTERNAL_DestroyRenderer(renderer);
8653 CHECK_D3D12_ERROR_AND_RETURN("Could not get adapter description", NULL);
8654 }
8655 res = IDXGIAdapter1_CheckInterfaceSupport(renderer->adapter, D3D_GUID(D3D_IID_IDXGIDevice), &umdVersion);
8656 if (FAILED(res)) {
8657 D3D12_INTERNAL_DestroyRenderer(renderer);
8658 CHECK_D3D12_ERROR_AND_RETURN("Could not get adapter driver version", NULL);
8659 }
8660
8661 SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: D3D12");
8662 SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "D3D12 Adapter: %S", adapterDesc.Description);
8663 SDL_LogInfo(
8664 SDL_LOG_CATEGORY_GPU,
8665 "D3D12 Driver: %d.%d.%d.%d",
8666 HIWORD(umdVersion.HighPart),
8667 LOWORD(umdVersion.HighPart),
8668 HIWORD(umdVersion.LowPart),
8669 LOWORD(umdVersion.LowPart));
8670#endif
8671
8672 // Load the D3D library
8673 renderer->d3d12_dll = SDL_LoadObject(D3D12_DLL);
8674 if (renderer->d3d12_dll == NULL) {
8675 D3D12_INTERNAL_DestroyRenderer(renderer);
8676 SET_STRING_ERROR_AND_RETURN("Could not find " D3D12_DLL, NULL);
8677 }
8678
8679 // Load the CreateDevice function
8680#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
8681 D3D12XboxCreateDeviceFunc = (PFN_D3D12_XBOX_CREATE_DEVICE)SDL_LoadFunction(
8682 renderer->d3d12_dll,
8683 "D3D12XboxCreateDevice");
8684 if (D3D12XboxCreateDeviceFunc == NULL) {
8685 D3D12_INTERNAL_DestroyRenderer(renderer);
8686 SET_STRING_ERROR_AND_RETURN("Could not load function: D3D12XboxCreateDevice", NULL);
8687 }
8688#else
8689 D3D12CreateDeviceFunc = (PFN_D3D12_CREATE_DEVICE)SDL_LoadFunction(
8690 renderer->d3d12_dll,
8691 D3D12_CREATE_DEVICE_FUNC);
8692 if (D3D12CreateDeviceFunc == NULL) {
8693 D3D12_INTERNAL_DestroyRenderer(renderer);
8694 SET_STRING_ERROR_AND_RETURN("Could not load function: " D3D12_CREATE_DEVICE_FUNC, NULL);
8695 }
8696#endif
8697
8698 renderer->D3D12SerializeRootSignature_func = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)SDL_LoadFunction(
8699 renderer->d3d12_dll,
8700 D3D12_SERIALIZE_ROOT_SIGNATURE_FUNC);
8701 if (renderer->D3D12SerializeRootSignature_func == NULL) {
8702 D3D12_INTERNAL_DestroyRenderer(renderer);
8703 SET_STRING_ERROR_AND_RETURN("Could not load function: " D3D12_SERIALIZE_ROOT_SIGNATURE_FUNC, NULL);
8704 }
8705
8706 // Initialize the D3D12 debug layer, if applicable
8707 if (debugMode) {
8708 D3D12_INTERNAL_TryInitializeD3D12Debug(renderer);
8709 }
8710
8711 // Create the D3D12Device
8712#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
8713 if (s_Device != NULL) {
8714 renderer->device = s_Device;
8715 } else {
8716 SDL_zero(createDeviceParams);
8717 createDeviceParams.Version = D3D12_SDK_VERSION;
8718 createDeviceParams.GraphicsCommandQueueRingSizeBytes = D3D12XBOX_DEFAULT_SIZE_BYTES;
8719 createDeviceParams.GraphicsScratchMemorySizeBytes = D3D12XBOX_DEFAULT_SIZE_BYTES;
8720 createDeviceParams.ComputeScratchMemorySizeBytes = D3D12XBOX_DEFAULT_SIZE_BYTES;
8721 createDeviceParams.DisableGeometryShaderAllocations = TRUE;
8722 createDeviceParams.DisableTessellationShaderAllocations = TRUE;
8723#if defined(SDL_PLATFORM_XBOXSERIES)
8724 createDeviceParams.DisableDXR = TRUE;
8725#endif
8726 if (debugMode) {
8727 createDeviceParams.ProcessDebugFlags = D3D12XBOX_PROCESS_DEBUG_FLAG_DEBUG;
8728 }
8729
8730 res = D3D12XboxCreateDeviceFunc(
8731 NULL,
8732 &createDeviceParams,
8733 IID_GRAPHICS_PPV_ARGS(&renderer->device));
8734 if (FAILED(res)) {
8735 D3D12_INTERNAL_DestroyRenderer(renderer);
8736 CHECK_D3D12_ERROR_AND_RETURN("Could not create D3D12Device", NULL);
8737 }
8738
8739 s_Device = renderer->device;
8740 }
8741#else
8742 res = D3D12CreateDeviceFunc(
8743 (IUnknown *)renderer->adapter,
8744 D3D_FEATURE_LEVEL_CHOICE,
8745 D3D_GUID(D3D_IID_ID3D12Device),
8746 (void **)&renderer->device);
8747
8748 if (FAILED(res)) {
8749 D3D12_INTERNAL_DestroyRenderer(renderer);
8750 CHECK_D3D12_ERROR_AND_RETURN("Could not create D3D12Device", NULL);
8751 }
8752
8753 // Initialize the D3D12 debug info queue, if applicable
8754 if (debugMode) {
8755 if (!D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(renderer)) {
8756 return NULL;
8757 }
8758 D3D12_INTERNAL_TryInitializeD3D12DebugInfoLogger(renderer);
8759 }
8760#endif
8761
8762 // Check UMA
8763 architecture.NodeIndex = 0;
8764 res = ID3D12Device_CheckFeatureSupport(
8765 renderer->device,
8766 D3D12_FEATURE_ARCHITECTURE,
8767 &architecture,
8768 sizeof(D3D12_FEATURE_DATA_ARCHITECTURE));
8769 if (FAILED(res)) {
8770 D3D12_INTERNAL_DestroyRenderer(renderer);
8771 CHECK_D3D12_ERROR_AND_RETURN("Could not get device architecture", NULL);
8772 }
8773
8774 renderer->UMA = (bool)architecture.UMA;
8775 renderer->UMACacheCoherent = (bool)architecture.CacheCoherentUMA;
8776
8777#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
8778 renderer->GPUUploadHeapSupported = false;
8779#else
8780 // Check "GPU Upload Heap" support (for fast uniform buffers)
8781 D3D12_FEATURE_DATA_D3D12_OPTIONS16 options16; // 15 wasn't enough, huh?
8782 renderer->GPUUploadHeapSupported = false;
8783 res = ID3D12Device_CheckFeatureSupport(
8784 renderer->device,
8785 D3D12_FEATURE_D3D12_OPTIONS16,
8786 &options16,
8787 sizeof(options16));
8788
8789 if (SUCCEEDED(res)) {
8790 renderer->GPUUploadHeapSupported = options16.GPUUploadHeapSupported;
8791 }
8792#endif
8793
8794 // Create command queue
8795#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
8796 if (s_CommandQueue != NULL) {
8797 renderer->commandQueue = s_CommandQueue;
8798 } else {
8799#endif
8800 queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
8801 queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
8802 queueDesc.NodeMask = 0;
8803 queueDesc.Priority = 0;
8804
8805 res = ID3D12Device_CreateCommandQueue(
8806 renderer->device,
8807 &queueDesc,
8808 D3D_GUID(D3D_IID_ID3D12CommandQueue),
8809 (void **)&renderer->commandQueue);
8810
8811 if (FAILED(res)) {
8812 D3D12_INTERNAL_DestroyRenderer(renderer);
8813 CHECK_D3D12_ERROR_AND_RETURN("Could not create D3D12CommandQueue", NULL);
8814 }
8815#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
8816 s_CommandQueue = renderer->commandQueue;
8817 }
8818#endif
8819
8820 // Create indirect command signatures
8821
8822 D3D12_COMMAND_SIGNATURE_DESC commandSignatureDesc;
8823 D3D12_INDIRECT_ARGUMENT_DESC indirectArgumentDesc;
8824 SDL_zero(indirectArgumentDesc);
8825
8826 indirectArgumentDesc.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;
8827 commandSignatureDesc.NodeMask = 0;
8828 commandSignatureDesc.ByteStride = sizeof(SDL_GPUIndirectDrawCommand);
8829 commandSignatureDesc.NumArgumentDescs = 1;
8830 commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
8831
8832 res = ID3D12Device_CreateCommandSignature(
8833 renderer->device,
8834 &commandSignatureDesc,
8835 NULL,
8836 D3D_GUID(D3D_IID_ID3D12CommandSignature),
8837 (void **)&renderer->indirectDrawCommandSignature);
8838 if (FAILED(res)) {
8839 D3D12_INTERNAL_DestroyRenderer(renderer);
8840 CHECK_D3D12_ERROR_AND_RETURN("Could not create indirect draw command signature", NULL);
8841 }
8842
8843 indirectArgumentDesc.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
8844 commandSignatureDesc.ByteStride = sizeof(SDL_GPUIndexedIndirectDrawCommand);
8845 commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
8846
8847 res = ID3D12Device_CreateCommandSignature(
8848 renderer->device,
8849 &commandSignatureDesc,
8850 NULL,
8851 D3D_GUID(D3D_IID_ID3D12CommandSignature),
8852 (void **)&renderer->indirectIndexedDrawCommandSignature);
8853 if (FAILED(res)) {
8854 D3D12_INTERNAL_DestroyRenderer(renderer);
8855 CHECK_D3D12_ERROR_AND_RETURN("Could not create indirect indexed draw command signature", NULL);
8856 }
8857
8858 indirectArgumentDesc.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH;
8859 commandSignatureDesc.ByteStride = sizeof(SDL_GPUIndirectDispatchCommand);
8860 commandSignatureDesc.pArgumentDescs = &indirectArgumentDesc;
8861
8862 res = ID3D12Device_CreateCommandSignature(
8863 renderer->device,
8864 &commandSignatureDesc,
8865 NULL,
8866 D3D_GUID(D3D_IID_ID3D12CommandSignature),
8867 (void **)&renderer->indirectDispatchCommandSignature);
8868 if (FAILED(res)) {
8869 D3D12_INTERNAL_DestroyRenderer(renderer);
8870 CHECK_D3D12_ERROR_AND_RETURN("Could not create indirect dispatch command signature", NULL);
8871 }
8872
8873 // Initialize pools
8874
8875 renderer->submittedCommandBufferCapacity = 4;
8876 renderer->submittedCommandBufferCount = 0;
8877 renderer->submittedCommandBuffers = (D3D12CommandBuffer **)SDL_calloc(
8878 renderer->submittedCommandBufferCapacity, sizeof(D3D12CommandBuffer *));
8879 if (!renderer->submittedCommandBuffers) {
8880 D3D12_INTERNAL_DestroyRenderer(renderer);
8881 return NULL;
8882 }
8883
8884 renderer->uniformBufferPoolCapacity = 4;
8885 renderer->uniformBufferPoolCount = 0;
8886 renderer->uniformBufferPool = (D3D12UniformBuffer **)SDL_calloc(
8887 renderer->uniformBufferPoolCapacity, sizeof(D3D12UniformBuffer *));
8888 if (!renderer->uniformBufferPool) {
8889 D3D12_INTERNAL_DestroyRenderer(renderer);
8890 return NULL;
8891 }
8892
8893 renderer->claimedWindowCapacity = 4;
8894 renderer->claimedWindowCount = 0;
8895 renderer->claimedWindows = (D3D12WindowData **)SDL_calloc(
8896 renderer->claimedWindowCapacity, sizeof(D3D12WindowData *));
8897 if (!renderer->claimedWindows) {
8898 D3D12_INTERNAL_DestroyRenderer(renderer);
8899 return NULL;
8900 }
8901
8902 renderer->availableFenceCapacity = 4;
8903 renderer->availableFenceCount = 0;
8904 renderer->availableFences = (D3D12Fence **)SDL_calloc(
8905 renderer->availableFenceCapacity, sizeof(D3D12Fence *));
8906 if (!renderer->availableFences) {
8907 D3D12_INTERNAL_DestroyRenderer(renderer);
8908 return NULL;
8909 }
8910
8911 // Initialize staging descriptor pools
8912 for (Uint32 i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; i += 1) {
8913 renderer->stagingDescriptorPools[i] = D3D12_INTERNAL_CreateStagingDescriptorPool(
8914 renderer,
8915 (D3D12_DESCRIPTOR_HEAP_TYPE)i);
8916
8917 if (renderer->stagingDescriptorPools[i] == NULL) {
8918 D3D12_INTERNAL_DestroyRenderer(renderer);
8919 return NULL;
8920 }
8921 }
8922
8923 // Initialize GPU descriptor heaps
8924 for (Uint32 i = 0; i < 2; i += 1) {
8925 renderer->gpuDescriptorHeapPools[i].lock = SDL_CreateMutex();
8926 renderer->gpuDescriptorHeapPools[i].capacity = 4;
8927 renderer->gpuDescriptorHeapPools[i].count = 4;
8928 renderer->gpuDescriptorHeapPools[i].heaps = (D3D12DescriptorHeap **)SDL_calloc(
8929 renderer->gpuDescriptorHeapPools[i].capacity, sizeof(D3D12DescriptorHeap *));
8930
8931 for (Uint32 j = 0; j < renderer->gpuDescriptorHeapPools[i].capacity; j += 1) {
8932 renderer->gpuDescriptorHeapPools[i].heaps[j] = D3D12_INTERNAL_CreateDescriptorHeap(
8933 renderer,
8934 (D3D12_DESCRIPTOR_HEAP_TYPE)i,
8935 i == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV ? VIEW_GPU_DESCRIPTOR_COUNT : SAMPLER_GPU_DESCRIPTOR_COUNT,
8936 false);
8937
8938 if (renderer->gpuDescriptorHeapPools[i].heaps[j] == NULL) {
8939 D3D12_INTERNAL_DestroyRenderer(renderer);
8940 return NULL;
8941 }
8942 }
8943 }
8944
8945 // Deferred resource releasing
8946
8947 renderer->buffersToDestroyCapacity = 4;
8948 renderer->buffersToDestroyCount = 0;
8949 renderer->buffersToDestroy = (D3D12Buffer **)SDL_calloc(
8950 renderer->buffersToDestroyCapacity, sizeof(D3D12Buffer *));
8951 if (!renderer->buffersToDestroy) {
8952 D3D12_INTERNAL_DestroyRenderer(renderer);
8953 return NULL;
8954 }
8955
8956 renderer->texturesToDestroyCapacity = 4;
8957 renderer->texturesToDestroyCount = 0;
8958 renderer->texturesToDestroy = (D3D12Texture **)SDL_calloc(
8959 renderer->texturesToDestroyCapacity, sizeof(D3D12Texture *));
8960 if (!renderer->texturesToDestroy) {
8961 D3D12_INTERNAL_DestroyRenderer(renderer);
8962 return NULL;
8963 }
8964
8965 renderer->samplersToDestroyCapacity = 4;
8966 renderer->samplersToDestroyCount = 0;
8967 renderer->samplersToDestroy = (D3D12Sampler **)SDL_calloc(
8968 renderer->samplersToDestroyCapacity, sizeof(D3D12Sampler *));
8969 if (!renderer->samplersToDestroy) {
8970 D3D12_INTERNAL_DestroyRenderer(renderer);
8971 return NULL;
8972 }
8973
8974 renderer->graphicsPipelinesToDestroyCapacity = 4;
8975 renderer->graphicsPipelinesToDestroyCount = 0;
8976 renderer->graphicsPipelinesToDestroy = (D3D12GraphicsPipeline **)SDL_calloc(
8977 renderer->graphicsPipelinesToDestroyCapacity, sizeof(D3D12GraphicsPipeline *));
8978 if (!renderer->graphicsPipelinesToDestroy) {
8979 D3D12_INTERNAL_DestroyRenderer(renderer);
8980 return NULL;
8981 }
8982
8983 renderer->computePipelinesToDestroyCapacity = 4;
8984 renderer->computePipelinesToDestroyCount = 0;
8985 renderer->computePipelinesToDestroy = (D3D12ComputePipeline **)SDL_calloc(
8986 renderer->computePipelinesToDestroyCapacity, sizeof(D3D12ComputePipeline *));
8987 if (!renderer->computePipelinesToDestroy) {
8988 D3D12_INTERNAL_DestroyRenderer(renderer);
8989 return NULL;
8990 }
8991
8992 // Locks
8993 renderer->acquireCommandBufferLock = SDL_CreateMutex();
8994 renderer->acquireUniformBufferLock = SDL_CreateMutex();
8995 renderer->submitLock = SDL_CreateMutex();
8996 renderer->windowLock = SDL_CreateMutex();
8997 renderer->fenceLock = SDL_CreateMutex();
8998 renderer->disposeLock = SDL_CreateMutex();
8999
9000 renderer->debug_mode = debugMode;
9001 renderer->allowedFramesInFlight = 2;
9002
9003 renderer->semantic = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING, "TEXCOORD");
9004
9005 // Blit resources
9006 D3D12_INTERNAL_InitBlitResources(renderer);
9007
9008#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
9009 res = renderer->device->SetFrameIntervalX(
9010 NULL,
9011 D3D12XBOX_FRAME_INTERVAL_60_HZ,
9012 renderer->allowedFramesInFlight - 1,
9013 D3D12XBOX_FRAME_INTERVAL_FLAG_NONE);
9014 if (FAILED(res)) {
9015 D3D12_INTERNAL_DestroyRenderer(renderer);
9016 CHECK_D3D12_ERROR_AND_RETURN("Could not get set frame interval", NULL);
9017 }
9018
9019 res = renderer->device->ScheduleFrameEventX(
9020 D3D12XBOX_FRAME_EVENT_ORIGIN,
9021 0,
9022 NULL,
9023 D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE);
9024 if (FAILED(res)) {
9025 D3D12_INTERNAL_DestroyRenderer(renderer);
9026 CHECK_D3D12_ERROR_AND_RETURN("Could not schedule frame events", NULL);
9027 }
9028#endif
9029
9030 // Create the SDL_GPU Device
9031 result = (SDL_GPUDevice *)SDL_calloc(1, sizeof(SDL_GPUDevice));
9032
9033 if (!result) {
9034 D3D12_INTERNAL_DestroyRenderer(renderer);
9035 return NULL;
9036 }
9037
9038 ASSIGN_DRIVER(D3D12)
9039 result->driverData = (SDL_GPURenderer *)renderer;
9040 result->debug_mode = debugMode;
9041 renderer->sdlGPUDevice = result;
9042
9043 return result;
9044}
9045
9046SDL_GPUBootstrap D3D12Driver = {
9047 "direct3d12",
9048 SDL_GPU_SHADERFORMAT_DXIL | SDL_GPU_SHADERFORMAT_DXBC,
9049 D3D12_PrepareDriver,
9050 D3D12_CreateDevice
9051};
9052
9053#endif // SDL_GPU_D3D12
9054
9055// GDK-specific APIs
9056
9057#ifdef SDL_PLATFORM_GDK
9058
9059void SDL_GDKSuspendGPU(SDL_GPUDevice *device)
9060{
9061#if defined(SDL_GPU_D3D12) && (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
9062 D3D12Renderer *renderer = (D3D12Renderer *)device->driverData;
9063 HRESULT res;
9064 if (device == NULL) {
9065 SET_STRING_ERROR_AND_RETURN("Invalid GPU device", );
9066 }
9067
9068 SDL_LockMutex(renderer->submitLock);
9069 res = renderer->commandQueue->SuspendX(0);
9070 if (FAILED(res)) {
9071 SDL_LogError(SDL_LOG_CATEGORY_GPU, "SuspendX failed: %X", res);
9072 }
9073 SDL_UnlockMutex(renderer->submitLock);
9074#endif
9075}
9076
9077void SDL_GDKResumeGPU(SDL_GPUDevice *device)
9078{
9079#if defined(SDL_GPU_D3D12) && (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
9080 D3D12Renderer *renderer = (D3D12Renderer *)device->driverData;
9081 HRESULT res;
9082 if (device == NULL) {
9083 SET_STRING_ERROR_AND_RETURN("Invalid GPU device", );
9084 }
9085
9086 SDL_LockMutex(renderer->submitLock);
9087 res = renderer->commandQueue->ResumeX();
9088 if (FAILED(res)) {
9089 SDL_LogError(SDL_LOG_CATEGORY_GPU, "ResumeX failed: %X", res);
9090 }
9091 SDL_UnlockMutex(renderer->submitLock);
9092
9093 res = renderer->device->SetFrameIntervalX(
9094 NULL,
9095 D3D12XBOX_FRAME_INTERVAL_60_HZ,
9096 renderer->allowedFramesInFlight - 1,
9097 D3D12XBOX_FRAME_INTERVAL_FLAG_NONE);
9098 if (FAILED(res)) {
9099 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not set frame interval: %X", res);
9100 }
9101
9102 res = renderer->device->ScheduleFrameEventX(
9103 D3D12XBOX_FRAME_EVENT_ORIGIN,
9104 0,
9105 NULL,
9106 D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE);
9107 if (FAILED(res)) {
9108 SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not schedule frame events: %X", res);
9109 }
9110#endif
9111}
9112
9113#endif // SDL_PLATFORM_GDK
diff --git a/contrib/SDL-3.2.8/src/gpu/d3d12/compile_shaders.bat b/contrib/SDL-3.2.8/src/gpu/d3d12/compile_shaders.bat
new file mode 100644
index 0000000..7aa78ef
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/gpu/d3d12/compile_shaders.bat
@@ -0,0 +1,18 @@
1rem This script runs for the Windows build, but also via the _xbox variant with these vars set.
2rem Make sure to default to building for Windows if they're not set.
3if %DXC%.==. set DXC=dxc
4if %SUFFIX%.==. set SUFFIX=.h
5
6echo Building with %DXC%
7echo Suffix %SUFFIX%
8
9cd "%~dp0"
10
11%DXC% -E FullscreenVert -T vs_6_0 -Fh D3D12_FullscreenVert.h D3D_Blit.hlsl
12%DXC% -E BlitFrom2D -T ps_6_0 -Fh D3D12_BlitFrom2D.h D3D_Blit.hlsl
13%DXC% -E BlitFrom2DArray -T ps_6_0 -Fh D3D12_BlitFrom2DArray.h D3D_Blit.hlsl
14%DXC% -E BlitFrom3D -T ps_6_0 -Fh D3D12_BlitFrom3D.h D3D_Blit.hlsl
15%DXC% -E BlitFromCube -T ps_6_0 -Fh D3D12_BlitFromCube.h D3D_Blit.hlsl
16%DXC% -E BlitFromCubeArray -T ps_6_0 -Fh D3D12_BlitFromCubeArray.h D3D_Blit.hlsl
17copy /b D3D12_FullscreenVert.h+D3D12_BlitFrom2D.h+D3D12_BlitFrom2DArray.h+D3D12_BlitFrom3D.h+D3D12_BlitFromCube.h+D3D12_BlitFromCubeArray.h D3D12_Blit%SUFFIX%
18del D3D12_FullscreenVert.h D3D12_BlitFrom2D.h D3D12_BlitFrom2DArray.h D3D12_BlitFrom3D.h D3D12_BlitFromCube.h D3D12_BlitFromCubeArray.h
diff --git a/contrib/SDL-3.2.8/src/gpu/d3d12/compile_shaders_xbox.bat b/contrib/SDL-3.2.8/src/gpu/d3d12/compile_shaders_xbox.bat
new file mode 100644
index 0000000..311b172
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/gpu/d3d12/compile_shaders_xbox.bat
@@ -0,0 +1,13 @@
1if %2.==one. goto setxboxone
2rem Xbox Series compile
3set DXC="%GameDKLatest%\GXDK\bin\Scarlett\DXC.exe"
4set SUFFIX=_Series.h
5goto startbuild
6
7:setxboxone
8set DXC="%GameDKLatest%\GXDK\bin\XboxOne\DXC.exe"
9set SUFFIX=_One.h
10
11:startbuild
12
13call "%~dp0\compile_shaders.bat"