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