1 use std::iter;
2 use winapi::{
3 shared::{dxgi1_2, dxgiformat},
4 um::{d3d12, d3dcommon},
5 };
6
map_texture_format(format: wgt::TextureFormat) -> dxgiformat::DXGI_FORMAT7 pub(super) fn map_texture_format(format: wgt::TextureFormat) -> dxgiformat::DXGI_FORMAT {
8 use wgt::TextureFormat as Tf;
9 use winapi::shared::dxgiformat::*;
10
11 match format {
12 Tf::R8Unorm => DXGI_FORMAT_R8_UNORM,
13 Tf::R8Snorm => DXGI_FORMAT_R8_SNORM,
14 Tf::R8Uint => DXGI_FORMAT_R8_UINT,
15 Tf::R8Sint => DXGI_FORMAT_R8_SINT,
16 Tf::R16Uint => DXGI_FORMAT_R16_UINT,
17 Tf::R16Sint => DXGI_FORMAT_R16_SINT,
18 Tf::R16Unorm => DXGI_FORMAT_R16_UNORM,
19 Tf::R16Snorm => DXGI_FORMAT_R16_SNORM,
20 Tf::R16Float => DXGI_FORMAT_R16_FLOAT,
21 Tf::Rg8Unorm => DXGI_FORMAT_R8G8_UNORM,
22 Tf::Rg8Snorm => DXGI_FORMAT_R8G8_SNORM,
23 Tf::Rg8Uint => DXGI_FORMAT_R8G8_UINT,
24 Tf::Rg8Sint => DXGI_FORMAT_R8G8_SINT,
25 Tf::Rg16Unorm => DXGI_FORMAT_R16G16_UNORM,
26 Tf::Rg16Snorm => DXGI_FORMAT_R16G16_SNORM,
27 Tf::R32Uint => DXGI_FORMAT_R32_UINT,
28 Tf::R32Sint => DXGI_FORMAT_R32_SINT,
29 Tf::R32Float => DXGI_FORMAT_R32_FLOAT,
30 Tf::Rg16Uint => DXGI_FORMAT_R16G16_UINT,
31 Tf::Rg16Sint => DXGI_FORMAT_R16G16_SINT,
32 Tf::Rg16Float => DXGI_FORMAT_R16G16_FLOAT,
33 Tf::Rgba8Unorm => DXGI_FORMAT_R8G8B8A8_UNORM,
34 Tf::Rgba8UnormSrgb => DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
35 Tf::Bgra8UnormSrgb => DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
36 Tf::Rgba8Snorm => DXGI_FORMAT_R8G8B8A8_SNORM,
37 Tf::Bgra8Unorm => DXGI_FORMAT_B8G8R8A8_UNORM,
38 Tf::Rgba8Uint => DXGI_FORMAT_R8G8B8A8_UINT,
39 Tf::Rgba8Sint => DXGI_FORMAT_R8G8B8A8_SINT,
40 Tf::Rgb10a2Unorm => DXGI_FORMAT_R10G10B10A2_UNORM,
41 Tf::Rg11b10Float => DXGI_FORMAT_R11G11B10_FLOAT,
42 Tf::Rg32Uint => DXGI_FORMAT_R32G32_UINT,
43 Tf::Rg32Sint => DXGI_FORMAT_R32G32_SINT,
44 Tf::Rg32Float => DXGI_FORMAT_R32G32_FLOAT,
45 Tf::Rgba16Uint => DXGI_FORMAT_R16G16B16A16_UINT,
46 Tf::Rgba16Sint => DXGI_FORMAT_R16G16B16A16_SINT,
47 Tf::Rgba16Unorm => DXGI_FORMAT_R16G16B16A16_UNORM,
48 Tf::Rgba16Snorm => DXGI_FORMAT_R16G16B16A16_SNORM,
49 Tf::Rgba16Float => DXGI_FORMAT_R16G16B16A16_FLOAT,
50 Tf::Rgba32Uint => DXGI_FORMAT_R32G32B32A32_UINT,
51 Tf::Rgba32Sint => DXGI_FORMAT_R32G32B32A32_SINT,
52 Tf::Rgba32Float => DXGI_FORMAT_R32G32B32A32_FLOAT,
53 Tf::Depth32Float => DXGI_FORMAT_D32_FLOAT,
54 Tf::Depth24Plus => DXGI_FORMAT_D24_UNORM_S8_UINT,
55 Tf::Depth24PlusStencil8 => DXGI_FORMAT_D24_UNORM_S8_UINT,
56 Tf::Rgb9e5Ufloat => DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
57 Tf::Bc1RgbaUnorm => DXGI_FORMAT_BC1_UNORM,
58 Tf::Bc1RgbaUnormSrgb => DXGI_FORMAT_BC1_UNORM_SRGB,
59 Tf::Bc2RgbaUnorm => DXGI_FORMAT_BC2_UNORM,
60 Tf::Bc2RgbaUnormSrgb => DXGI_FORMAT_BC2_UNORM_SRGB,
61 Tf::Bc3RgbaUnorm => DXGI_FORMAT_BC3_UNORM,
62 Tf::Bc3RgbaUnormSrgb => DXGI_FORMAT_BC3_UNORM_SRGB,
63 Tf::Bc4RUnorm => DXGI_FORMAT_BC4_UNORM,
64 Tf::Bc4RSnorm => DXGI_FORMAT_BC4_SNORM,
65 Tf::Bc5RgUnorm => DXGI_FORMAT_BC5_UNORM,
66 Tf::Bc5RgSnorm => DXGI_FORMAT_BC5_SNORM,
67 Tf::Bc6hRgbUfloat => DXGI_FORMAT_BC6H_UF16,
68 Tf::Bc6hRgbSfloat => DXGI_FORMAT_BC6H_SF16,
69 Tf::Bc7RgbaUnorm => DXGI_FORMAT_BC7_UNORM,
70 Tf::Bc7RgbaUnormSrgb => DXGI_FORMAT_BC7_UNORM_SRGB,
71 Tf::Etc2Rgb8Unorm
72 | Tf::Etc2Rgb8UnormSrgb
73 | Tf::Etc2Rgb8A1Unorm
74 | Tf::Etc2Rgb8A1UnormSrgb
75 | Tf::Etc2Rgba8Unorm
76 | Tf::Etc2Rgba8UnormSrgb
77 | Tf::EacR11Unorm
78 | Tf::EacR11Snorm
79 | Tf::EacRg11Unorm
80 | Tf::EacRg11Snorm
81 | Tf::Astc4x4RgbaUnorm
82 | Tf::Astc4x4RgbaUnormSrgb
83 | Tf::Astc5x4RgbaUnorm
84 | Tf::Astc5x4RgbaUnormSrgb
85 | Tf::Astc5x5RgbaUnorm
86 | Tf::Astc5x5RgbaUnormSrgb
87 | Tf::Astc6x5RgbaUnorm
88 | Tf::Astc6x5RgbaUnormSrgb
89 | Tf::Astc6x6RgbaUnorm
90 | Tf::Astc6x6RgbaUnormSrgb
91 | Tf::Astc8x5RgbaUnorm
92 | Tf::Astc8x5RgbaUnormSrgb
93 | Tf::Astc8x6RgbaUnorm
94 | Tf::Astc8x6RgbaUnormSrgb
95 | Tf::Astc10x5RgbaUnorm
96 | Tf::Astc10x5RgbaUnormSrgb
97 | Tf::Astc10x6RgbaUnorm
98 | Tf::Astc10x6RgbaUnormSrgb
99 | Tf::Astc8x8RgbaUnorm
100 | Tf::Astc8x8RgbaUnormSrgb
101 | Tf::Astc10x8RgbaUnorm
102 | Tf::Astc10x8RgbaUnormSrgb
103 | Tf::Astc10x10RgbaUnorm
104 | Tf::Astc10x10RgbaUnormSrgb
105 | Tf::Astc12x10RgbaUnorm
106 | Tf::Astc12x10RgbaUnormSrgb
107 | Tf::Astc12x12RgbaUnorm
108 | Tf::Astc12x12RgbaUnormSrgb => unreachable!(),
109 }
110 }
111
112 //Note: DXGI doesn't allow sRGB format on the swapchain,
113 // but creating RTV of swapchain buffers with sRGB works.
map_texture_format_nosrgb(format: wgt::TextureFormat) -> dxgiformat::DXGI_FORMAT114 pub fn map_texture_format_nosrgb(format: wgt::TextureFormat) -> dxgiformat::DXGI_FORMAT {
115 match format {
116 wgt::TextureFormat::Bgra8UnormSrgb => dxgiformat::DXGI_FORMAT_B8G8R8A8_UNORM,
117 wgt::TextureFormat::Rgba8UnormSrgb => dxgiformat::DXGI_FORMAT_R8G8B8A8_UNORM,
118 _ => map_texture_format(format),
119 }
120 }
121
122 //Note: SRV and UAV can't use the depth formats directly
123 //TODO: stencil views?
map_texture_format_nodepth(format: wgt::TextureFormat) -> dxgiformat::DXGI_FORMAT124 pub fn map_texture_format_nodepth(format: wgt::TextureFormat) -> dxgiformat::DXGI_FORMAT {
125 match format {
126 wgt::TextureFormat::Depth32Float => dxgiformat::DXGI_FORMAT_R32_FLOAT,
127 wgt::TextureFormat::Depth24Plus | wgt::TextureFormat::Depth24PlusStencil8 => {
128 dxgiformat::DXGI_FORMAT_R24_UNORM_X8_TYPELESS
129 }
130 _ => {
131 assert_eq!(
132 crate::FormatAspects::from(format),
133 crate::FormatAspects::COLOR
134 );
135 map_texture_format(format)
136 }
137 }
138 }
139
map_texture_format_depth_typeless(format: wgt::TextureFormat) -> dxgiformat::DXGI_FORMAT140 pub fn map_texture_format_depth_typeless(format: wgt::TextureFormat) -> dxgiformat::DXGI_FORMAT {
141 match format {
142 wgt::TextureFormat::Depth32Float => dxgiformat::DXGI_FORMAT_R32_TYPELESS,
143 wgt::TextureFormat::Depth24Plus | wgt::TextureFormat::Depth24PlusStencil8 => {
144 dxgiformat::DXGI_FORMAT_R24G8_TYPELESS
145 }
146 _ => unreachable!(),
147 }
148 }
149
map_index_format(format: wgt::IndexFormat) -> dxgiformat::DXGI_FORMAT150 pub fn map_index_format(format: wgt::IndexFormat) -> dxgiformat::DXGI_FORMAT {
151 match format {
152 wgt::IndexFormat::Uint16 => dxgiformat::DXGI_FORMAT_R16_UINT,
153 wgt::IndexFormat::Uint32 => dxgiformat::DXGI_FORMAT_R32_UINT,
154 }
155 }
156
map_vertex_format(format: wgt::VertexFormat) -> dxgiformat::DXGI_FORMAT157 pub fn map_vertex_format(format: wgt::VertexFormat) -> dxgiformat::DXGI_FORMAT {
158 use wgt::VertexFormat as Vf;
159 use winapi::shared::dxgiformat::*;
160
161 match format {
162 Vf::Unorm8x2 => DXGI_FORMAT_R8G8_UNORM,
163 Vf::Snorm8x2 => DXGI_FORMAT_R8G8_SNORM,
164 Vf::Uint8x2 => DXGI_FORMAT_R8G8_UINT,
165 Vf::Sint8x2 => DXGI_FORMAT_R8G8_SINT,
166 Vf::Unorm8x4 => DXGI_FORMAT_R8G8B8A8_UNORM,
167 Vf::Snorm8x4 => DXGI_FORMAT_R8G8B8A8_SNORM,
168 Vf::Uint8x4 => DXGI_FORMAT_R8G8B8A8_UINT,
169 Vf::Sint8x4 => DXGI_FORMAT_R8G8B8A8_SINT,
170 Vf::Unorm16x2 => DXGI_FORMAT_R16G16_UNORM,
171 Vf::Snorm16x2 => DXGI_FORMAT_R16G16_SNORM,
172 Vf::Uint16x2 => DXGI_FORMAT_R16G16_UINT,
173 Vf::Sint16x2 => DXGI_FORMAT_R16G16_SINT,
174 Vf::Float16x2 => DXGI_FORMAT_R16G16_FLOAT,
175 Vf::Unorm16x4 => DXGI_FORMAT_R16G16B16A16_UNORM,
176 Vf::Snorm16x4 => DXGI_FORMAT_R16G16B16A16_SNORM,
177 Vf::Uint16x4 => DXGI_FORMAT_R16G16B16A16_UINT,
178 Vf::Sint16x4 => DXGI_FORMAT_R16G16B16A16_SINT,
179 Vf::Float16x4 => DXGI_FORMAT_R16G16B16A16_FLOAT,
180 Vf::Uint32 => DXGI_FORMAT_R32_UINT,
181 Vf::Sint32 => DXGI_FORMAT_R32_SINT,
182 Vf::Float32 => DXGI_FORMAT_R32_FLOAT,
183 Vf::Uint32x2 => DXGI_FORMAT_R32G32_UINT,
184 Vf::Sint32x2 => DXGI_FORMAT_R32G32_SINT,
185 Vf::Float32x2 => DXGI_FORMAT_R32G32_FLOAT,
186 Vf::Uint32x3 => DXGI_FORMAT_R32G32B32_UINT,
187 Vf::Sint32x3 => DXGI_FORMAT_R32G32B32_SINT,
188 Vf::Float32x3 => DXGI_FORMAT_R32G32B32_FLOAT,
189 Vf::Uint32x4 => DXGI_FORMAT_R32G32B32A32_UINT,
190 Vf::Sint32x4 => DXGI_FORMAT_R32G32B32A32_SINT,
191 Vf::Float32x4 => DXGI_FORMAT_R32G32B32A32_FLOAT,
192 Vf::Float64 | Vf::Float64x2 | Vf::Float64x3 | Vf::Float64x4 => unimplemented!(),
193 }
194 }
195
map_acomposite_alpha_mode(mode: crate::CompositeAlphaMode) -> dxgi1_2::DXGI_ALPHA_MODE196 pub fn map_acomposite_alpha_mode(mode: crate::CompositeAlphaMode) -> dxgi1_2::DXGI_ALPHA_MODE {
197 use crate::CompositeAlphaMode as Cam;
198 match mode {
199 Cam::Opaque => dxgi1_2::DXGI_ALPHA_MODE_IGNORE,
200 Cam::PreMultiplied => dxgi1_2::DXGI_ALPHA_MODE_PREMULTIPLIED,
201 Cam::PostMultiplied => dxgi1_2::DXGI_ALPHA_MODE_STRAIGHT,
202 }
203 }
204
map_buffer_usage_to_resource_flags(usage: crate::BufferUses) -> d3d12::D3D12_RESOURCE_FLAGS205 pub fn map_buffer_usage_to_resource_flags(usage: crate::BufferUses) -> d3d12::D3D12_RESOURCE_FLAGS {
206 let mut flags = 0;
207 if usage.contains(crate::BufferUses::STORAGE_WRITE) {
208 flags |= d3d12::D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
209 }
210 flags
211 }
212
map_texture_dimension(dim: wgt::TextureDimension) -> d3d12::D3D12_RESOURCE_DIMENSION213 pub fn map_texture_dimension(dim: wgt::TextureDimension) -> d3d12::D3D12_RESOURCE_DIMENSION {
214 match dim {
215 wgt::TextureDimension::D1 => d3d12::D3D12_RESOURCE_DIMENSION_TEXTURE1D,
216 wgt::TextureDimension::D2 => d3d12::D3D12_RESOURCE_DIMENSION_TEXTURE2D,
217 wgt::TextureDimension::D3 => d3d12::D3D12_RESOURCE_DIMENSION_TEXTURE3D,
218 }
219 }
220
map_texture_usage_to_resource_flags( usage: crate::TextureUses, ) -> d3d12::D3D12_RESOURCE_FLAGS221 pub fn map_texture_usage_to_resource_flags(
222 usage: crate::TextureUses,
223 ) -> d3d12::D3D12_RESOURCE_FLAGS {
224 let mut flags = 0;
225
226 if usage.contains(crate::TextureUses::COLOR_TARGET) {
227 flags |= d3d12::D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
228 }
229 if usage.intersects(
230 crate::TextureUses::DEPTH_STENCIL_READ | crate::TextureUses::DEPTH_STENCIL_WRITE,
231 ) {
232 flags |= d3d12::D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
233 if !usage.contains(crate::TextureUses::RESOURCE) {
234 flags |= d3d12::D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
235 }
236 }
237 if usage.contains(crate::TextureUses::STORAGE_WRITE) {
238 flags |= d3d12::D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
239 }
240
241 flags
242 }
243
map_address_mode(mode: wgt::AddressMode) -> d3d12::D3D12_TEXTURE_ADDRESS_MODE244 pub fn map_address_mode(mode: wgt::AddressMode) -> d3d12::D3D12_TEXTURE_ADDRESS_MODE {
245 use wgt::AddressMode as Am;
246 match mode {
247 Am::Repeat => d3d12::D3D12_TEXTURE_ADDRESS_MODE_WRAP,
248 Am::MirrorRepeat => d3d12::D3D12_TEXTURE_ADDRESS_MODE_MIRROR,
249 Am::ClampToEdge => d3d12::D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
250 Am::ClampToBorder => d3d12::D3D12_TEXTURE_ADDRESS_MODE_BORDER,
251 //Am::MirrorClamp => d3d12::D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE,
252 }
253 }
254
map_filter_mode(mode: wgt::FilterMode) -> d3d12::D3D12_FILTER_TYPE255 pub fn map_filter_mode(mode: wgt::FilterMode) -> d3d12::D3D12_FILTER_TYPE {
256 match mode {
257 wgt::FilterMode::Nearest => d3d12::D3D12_FILTER_TYPE_POINT,
258 wgt::FilterMode::Linear => d3d12::D3D12_FILTER_TYPE_LINEAR,
259 }
260 }
261
map_comparison(func: wgt::CompareFunction) -> d3d12::D3D12_COMPARISON_FUNC262 pub fn map_comparison(func: wgt::CompareFunction) -> d3d12::D3D12_COMPARISON_FUNC {
263 use wgt::CompareFunction as Cf;
264 match func {
265 Cf::Never => d3d12::D3D12_COMPARISON_FUNC_NEVER,
266 Cf::Less => d3d12::D3D12_COMPARISON_FUNC_LESS,
267 Cf::LessEqual => d3d12::D3D12_COMPARISON_FUNC_LESS_EQUAL,
268 Cf::Equal => d3d12::D3D12_COMPARISON_FUNC_EQUAL,
269 Cf::GreaterEqual => d3d12::D3D12_COMPARISON_FUNC_GREATER_EQUAL,
270 Cf::Greater => d3d12::D3D12_COMPARISON_FUNC_GREATER,
271 Cf::NotEqual => d3d12::D3D12_COMPARISON_FUNC_NOT_EQUAL,
272 Cf::Always => d3d12::D3D12_COMPARISON_FUNC_ALWAYS,
273 }
274 }
275
map_border_color(border_color: Option<wgt::SamplerBorderColor>) -> [f32; 4]276 pub fn map_border_color(border_color: Option<wgt::SamplerBorderColor>) -> [f32; 4] {
277 use wgt::SamplerBorderColor as Sbc;
278 match border_color {
279 Some(Sbc::TransparentBlack) | None => [0.0; 4],
280 Some(Sbc::OpaqueBlack) => [0.0, 0.0, 0.0, 1.0],
281 Some(Sbc::OpaqueWhite) => [1.0; 4],
282 }
283 }
284
map_visibility(visibility: wgt::ShaderStages) -> native::ShaderVisibility285 pub fn map_visibility(visibility: wgt::ShaderStages) -> native::ShaderVisibility {
286 match visibility {
287 wgt::ShaderStages::VERTEX => native::ShaderVisibility::VS,
288 wgt::ShaderStages::FRAGMENT => native::ShaderVisibility::PS,
289 _ => native::ShaderVisibility::All,
290 }
291 }
292
map_binding_type(ty: &wgt::BindingType) -> native::DescriptorRangeType293 pub fn map_binding_type(ty: &wgt::BindingType) -> native::DescriptorRangeType {
294 use wgt::BindingType as Bt;
295 match *ty {
296 Bt::Sampler { .. } => native::DescriptorRangeType::Sampler,
297 Bt::Buffer {
298 ty: wgt::BufferBindingType::Uniform,
299 ..
300 } => native::DescriptorRangeType::CBV,
301 Bt::Buffer {
302 ty: wgt::BufferBindingType::Storage { read_only: true },
303 ..
304 }
305 | Bt::Texture { .. } => native::DescriptorRangeType::SRV,
306 Bt::Buffer {
307 ty: wgt::BufferBindingType::Storage { read_only: false },
308 ..
309 }
310 | Bt::StorageTexture { .. } => native::DescriptorRangeType::UAV,
311 }
312 }
313
map_label(name: &str) -> Vec<u16>314 pub fn map_label(name: &str) -> Vec<u16> {
315 name.encode_utf16().chain(iter::once(0)).collect()
316 }
317
map_buffer_usage_to_state(usage: crate::BufferUses) -> d3d12::D3D12_RESOURCE_STATES318 pub fn map_buffer_usage_to_state(usage: crate::BufferUses) -> d3d12::D3D12_RESOURCE_STATES {
319 use crate::BufferUses as Bu;
320 let mut state = d3d12::D3D12_RESOURCE_STATE_COMMON;
321
322 if usage.intersects(Bu::COPY_SRC) {
323 state |= d3d12::D3D12_RESOURCE_STATE_COPY_SOURCE;
324 }
325 if usage.intersects(Bu::COPY_DST) {
326 state |= d3d12::D3D12_RESOURCE_STATE_COPY_DEST;
327 }
328 if usage.intersects(Bu::INDEX) {
329 state |= d3d12::D3D12_RESOURCE_STATE_INDEX_BUFFER;
330 }
331 if usage.intersects(Bu::VERTEX | Bu::UNIFORM) {
332 state |= d3d12::D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
333 }
334 if usage.intersects(Bu::STORAGE_WRITE) {
335 state |= d3d12::D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
336 } else if usage.intersects(Bu::STORAGE_READ) {
337 state |= d3d12::D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
338 | d3d12::D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
339 }
340 if usage.intersects(Bu::INDIRECT) {
341 state |= d3d12::D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT;
342 }
343 state
344 }
345
map_texture_usage_to_state(usage: crate::TextureUses) -> d3d12::D3D12_RESOURCE_STATES346 pub fn map_texture_usage_to_state(usage: crate::TextureUses) -> d3d12::D3D12_RESOURCE_STATES {
347 use crate::TextureUses as Tu;
348 let mut state = d3d12::D3D12_RESOURCE_STATE_COMMON;
349 //Note: `RESOLVE_SOURCE` and `RESOLVE_DEST` are not used here
350 //Note: `PRESENT` is the same as `COMMON`
351 if usage == crate::TextureUses::UNINITIALIZED {
352 return state;
353 }
354
355 if usage.intersects(Tu::COPY_SRC) {
356 state |= d3d12::D3D12_RESOURCE_STATE_COPY_SOURCE;
357 }
358 if usage.intersects(Tu::COPY_DST) {
359 state |= d3d12::D3D12_RESOURCE_STATE_COPY_DEST;
360 }
361 if usage.intersects(Tu::RESOURCE) {
362 state |= d3d12::D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
363 | d3d12::D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
364 }
365 if usage.intersects(Tu::COLOR_TARGET) {
366 state |= d3d12::D3D12_RESOURCE_STATE_RENDER_TARGET;
367 }
368 if usage.intersects(Tu::DEPTH_STENCIL_READ) {
369 state |= d3d12::D3D12_RESOURCE_STATE_DEPTH_READ;
370 }
371 if usage.intersects(Tu::DEPTH_STENCIL_WRITE) {
372 state |= d3d12::D3D12_RESOURCE_STATE_DEPTH_WRITE;
373 }
374 if usage.intersects(Tu::STORAGE_READ | Tu::STORAGE_WRITE) {
375 state |= d3d12::D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
376 }
377 state
378 }
379
map_topology( topology: wgt::PrimitiveTopology, ) -> ( d3d12::D3D12_PRIMITIVE_TOPOLOGY_TYPE, d3d12::D3D12_PRIMITIVE_TOPOLOGY, )380 pub fn map_topology(
381 topology: wgt::PrimitiveTopology,
382 ) -> (
383 d3d12::D3D12_PRIMITIVE_TOPOLOGY_TYPE,
384 d3d12::D3D12_PRIMITIVE_TOPOLOGY,
385 ) {
386 match topology {
387 wgt::PrimitiveTopology::PointList => (
388 d3d12::D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT,
389 d3dcommon::D3D_PRIMITIVE_TOPOLOGY_POINTLIST,
390 ),
391 wgt::PrimitiveTopology::LineList => (
392 d3d12::D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE,
393 d3dcommon::D3D_PRIMITIVE_TOPOLOGY_LINELIST,
394 ),
395 wgt::PrimitiveTopology::LineStrip => (
396 d3d12::D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE,
397 d3dcommon::D3D_PRIMITIVE_TOPOLOGY_LINESTRIP,
398 ),
399 wgt::PrimitiveTopology::TriangleList => (
400 d3d12::D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
401 d3dcommon::D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
402 ),
403 wgt::PrimitiveTopology::TriangleStrip => (
404 d3d12::D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
405 d3dcommon::D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
406 ),
407 }
408 }
409
map_polygon_mode(mode: wgt::PolygonMode) -> d3d12::D3D12_FILL_MODE410 pub fn map_polygon_mode(mode: wgt::PolygonMode) -> d3d12::D3D12_FILL_MODE {
411 match mode {
412 wgt::PolygonMode::Point => {
413 log::error!("Point rasterization is not supported");
414 d3d12::D3D12_FILL_MODE_WIREFRAME
415 }
416 wgt::PolygonMode::Line => d3d12::D3D12_FILL_MODE_WIREFRAME,
417 wgt::PolygonMode::Fill => d3d12::D3D12_FILL_MODE_SOLID,
418 }
419 }
420
map_blend_factor(factor: wgt::BlendFactor, is_alpha: bool) -> d3d12::D3D12_BLEND421 fn map_blend_factor(factor: wgt::BlendFactor, is_alpha: bool) -> d3d12::D3D12_BLEND {
422 use wgt::BlendFactor as Bf;
423 match factor {
424 Bf::Zero => d3d12::D3D12_BLEND_ZERO,
425 Bf::One => d3d12::D3D12_BLEND_ONE,
426 Bf::Src if is_alpha => d3d12::D3D12_BLEND_SRC_ALPHA,
427 Bf::Src => d3d12::D3D12_BLEND_SRC_COLOR,
428 Bf::OneMinusSrc if is_alpha => d3d12::D3D12_BLEND_INV_SRC_ALPHA,
429 Bf::OneMinusSrc => d3d12::D3D12_BLEND_INV_SRC_COLOR,
430 Bf::Dst if is_alpha => d3d12::D3D12_BLEND_DEST_ALPHA,
431 Bf::Dst => d3d12::D3D12_BLEND_DEST_COLOR,
432 Bf::OneMinusDst if is_alpha => d3d12::D3D12_BLEND_INV_DEST_ALPHA,
433 Bf::OneMinusDst => d3d12::D3D12_BLEND_INV_DEST_COLOR,
434 Bf::SrcAlpha => d3d12::D3D12_BLEND_SRC_ALPHA,
435 Bf::OneMinusSrcAlpha => d3d12::D3D12_BLEND_INV_SRC_ALPHA,
436 Bf::DstAlpha => d3d12::D3D12_BLEND_DEST_ALPHA,
437 Bf::OneMinusDstAlpha => d3d12::D3D12_BLEND_INV_DEST_ALPHA,
438 Bf::Constant => d3d12::D3D12_BLEND_BLEND_FACTOR,
439 Bf::OneMinusConstant => d3d12::D3D12_BLEND_INV_BLEND_FACTOR,
440 Bf::SrcAlphaSaturated => d3d12::D3D12_BLEND_SRC_ALPHA_SAT,
441 //Bf::Src1Color if is_alpha => d3d12::D3D12_BLEND_SRC1_ALPHA,
442 //Bf::Src1Color => d3d12::D3D12_BLEND_SRC1_COLOR,
443 //Bf::OneMinusSrc1Color if is_alpha => d3d12::D3D12_BLEND_INV_SRC1_ALPHA,
444 //Bf::OneMinusSrc1Color => d3d12::D3D12_BLEND_INV_SRC1_COLOR,
445 //Bf::Src1Alpha => d3d12::D3D12_BLEND_SRC1_ALPHA,
446 //Bf::OneMinusSrc1Alpha => d3d12::D3D12_BLEND_INV_SRC1_ALPHA,
447 }
448 }
449
map_blend_component( component: &wgt::BlendComponent, is_alpha: bool, ) -> ( d3d12::D3D12_BLEND_OP, d3d12::D3D12_BLEND, d3d12::D3D12_BLEND, )450 fn map_blend_component(
451 component: &wgt::BlendComponent,
452 is_alpha: bool,
453 ) -> (
454 d3d12::D3D12_BLEND_OP,
455 d3d12::D3D12_BLEND,
456 d3d12::D3D12_BLEND,
457 ) {
458 let raw_op = match component.operation {
459 wgt::BlendOperation::Add => d3d12::D3D12_BLEND_OP_ADD,
460 wgt::BlendOperation::Subtract => d3d12::D3D12_BLEND_OP_SUBTRACT,
461 wgt::BlendOperation::ReverseSubtract => d3d12::D3D12_BLEND_OP_REV_SUBTRACT,
462 wgt::BlendOperation::Min => d3d12::D3D12_BLEND_OP_MIN,
463 wgt::BlendOperation::Max => d3d12::D3D12_BLEND_OP_MAX,
464 };
465 let raw_src = map_blend_factor(component.src_factor, is_alpha);
466 let raw_dst = map_blend_factor(component.dst_factor, is_alpha);
467 (raw_op, raw_src, raw_dst)
468 }
469
map_render_targets( color_targets: &[wgt::ColorTargetState], ) -> [d3d12::D3D12_RENDER_TARGET_BLEND_DESC; d3d12::D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT as usize]470 pub fn map_render_targets(
471 color_targets: &[wgt::ColorTargetState],
472 ) -> [d3d12::D3D12_RENDER_TARGET_BLEND_DESC; d3d12::D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT as usize]
473 {
474 let dummy_target = d3d12::D3D12_RENDER_TARGET_BLEND_DESC {
475 BlendEnable: 0,
476 LogicOpEnable: 0,
477 SrcBlend: d3d12::D3D12_BLEND_ZERO,
478 DestBlend: d3d12::D3D12_BLEND_ZERO,
479 BlendOp: d3d12::D3D12_BLEND_OP_ADD,
480 SrcBlendAlpha: d3d12::D3D12_BLEND_ZERO,
481 DestBlendAlpha: d3d12::D3D12_BLEND_ZERO,
482 BlendOpAlpha: d3d12::D3D12_BLEND_OP_ADD,
483 LogicOp: d3d12::D3D12_LOGIC_OP_CLEAR,
484 RenderTargetWriteMask: 0,
485 };
486 let mut raw_targets = [dummy_target; d3d12::D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT as usize];
487
488 for (raw, ct) in raw_targets.iter_mut().zip(color_targets.iter()) {
489 raw.RenderTargetWriteMask = ct.write_mask.bits() as u8;
490 if let Some(ref blend) = ct.blend {
491 let (color_op, color_src, color_dst) = map_blend_component(&blend.color, false);
492 let (alpha_op, alpha_src, alpha_dst) = map_blend_component(&blend.alpha, true);
493 raw.BlendEnable = 1;
494 raw.BlendOp = color_op;
495 raw.SrcBlend = color_src;
496 raw.DestBlend = color_dst;
497 raw.BlendOpAlpha = alpha_op;
498 raw.SrcBlendAlpha = alpha_src;
499 raw.DestBlendAlpha = alpha_dst;
500 }
501 }
502
503 raw_targets
504 }
505
map_stencil_op(op: wgt::StencilOperation) -> d3d12::D3D12_STENCIL_OP506 fn map_stencil_op(op: wgt::StencilOperation) -> d3d12::D3D12_STENCIL_OP {
507 use wgt::StencilOperation as So;
508 match op {
509 So::Keep => d3d12::D3D12_STENCIL_OP_KEEP,
510 So::Zero => d3d12::D3D12_STENCIL_OP_ZERO,
511 So::Replace => d3d12::D3D12_STENCIL_OP_REPLACE,
512 So::IncrementClamp => d3d12::D3D12_STENCIL_OP_INCR_SAT,
513 So::IncrementWrap => d3d12::D3D12_STENCIL_OP_INCR,
514 So::DecrementClamp => d3d12::D3D12_STENCIL_OP_DECR_SAT,
515 So::DecrementWrap => d3d12::D3D12_STENCIL_OP_DECR,
516 So::Invert => d3d12::D3D12_STENCIL_OP_INVERT,
517 }
518 }
519
map_stencil_face(face: &wgt::StencilFaceState) -> d3d12::D3D12_DEPTH_STENCILOP_DESC520 fn map_stencil_face(face: &wgt::StencilFaceState) -> d3d12::D3D12_DEPTH_STENCILOP_DESC {
521 d3d12::D3D12_DEPTH_STENCILOP_DESC {
522 StencilFailOp: map_stencil_op(face.fail_op),
523 StencilDepthFailOp: map_stencil_op(face.depth_fail_op),
524 StencilPassOp: map_stencil_op(face.pass_op),
525 StencilFunc: map_comparison(face.compare),
526 }
527 }
528
map_depth_stencil(ds: &wgt::DepthStencilState) -> d3d12::D3D12_DEPTH_STENCIL_DESC529 pub fn map_depth_stencil(ds: &wgt::DepthStencilState) -> d3d12::D3D12_DEPTH_STENCIL_DESC {
530 d3d12::D3D12_DEPTH_STENCIL_DESC {
531 DepthEnable: if ds.is_depth_enabled() { 1 } else { 0 },
532 DepthWriteMask: if ds.depth_write_enabled {
533 d3d12::D3D12_DEPTH_WRITE_MASK_ALL
534 } else {
535 d3d12::D3D12_DEPTH_WRITE_MASK_ZERO
536 },
537 DepthFunc: map_comparison(ds.depth_compare),
538 StencilEnable: if ds.stencil.is_enabled() { 1 } else { 0 },
539 StencilReadMask: ds.stencil.read_mask as u8,
540 StencilWriteMask: ds.stencil.write_mask as u8,
541 FrontFace: map_stencil_face(&ds.stencil.front),
542 BackFace: map_stencil_face(&ds.stencil.back),
543 }
544 }
545