1use crate::{
2 makepad_shader_compiler::generate_hlsl,
3 makepad_math::*,
4 makepad_error_log::*,
5 os::{
6 windows::win32_app::{TRUE, FALSE,},
7 windows::win32_window::Win32Window,
8 },
9 texture::Texture,
10 draw_list::DrawListId,
11 event::WindowGeom,
12 cx::Cx,
13 draw_shader::CxDrawShaderMapping,
14 pass::{PassClearColor, PassClearDepth, PassId},
15 window::WindowId,
16 texture::{
17 TextureFormat,
18 TextureDesc,
19 TextureId,
20 },
21 windows::{
22 core::{
23 PCSTR,
24 ComInterface,
25 Interface,
26 },
27 Win32::{
28 Foundation::{
29 HINSTANCE,
30 HANDLE,
31 S_FALSE,
32 },
33 Graphics::{
34 Direct3D11::{
35 D3D11_BIND_INDEX_BUFFER,
36 D3D11_BIND_VERTEX_BUFFER,
37 D3D11_VIEWPORT,
38 D3D11_BUFFER_DESC,
39 D3D11_USAGE_DEFAULT,
40 D3D11_BIND_CONSTANT_BUFFER,
41 D3D11_RESOURCE_MISC_FLAG,
42 D3D11_SUBRESOURCE_DATA,
43 D3D11_CREATE_DEVICE_FLAG,
44 D3D11_SDK_VERSION,
45 D3D11_BIND_FLAG,
46 D3D11_BIND_SHADER_RESOURCE,
47 D3D11_TEXTURE2D_DESC,
48 D3D11_BIND_RENDER_TARGET,
49 D3D11_BIND_DEPTH_STENCIL,
50 D3D11_DEPTH_STENCIL_DESC,
51 D3D11_DEPTH_WRITE_MASK_ALL,
52 D3D11_COMPARISON_LESS_EQUAL,
53 D3D11_DEPTH_STENCILOP_DESC,
54 D3D11_STENCIL_OP_REPLACE,
55 D3D11_COMPARISON_ALWAYS,
56 D3D11_DEPTH_STENCIL_VIEW_DESC,
57 D3D11_DSV_DIMENSION_TEXTURE2D,
58 D3D11_CLEAR_DEPTH,
59 D3D11_CLEAR_STENCIL,
60 D3D11_BLEND_DESC,
61 D3D11_RENDER_TARGET_BLEND_DESC,
62 D3D11_BLEND_ONE,
63 D3D11_BLEND_INV_SRC_ALPHA,
64 D3D11_BLEND_OP_ADD,
65 D3D11_COLOR_WRITE_ENABLE_ALL,
66 D3D11_RASTERIZER_DESC,
67 D3D11_CULL_NONE,
68 D3D11_FILL_SOLID,
69 D3D11_INPUT_ELEMENT_DESC,
70 D3D11_INPUT_PER_VERTEX_DATA,
71 D3D11_INPUT_PER_INSTANCE_DATA,
72 D3D11_MAPPED_SUBRESOURCE,
73 D3D11_USAGE_DYNAMIC,
74 D3D11_CPU_ACCESS_WRITE,
75 D3D11_MAP_WRITE_DISCARD,
76 D3D11_QUERY_DESC,
77 D3D11_QUERY_EVENT,
78 ID3D11Device,
79 ID3D11DeviceContext,
80 ID3D11RenderTargetView,
81 ID3D11Texture2D,
82 ID3D11ShaderResourceView,
83 ID3D11DepthStencilView,
84 ID3D11BlendState,
85 ID3D11RasterizerState,
86 ID3D11DepthStencilState,
87 ID3D11PixelShader,
88 ID3D11VertexShader,
89 ID3D11InputLayout,
90 ID3D11Buffer,
91 D3D11CreateDevice,
92 ID3D11Resource,
93 ID3D11Query,
94 },
95 Direct3D::{
96 Fxc::D3DCompile,
97 ID3DBlob,
98 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
99 D3D_DRIVER_TYPE_UNKNOWN,
100 D3D_FEATURE_LEVEL_11_0,
101 },
102 Dxgi::{
103 IDXGIFactory2,
104 IDXGIResource,
105 IDXGISwapChain1,
106 CreateDXGIFactory2,
107 DXGI_SWAP_CHAIN_DESC1,
108 DXGI_USAGE_RENDER_TARGET_OUTPUT,
109 DXGI_SCALING_NONE,
110 DXGI_SWAP_EFFECT_FLIP_DISCARD,
111 DXGI_RGBA,
112 Common::{
113 DXGI_FORMAT,
114 DXGI_ALPHA_MODE_IGNORE,
115 DXGI_FORMAT_R8G8B8A8_UNORM,
116 DXGI_FORMAT_B8G8R8A8_UNORM,
117 DXGI_SAMPLE_DESC,
118 DXGI_FORMAT_R32G32B32A32_FLOAT,
119 DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
120 DXGI_FORMAT_R32_UINT,
121 DXGI_FORMAT_R32_FLOAT,
122 DXGI_FORMAT_R32G32_FLOAT,
123 DXGI_FORMAT_R32G32B32_FLOAT,
124 },
125 },
126 },
127 },
128 },
129};
130
131impl Cx {
132
133 fn render_view(
134 &mut self,
135 pass_id: PassId,
136 draw_list_id: DrawListId,
137 zbias: &mut f32,
138 zbias_step: f32,
139 d3d11_cx: &D3d11Cx
140 ) {
141 let draw_items_len = self.draw_lists[draw_list_id].draw_items.len();
143 self.draw_lists[draw_list_id].uniform_view_transform(&Mat4::identity());
145
146 {
147 let draw_list = &mut self.draw_lists[draw_list_id];
148 draw_list.os.view_uniforms.update_with_f32_constant_data(d3d11_cx, draw_list.draw_list_uniforms.as_slice());
149 }
150
151 for draw_item_id in 0..draw_items_len {
152 if let Some(sub_list_id) = self.draw_lists[draw_list_id].draw_items[draw_item_id].kind.sub_list() {
153 self.render_view(
154 pass_id,
155 sub_list_id,
156 zbias,
157 zbias_step,
158 d3d11_cx,
159 );
160 }
161 else {
162 let draw_list = &mut self.draw_lists[draw_list_id];
163 let draw_item = &mut draw_list.draw_items[draw_item_id];
164 let draw_call = if let Some(draw_call) = draw_item.kind.draw_call_mut() {
165 draw_call
166 } else {
167 continue;
168 };
169 let sh = &self.draw_shaders[draw_call.draw_shader.draw_shader_id];
170 if sh.os_shader_id.is_none() { continue;
172 }
173 let shp = &self.draw_shaders.os_shaders[sh.os_shader_id.unwrap()];
174
175 if draw_call.instance_dirty {
176 draw_call.instance_dirty = false;
177 if draw_item.instances.as_ref().unwrap().len() == 0 {
178 continue;
179 }
180 draw_item.os.inst_vbuf.update_with_f32_vertex_data(d3d11_cx, draw_item.instances.as_ref().unwrap());
182 }
183
184 draw_call.draw_uniforms.set_zbias(*zbias);
186 *zbias += zbias_step;
187
188 draw_item.os.draw_uniforms.update_with_f32_constant_data(d3d11_cx, draw_call.draw_uniforms.as_slice());
189
190 if draw_call.uniforms_dirty {
191 draw_call.uniforms_dirty = false;
192 if draw_call.user_uniforms.len() != 0 {
193 draw_item.os.user_uniforms.update_with_f32_constant_data(d3d11_cx, &mut draw_call.user_uniforms);
194 }
195 }
196
197 let instances = (draw_item.instances.as_ref().unwrap().len() / sh.mapping.instances.total_slots) as u64;
198
199 if instances == 0 {
200 continue;
201 }
202
203 let geometry_id = if let Some(geometry_id) = draw_call.geometry_id {geometry_id}
204 else {
205 continue;
206 };
207
208 let geometry = &mut self.geometries[geometry_id];
209
210 if geometry.dirty {
211 geometry.os.geom_ibuf.update_with_u32_index_data(d3d11_cx, &geometry.indices);
212 geometry.os.geom_vbuf.update_with_f32_vertex_data(d3d11_cx, &geometry.vertices);
213 geometry.dirty = false;
214 }
215
216 unsafe {
217 d3d11_cx.context.VSSetShader(&shp.vertex_shader, None);
218 d3d11_cx.context.PSSetShader(&shp.pixel_shader, None);
219 d3d11_cx.context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
220 d3d11_cx.context.IASetInputLayout(&shp.input_layout);
221
222 let geom_ibuf = geometry.os.geom_ibuf.buffer.as_ref().unwrap();
223 d3d11_cx.context.IASetIndexBuffer(geom_ibuf, DXGI_FORMAT_R32_UINT, 0);
224
225 let geom_slots = sh.mapping.geometries.total_slots;
226 let inst_slots = sh.mapping.instances.total_slots;
227 let strides = [(geom_slots * 4) as u32, (inst_slots * 4) as u32];
228 let offsets = [0u32, 0u32];
229 let buffers = [geometry.os.geom_vbuf.buffer.clone(), draw_item.os.inst_vbuf.buffer.clone()];
230 d3d11_cx.context.IASetVertexBuffers(0, 2, Some(buffers.as_ptr()), Some(strides.as_ptr()), Some(offsets.as_ptr()));
231
232 fn buffer_slot(d3d11_cx: &D3d11Cx, index: u32, buffer: &Option<ID3D11Buffer>) {
233 unsafe {
234 if let Some(buffer) = buffer.clone() {
235 let buffers = [Some(buffer)];
236 d3d11_cx.context.VSSetConstantBuffers(index, Some(&buffers));
237 d3d11_cx.context.PSSetConstantBuffers(index, Some(&buffers));
238 }
239 else {
240 d3d11_cx.context.VSSetConstantBuffers(index, None);
241 d3d11_cx.context.PSSetConstantBuffers(index, None);
242 }
243 }
244 }
245 buffer_slot(d3d11_cx, 0, &shp.live_uniforms.buffer);
246 buffer_slot(d3d11_cx, 1, &shp.const_table_uniforms.buffer);
247 buffer_slot(d3d11_cx, 2, &draw_item.os.draw_uniforms.buffer);
248 buffer_slot(d3d11_cx, 3, &self.passes[pass_id].os.pass_uniforms.buffer);
249 buffer_slot(d3d11_cx, 4, &draw_list.os.view_uniforms.buffer);
250 buffer_slot(d3d11_cx, 5, &draw_item.os.user_uniforms.buffer);
251 }
252
253 for i in 0..sh.mapping.textures.len() {
254
255 let texture_id = if let Some(texture_id) = draw_call.texture_slots[i] {
256 texture_id
257 } else {
258 continue;
259 };
260
261 let cxtexture = &mut self.textures[texture_id];
262
263 match cxtexture.desc.format { TextureFormat::Default | TextureFormat::ImageBGRA => {
265 if cxtexture.update_image {
266 cxtexture.update_image = false;
267 cxtexture.os.update_platform_texture_image_bgra(
268 d3d11_cx,
269 cxtexture.desc.width.unwrap() as u32,
270 cxtexture.desc.height.unwrap() as u32,
271 &cxtexture.image_u32,
272 );
273 }
274 },
275 TextureFormat::SharedBGRA(_) => {
276 cxtexture.os.update_shared_texture(
277 &d3d11_cx.device,
278 &cxtexture.desc
279 );
280 },
281 _ => ()
282 }
283 unsafe {
284 if let Some(sr) = &cxtexture.os.shader_resource_view {
285 d3d11_cx.context.PSSetShaderResources(i as u32, Some(&[Some(sr.clone())]));
286 d3d11_cx.context.VSSetShaderResources(i as u32, Some(&[Some(sr.clone())]));
287 }
288 else {
289 d3d11_cx.context.PSSetShaderResources(i as u32, None);
290 d3d11_cx.context.VSSetShaderResources(i as u32, None);
291 }
292 }
293 }
294 unsafe {
298 d3d11_cx.context.DrawIndexedInstanced(
299 geometry.indices.len() as u32,
300 instances as u32,
301 0,
302 0,
303 0
304 )
305 };
306 }
307 }
308 }
309
310 pub fn get_shared_handle(&self, _texture: &Texture) -> HANDLE {
311 self.textures[_texture.texture_id()].os.shared_handle
312 }
313
314 pub fn setup_pass_render_targets(&mut self, pass_id: PassId, first_target: &Option<ID3D11RenderTargetView >, d3d11_cx: &D3d11Cx) {
315
316 let dpi_factor = self.passes[pass_id].dpi_factor.unwrap();
317
318 let pass_rect = self.get_pass_rect(pass_id, dpi_factor).unwrap();
319 self.passes[pass_id].set_matrix(pass_rect.pos, pass_rect.size);
320 self.passes[pass_id].paint_dirty = false;
321
322 self.passes[pass_id].set_dpi_factor(dpi_factor);
323
324 let viewport = D3D11_VIEWPORT {
325 Width: (pass_rect.size.x * dpi_factor) as f32,
326 Height: (pass_rect.size.y * dpi_factor) as f32,
327 MinDepth: 0.,
328 MaxDepth: 1.,
329 TopLeftX: 0.0,
330 TopLeftY: 0.0
331 };
332 unsafe {
333 d3d11_cx.context.RSSetViewports(Some(&[viewport]));
334 }
335 if viewport.Width < 1.0 || viewport.Height < 1.0{
336 return
337 }
338 let mut color_textures = Vec::<Option<ID3D11RenderTargetView>>::new();
340
341 if let Some(render_target) = first_target {
342 color_textures.push(Some(render_target.clone()));
343 let color = self.passes[pass_id].clear_color;
344 let color = [color.x, color.y, color.z, color.w];
345 unsafe {d3d11_cx.context.ClearRenderTargetView(first_target.as_ref().unwrap(), &color)}
346 }
347 else {
348 for color_texture in self.passes[pass_id].color_textures.iter() {
349 let cxtexture = &mut self.textures[color_texture.texture_id];
350 let is_initial = cxtexture.os.update_render_target(d3d11_cx, &cxtexture.desc, pass_rect.size * dpi_factor);
351 let render_target = cxtexture.os.render_target_view.clone();
352 color_textures.push(Some(render_target.clone().unwrap()));
353 match color_texture.clear_color {
355 PassClearColor::InitWith(color) => {
356 if is_initial {
357 let color = [color.x, color.y, color.z, color.w];
358 unsafe {d3d11_cx.context.ClearRenderTargetView(render_target.as_ref().unwrap(), &color)}
359 }
360 },
361 PassClearColor::ClearWith(color) => {
362 let color = [color.x, color.y, color.z, color.w];
363 unsafe {d3d11_cx.context.ClearRenderTargetView(render_target.as_ref().unwrap(), &color)}
364 }
365 }
366 }
367 }
368
369 if let Some(depth_texture_id) = self.passes[pass_id].depth_texture {
371 let cxtexture = &mut self.textures[depth_texture_id];
372 let is_initial = cxtexture.os.update_depth_stencil(d3d11_cx, &cxtexture.desc, pass_rect.size * dpi_factor);
373 match self.passes[pass_id].clear_depth {
374 PassClearDepth::InitWith(depth_clear) => {
375 if is_initial {
376 unsafe {d3d11_cx.context.ClearDepthStencilView(
377 cxtexture.os.depth_stencil_view.as_ref().unwrap(),
378 D3D11_CLEAR_DEPTH.0 as u32 | D3D11_CLEAR_STENCIL.0 as u32,
379 depth_clear,
380 0
381 )}
382 }
383 },
384 PassClearDepth::ClearWith(depth_clear) => {
385 unsafe {d3d11_cx.context.ClearDepthStencilView(
386 cxtexture.os.depth_stencil_view.as_ref().unwrap(),
387 D3D11_CLEAR_DEPTH.0 as u32 | D3D11_CLEAR_STENCIL.0 as u32,
388 depth_clear,
389 0
390 )}
391 }
392 }
393 unsafe {d3d11_cx.context.OMSetRenderTargets(
394 Some(&color_textures),
395 None, )}
397 }
398 else {
399 unsafe {d3d11_cx.context.OMSetRenderTargets(
400 Some(&color_textures),
401 None
402 )}
403 }
404
405 self.passes[pass_id].os.set_states(d3d11_cx);
407
408 let cxpass = &mut self.passes[pass_id];
409
410 cxpass.os.pass_uniforms.update_with_f32_constant_data(&d3d11_cx, cxpass.pass_uniforms.as_slice());
411 }
412
413 pub fn draw_pass_to_window(&mut self, pass_id: PassId, vsync: bool, d3d11_window: &mut D3d11Window, d3d11_cx: &D3d11Cx) {
414 let draw_list_id = self.passes[pass_id].main_draw_list_id.unwrap();
416
417 self.setup_pass_render_targets(pass_id, &d3d11_window.render_target_view, d3d11_cx);
418
419 let mut zbias = 0.0;
420 let zbias_step = self.passes[pass_id].zbias_step;
421
422 self.render_view(
423 pass_id,
424 draw_list_id,
425 &mut zbias,
426 zbias_step,
427 d3d11_cx
428 );
429 d3d11_window.present(vsync);
430 if d3d11_window.first_draw {
431 d3d11_window.win32_window.show();
432 d3d11_window.first_draw = false;
433 }
434 }
436
437 pub fn draw_pass_to_texture(&mut self, pass_id: PassId, d3d11_cx: &D3d11Cx,texture_id: TextureId) {
438 let draw_list_id = self.passes[pass_id].main_draw_list_id.unwrap();
440
441 let render_target_view = self.textures[texture_id].os.render_target_view.clone();
442 self.setup_pass_render_targets(pass_id, &render_target_view, d3d11_cx);
443
444 let mut zbias = 0.0;
445 let zbias_step = self.passes[pass_id].zbias_step;
446 self.render_view(
447 pass_id,
448 draw_list_id,
449 &mut zbias,
450 zbias_step,
451 &d3d11_cx,
452 );
453 }
454
455 pub fn draw_pass_to_magic_texture(&mut self, pass_id: PassId, d3d11_cx: &D3d11Cx) {
456 let draw_list_id = self.passes[pass_id].main_draw_list_id.unwrap();
458
459 self.setup_pass_render_targets(pass_id, &None, d3d11_cx);
460
461 let mut zbias = 0.0;
462 let zbias_step = self.passes[pass_id].zbias_step;
463 self.render_view(
464 pass_id,
465 draw_list_id,
466 &mut zbias,
467 zbias_step,
468 &d3d11_cx,
469 );
470 }
471
472 pub (crate) fn hlsl_compile_shaders(&mut self, d3d11_cx: &D3d11Cx) {
473 for draw_shader_ptr in &self.draw_shaders.compile_set {
474 if let Some(item) = self.draw_shaders.ptr_to_item.get(&draw_shader_ptr) {
475 let cx_shader = &mut self.draw_shaders.shaders[item.draw_shader_id];
476 let draw_shader_def = self.shader_registry.draw_shader_defs.get(&draw_shader_ptr);
477 let hlsl = generate_hlsl::generate_shader(
478 draw_shader_def.as_ref().unwrap(),
479 &cx_shader.mapping.const_table,
480 &self.shader_registry
481 );
482
483 if cx_shader.mapping.flags.debug {
484 log!("{}", hlsl);
485 }
486 for (index, ds) in self.draw_shaders.os_shaders.iter().enumerate() {
488 if ds.hlsl == hlsl {
489 cx_shader.os_shader_id = Some(index);
490 break;
491 }
492 }
493 if cx_shader.os_shader_id.is_none() {
494 if let Some(shp) = CxOsDrawShader::new(d3d11_cx, hlsl, &cx_shader.mapping) {
495 cx_shader.os_shader_id = Some(self.draw_shaders.os_shaders.len());
496 self.draw_shaders.os_shaders.push(shp);
497 }
498 }
499 }
500 }
501 self.draw_shaders.compile_set.clear();
502 }
503
504 pub fn share_texture_for_presentable_image(
505 &mut self,
506 texture: &Texture,
507 ) -> crate::cx_stdin::SharedPresentableImageOsHandle {
508 let cxtexture = &mut self.textures[texture.texture_id()];
509 cxtexture.os.update_shared_texture(self.os.d3d11_device.as_ref().unwrap(), &cxtexture.desc);
510 cxtexture.os.shared_handle.0 as u64
511 }
512}
513
514pub struct D3d11Window {
515 pub window_id: WindowId,
516 pub is_in_resize: bool,
517 pub window_geom: WindowGeom,
518 pub win32_window: Box<Win32Window>,
519 pub render_target_view: Option<ID3D11RenderTargetView >,
520 pub swap_texture: Option<ID3D11Texture2D >,
521 pub alloc_size: DVec2,
522 pub first_draw: bool,
523 pub swap_chain: IDXGISwapChain1,
524}
525
526impl D3d11Window {
527 pub fn new(window_id: WindowId, d3d11_cx: &D3d11Cx, inner_size: DVec2, position: Option<DVec2>, title: &str) -> D3d11Window {
528
529 let mut win32_window = Box::new(Win32Window::new(window_id, title, position));
532 win32_window.init(inner_size);
533
534 let wg = win32_window.get_window_geom();
535
536 let sc_desc = DXGI_SWAP_CHAIN_DESC1 {
537 AlphaMode: DXGI_ALPHA_MODE_IGNORE,
538 BufferCount: 2,
539 Width: (wg.inner_size.x * wg.dpi_factor) as u32,
540 Height: (wg.inner_size.y * wg.dpi_factor) as u32,
541 Format: DXGI_FORMAT_B8G8R8A8_UNORM,
542 Flags: 0,
543 BufferUsage: DXGI_USAGE_RENDER_TARGET_OUTPUT,
544 SampleDesc: DXGI_SAMPLE_DESC {Count: 1, Quality: 0,},
545 Scaling: DXGI_SCALING_NONE,
546 Stereo: FALSE,
547 SwapEffect: DXGI_SWAP_EFFECT_FLIP_DISCARD,
548 };
549
550 unsafe {
551 let swap_chain = d3d11_cx.factory.CreateSwapChainForHwnd(
552 &d3d11_cx.device,
553 win32_window.hwnd,
554 &sc_desc,
555 None,
556 None,
557 ).unwrap();
558
559 let swap_texture = swap_chain.GetBuffer(0).unwrap();
560 let mut render_target_view = None;
561 d3d11_cx.device.CreateRenderTargetView(&swap_texture, None, Some(&mut render_target_view)).unwrap();
562 swap_chain.SetBackgroundColor(&mut DXGI_RGBA {
563 r: 0.3,
564 g: 0.3,
565 b: 0.3,
566 a: 1.0
567 }).unwrap();
568 D3d11Window {
569 first_draw: true,
570 is_in_resize: false,
571 window_id: window_id,
572 alloc_size: wg.inner_size,
573 window_geom: wg,
574 win32_window: win32_window,
575 swap_texture: Some(swap_texture),
576 render_target_view: render_target_view,
577 swap_chain: swap_chain,
578 }
579 }
580 }
581
582 pub fn start_resize(&mut self) {
583 self.is_in_resize = true;
584 }
585
586 pub fn stop_resize(&mut self) {
588 self.is_in_resize = false;
589 self.alloc_size = DVec2::default();
590 }
591
592
593 pub fn resize_buffers(&mut self, d3d11_cx: &D3d11Cx) {
594 if self.alloc_size == self.window_geom.inner_size {
595 return
596 }
597 self.alloc_size = self.window_geom.inner_size;
598 self.swap_texture = None;
599 self.render_target_view = None;
600
601 unsafe {
602 let wg = &self.window_geom;
603 self.swap_chain.ResizeBuffers(
604 2,
605 (wg.inner_size.x * wg.dpi_factor) as u32,
606 (wg.inner_size.y * wg.dpi_factor) as u32,
607 DXGI_FORMAT_B8G8R8A8_UNORM,
608 0
609 ).unwrap();
610
611 let swap_texture = self.swap_chain.GetBuffer(0).unwrap();
612 let mut render_target_view = None;
613 d3d11_cx.device.CreateRenderTargetView(&swap_texture, None, Some(&mut render_target_view)).unwrap();
614
615 self.swap_texture = Some(swap_texture);
616 self.render_target_view = render_target_view;
617 }
618 }
619
620 pub fn present(&mut self, vsync: bool) {
621 unsafe {self.swap_chain.Present(if vsync {1}else {0}, 0).unwrap()};
622 }
623
624}
625
626#[derive(Clone)]
627pub struct D3d11Cx {
628 pub device: ID3D11Device,
629 pub context: ID3D11DeviceContext,
630 pub query: ID3D11Query,
631 pub factory: IDXGIFactory2,
632}
633
634impl D3d11Cx {
635
636 pub fn new() -> D3d11Cx {
637 unsafe {
638 let factory: IDXGIFactory2 = CreateDXGIFactory2(0).unwrap();
639 let adapter = factory.EnumAdapters(0).unwrap();
640 let mut device: Option<ID3D11Device> = None;
641 let mut context: Option<ID3D11DeviceContext> = None;
642 let mut query: Option<ID3D11Query> = None;
643 D3D11CreateDevice(
644 &adapter,
645 D3D_DRIVER_TYPE_UNKNOWN,
646 HINSTANCE(0),
647 D3D11_CREATE_DEVICE_FLAG(0),
648 Some(&[D3D_FEATURE_LEVEL_11_0]),
649 D3D11_SDK_VERSION,
650 Some(&mut device),
651 None,
652 Some(&mut context)
653 ).unwrap();
654
655 let device = device.unwrap();
656 let context = context.unwrap();
657
658 device.CreateQuery(&D3D11_QUERY_DESC {
659 Query: D3D11_QUERY_EVENT,
660 MiscFlags: 0,
661 },Some(&mut query)).unwrap();
662
663 let query = query.unwrap();
664
665 D3d11Cx {
666 device,
667 context,
668 factory,
669 query,
670 }
671 }
672 }
673
674 pub fn start_querying(&self) {
675
676 unsafe { self.context.End(&self.query) };
678 }
679
680 pub fn is_gpu_done(&self) -> bool {
681 let hresult = unsafe { (Interface::vtable(&self.context).GetData)(Interface::as_raw(&self.context),Interface::as_raw(&self.query),std::ptr::null_mut(),0,0) };
682 hresult != S_FALSE
683 }
684}
685
686#[derive(Clone, Default)]
687pub struct CxOsView {
688 pub view_uniforms: D3d11Buffer
689}
690
691#[derive(Default, Clone)]
692pub struct CxOsDrawCall {
693 pub draw_uniforms: D3d11Buffer,
694 pub user_uniforms: D3d11Buffer,
695 pub inst_vbuf: D3d11Buffer
696}
697
698#[derive(Default, Clone)]
699pub struct D3d11Buffer {
700 pub last_size: usize,
701 pub buffer: Option<ID3D11Buffer>
702}
703
704impl D3d11Buffer {
705 fn create_buffer_or_update(&mut self, d3d11_cx: &D3d11Cx, buffer_desc: &D3D11_BUFFER_DESC, sub_data: &D3D11_SUBRESOURCE_DATA, len_slots: usize, data: *const std::ffi::c_void) {
706 if self.last_size == len_slots {
707 let mut mapped = D3D11_MAPPED_SUBRESOURCE::default();
708 let p_mapped : *mut _ = &mut mapped;
709 unsafe {
710 d3d11_cx.context.Map(self.buffer.as_ref().unwrap(),
711 0, D3D11_MAP_WRITE_DISCARD, 0, Some(p_mapped)).unwrap();
712
713 std::ptr::copy_nonoverlapping(data, mapped.pData, len_slots * 4);
714 d3d11_cx.context.Unmap(self.buffer.as_ref().unwrap(), 0);
715 }
716 } else {
717 self.last_size = len_slots;
718 unsafe { d3d11_cx.device.CreateBuffer(buffer_desc, Some(sub_data), Some(&mut self.buffer)).unwrap() }
719 }
720 }
721
722 pub fn update_with_data(&mut self, d3d11_cx: &D3d11Cx, bind_flags: D3D11_BIND_FLAG, len_slots: usize, data: *const std::ffi::c_void) {
723 let buffer_desc = D3D11_BUFFER_DESC {
724 Usage: D3D11_USAGE_DYNAMIC,
725 ByteWidth: (len_slots * 4) as u32,
726 BindFlags: bind_flags.0 as u32,
727 CPUAccessFlags: D3D11_CPU_ACCESS_WRITE.0 as u32,
728 MiscFlags: 0,
729 StructureByteStride: 0
730 };
731
732 let sub_data = D3D11_SUBRESOURCE_DATA {
733 pSysMem: data,
734 SysMemPitch: 0,
735 SysMemSlicePitch: 0
736 };
737 self.create_buffer_or_update(d3d11_cx, &buffer_desc, &sub_data, len_slots, data);
738 }
739
740 pub fn update_with_u32_index_data(&mut self, d3d11_cx: &D3d11Cx, data: &[u32]) {
741 self.update_with_data(d3d11_cx, D3D11_BIND_INDEX_BUFFER, data.len(), data.as_ptr() as *const _);
742 }
743
744 pub fn update_with_f32_vertex_data(&mut self, d3d11_cx: &D3d11Cx, data: &[f32]) {
745 self.update_with_data(d3d11_cx, D3D11_BIND_VERTEX_BUFFER, data.len(), data.as_ptr() as *const _);
746 }
747
748 pub fn update_with_f32_constant_data(&mut self, d3d11_cx: &D3d11Cx, data: &[f32]) {
749 if data.len() == 0 {
750 return
751 }
752 if (data.len() & 3) != 0 { let mut new_data = data.to_vec();
754 let steps = 4 - (data.len() & 3);
755 for _ in 0..steps {
756 new_data.push(0.0);
757 };
758 return self.update_with_f32_constant_data(d3d11_cx, &new_data);
759 }
760 let sub_data = D3D11_SUBRESOURCE_DATA {
761 pSysMem: data.as_ptr() as *const _,
762 SysMemPitch: 0,
763 SysMemSlicePitch: 0
764 };
765 let len_slots = data.len();
766
767 let buffer_desc = D3D11_BUFFER_DESC {
768 Usage: D3D11_USAGE_DYNAMIC,
769 ByteWidth: (len_slots * 4) as u32,
770 BindFlags: D3D11_BIND_CONSTANT_BUFFER.0 as u32,
771 CPUAccessFlags: D3D11_CPU_ACCESS_WRITE.0 as u32,
772 MiscFlags: 0,
773 StructureByteStride: 0
774 };
775 let data = unsafe { core::slice::from_raw_parts(data.as_ptr() as *const u8, std::mem::size_of::<f32>() * data.len()).as_ptr() as *const _ };
776 self.create_buffer_or_update(d3d11_cx, &buffer_desc, &sub_data, len_slots, data);
777 }
778}
779
780
781#[derive(Default)]
782pub struct CxOsTexture {
783 width: u32,
784 height: u32,
785 texture: Option<ID3D11Texture2D >,
787 pub shared_handle: HANDLE,
788 shader_resource_view: Option<ID3D11ShaderResourceView >,
789 render_target_view: Option<ID3D11RenderTargetView >,
790 depth_stencil_view: Option<ID3D11DepthStencilView >,
791}
792
793impl CxOsTexture {
794
795 pub fn update_render_target(
796 &mut self,
797 d3d11_cx: &D3d11Cx,
798 desc: &TextureDesc,
799 default_size: DVec2
800 ) -> bool {
801
802 let width = desc.width.unwrap_or(default_size.x as usize) as u32;
803 let height = desc.height.unwrap_or(default_size.y as usize) as u32;
804
805 if self.width == width && self.height == height || width == 0 || height == 0{
806 return false
807 }
808
809 let format;
810 let misc_flags;
811 match desc.format {
812 TextureFormat::Default | TextureFormat::RenderBGRA => {
813 format = DXGI_FORMAT_R8G8B8A8_UNORM;
814 misc_flags = D3D11_RESOURCE_MISC_FLAG(2); },
816 TextureFormat::RenderBGRAf16 => {
817 format = DXGI_FORMAT_R32G32B32A32_FLOAT;
818 misc_flags = D3D11_RESOURCE_MISC_FLAG(0);
819 },
820 TextureFormat::RenderBGRAf32 => {
821 format = DXGI_FORMAT_R32G32B32A32_FLOAT;
822 misc_flags = D3D11_RESOURCE_MISC_FLAG(0);
823 },
824 _ => {
825 panic!("Wrong format for update_render_target");
826 }
827 }
828 let texture_desc = D3D11_TEXTURE2D_DESC {
829 Width: width as u32,
830 Height: height as u32,
831 MipLevels: 1,
832 ArraySize: 1,
833 Format: format,
834 SampleDesc: DXGI_SAMPLE_DESC {Count: 1, Quality: 0},
835 Usage: D3D11_USAGE_DEFAULT,
836 BindFlags: (D3D11_BIND_RENDER_TARGET.0 | D3D11_BIND_SHADER_RESOURCE.0) as u32,
837 CPUAccessFlags: 0,
838 MiscFlags: misc_flags.0 as u32,
839 };
840
841 let mut texture = None;
842 unsafe {d3d11_cx.device.CreateTexture2D(&texture_desc, None, Some(&mut texture)).unwrap()};
843 let resource: ID3D11Resource = texture.clone().unwrap().cast().unwrap();
844 let mut shader_resource_view = None;
845 unsafe {d3d11_cx.device.CreateShaderResourceView(&resource, None, Some(&mut shader_resource_view)).unwrap()};
846 let mut render_target_view = None;
847 unsafe {d3d11_cx.device.CreateRenderTargetView(&resource, None, Some(&mut render_target_view)).unwrap()};
848
849 self.width = width;
850 self.height = height;
851 self.texture = texture;
852 self.shader_resource_view = shader_resource_view;
853 self.render_target_view = render_target_view;
854
855 return true
856 }
857
858 pub fn update_depth_stencil(
859 &mut self,
860 d3d11_cx: &D3d11Cx,
861 desc: &TextureDesc,
862 default_size: DVec2
863 ) -> bool {
864
865 let width = desc.width.unwrap_or(default_size.x as usize) as u32;
866 let height = desc.height.unwrap_or(default_size.y as usize) as u32;
867
868 if self.width == width && self.height == height {
869 return false
870 }
871 if width == 0 || height == 0{
872 return false;
873 }
874
875 let format;
876 match desc.format {
877 TextureFormat::Default | TextureFormat::Depth32Stencil8 => {
878 format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
879 }
880 _ => {
881 panic!("Wrong format for update_depth_stencil");
882 }
883 }
884 let texture_desc = D3D11_TEXTURE2D_DESC {
885 Width: width as u32,
886 Height: height as u32,
887 MipLevels: 1,
888 ArraySize: 1,
889 Format: format,
890 SampleDesc: DXGI_SAMPLE_DESC {Count: 1, Quality: 0},
891 Usage: D3D11_USAGE_DEFAULT,
892 BindFlags: D3D11_BIND_DEPTH_STENCIL.0 as u32, CPUAccessFlags: 0,
894 MiscFlags: 0,
895 };
896
897 let mut texture = None;
898 unsafe {d3d11_cx.device.CreateTexture2D(&texture_desc, None, Some(&mut texture)).unwrap()};
899 let resource: ID3D11Resource = texture.clone().unwrap().cast().unwrap();
900 let dsv_desc = D3D11_DEPTH_STENCIL_VIEW_DESC {
903 Format: DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
904 ViewDimension: D3D11_DSV_DIMENSION_TEXTURE2D,
905 Flags: 0,
906 ..Default::default()
907 };
908
909 let mut depth_stencil_view = None;
910 unsafe {d3d11_cx.device.CreateDepthStencilView(&resource, Some(&dsv_desc), Some(&mut depth_stencil_view)).unwrap()};
911
912 self.width = width;
913 self.height = height;
914 self.depth_stencil_view = depth_stencil_view;
915 self.texture = texture;
916 self.shader_resource_view = None; return true
919 }
920
921 pub fn update_platform_texture_image_bgra(
922 &mut self,
923 d3d11_cx: &D3d11Cx,
924 width: u32,
925 height: u32,
926 image_u32: &Vec<u32>
927 ) {
928 if image_u32.len() != (width * height) as usize {
929 println!("update_platform_texture_image_bgra with wrong buffer_u32 size!");
930 return;
931 }
932
933 let sub_data = D3D11_SUBRESOURCE_DATA {
934 pSysMem: image_u32.as_ptr() as *const _,
935 SysMemPitch: (width * 4) as u32,
936 SysMemSlicePitch: 0
937 };
938
939 let texture_desc = D3D11_TEXTURE2D_DESC {
940 Width: width as u32,
941 Height: height as u32,
942 MipLevels: 1,
943 ArraySize: 1,
944 Format: DXGI_FORMAT_B8G8R8A8_UNORM,
945 SampleDesc: DXGI_SAMPLE_DESC {
946 Count: 1,
947 Quality: 0
948 },
949 Usage: D3D11_USAGE_DEFAULT,
950 BindFlags: D3D11_BIND_SHADER_RESOURCE.0 as u32,
951 CPUAccessFlags: 0,
952 MiscFlags: 0,
953 };
954
955 let mut texture = None;
956 unsafe {d3d11_cx.device.CreateTexture2D(&texture_desc, Some(&sub_data), Some(&mut texture)).unwrap()};
957 let resource: ID3D11Resource = texture.clone().unwrap().cast().unwrap();
958 let mut shader_resource_view = None;
959 unsafe {d3d11_cx.device.CreateShaderResourceView(&resource, None, Some(&mut shader_resource_view)).unwrap()};
960
961 self.width = width;
962 self.height = height;
963 self.texture = texture;
964 self.shader_resource_view = shader_resource_view;
965 }
966
967 fn update_shared_texture(
968 &mut self,
969 d3d11_device: &ID3D11Device,
970 desc: &TextureDesc,
971 ) {
972 if desc.width.is_none() || desc.height.is_none() {
974 log!("Shared texture width/height is undefined, cannot allocate it");
975 return
976 }
977
978 let width = desc.width.unwrap() as u32;
979 let height = desc.height.unwrap() as u32;
980
981 if (width != self.width) || (height != self.height) {
982
983 let texture_desc = D3D11_TEXTURE2D_DESC {
984 Width: width as u32,
985 Height: height as u32,
986 MipLevels: 1,
987 ArraySize: 1,
988 Format: DXGI_FORMAT_R8G8B8A8_UNORM,
989 SampleDesc: DXGI_SAMPLE_DESC {
990 Count: 1,
991 Quality: 0
992 },
993 Usage: D3D11_USAGE_DEFAULT,
994 BindFlags: (D3D11_BIND_RENDER_TARGET.0 | D3D11_BIND_SHADER_RESOURCE.0) as u32,
995 CPUAccessFlags: 0,
996 MiscFlags: 2, };
998
999 let mut texture = None;
1000 unsafe {d3d11_device.CreateTexture2D(&texture_desc, None, Some(&mut texture)).unwrap()};
1001 let resource: ID3D11Resource = texture.clone().unwrap().cast().unwrap();
1002 let mut shader_resource_view = None;
1003 unsafe {d3d11_device.CreateShaderResourceView(&resource, None, Some(&mut shader_resource_view)).unwrap()};
1004
1005 let dxgi_resource: IDXGIResource = resource.cast().unwrap();
1007 let handle = unsafe { dxgi_resource.GetSharedHandle().unwrap() };
1013 self.width = width;
1016 self.height = height;
1017 self.texture = texture;
1018 self.shader_resource_view = shader_resource_view;
1019 self.shared_handle = handle;
1020 }
1021 }
1022
1023 pub fn update_from_shared_handle(&mut self,
1024 d3d11_cx: &D3d11Cx,
1025 handle: HANDLE,
1026 ) {
1027 let mut texture: Option<ID3D11Texture2D> = None;
1028 if let Ok(()) = unsafe { d3d11_cx.device.OpenSharedResource(handle,&mut texture) } {
1029
1030 let resource: ID3D11Resource = texture.clone().unwrap().cast().unwrap();
1031 let mut shader_resource_view = None;
1032 unsafe {d3d11_cx.device.CreateShaderResourceView(&resource, None, Some(&mut shader_resource_view)).unwrap()};
1033 let mut render_target_view = None;
1034 unsafe {d3d11_cx.device.CreateRenderTargetView(&resource, None, Some(&mut render_target_view)).unwrap()};
1035
1036 self.texture = texture;
1037 self.render_target_view = render_target_view;
1038 self.shader_resource_view = shader_resource_view;
1039 }
1040 }
1041}
1042
1043impl CxOsPass {
1044 pub fn set_states(&mut self, d3d11_cx: &D3d11Cx,) {
1045
1046 if self.blend_state.is_none() {
1047
1048 let mut blend_desc: D3D11_BLEND_DESC = Default::default();
1049 blend_desc.AlphaToCoverageEnable = FALSE;
1050 blend_desc.RenderTarget[0] = D3D11_RENDER_TARGET_BLEND_DESC {
1051 BlendEnable: TRUE,
1052 SrcBlend: D3D11_BLEND_ONE,
1053 SrcBlendAlpha: D3D11_BLEND_ONE,
1054 DestBlend: D3D11_BLEND_INV_SRC_ALPHA,
1055 DestBlendAlpha: D3D11_BLEND_INV_SRC_ALPHA,
1056 BlendOp: D3D11_BLEND_OP_ADD,
1057 BlendOpAlpha: D3D11_BLEND_OP_ADD,
1058 RenderTargetWriteMask: D3D11_COLOR_WRITE_ENABLE_ALL.0 as u8,
1059 };
1060 unsafe {d3d11_cx.device.CreateBlendState(&blend_desc, Some(&mut self.blend_state)).unwrap()}
1061 }
1062
1063 if self.raster_state.is_none() {
1064 let raster_desc = D3D11_RASTERIZER_DESC {
1065 AntialiasedLineEnable: FALSE,
1066 CullMode: D3D11_CULL_NONE,
1067 DepthBias: 0,
1068 DepthBiasClamp: 0.0,
1069 DepthClipEnable: TRUE,
1070 FillMode: D3D11_FILL_SOLID,
1071 FrontCounterClockwise: FALSE,
1072 MultisampleEnable: FALSE,
1073 ScissorEnable: FALSE,
1074 SlopeScaledDepthBias: 0.0,
1075 };
1076 unsafe {d3d11_cx.device.CreateRasterizerState(&raster_desc, Some(&mut self.raster_state)).unwrap()}
1077 }
1078
1079 if self.depth_stencil_state.is_none() {
1080 let ds_desc = D3D11_DEPTH_STENCIL_DESC {
1081 DepthEnable: TRUE,
1082 DepthWriteMask: D3D11_DEPTH_WRITE_MASK_ALL,
1083 DepthFunc: D3D11_COMPARISON_LESS_EQUAL,
1084 StencilEnable: FALSE,
1085 StencilReadMask: 0xff,
1086 StencilWriteMask: 0xff,
1087 FrontFace: D3D11_DEPTH_STENCILOP_DESC {
1088 StencilFailOp: D3D11_STENCIL_OP_REPLACE,
1089 StencilDepthFailOp: D3D11_STENCIL_OP_REPLACE,
1090 StencilPassOp: D3D11_STENCIL_OP_REPLACE,
1091 StencilFunc: D3D11_COMPARISON_ALWAYS,
1092 },
1093 BackFace: D3D11_DEPTH_STENCILOP_DESC {
1094 StencilFailOp: D3D11_STENCIL_OP_REPLACE,
1095 StencilDepthFailOp: D3D11_STENCIL_OP_REPLACE,
1096 StencilPassOp: D3D11_STENCIL_OP_REPLACE,
1097 StencilFunc: D3D11_COMPARISON_ALWAYS,
1098 },
1099 };
1100 unsafe {d3d11_cx.device.CreateDepthStencilState(&ds_desc, Some(&mut self.depth_stencil_state)).unwrap()}
1101 }
1102
1103 unsafe {
1104 d3d11_cx.context.RSSetState(self.raster_state.as_ref().unwrap());
1105 let blend_factor = [0., 0., 0., 0.];
1106 d3d11_cx.context.OMSetBlendState(self.blend_state.as_ref().unwrap(), Some(&blend_factor), 0xffffffff);
1107 d3d11_cx.context.OMSetDepthStencilState(self.depth_stencil_state.as_ref().unwrap(), 0);
1108 }
1109 }
1110}
1111
1112#[derive(Default, Clone)]
1113pub struct CxOsPass {
1114 pass_uniforms: D3d11Buffer,
1115 blend_state: Option<ID3D11BlendState >,
1116 raster_state: Option<ID3D11RasterizerState >,
1117 depth_stencil_state: Option<ID3D11DepthStencilState >
1118}
1119
1120#[derive(Default, Clone)]
1121pub struct CxOsGeometry {
1122 pub geom_vbuf: D3d11Buffer,
1123 pub geom_ibuf: D3d11Buffer,
1124}
1125
1126#[derive(Clone)]
1127pub struct CxOsDrawShader {
1128 pub hlsl: String,
1129 pub const_table_uniforms: D3d11Buffer,
1130 pub live_uniforms: D3d11Buffer,
1131 pub pixel_shader: ID3D11PixelShader,
1132 pub vertex_shader: ID3D11VertexShader,
1133 pub pixel_shader_blob: ID3DBlob,
1134 pub vertex_shader_blob: ID3DBlob,
1135 pub input_layout: ID3D11InputLayout
1136}
1137
1138impl CxOsDrawShader {
1139
1140 fn new(d3d11_cx: &D3d11Cx, hlsl: String, mapping: &CxDrawShaderMapping) -> Option<Self> {
1141
1142 fn compile_shader(target: &str, entry: &str, shader: &str) -> Result<ID3DBlob, String> {
1143 unsafe {
1144 let shader_bytes = shader.as_bytes();
1145 let mut blob = None;
1146 let mut errors = None;
1147 if D3DCompile(
1148 shader_bytes.as_ptr() as *const _,
1149 shader_bytes.len(),
1150 PCSTR("makepad_shader\0".as_ptr()), None, None, PCSTR(entry.as_ptr()), PCSTR(target.as_ptr()), 0, 0, &mut blob,
1158 Some(&mut errors)
1159 ).is_ok() {
1160 return Ok(blob.unwrap());
1161 };
1162 let error = errors.unwrap();
1163 let pointer = error.GetBufferPointer();
1164 let size = error.GetBufferSize();
1165 let slice = std::slice::from_raw_parts(pointer as *const u8, size as usize);
1166 return Err(String::from_utf8_lossy(slice).into_owned());
1167 }
1168 }
1169 fn split_source(src: &str) -> String {
1170 let mut r = String::new();
1171 let split = src.split("\n");
1172 for (line, chunk) in split.enumerate() {
1173 r.push_str(&(line + 1).to_string());
1174 r.push_str(":");
1175 r.push_str(chunk);
1176 r.push_str("\n");
1177 }
1178 return r
1179 }
1180
1181 fn slots_to_dxgi_format(slots: usize) -> DXGI_FORMAT {
1182
1183 match slots {
1184 1 => DXGI_FORMAT_R32_FLOAT,
1185 2 => DXGI_FORMAT_R32G32_FLOAT,
1186 3 => DXGI_FORMAT_R32G32B32_FLOAT,
1187 4 => DXGI_FORMAT_R32G32B32A32_FLOAT,
1188 _ => panic!("slots_to_dxgi_format unsupported slotcount {}", slots)
1189 }
1190 }
1191
1192 let vs_blob = match compile_shader("vs_5_0\0", "vertex_main\0", &hlsl) {
1193 Err(msg) => {
1194 println!("Cannot compile vertexshader\n{}\n{}", msg, split_source(&hlsl));
1195 return None
1196 },
1197 Ok(blob) => {
1198 blob
1199 }
1200 };
1201
1202 let ps_blob = match compile_shader("ps_5_0\0", "pixel_main\0", &hlsl) {
1203 Err(msg) => {
1204 println!("Cannot compile pixelshader\n{}\n{}", msg, split_source(&hlsl));
1205 return None
1206 },
1207 Ok(blob) => {
1208 blob
1209 }
1210 };
1211
1212 let mut vs = None;
1213 unsafe {d3d11_cx.device.CreateVertexShader(
1214 std::slice::from_raw_parts(vs_blob.GetBufferPointer() as *const u8, vs_blob.GetBufferSize() as usize),
1215 None,
1216 Some(&mut vs)
1217 ).unwrap()};
1218
1219 let mut ps = None;
1220 unsafe {d3d11_cx.device.CreatePixelShader(
1221 std::slice::from_raw_parts(ps_blob.GetBufferPointer() as *const u8, ps_blob.GetBufferSize() as usize),
1222 None,
1223 Some(&mut ps)
1224 ).unwrap()};
1225
1226 let mut layout_desc = Vec::new();
1227 let mut strings = Vec::new();
1228
1229 for (index, geom) in mapping.geometries.inputs.iter().enumerate() {
1230
1231 strings.push(format!("GEOM{}\0", generate_hlsl::index_to_char(index))); layout_desc.push(D3D11_INPUT_ELEMENT_DESC {
1234 SemanticName: PCSTR(strings.last().unwrap().as_ptr()),
1235 SemanticIndex: 0,
1236 Format: slots_to_dxgi_format(geom.slots),
1237 InputSlot: 0,
1238 AlignedByteOffset: (geom.offset * 4) as u32,
1239 InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
1240 InstanceDataStepRate: 0
1241 })
1242 }
1243
1244 let mut index = 0;
1245 for inst in &mapping.instances.inputs {
1246 if inst.slots == 16 {
1247 for i in 0..4 {
1248 strings.push(format!("INST{}\0", generate_hlsl::index_to_char(index))); layout_desc.push(D3D11_INPUT_ELEMENT_DESC {
1250 SemanticName: PCSTR(strings.last().unwrap().as_ptr()),
1251 SemanticIndex: 0,
1252 Format: slots_to_dxgi_format(4),
1253 InputSlot: 1,
1254 AlignedByteOffset: (inst.offset * 4 + i * 16) as u32,
1255 InputSlotClass: D3D11_INPUT_PER_INSTANCE_DATA,
1256 InstanceDataStepRate: 1
1257 });
1258 index += 1;
1259 }
1260 }
1261 else if inst.slots == 9 {
1262 for i in 0..3 {
1263 strings.push(format!("INST{}\0", generate_hlsl::index_to_char(index))); layout_desc.push(D3D11_INPUT_ELEMENT_DESC {
1265 SemanticName: PCSTR(strings.last().unwrap().as_ptr()),
1266 SemanticIndex: 0,
1267 Format: slots_to_dxgi_format(3),
1268 InputSlot: 1,
1269 AlignedByteOffset: (inst.offset * 4 + i * 9) as u32,
1270 InputSlotClass: D3D11_INPUT_PER_INSTANCE_DATA,
1271 InstanceDataStepRate: 1
1272 });
1273 index += 1;
1274 }
1275 }
1276 else {
1277 strings.push(format!("INST{}\0", generate_hlsl::index_to_char(index))); layout_desc.push(D3D11_INPUT_ELEMENT_DESC {
1279 SemanticName: PCSTR(strings.last().unwrap().as_ptr()),
1280 SemanticIndex: 0,
1281 Format: slots_to_dxgi_format(inst.slots),
1282 InputSlot: 1,
1283 AlignedByteOffset: (inst.offset * 4) as u32,
1284 InputSlotClass: D3D11_INPUT_PER_INSTANCE_DATA,
1285 InstanceDataStepRate: 1
1286 });
1287 index += 1;
1288 }
1289 }
1290
1291 let mut input_layout = None;
1292 unsafe {
1293 d3d11_cx.device.CreateInputLayout(
1294 &layout_desc,
1295 std::slice::from_raw_parts(vs_blob.GetBufferPointer() as *const u8, vs_blob.GetBufferSize() as usize),
1296 Some(&mut input_layout)
1297 ).unwrap()
1298 };
1299
1300 let mut live_uniforms = D3d11Buffer::default();
1301 live_uniforms.update_with_f32_constant_data(d3d11_cx, mapping.live_uniforms_buf.as_ref());
1302
1303 let mut const_table_uniforms = D3d11Buffer::default();
1304 const_table_uniforms.update_with_f32_constant_data(d3d11_cx, mapping.const_table.table.as_ref());
1305
1306 Some(Self {
1307 hlsl,
1308 const_table_uniforms,
1309 live_uniforms,
1310 pixel_shader: ps.unwrap(),
1311 vertex_shader: vs.unwrap(),
1312 pixel_shader_blob: ps_blob,
1313 vertex_shader_blob: vs_blob,
1314 input_layout: input_layout.unwrap()
1315 })
1316 }
1317}