1 use hal::format::Format;
2 use hal::image::{Anisotropic, Filter, WrapMode};
3 use hal::pso::{
4 BlendDesc,
5 BlendOp,
6 ColorBlendDesc,
7 Comparison,
8 DepthBias,
9 DepthStencilDesc,
10 Face,
11 Factor,
12 FrontFace,
13 InputAssemblerDesc,
14 PolygonMode,
15 Rasterizer,
16 Rect,
17 Sided,
18 Stage,
19 State,
20 StencilFace,
21 StencilOp,
22 StencilValue,
23 Viewport,
24 };
25 use hal::IndexType;
26
27 use spirv_cross::spirv;
28
29 use winapi::shared::dxgiformat::*;
30 use winapi::shared::minwindef::{FALSE, INT, TRUE};
31
32 use winapi::um::d3d11::*;
33 use winapi::um::d3dcommon::*;
34
35 use std::mem;
36
map_index_type(ty: IndexType) -> DXGI_FORMAT37 pub fn map_index_type(ty: IndexType) -> DXGI_FORMAT {
38 match ty {
39 IndexType::U16 => DXGI_FORMAT_R16_UINT,
40 IndexType::U32 => DXGI_FORMAT_R32_UINT,
41 }
42 }
43
44 // TODO: add aspect parameter
viewable_format(format: DXGI_FORMAT) -> DXGI_FORMAT45 pub fn viewable_format(format: DXGI_FORMAT) -> DXGI_FORMAT {
46 match format {
47 DXGI_FORMAT_D32_FLOAT_S8X24_UINT => DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS,
48 DXGI_FORMAT_D32_FLOAT => DXGI_FORMAT_R32_FLOAT,
49 DXGI_FORMAT_D16_UNORM => DXGI_FORMAT_R16_UNORM,
50 _ => format,
51 }
52 }
53
54 // TODO: stolen from d3d12 backend, maybe share function somehow?
map_format(format: Format) -> Option<DXGI_FORMAT>55 pub fn map_format(format: Format) -> Option<DXGI_FORMAT> {
56 use hal::format::Format::*;
57
58 let format = match format {
59 R5g6b5Unorm => DXGI_FORMAT_B5G6R5_UNORM,
60 R5g5b5a1Unorm => DXGI_FORMAT_B5G5R5A1_UNORM,
61 R8Unorm => DXGI_FORMAT_R8_UNORM,
62 R8Snorm => DXGI_FORMAT_R8_SNORM,
63 R8Uint => DXGI_FORMAT_R8_UINT,
64 R8Sint => DXGI_FORMAT_R8_SINT,
65 Rg8Unorm => DXGI_FORMAT_R8G8_UNORM,
66 Rg8Snorm => DXGI_FORMAT_R8G8_SNORM,
67 Rg8Uint => DXGI_FORMAT_R8G8_UINT,
68 Rg8Sint => DXGI_FORMAT_R8G8_SINT,
69 Rgba8Unorm => DXGI_FORMAT_R8G8B8A8_UNORM,
70 Rgba8Snorm => DXGI_FORMAT_R8G8B8A8_SNORM,
71 Rgba8Uint => DXGI_FORMAT_R8G8B8A8_UINT,
72 Rgba8Sint => DXGI_FORMAT_R8G8B8A8_SINT,
73 Rgba8Srgb => DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
74 Bgra8Unorm => DXGI_FORMAT_B8G8R8A8_UNORM,
75 Bgra8Srgb => DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
76 A2b10g10r10Unorm => DXGI_FORMAT_R10G10B10A2_UNORM,
77 A2b10g10r10Uint => DXGI_FORMAT_R10G10B10A2_UINT,
78 R16Unorm => DXGI_FORMAT_R16_UNORM,
79 R16Snorm => DXGI_FORMAT_R16_SNORM,
80 R16Uint => DXGI_FORMAT_R16_UINT,
81 R16Sint => DXGI_FORMAT_R16_SINT,
82 R16Sfloat => DXGI_FORMAT_R16_FLOAT,
83 Rg16Unorm => DXGI_FORMAT_R16G16_UNORM,
84 Rg16Snorm => DXGI_FORMAT_R16G16_SNORM,
85 Rg16Uint => DXGI_FORMAT_R16G16_UINT,
86 Rg16Sint => DXGI_FORMAT_R16G16_SINT,
87 Rg16Sfloat => DXGI_FORMAT_R16G16_FLOAT,
88 Rgba16Unorm => DXGI_FORMAT_R16G16B16A16_UNORM,
89 Rgba16Snorm => DXGI_FORMAT_R16G16B16A16_SNORM,
90 Rgba16Uint => DXGI_FORMAT_R16G16B16A16_UINT,
91 Rgba16Sint => DXGI_FORMAT_R16G16B16A16_SINT,
92 Rgba16Sfloat => DXGI_FORMAT_R16G16B16A16_FLOAT,
93 R32Uint => DXGI_FORMAT_R32_UINT,
94 R32Sint => DXGI_FORMAT_R32_SINT,
95 R32Sfloat => DXGI_FORMAT_R32_FLOAT,
96 Rg32Uint => DXGI_FORMAT_R32G32_UINT,
97 Rg32Sint => DXGI_FORMAT_R32G32_SINT,
98 Rg32Sfloat => DXGI_FORMAT_R32G32_FLOAT,
99 Rgb32Uint => DXGI_FORMAT_R32G32B32_UINT,
100 Rgb32Sint => DXGI_FORMAT_R32G32B32_SINT,
101 Rgb32Sfloat => DXGI_FORMAT_R32G32B32_FLOAT,
102 Rgba32Uint => DXGI_FORMAT_R32G32B32A32_UINT,
103 Rgba32Sint => DXGI_FORMAT_R32G32B32A32_SINT,
104 Rgba32Sfloat => DXGI_FORMAT_R32G32B32A32_FLOAT,
105 B10g11r11Ufloat => DXGI_FORMAT_R11G11B10_FLOAT,
106 E5b9g9r9Ufloat => DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
107 D16Unorm => DXGI_FORMAT_D16_UNORM,
108 D32Sfloat => DXGI_FORMAT_D32_FLOAT,
109 D32SfloatS8Uint => DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
110 Bc1RgbUnorm => DXGI_FORMAT_BC1_UNORM,
111 Bc1RgbSrgb => DXGI_FORMAT_BC1_UNORM_SRGB,
112 Bc2Unorm => DXGI_FORMAT_BC2_UNORM,
113 Bc2Srgb => DXGI_FORMAT_BC2_UNORM_SRGB,
114 Bc3Unorm => DXGI_FORMAT_BC3_UNORM,
115 Bc3Srgb => DXGI_FORMAT_BC3_UNORM_SRGB,
116 Bc4Unorm => DXGI_FORMAT_BC4_UNORM,
117 Bc4Snorm => DXGI_FORMAT_BC4_SNORM,
118 Bc5Unorm => DXGI_FORMAT_BC5_UNORM,
119 Bc5Snorm => DXGI_FORMAT_BC5_SNORM,
120 Bc6hUfloat => DXGI_FORMAT_BC6H_UF16,
121 Bc6hSfloat => DXGI_FORMAT_BC6H_SF16,
122 Bc7Unorm => DXGI_FORMAT_BC7_UNORM,
123 Bc7Srgb => DXGI_FORMAT_BC7_UNORM_SRGB,
124
125 _ => return None,
126 };
127
128 Some(format)
129 }
130
map_format_nosrgb(format: Format) -> Option<DXGI_FORMAT>131 pub fn map_format_nosrgb(format: Format) -> Option<DXGI_FORMAT> {
132 // NOTE: DXGI doesn't allow sRGB format on the swapchain, but
133 // creating RTV of swapchain buffers with sRGB works
134 match format {
135 Format::Bgra8Srgb => Some(DXGI_FORMAT_B8G8R8A8_UNORM),
136 Format::Rgba8Srgb => Some(DXGI_FORMAT_R8G8B8A8_UNORM),
137 _ => map_format(format),
138 }
139 }
140
141 #[derive(Debug, Clone)]
142 pub struct DecomposedDxgiFormat {
143 pub typeless: DXGI_FORMAT,
144 pub srv: Option<DXGI_FORMAT>,
145 pub rtv: Option<DXGI_FORMAT>,
146 pub uav: Option<DXGI_FORMAT>,
147 pub dsv: Option<DXGI_FORMAT>,
148 // the format we use internally for operating on textures (eg. Rgba8 uses R32 internally for
149 // copies)
150 pub copy_uav: Option<DXGI_FORMAT>,
151 pub copy_srv: Option<DXGI_FORMAT>,
152 }
153
154 impl DecomposedDxgiFormat {
155 pub const UNKNOWN: DecomposedDxgiFormat = DecomposedDxgiFormat {
156 typeless: DXGI_FORMAT_UNKNOWN,
157 srv: None,
158 rtv: None,
159 uav: None,
160 dsv: None,
161 copy_uav: None,
162 copy_srv: None,
163 };
164
165 // TODO: we probably want to pass in usage flags or similar to allow for our `typeless_format`
166 // field to only contain the input format (eg. depth only rather than typeless likely
167 // improves perf since the driver doesn't need to expose internals)
168 //
169 // TODO: we also want aspect for determining depth/stencil
from_dxgi_format(format: DXGI_FORMAT) -> DecomposedDxgiFormat170 pub fn from_dxgi_format(format: DXGI_FORMAT) -> DecomposedDxgiFormat {
171 match format {
172 DXGI_FORMAT_R8G8B8A8_UNORM
173 | DXGI_FORMAT_R8G8B8A8_SNORM
174 | DXGI_FORMAT_R8G8B8A8_UINT
175 | DXGI_FORMAT_R8G8B8A8_SINT
176 | DXGI_FORMAT_R8G8B8A8_UNORM_SRGB => DecomposedDxgiFormat {
177 typeless: DXGI_FORMAT_R8G8B8A8_TYPELESS,
178 srv: Some(format),
179 rtv: Some(format),
180 uav: Some(format),
181 dsv: None,
182 copy_uav: Some(DXGI_FORMAT_R32_UINT),
183 copy_srv: Some(DXGI_FORMAT_R8G8B8A8_UINT),
184 },
185
186 DXGI_FORMAT_B8G8R8A8_UNORM | DXGI_FORMAT_B8G8R8A8_UNORM_SRGB => DecomposedDxgiFormat {
187 typeless: DXGI_FORMAT_B8G8R8A8_TYPELESS,
188 srv: Some(format),
189 rtv: Some(format),
190 uav: Some(DXGI_FORMAT_B8G8R8A8_UNORM),
191 dsv: None,
192 copy_uav: Some(DXGI_FORMAT_R32_UINT),
193 copy_srv: Some(DXGI_FORMAT_B8G8R8A8_UNORM),
194 },
195
196 DXGI_FORMAT_A8_UNORM => DecomposedDxgiFormat {
197 typeless: format,
198 srv: Some(format),
199 rtv: Some(format),
200 uav: Some(format),
201 dsv: None,
202 copy_uav: Some(format),
203 copy_srv: Some(format),
204 },
205
206 DXGI_FORMAT_R8_UNORM | DXGI_FORMAT_R8_SNORM | DXGI_FORMAT_R8_UINT
207 | DXGI_FORMAT_R8_SINT => DecomposedDxgiFormat {
208 typeless: DXGI_FORMAT_R8_TYPELESS,
209 srv: Some(format),
210 rtv: Some(format),
211 uav: Some(format),
212 dsv: None,
213 copy_uav: Some(DXGI_FORMAT_R8_UINT),
214 copy_srv: Some(DXGI_FORMAT_R8_UINT),
215 },
216
217 DXGI_FORMAT_R8G8_UNORM
218 | DXGI_FORMAT_R8G8_SNORM
219 | DXGI_FORMAT_R8G8_UINT
220 | DXGI_FORMAT_R8G8_SINT => DecomposedDxgiFormat {
221 typeless: DXGI_FORMAT_R8G8_TYPELESS,
222 srv: Some(format),
223 rtv: Some(format),
224 uav: Some(format),
225 dsv: None,
226 copy_uav: Some(DXGI_FORMAT_R8G8_UINT),
227 copy_srv: Some(DXGI_FORMAT_R8G8_UINT),
228 },
229
230 DXGI_FORMAT_D16_UNORM => DecomposedDxgiFormat {
231 typeless: DXGI_FORMAT_R16_TYPELESS,
232 srv: Some(DXGI_FORMAT_R16_FLOAT),
233 rtv: Some(DXGI_FORMAT_R16_FLOAT),
234 uav: Some(DXGI_FORMAT_R16_FLOAT),
235 dsv: Some(format),
236 copy_uav: Some(DXGI_FORMAT_R16_UINT),
237 copy_srv: Some(DXGI_FORMAT_R16_UINT),
238 },
239
240 DXGI_FORMAT_R16_UNORM
241 | DXGI_FORMAT_R16_SNORM
242 | DXGI_FORMAT_R16_UINT
243 | DXGI_FORMAT_R16_SINT
244 | DXGI_FORMAT_R16_FLOAT => DecomposedDxgiFormat {
245 typeless: DXGI_FORMAT_R16_TYPELESS,
246 srv: Some(format),
247 rtv: Some(format),
248 uav: Some(format),
249 dsv: Some(DXGI_FORMAT_D16_UNORM),
250 copy_uav: Some(DXGI_FORMAT_R16_UINT),
251 copy_srv: Some(DXGI_FORMAT_R16_UINT),
252 },
253
254 DXGI_FORMAT_R16G16_UNORM
255 | DXGI_FORMAT_R16G16_SNORM
256 | DXGI_FORMAT_R16G16_UINT
257 | DXGI_FORMAT_R16G16_SINT
258 | DXGI_FORMAT_R16G16_FLOAT => DecomposedDxgiFormat {
259 typeless: DXGI_FORMAT_R16G16_TYPELESS,
260 srv: Some(format),
261 rtv: Some(format),
262 uav: Some(format),
263 dsv: None,
264 copy_uav: Some(DXGI_FORMAT_R32_UINT),
265 copy_srv: Some(DXGI_FORMAT_R16G16_UINT),
266 },
267
268 DXGI_FORMAT_R16G16B16A16_UNORM
269 | DXGI_FORMAT_R16G16B16A16_SNORM
270 | DXGI_FORMAT_R16G16B16A16_UINT
271 | DXGI_FORMAT_R16G16B16A16_SINT
272 | DXGI_FORMAT_R16G16B16A16_FLOAT => DecomposedDxgiFormat {
273 typeless: DXGI_FORMAT_R16G16B16A16_TYPELESS,
274 srv: Some(format),
275 rtv: Some(format),
276 uav: Some(format),
277 dsv: None,
278 copy_uav: Some(DXGI_FORMAT_R16G16B16A16_UINT),
279 copy_srv: Some(DXGI_FORMAT_R16G16B16A16_UINT),
280 },
281
282 DXGI_FORMAT_D32_FLOAT_S8X24_UINT => DecomposedDxgiFormat {
283 typeless: DXGI_FORMAT_R32G8X24_TYPELESS,
284 // TODO: depth or stencil?
285 srv: Some(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS),
286 rtv: None,
287 uav: None,
288 dsv: Some(format),
289 copy_uav: None,
290 copy_srv: Some(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS),
291 },
292
293 DXGI_FORMAT_D32_FLOAT => DecomposedDxgiFormat {
294 typeless: DXGI_FORMAT_R32_TYPELESS,
295 srv: Some(DXGI_FORMAT_R32_FLOAT),
296 rtv: None,
297 uav: None,
298 dsv: Some(format),
299 copy_uav: Some(DXGI_FORMAT_R32_UINT),
300 copy_srv: Some(DXGI_FORMAT_R32_UINT),
301 },
302
303 DXGI_FORMAT_R32_UINT | DXGI_FORMAT_R32_SINT | DXGI_FORMAT_R32_FLOAT => {
304 DecomposedDxgiFormat {
305 typeless: DXGI_FORMAT_R32_TYPELESS,
306 srv: Some(format),
307 rtv: Some(format),
308 uav: Some(format),
309 dsv: Some(DXGI_FORMAT_D32_FLOAT),
310 copy_uav: Some(DXGI_FORMAT_R32_UINT),
311 copy_srv: Some(DXGI_FORMAT_R32_UINT),
312 }
313 }
314
315 DXGI_FORMAT_R32G32_UINT | DXGI_FORMAT_R32G32_SINT | DXGI_FORMAT_R32G32_FLOAT => {
316 DecomposedDxgiFormat {
317 typeless: DXGI_FORMAT_R32G32_TYPELESS,
318 srv: Some(format),
319 rtv: Some(format),
320 uav: Some(format),
321 dsv: None,
322 copy_uav: Some(DXGI_FORMAT_R32G32_UINT),
323 copy_srv: Some(DXGI_FORMAT_R32G32_UINT),
324 }
325 }
326
327 // TODO: should we just convert to Rgba32 internally?
328 DXGI_FORMAT_R32G32B32_UINT
329 | DXGI_FORMAT_R32G32B32_SINT
330 | DXGI_FORMAT_R32G32B32_FLOAT => DecomposedDxgiFormat {
331 typeless: DXGI_FORMAT_R32G32_TYPELESS,
332 srv: Some(format),
333 rtv: None,
334 uav: None,
335 dsv: None,
336 copy_uav: Some(DXGI_FORMAT_R32G32B32_UINT),
337 copy_srv: Some(DXGI_FORMAT_R32G32B32_UINT),
338 },
339
340 DXGI_FORMAT_R32G32B32A32_UINT
341 | DXGI_FORMAT_R32G32B32A32_SINT
342 | DXGI_FORMAT_R32G32B32A32_FLOAT => DecomposedDxgiFormat {
343 typeless: DXGI_FORMAT_R32G32B32A32_TYPELESS,
344 srv: Some(format),
345 rtv: Some(format),
346 uav: Some(format),
347 dsv: None,
348 copy_uav: Some(DXGI_FORMAT_R32G32B32A32_UINT),
349 copy_srv: Some(DXGI_FORMAT_R32G32B32A32_UINT),
350 },
351
352 DXGI_FORMAT_R10G10B10A2_UNORM | DXGI_FORMAT_R10G10B10A2_UINT => DecomposedDxgiFormat {
353 typeless: DXGI_FORMAT_R10G10B10A2_TYPELESS,
354 srv: Some(format),
355 rtv: Some(format),
356 uav: Some(format),
357 dsv: None,
358 copy_uav: Some(DXGI_FORMAT_R32_UINT),
359 copy_srv: Some(DXGI_FORMAT_R10G10B10A2_UINT),
360 },
361
362 DXGI_FORMAT_R11G11B10_FLOAT => DecomposedDxgiFormat {
363 typeless: format,
364 srv: Some(format),
365 rtv: Some(format),
366 uav: Some(format),
367 dsv: None,
368 copy_uav: Some(format),
369 copy_srv: Some(format),
370 },
371
372 DXGI_FORMAT_R9G9B9E5_SHAREDEXP => DecomposedDxgiFormat {
373 typeless: format,
374 srv: Some(format),
375 rtv: None,
376 uav: None,
377 dsv: None,
378 // NOTE: read only
379 copy_uav: None,
380 copy_srv: Some(format),
381 },
382
383 DXGI_FORMAT_BC1_UNORM | DXGI_FORMAT_BC1_UNORM_SRGB => DecomposedDxgiFormat {
384 typeless: DXGI_FORMAT_BC1_TYPELESS,
385 srv: Some(format),
386 rtv: None,
387 uav: None,
388 dsv: None,
389 // NOTE: read only
390 copy_uav: None,
391 copy_srv: Some(format),
392 },
393
394 DXGI_FORMAT_BC2_UNORM | DXGI_FORMAT_BC2_UNORM_SRGB => DecomposedDxgiFormat {
395 typeless: DXGI_FORMAT_BC2_TYPELESS,
396 srv: Some(format),
397 rtv: None,
398 uav: None,
399 dsv: None,
400 // NOTE: read only
401 copy_uav: None,
402 copy_srv: Some(format),
403 },
404
405 DXGI_FORMAT_BC3_UNORM | DXGI_FORMAT_BC3_UNORM_SRGB => DecomposedDxgiFormat {
406 typeless: DXGI_FORMAT_BC3_TYPELESS,
407 srv: Some(format),
408 rtv: None,
409 uav: None,
410 dsv: None,
411 // NOTE: read only
412 copy_uav: None,
413 copy_srv: Some(format),
414 },
415
416 DXGI_FORMAT_BC4_UNORM | DXGI_FORMAT_BC4_SNORM => DecomposedDxgiFormat {
417 typeless: DXGI_FORMAT_BC4_TYPELESS,
418 srv: Some(format),
419 rtv: None,
420 uav: None,
421 dsv: None,
422 // NOTE: read only
423 copy_uav: None,
424 copy_srv: Some(format),
425 },
426
427 DXGI_FORMAT_BC5_UNORM | DXGI_FORMAT_BC5_SNORM => DecomposedDxgiFormat {
428 typeless: format,
429 srv: Some(format),
430 rtv: None,
431 uav: None,
432 dsv: None,
433 // NOTE: read only
434 copy_uav: None,
435 copy_srv: Some(format),
436 },
437
438 DXGI_FORMAT_BC6H_UF16 | DXGI_FORMAT_BC6H_SF16 => DecomposedDxgiFormat {
439 typeless: DXGI_FORMAT_BC6H_TYPELESS,
440 srv: Some(format),
441 rtv: None,
442 uav: None,
443 dsv: None,
444 // NOTE: read only
445 copy_uav: None,
446 copy_srv: Some(format),
447 },
448
449 // TODO: srgb craziness
450 DXGI_FORMAT_BC7_UNORM | DXGI_FORMAT_BC7_UNORM_SRGB => DecomposedDxgiFormat {
451 typeless: DXGI_FORMAT_BC7_TYPELESS,
452 srv: Some(format),
453 rtv: None,
454 uav: None,
455 dsv: None,
456 // NOTE: read only
457 copy_uav: None,
458 copy_srv: Some(format),
459 },
460
461 _ => unimplemented!(),
462 }
463 }
464 }
465
map_viewport(viewport: &Viewport) -> D3D11_VIEWPORT466 pub fn map_viewport(viewport: &Viewport) -> D3D11_VIEWPORT {
467 D3D11_VIEWPORT {
468 TopLeftX: viewport.rect.x as _,
469 TopLeftY: viewport.rect.y as _,
470 Width: viewport.rect.w as _,
471 Height: viewport.rect.h as _,
472 MinDepth: viewport.depth.start,
473 MaxDepth: viewport.depth.end,
474 }
475 }
476
map_rect(rect: &Rect) -> D3D11_RECT477 pub fn map_rect(rect: &Rect) -> D3D11_RECT {
478 D3D11_RECT {
479 left: rect.x as _,
480 top: rect.y as _,
481 right: (rect.x + rect.w) as _,
482 bottom: (rect.y + rect.h) as _,
483 }
484 }
485
map_topology(ia: &InputAssemblerDesc) -> D3D11_PRIMITIVE_TOPOLOGY486 pub fn map_topology(ia: &InputAssemblerDesc) -> D3D11_PRIMITIVE_TOPOLOGY {
487 use hal::pso::Primitive::*;
488 match (ia.primitive, ia.with_adjacency) {
489 (PointList, false) => D3D_PRIMITIVE_TOPOLOGY_POINTLIST,
490 (PointList, true) => panic!("Points can't have adjacency info"),
491 (LineList, false) => D3D_PRIMITIVE_TOPOLOGY_LINELIST,
492 (LineList, true) => D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
493 (LineStrip, false) => D3D_PRIMITIVE_TOPOLOGY_LINESTRIP,
494 (LineStrip, true) => D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
495 (TriangleList, false) => D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
496 (TriangleList, true) => D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ,
497 (TriangleStrip, false) => D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
498 (TriangleStrip, true) => D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ,
499 (PatchList(num), false) => {
500 assert!(num != 0);
501 D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + (num as u32) - 1
502 }
503 (_, true) => panic!("Patches can't have adjacency info"),
504 }
505 }
506
map_fill_mode(mode: PolygonMode) -> D3D11_FILL_MODE507 fn map_fill_mode(mode: PolygonMode) -> D3D11_FILL_MODE {
508 match mode {
509 PolygonMode::Fill => D3D11_FILL_SOLID,
510 PolygonMode::Line(_) => D3D11_FILL_WIREFRAME,
511 // TODO: return error
512 _ => unimplemented!(),
513 }
514 }
515
map_cull_mode(mode: Face) -> D3D11_CULL_MODE516 fn map_cull_mode(mode: Face) -> D3D11_CULL_MODE {
517 match mode {
518 Face::NONE => D3D11_CULL_NONE,
519 Face::FRONT => D3D11_CULL_FRONT,
520 Face::BACK => D3D11_CULL_BACK,
521 _ => panic!("Culling both front and back faces is not supported"),
522 }
523 }
524
map_rasterizer_desc(desc: &Rasterizer) -> D3D11_RASTERIZER_DESC525 pub(crate) fn map_rasterizer_desc(desc: &Rasterizer) -> D3D11_RASTERIZER_DESC {
526 let bias = match desc.depth_bias {
527 //TODO: support dynamic depth bias
528 Some(State::Static(db)) => db,
529 Some(_) | None => DepthBias::default(),
530 };
531 D3D11_RASTERIZER_DESC {
532 FillMode: map_fill_mode(desc.polygon_mode),
533 CullMode: map_cull_mode(desc.cull_face),
534 FrontCounterClockwise: match desc.front_face {
535 FrontFace::Clockwise => FALSE,
536 FrontFace::CounterClockwise => TRUE,
537 },
538 DepthBias: bias.const_factor as INT,
539 DepthBiasClamp: bias.clamp,
540 SlopeScaledDepthBias: bias.slope_factor,
541 DepthClipEnable: !desc.depth_clamping as _,
542 // TODO:
543 ScissorEnable: TRUE,
544 // TODO: msaa
545 MultisampleEnable: FALSE,
546 // TODO: line aa?
547 AntialiasedLineEnable: FALSE,
548 // TODO: conservative raster in >=11.x
549 }
550 }
551
map_blend_factor(factor: Factor) -> D3D11_BLEND552 fn map_blend_factor(factor: Factor) -> D3D11_BLEND {
553 match factor {
554 Factor::Zero => D3D11_BLEND_ZERO,
555 Factor::One => D3D11_BLEND_ONE,
556 Factor::SrcColor => D3D11_BLEND_SRC_COLOR,
557 Factor::OneMinusSrcColor => D3D11_BLEND_INV_SRC_COLOR,
558 Factor::DstColor => D3D11_BLEND_DEST_COLOR,
559 Factor::OneMinusDstColor => D3D11_BLEND_INV_DEST_COLOR,
560 Factor::SrcAlpha => D3D11_BLEND_SRC_ALPHA,
561 Factor::OneMinusSrcAlpha => D3D11_BLEND_INV_SRC_ALPHA,
562 Factor::DstAlpha => D3D11_BLEND_DEST_ALPHA,
563 Factor::OneMinusDstAlpha => D3D11_BLEND_INV_DEST_ALPHA,
564 Factor::ConstColor | Factor::ConstAlpha => D3D11_BLEND_BLEND_FACTOR,
565 Factor::OneMinusConstColor | Factor::OneMinusConstAlpha => D3D11_BLEND_INV_BLEND_FACTOR,
566 Factor::SrcAlphaSaturate => D3D11_BLEND_SRC_ALPHA_SAT,
567 Factor::Src1Color => D3D11_BLEND_SRC1_COLOR,
568 Factor::OneMinusSrc1Color => D3D11_BLEND_INV_SRC1_COLOR,
569 Factor::Src1Alpha => D3D11_BLEND_SRC1_ALPHA,
570 Factor::OneMinusSrc1Alpha => D3D11_BLEND_INV_SRC1_ALPHA,
571 }
572 }
573
map_alpha_blend_factor(factor: Factor) -> D3D11_BLEND574 fn map_alpha_blend_factor(factor: Factor) -> D3D11_BLEND {
575 match factor {
576 Factor::Zero => D3D11_BLEND_ZERO,
577 Factor::One => D3D11_BLEND_ONE,
578 Factor::SrcColor | Factor::SrcAlpha => D3D11_BLEND_SRC_ALPHA,
579 Factor::DstColor | Factor::DstAlpha => D3D11_BLEND_DEST_ALPHA,
580 Factor::OneMinusSrcColor | Factor::OneMinusSrcAlpha => D3D11_BLEND_INV_SRC_ALPHA,
581 Factor::OneMinusDstColor | Factor::OneMinusDstAlpha => D3D11_BLEND_INV_DEST_ALPHA,
582 Factor::ConstColor | Factor::ConstAlpha => D3D11_BLEND_BLEND_FACTOR,
583 Factor::OneMinusConstColor | Factor::OneMinusConstAlpha => D3D11_BLEND_INV_BLEND_FACTOR,
584 Factor::SrcAlphaSaturate => D3D11_BLEND_SRC_ALPHA_SAT,
585 Factor::Src1Color | Factor::Src1Alpha => D3D11_BLEND_SRC1_ALPHA,
586 Factor::OneMinusSrc1Color | Factor::OneMinusSrc1Alpha => D3D11_BLEND_INV_SRC1_ALPHA,
587 }
588 }
589
map_blend_op(operation: BlendOp) -> (D3D11_BLEND_OP, D3D11_BLEND, D3D11_BLEND)590 fn map_blend_op(operation: BlendOp) -> (D3D11_BLEND_OP, D3D11_BLEND, D3D11_BLEND) {
591 match operation {
592 BlendOp::Add { src, dst } => (
593 D3D11_BLEND_OP_ADD,
594 map_blend_factor(src),
595 map_blend_factor(dst),
596 ),
597 BlendOp::Sub { src, dst } => (
598 D3D11_BLEND_OP_SUBTRACT,
599 map_blend_factor(src),
600 map_blend_factor(dst),
601 ),
602 BlendOp::RevSub { src, dst } => (
603 D3D11_BLEND_OP_REV_SUBTRACT,
604 map_blend_factor(src),
605 map_blend_factor(dst),
606 ),
607 BlendOp::Min => (D3D11_BLEND_OP_MIN, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO),
608 BlendOp::Max => (D3D11_BLEND_OP_MAX, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO),
609 }
610 }
611
map_alpha_blend_op(operation: BlendOp) -> (D3D11_BLEND_OP, D3D11_BLEND, D3D11_BLEND)612 fn map_alpha_blend_op(operation: BlendOp) -> (D3D11_BLEND_OP, D3D11_BLEND, D3D11_BLEND) {
613 match operation {
614 BlendOp::Add { src, dst } => (
615 D3D11_BLEND_OP_ADD,
616 map_alpha_blend_factor(src),
617 map_alpha_blend_factor(dst),
618 ),
619 BlendOp::Sub { src, dst } => (
620 D3D11_BLEND_OP_SUBTRACT,
621 map_alpha_blend_factor(src),
622 map_alpha_blend_factor(dst),
623 ),
624 BlendOp::RevSub { src, dst } => (
625 D3D11_BLEND_OP_REV_SUBTRACT,
626 map_alpha_blend_factor(src),
627 map_alpha_blend_factor(dst),
628 ),
629 BlendOp::Min => (D3D11_BLEND_OP_MIN, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO),
630 BlendOp::Max => (D3D11_BLEND_OP_MAX, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO),
631 }
632 }
633
map_blend_targets( render_target_blends: &[ColorBlendDesc], ) -> [D3D11_RENDER_TARGET_BLEND_DESC; 8]634 fn map_blend_targets(
635 render_target_blends: &[ColorBlendDesc],
636 ) -> [D3D11_RENDER_TARGET_BLEND_DESC; 8] {
637 let mut targets: [D3D11_RENDER_TARGET_BLEND_DESC; 8] = [unsafe { mem::zeroed() }; 8];
638
639 for (mut target, color_desc) in targets.iter_mut().zip(render_target_blends.iter()) {
640 target.RenderTargetWriteMask = color_desc.mask.bits() as _;
641 if let Some(ref blend) = color_desc.blend {
642 let (color_op, color_src, color_dst) = map_blend_op(blend.color);
643 let (alpha_op, alpha_src, alpha_dst) = map_alpha_blend_op(blend.alpha);
644 target.BlendEnable = TRUE;
645 target.BlendOp = color_op;
646 target.SrcBlend = color_src;
647 target.DestBlend = color_dst;
648 target.BlendOpAlpha = alpha_op;
649 target.SrcBlendAlpha = alpha_src;
650 target.DestBlendAlpha = alpha_dst;
651 }
652 }
653
654 targets
655 }
656
map_blend_desc(desc: &BlendDesc) -> D3D11_BLEND_DESC657 pub(crate) fn map_blend_desc(desc: &BlendDesc) -> D3D11_BLEND_DESC {
658 D3D11_BLEND_DESC {
659 // TODO: msaa
660 AlphaToCoverageEnable: FALSE,
661 IndependentBlendEnable: TRUE,
662 RenderTarget: map_blend_targets(&desc.targets),
663 }
664 }
665
map_comparison(func: Comparison) -> D3D11_COMPARISON_FUNC666 pub fn map_comparison(func: Comparison) -> D3D11_COMPARISON_FUNC {
667 match func {
668 Comparison::Never => D3D11_COMPARISON_NEVER,
669 Comparison::Less => D3D11_COMPARISON_LESS,
670 Comparison::LessEqual => D3D11_COMPARISON_LESS_EQUAL,
671 Comparison::Equal => D3D11_COMPARISON_EQUAL,
672 Comparison::GreaterEqual => D3D11_COMPARISON_GREATER_EQUAL,
673 Comparison::Greater => D3D11_COMPARISON_GREATER,
674 Comparison::NotEqual => D3D11_COMPARISON_NOT_EQUAL,
675 Comparison::Always => D3D11_COMPARISON_ALWAYS,
676 }
677 }
678
map_stencil_op(op: StencilOp) -> D3D11_STENCIL_OP679 fn map_stencil_op(op: StencilOp) -> D3D11_STENCIL_OP {
680 match op {
681 StencilOp::Keep => D3D11_STENCIL_OP_KEEP,
682 StencilOp::Zero => D3D11_STENCIL_OP_ZERO,
683 StencilOp::Replace => D3D11_STENCIL_OP_REPLACE,
684 StencilOp::IncrementClamp => D3D11_STENCIL_OP_INCR_SAT,
685 StencilOp::IncrementWrap => D3D11_STENCIL_OP_INCR,
686 StencilOp::DecrementClamp => D3D11_STENCIL_OP_DECR_SAT,
687 StencilOp::DecrementWrap => D3D11_STENCIL_OP_DECR,
688 StencilOp::Invert => D3D11_STENCIL_OP_INVERT,
689 }
690 }
691
map_stencil_side(side: &StencilFace) -> D3D11_DEPTH_STENCILOP_DESC692 fn map_stencil_side(side: &StencilFace) -> D3D11_DEPTH_STENCILOP_DESC {
693 D3D11_DEPTH_STENCILOP_DESC {
694 StencilFailOp: map_stencil_op(side.op_fail),
695 StencilDepthFailOp: map_stencil_op(side.op_depth_fail),
696 StencilPassOp: map_stencil_op(side.op_pass),
697 StencilFunc: map_comparison(side.fun),
698 }
699 }
700
map_depth_stencil_desc( desc: &DepthStencilDesc, ) -> (D3D11_DEPTH_STENCIL_DESC, State<StencilValue>)701 pub(crate) fn map_depth_stencil_desc(
702 desc: &DepthStencilDesc,
703 ) -> (D3D11_DEPTH_STENCIL_DESC, State<StencilValue>) {
704 let (depth_on, depth_write, depth_func) = match desc.depth {
705 Some(ref depth) => (TRUE, depth.write, map_comparison(depth.fun)),
706 None => unsafe { mem::zeroed() },
707 };
708
709 let (stencil_on, front, back, read_mask, write_mask, stencil_ref) = match desc.stencil {
710 Some(ref stencil) => {
711 let read_masks = stencil.read_masks.static_or(Sided::new(!0));
712 let write_masks = stencil.read_masks.static_or(Sided::new(!0));
713 let reference_value = match stencil.reference_values {
714 State::Static(ref values) => {
715 if values.front != values.back {
716 error!("Different reference values for front ({}) and back ({}) of the stencil",
717 values.front, values.back);
718 }
719 State::Static(values.front)
720 }
721 State::Dynamic => State::Dynamic,
722 };
723 // TODO: cascade to create_pipeline
724 if read_masks.front != read_masks.back || write_masks.front != write_masks.back {
725 error!(
726 "Different sides are specified for read ({:?} and write ({:?}) stencil masks",
727 read_masks, write_masks
728 );
729 }
730 (
731 TRUE,
732 map_stencil_side(&stencil.faces.front),
733 map_stencil_side(&stencil.faces.back),
734 read_masks.front,
735 write_masks.front,
736 reference_value,
737 )
738 }
739 None => unsafe { mem::zeroed() },
740 };
741
742 (
743 D3D11_DEPTH_STENCIL_DESC {
744 DepthEnable: depth_on,
745 DepthWriteMask: if depth_write {
746 D3D11_DEPTH_WRITE_MASK_ALL
747 } else {
748 D3D11_DEPTH_WRITE_MASK_ZERO
749 },
750 DepthFunc: depth_func,
751 StencilEnable: stencil_on,
752 StencilReadMask: read_mask as _,
753 StencilWriteMask: write_mask as _,
754 FrontFace: front,
755 BackFace: back,
756 },
757 stencil_ref,
758 )
759 }
760
map_execution_model(model: spirv::ExecutionModel) -> Stage761 pub fn map_execution_model(model: spirv::ExecutionModel) -> Stage {
762 match model {
763 spirv::ExecutionModel::Vertex => Stage::Vertex,
764 spirv::ExecutionModel::Fragment => Stage::Fragment,
765 spirv::ExecutionModel::Geometry => Stage::Geometry,
766 spirv::ExecutionModel::GlCompute => Stage::Compute,
767 spirv::ExecutionModel::TessellationControl => Stage::Hull,
768 spirv::ExecutionModel::TessellationEvaluation => Stage::Domain,
769 spirv::ExecutionModel::Kernel => panic!("Kernel is not a valid execution model."),
770 }
771 }
772
map_stage(stage: Stage) -> spirv::ExecutionModel773 pub fn map_stage(stage: Stage) -> spirv::ExecutionModel {
774 match stage {
775 Stage::Vertex => spirv::ExecutionModel::Vertex,
776 Stage::Fragment => spirv::ExecutionModel::Fragment,
777 Stage::Geometry => spirv::ExecutionModel::Geometry,
778 Stage::Compute => spirv::ExecutionModel::GlCompute,
779 Stage::Hull => spirv::ExecutionModel::TessellationControl,
780 Stage::Domain => spirv::ExecutionModel::TessellationEvaluation,
781 }
782 }
783
map_wrapping(wrap: WrapMode) -> D3D11_TEXTURE_ADDRESS_MODE784 pub fn map_wrapping(wrap: WrapMode) -> D3D11_TEXTURE_ADDRESS_MODE {
785 match wrap {
786 WrapMode::Tile => D3D11_TEXTURE_ADDRESS_WRAP,
787 WrapMode::Mirror => D3D11_TEXTURE_ADDRESS_MIRROR,
788 WrapMode::Clamp => D3D11_TEXTURE_ADDRESS_CLAMP,
789 WrapMode::Border => D3D11_TEXTURE_ADDRESS_BORDER,
790 }
791 }
792
map_anisotropic(anisotropic: Anisotropic) -> D3D11_FILTER793 pub fn map_anisotropic(anisotropic: Anisotropic) -> D3D11_FILTER {
794 match anisotropic {
795 Anisotropic::On(_) => D3D11_FILTER_ANISOTROPIC,
796 Anisotropic::Off => 0,
797 }
798 }
799
map_filter_type(filter: Filter) -> D3D11_FILTER_TYPE800 fn map_filter_type(filter: Filter) -> D3D11_FILTER_TYPE {
801 match filter {
802 Filter::Nearest => D3D11_FILTER_TYPE_POINT,
803 Filter::Linear => D3D11_FILTER_TYPE_LINEAR,
804 }
805 }
806
807 // Hopefully works just as well in d3d11 :)
map_filter( mag_filter: Filter, min_filter: Filter, mip_filter: Filter, reduction: D3D11_FILTER_REDUCTION_TYPE, anisotropic: Anisotropic, ) -> D3D11_FILTER808 pub fn map_filter(
809 mag_filter: Filter,
810 min_filter: Filter,
811 mip_filter: Filter,
812 reduction: D3D11_FILTER_REDUCTION_TYPE,
813 anisotropic: Anisotropic,
814 ) -> D3D11_FILTER {
815 let mag = map_filter_type(mag_filter);
816 let min = map_filter_type(min_filter);
817 let mip = map_filter_type(mip_filter);
818
819 (min & D3D11_FILTER_TYPE_MASK) << D3D11_MIN_FILTER_SHIFT
820 | (mag & D3D11_FILTER_TYPE_MASK) << D3D11_MAG_FILTER_SHIFT
821 | (mip & D3D11_FILTER_TYPE_MASK) << D3D11_MIP_FILTER_SHIFT
822 | (reduction & D3D11_FILTER_REDUCTION_TYPE_MASK) << D3D11_FILTER_REDUCTION_TYPE_SHIFT
823 | map_anisotropic(anisotropic)
824 }
825