makepad_render/
cx_dx11.rs

1use crate::cx_win32::*;
2use crate::cx::*;
3
4use winapi::shared::guiddef::GUID;
5use winapi::shared::minwindef::{TRUE, FALSE};
6use winapi::shared::{dxgi, dxgi1_2, dxgitype, dxgiformat, winerror};
7use winapi::um::{d3d11, d3dcommon, d3dcompiler};
8use winapi::Interface;
9use wio::com::ComPtr;
10use std::mem;
11use std::ptr;
12use std::ffi;
13//use std::ffi::c_void;
14//use std::sync::Mutex;
15
16impl Cx {
17    
18    pub fn render_view(
19        &mut self,
20        pass_id: usize,
21        view_id: usize,
22        scroll: Vec2,
23        clip: (Vec2, Vec2),
24        repaint_id: u64,
25        d3d11_cx: &D3d11Cx,
26        zbias: &mut f32,
27        zbias_step: f32
28    ) {
29        
30        // tad ugly otherwise the borrow checker locks 'self' and we can't recur
31        let draw_calls_len = self.views[view_id].draw_calls_len;
32        
33        self.views[view_id].uniform_view_transform(&Mat4::identity());
34        self.views[view_id].parent_scroll = scroll;
35        
36        let local_scroll = self.views[view_id].get_local_scroll();
37        let clip = self.views[view_id].intersect_clip(clip);
38        
39        let cxview = &mut self.views[view_id];
40        cxview.platform.view_uniforms.update_with_f32_constant_data(d3d11_cx, cxview.view_uniforms.as_slice());
41        
42        for draw_call_id in 0..draw_calls_len {
43            let sub_view_id = self.views[view_id].draw_calls[draw_call_id].sub_view_id;
44            if sub_view_id != 0 {
45                self.render_view(
46                    pass_id,
47                    sub_view_id,
48                    Vec2 {x: local_scroll.x + scroll.x, y: local_scroll.y + scroll.y},
49                    clip,
50                    repaint_id,
51                    d3d11_cx,
52                    zbias,
53                    zbias_step
54                );
55            }
56            else {
57                let cxview = &mut self.views[view_id];
58                
59                let draw_call = &mut cxview.draw_calls[draw_call_id];
60                let sh = &self.shaders[draw_call.shader_id];
61                let shp = sh.platform.as_ref().unwrap();
62                
63                if draw_call.instance_dirty {
64                    draw_call.instance_dirty = false;
65                    if draw_call.instance.len() == 0 {
66                        continue;
67                    }
68                    // update the instance buffer data
69                    draw_call.platform.inst_vbuf.update_with_f32_vertex_data(d3d11_cx, &draw_call.instance);
70                }
71                
72                // update the zbias uniform if we have it.
73                draw_call.set_zbias(*zbias);
74                draw_call.set_local_scroll(scroll, local_scroll);
75                draw_call.set_clip(clip);
76                *zbias += zbias_step;
77                
78                draw_call.platform.draw_uniforms.update_with_f32_constant_data(d3d11_cx, draw_call.draw_uniforms.as_slice());
79                
80                if draw_call.uniforms_dirty {
81                    draw_call.uniforms_dirty = false;
82                    if draw_call.uniforms.len() != 0 {
83                        draw_call.platform.uniforms.update_with_f32_constant_data(d3d11_cx, &mut draw_call.uniforms);
84                    }
85                }
86                
87                let instances = (draw_call.instance.len() / sh.mapping.instance_slots) as usize;
88                
89                if instances == 0 {
90                    continue;
91                }
92                
93                d3d11_cx.set_shaders(&shp.vertex_shader, &shp.pixel_shader);
94                
95                d3d11_cx.set_primitive_topology();
96                
97                d3d11_cx.set_input_layout(&shp.input_layout);
98                
99                d3d11_cx.set_index_buffer(&shp.geom_ibuf);
100                
101                d3d11_cx.set_vertex_buffers(&shp.geom_vbuf, sh.mapping.geometry_slots, &draw_call.platform.inst_vbuf, sh.mapping.instance_slots);
102                
103                d3d11_cx.set_constant_buffers(
104                    &self.passes[pass_id].platform.pass_uniforms,
105                    &cxview.platform.view_uniforms,
106                    &draw_call.platform.draw_uniforms,
107                    &draw_call.platform.uniforms
108                );
109                
110                for (i, texture_id) in draw_call.textures_2d.iter().enumerate() {
111                    let cxtexture = &mut self.textures[*texture_id as usize];
112                    match cxtexture.desc.format { // we only allocate Image and Mapped textures.
113                        TextureFormat::Default | TextureFormat::ImageBGRA => {
114                            if cxtexture.update_image {
115                                cxtexture.update_image = false;
116                                d3d11_cx.update_platform_texture_image_bgra(
117                                    &mut cxtexture.platform,
118                                    cxtexture.desc.width.unwrap(),
119                                    cxtexture.desc.height.unwrap(),
120                                    &cxtexture.image_u32,
121                                );
122                            }
123                            d3d11_cx.set_shader_resource(i, &cxtexture.platform.shader_resource);
124                        },
125                        
126                        TextureFormat::RenderBGRA | TextureFormat::RenderBGRAf16 | TextureFormat::RenderBGRAf32 => {
127                            d3d11_cx.set_shader_resource(i, &cxtexture.platform.shader_resource);
128                        },
129                        _ => ()
130                    }
131                }
132                d3d11_cx.draw_indexed_instanced(sh.shader_gen.geometry_indices.len(), instances);
133            }
134        }
135    }
136    
137    pub fn setup_pass_render_targets(&mut self, pass_id: usize, inherit_dpi_factor: f32, first_target: Option<&ComPtr<d3d11::ID3D11RenderTargetView>>, d3d11_cx: &D3d11Cx) {
138        
139        let pass_size = self.passes[pass_id].pass_size;
140        
141        self.passes[pass_id].set_ortho_matrix(Vec2::default(), pass_size);
142        self.passes[pass_id].uniform_camera_view(&Mat4::identity());
143        self.passes[pass_id].paint_dirty = false;
144        let dpi_factor = if let Some(override_dpi_factor) = self.passes[pass_id].override_dpi_factor {
145            override_dpi_factor
146        }
147        else {
148            inherit_dpi_factor
149        };
150        self.passes[pass_id].set_dpi_factor(dpi_factor);
151        
152        //let wg = &d3d11_window.window_geom;
153        d3d11_cx.set_viewport(pass_size.x * dpi_factor, pass_size.y * dpi_factor);
154        
155        // set up the color texture array
156        let mut color_textures = Vec::<*mut d3d11::ID3D11RenderTargetView>::new();
157        for (index, color_texture) in self.passes[pass_id].color_textures.iter().enumerate() {
158            let render_target;
159            let is_initial;
160            if index == 0 && first_target.is_some() {
161                render_target = first_target.unwrap();
162                is_initial = true;
163            }
164            else {
165                let cxtexture = &mut self.textures[color_texture.texture_id];
166                is_initial = d3d11_cx.update_render_target(cxtexture, dpi_factor, pass_size);
167                render_target = cxtexture.platform.render_target_view.as_ref().unwrap();
168            }
169            color_textures.push(render_target.as_raw() as *mut _);
170            // possibly clear it
171            match color_texture.clear_color {
172                ClearColor::InitWith(color) => {
173                    if is_initial {
174                        d3d11_cx.clear_render_target_view(&render_target, color); //self.clear_color);
175                    }
176                },
177                ClearColor::ClearWith(color) => {
178                    d3d11_cx.clear_render_target_view(&render_target, color); //self.clear_color);
179                }
180            }
181        }
182        
183        // attach/clear depth buffers, if any
184        if let Some(depth_texture_id) = self.passes[pass_id].depth_texture {
185            let cxtexture = &mut self.textures[depth_texture_id];
186            let is_initial = d3d11_cx.update_depth_stencil(cxtexture, dpi_factor, pass_size);
187            match self.passes[pass_id].clear_depth {
188                ClearDepth::InitWith(depth_clear) => {
189                    if is_initial {
190                        d3d11_cx.clear_depth_stencil_view(cxtexture.platform.depth_stencil_view.as_ref().unwrap(), depth_clear as f32);
191                    }
192                },
193                ClearDepth::ClearWith(depth_clear) => {
194                    d3d11_cx.clear_depth_stencil_view(cxtexture.platform.depth_stencil_view.as_ref().unwrap(), depth_clear as f32);
195                }
196            }
197            unsafe {d3d11_cx.context.OMSetRenderTargets(
198                color_textures.len() as u32,
199                color_textures.as_ptr(),
200                cxtexture.platform.depth_stencil_view.as_ref().unwrap().as_raw() as *mut _
201            )}
202        }
203        else {
204            unsafe {d3d11_cx.context.OMSetRenderTargets(
205                color_textures.len() as u32,
206                color_textures.as_ptr(),
207                ptr::null_mut()
208            )}
209        }
210        
211        // create depth, blend and raster states
212        if self.passes[pass_id].platform.blend_state.is_none() {
213            self.passes[pass_id].platform.blend_state = Some(
214                d3d11_cx.create_blend_state().expect("Cannot create blend state")
215            )
216        }
217        
218        if self.passes[pass_id].platform.raster_state.is_none() {
219            self.passes[pass_id].platform.raster_state = Some(
220                d3d11_cx.create_raster_state().expect("Cannot create raster state")
221            )
222        }
223        
224        d3d11_cx.set_raster_state(self.passes[pass_id].platform.raster_state.as_ref().unwrap());
225        d3d11_cx.set_blend_state(self.passes[pass_id].platform.blend_state.as_ref().unwrap());
226        let cxpass = &mut self.passes[pass_id];
227        cxpass.platform.pass_uniforms.update_with_f32_constant_data(&d3d11_cx, cxpass.pass_uniforms.as_slice());
228    }
229    
230    pub fn draw_pass_to_window(&mut self, pass_id: usize, vsync: bool, dpi_factor: f32, d3d11_window: &mut D3d11Window, d3d11_cx: &D3d11Cx) {
231        // let time1 = Cx::profile_time_ns();
232        let view_id = self.passes[pass_id].main_view_id.unwrap();
233        
234        self.setup_pass_render_targets(pass_id, dpi_factor, d3d11_window.render_target_view.as_ref(), d3d11_cx);
235        let mut zbias = 0.0;
236        let zbias_step = self.passes[pass_id].zbias_step;
237        self.render_view(
238            pass_id,
239            view_id,
240            Vec2::default(),
241            (Vec2 {x: -50000., y: -50000.}, Vec2 {x: 50000., y: 50000.}),
242            self.repaint_id,
243            &d3d11_cx,
244            &mut zbias,
245            zbias_step
246        );
247        d3d11_window.present(vsync);
248        //println!("{}", (Cx::profile_time_ns() - time1)as f64 / 1000.0);
249    }
250    
251    pub fn draw_pass_to_texture(&mut self, pass_id: usize, dpi_factor: f32, d3d11_cx: &D3d11Cx) {
252        // let time1 = Cx::profile_time_ns();
253        let view_id = self.passes[pass_id].main_view_id.unwrap();
254        self.setup_pass_render_targets(pass_id, dpi_factor, None, d3d11_cx);
255        let mut zbias = 0.0;
256        let zbias_step = self.passes[pass_id].zbias_step;
257        self.render_view(
258            pass_id,
259            view_id,
260            Vec2::default(),
261            (Vec2{x:-50000.,y:-50000.},Vec2{x:50000.,y:50000.}),
262            self.repaint_id,
263            &d3d11_cx,
264            &mut zbias,
265            zbias_step
266        );
267    }
268}
269
270
271pub struct D3d11RenderTarget {
272    pub render_target_view: Option<ComPtr<d3d11::ID3D11RenderTargetView>>,
273    //pub raster_state: ComPtr<d3d11::ID3D11RasterizerState>,
274    //pub blend_state: ComPtr<d3d11::ID3D11BlendState>,
275}
276
277/*
278impl D3d11RenderTarget {
279    pub fn new(d3d11_cx: &D3d11Cx) -> D3d11RenderTarget {
280        let raster_state = d3d11_cx.create_raster_state().expect("Cannot create_raster_state");
281        let blend_state = d3d11_cx.create_blend_state().expect("Cannot create_blend_state");
282        return D3d11RenderTarget {
283            raster_state: raster_state,
284            blend_state: blend_state,
285            render_target_view: None
286        }
287    }
288    
289    
290    pub fn create_from_textures(&mut self, d3d11_cx: &D3d11Cx, swap_texture: &ComPtr<d3d11::ID3D11Texture2D>) {
291        self.render_target_view = Some(d3d11_cx.create_render_target_view(swap_texture).expect("Cannot create_render_target_view"));
292    }
293    
294    pub fn disconnect_render_targets(&mut self) {
295        self.render_target_view = None;
296    }
297}
298*/
299pub struct D3d11Window {
300    pub window_id: usize,
301    pub is_in_resize: bool,
302    pub window_geom: WindowGeom,
303    pub win32_window: Win32Window,
304    pub render_target_view: Option<ComPtr<d3d11::ID3D11RenderTargetView>>,
305    //pub render_target: D3d11RenderTarget,
306    // pub depth_stencil_view: Option<ComPtr<d3d11::ID3D11DepthStencilView>>,
307    // pub depth_stencil_buffer: Option<ComPtr<d3d11::ID3D11Texture2D>>,
308    pub swap_texture: Option<ComPtr<d3d11::ID3D11Texture2D>>,
309    // pub d2d1_hwnd_target: Option<ComPtr<d2d1::ID2D1HwndRenderTarget>>,
310    // pub d2d1_bitmap: Option<ComPtr<d2d1::ID2D1Bitmap>>,
311    pub alloc_size: Vec2,
312    pub first_draw: bool,
313    pub swap_chain: ComPtr<dxgi1_2::IDXGISwapChain1>,
314}
315
316impl D3d11Window {
317    pub fn new(window_id: usize, d3d11_cx: &D3d11Cx, win32_app: &mut Win32App, inner_size: Vec2, position: Option<Vec2>, title: &str) -> D3d11Window {
318        let mut win32_window = Win32Window::new(win32_app, window_id);
319        
320        win32_window.init(title, inner_size, position);
321        let window_geom = win32_window.get_window_geom();
322        
323        let swap_chain = d3d11_cx.create_swap_chain_for_hwnd(&window_geom, &win32_window).expect("Cannot create_swap_chain_for_hwnd");
324        
325        let swap_texture = D3d11Cx::get_swap_texture(&swap_chain).expect("Cannot get swap texture");
326        
327        let render_target_view = Some(d3d11_cx.create_render_target_view(&swap_texture).expect("Cannot create_render_target_view"));
328        
329        //let mut render_target = D3d11RenderTarget::new(d3d11_cx);
330        //render_target.create_from_textures(d3d11_cx, &swap_texture);
331        
332        
333        //let depth_stencil_buffer = d3d11_cx.create_depth_stencil_buffer(&window_geom).expect("Cannot create_depth_stencil_buffer");
334        //let depth_stencil_view = d3d11_cx.create_depth_stencil_view(&depth_stencil_buffer).expect("Cannot create_depth_stencil_view");
335        //let depth_stencil_state = d3d11_cx.create_depth_stencil_state().expect("Cannot create_depth_stencil_state");
336        //unsafe {d3d11_cx.context.OMSetDepthStencilState(depth_stencil_state.as_raw() as *mut _, 1)}
337        
338        D3d11Window {
339            first_draw: true,
340            is_in_resize: false,
341            window_id: window_id,
342            alloc_size: window_geom.inner_size,
343            window_geom: window_geom,
344            win32_window: win32_window,
345            swap_texture: Some(swap_texture),
346            render_target_view: render_target_view,
347            //depth_stencil_buffer: Some(depth_stencil_buffer),
348            //render_target_view: Some(render_target_view),
349            //depth_stencil_view: Some(depth_stencil_view),
350            //d2d1_hwnd_target: None,
351            //d2d1_bitmap: None,
352            swap_chain: swap_chain,
353            //raster_state: raster_state,
354            //blend_state: blend_state
355        }
356    }
357    
358    pub fn start_resize(&mut self) {
359        self.is_in_resize = true;
360    }
361    
362    // switch back to swapchain
363    pub fn stop_resize(&mut self) {
364        self.is_in_resize = false;
365        self.alloc_size = Vec2::default();
366    }
367    
368    //fn alloc_buffers_from_texture(&mut self, d3d11_cx: &D3d11Cx) {
369    //    let swap_texture = self.swap_texture.as_ref().unwrap();
370    //    let render_target_view = d3d11_cx.create_render_target_view(&swap_texture).expect("Cannot create_render_target_view");
371    //let depth_stencil_buffer = d3d11_cx.create_depth_stencil_buffer(&self.window_geom).expect("Cannot create_depth_stencil_buffer");
372    //let depth_stencil_view = d3d11_cx.create_depth_stencil_view(&depth_stencil_buffer).expect("Cannot create_depth_stencil_view");
373    //    self.alloc_size = self.window_geom.inner_size;
374    //    self.render_target_view = Some(render_target_view);
375    //    self.depth_stencil_view = Some(depth_stencil_view);
376    //    self.depth_stencil_buffer = Some(depth_stencil_buffer);
377    // }
378    
379    pub fn resize_buffers(&mut self, d3d11_cx: &D3d11Cx) {
380        if self.alloc_size == self.window_geom.inner_size {
381            return
382        }
383        self.alloc_size = self.window_geom.inner_size;
384        self.swap_texture = None;
385        self.render_target_view = None;
386        
387        d3d11_cx.resize_swap_chain(&self.window_geom, &self.swap_chain);
388        
389        let swap_texture = D3d11Cx::get_swap_texture(&self.swap_chain).expect("Cannot get swap texture");
390        
391        self.render_target_view = Some(d3d11_cx.create_render_target_view(&swap_texture).expect("Cannot create_render_target_view"));
392        
393        self.swap_texture = Some(swap_texture);
394    }
395    
396    pub fn present(&mut self, vsync: bool) {
397        unsafe {self.swap_chain.Present(if vsync {1}else {0}, 0)};
398    }
399    
400}
401
402#[derive(Clone)]
403pub struct D3d11Cx {
404    pub device: ComPtr<d3d11::ID3D11Device>,
405    pub context: ComPtr<d3d11::ID3D11DeviceContext>,
406    pub factory: ComPtr<dxgi1_2::IDXGIFactory2>,
407    //    pub d2d1_factory: ComPtr<d2d1::ID2D1Factory>
408}
409
410impl D3d11Cx {
411    
412    pub fn new() -> D3d11Cx {
413        let factory = D3d11Cx::create_dxgi_factory1(&dxgi1_2::IDXGIFactory2::uuidof()).expect("cannot create_dxgi_factory1");
414        let adapter = D3d11Cx::enum_adapters(&factory).expect("cannot enum_adapters");
415        let (device, context) = D3d11Cx::create_d3d11_device(&adapter).expect("cannot create_d3d11_device");
416        // let d2d1_factory = D3d11Cx::create_d2d1_factory().expect("cannot create_d2d1_factory");
417        D3d11Cx {
418            device: device,
419            context: context,
420            factory: factory,
421            //    d2d1_factory: d2d1_factory
422        }
423    }
424    
425    pub fn disconnect_rendertargets(&self) {
426        unsafe {self.context.OMSetRenderTargets(0, ptr::null(), ptr::null_mut())}
427    }
428    
429    pub fn set_viewport(&self, width: f32, height: f32) {
430        let viewport = d3d11::D3D11_VIEWPORT {
431            Width: width,
432            Height: height,
433            MinDepth: 0.,
434            MaxDepth: 1.,
435            TopLeftX: 0.0,
436            TopLeftY: 0.0
437        };
438        unsafe {self.context.RSSetViewports(1, &viewport)}
439    }
440    
441    /*pub fn set_rendertargets(&self, d3d11_target: &D3d11RenderTarget) {
442        unsafe {self.context.OMSetRenderTargets(
443            1,
444            [d3d11_target.render_target_view.as_ref().unwrap().as_raw() as *mut _].as_ptr(),
445            ptr::null_mut() //,//d3d11_window.depth_stencil_view.as_ref().unwrap().as_raw() as *mut _
446        )}
447    }*/
448    
449    pub fn clear_render_target_view(&self, render_target_view: &ComPtr<d3d11::ID3D11RenderTargetView>, color: Color) {
450        let color = [color.r, color.g, color.b, color.a];
451        unsafe {self.context.ClearRenderTargetView(render_target_view.as_raw() as *mut _, &color)}
452    }
453    
454    pub fn clear_depth_stencil_view(&self, depth_stencil_view: &ComPtr<d3d11::ID3D11DepthStencilView>, depth: f32) {
455        unsafe {self.context.ClearDepthStencilView(depth_stencil_view.as_raw() as *mut _, d3d11::D3D11_CLEAR_DEPTH | d3d11::D3D11_CLEAR_STENCIL, depth, 0)}
456    }
457    
458    //fn clear_depth_stencil_view(&self, d3d11_window: &D3d11Window) {
459    //    unsafe {self.context.ClearDepthStencilView(d3d11_window.depth_stencil_view.as_ref().unwrap().as_raw() as *mut _, d3d11::D3D11_CLEAR_DEPTH, 1.0, 0)}
460    //}
461    
462    pub fn set_raster_state(&self, raster_state: &ComPtr<d3d11::ID3D11RasterizerState>,) {
463        unsafe {self.context.RSSetState(raster_state.as_raw() as *mut _)}
464    }
465    
466    pub fn set_blend_state(&self, blend_state: &ComPtr<d3d11::ID3D11BlendState>,) {
467        let blend_factor = [0., 0., 0., 0.];
468        unsafe {self.context.OMSetBlendState(blend_state.as_raw() as *mut _, &blend_factor, 0xffffffff)}
469    }
470    
471    pub fn set_input_layout(&self, input_layout: &ComPtr<d3d11::ID3D11InputLayout>) {
472        unsafe {self.context.IASetInputLayout(input_layout.as_raw() as *mut _)}
473    }
474    
475    pub fn set_index_buffer(&self, index_buffer: &D3d11Buffer) {
476        if let Some(buf) = &index_buffer.buffer {
477            unsafe {self.context.IASetIndexBuffer(buf.as_raw() as *mut _, dxgiformat::DXGI_FORMAT_R32_UINT, 0)}
478        }
479    }
480    
481    pub fn set_shaders(&self, vertex_shader: &ComPtr<d3d11::ID3D11VertexShader>, pixel_shader: &ComPtr<d3d11::ID3D11PixelShader>) {
482        unsafe {self.context.VSSetShader(vertex_shader.as_raw() as *mut _, ptr::null(), 0)}
483        unsafe {self.context.PSSetShader(pixel_shader.as_raw() as *mut _, ptr::null(), 0)}
484    }
485    
486    pub fn set_shader_resource(&self, index: usize, texture: &Option<ComPtr<d3d11::ID3D11ShaderResourceView>>) {
487        if let Some(texture) = texture {
488            let raw = [texture.as_raw() as *const std::ffi::c_void];
489            unsafe {self.context.PSSetShaderResources(index as u32, 1, raw.as_ptr() as *const *mut _)}
490            unsafe {self.context.VSSetShaderResources(index as u32, 1, raw.as_ptr() as *const *mut _)}
491        }
492    }
493    
494    //fn set_raster_state(&self, d3d11_window: &D3d11Window) {
495    //    unsafe {self.context.RSSetState(d3d11_window.raster_state.as_raw() as *mut _)};
496    // }
497    
498    pub fn set_primitive_topology(&self) {
499        unsafe {self.context.IASetPrimitiveTopology(d3dcommon::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST)}
500    }
501    
502    pub fn set_vertex_buffers(&self, geom_buf: &D3d11Buffer, geom_slots: usize, inst_buf: &D3d11Buffer, inst_slots: usize) {
503        let geom_buf = geom_buf.buffer.as_ref().unwrap();
504        let inst_buf = inst_buf.buffer.as_ref().unwrap();
505        
506        let strides = [(geom_slots * 4) as u32, (inst_slots * 4) as u32];
507        let offsets = [0u32, 0u32];
508        let buffers = [geom_buf.as_raw() as *const std::ffi::c_void, inst_buf.as_raw() as *const std::ffi::c_void];
509        unsafe {self.context.IASetVertexBuffers(
510            0,
511            2,
512            buffers.as_ptr() as *const *mut _,
513            strides.as_ptr() as *const _,
514            offsets.as_ptr() as *const _
515        )};
516    }
517    
518    pub fn set_constant_buffers(&self, pass_uni: &D3d11Buffer, view_uni: &D3d11Buffer, draw_uni: &D3d11Buffer, uni: &D3d11Buffer) {
519        let pass_uni = pass_uni.buffer.as_ref().unwrap();
520        let view_uni = view_uni.buffer.as_ref().unwrap();
521        let draw_uni = draw_uni.buffer.as_ref().unwrap();
522        if let Some(uni) = uni.buffer.as_ref() {
523            let buffers = [
524                pass_uni.as_raw() as *const std::ffi::c_void,
525                view_uni.as_raw() as *const std::ffi::c_void,
526                draw_uni.as_raw() as *const std::ffi::c_void,
527                uni.as_raw() as *const std::ffi::c_void,
528            ];
529            unsafe {self.context.VSSetConstantBuffers(
530                0,
531                4,
532                buffers.as_ptr() as *const *mut _,
533            )};
534            unsafe {self.context.PSSetConstantBuffers(
535                0,
536                4,
537                buffers.as_ptr() as *const *mut _,
538            )};
539        }
540        else {
541            let buffers = [
542                pass_uni.as_raw() as *const std::ffi::c_void,
543                view_uni.as_raw() as *const std::ffi::c_void,
544                draw_uni.as_raw() as *const std::ffi::c_void,
545            ];
546            unsafe {self.context.VSSetConstantBuffers(
547                0,
548                3,
549                buffers.as_ptr() as *const *mut _,
550            )};
551            unsafe {self.context.PSSetConstantBuffers(
552                0,
553                3,
554                buffers.as_ptr() as *const *mut _,
555            )};
556        }
557    }
558    
559    pub fn draw_indexed_instanced(&self, num_vertices: usize, num_instances: usize) {
560        
561        
562        unsafe {self.context.DrawIndexedInstanced(
563            num_vertices as u32,
564            num_instances as u32,
565            0,
566            0,
567            0
568        )};
569    }
570    
571    pub fn compile_shader(&self, stage: &str, entry: &[u8], shader: &[u8])
572        -> Result<ComPtr<d3dcommon::ID3DBlob>, SlErr> {
573        
574        let mut blob = ptr::null_mut();
575        let mut error = ptr::null_mut();
576        let entry = ffi::CString::new(entry).unwrap();
577        let stage = format!("{}_5_0\0", stage);
578        let hr = unsafe {d3dcompiler::D3DCompile(
579            shader.as_ptr() as *const _,
580            shader.len(),
581            ptr::null(),
582            ptr::null(),
583            ptr::null_mut(),
584            entry.as_ptr() as *const _,
585            stage.as_ptr() as *const i8,
586            1,
587            0,
588            &mut blob as *mut *mut _,
589            &mut error as *mut *mut _
590        )};
591        if !winerror::SUCCEEDED(hr) {
592            let error = unsafe {ComPtr::<d3dcommon::ID3DBlob>::from_raw(error)};
593            let message = unsafe {
594                let pointer = error.GetBufferPointer();
595                let size = error.GetBufferSize();
596                let slice = std::slice::from_raw_parts(pointer as *const u8, size as usize);
597                String::from_utf8_lossy(slice).into_owned()
598            };
599            
600            Err(SlErr {msg: message})
601        } else {
602            Ok(unsafe {ComPtr::<d3dcommon::ID3DBlob>::from_raw(blob)})
603        }
604    }
605    
606    pub fn create_input_layout(&self, vs: &ComPtr<d3dcommon::ID3DBlob>, layout_desc: &Vec<d3d11::D3D11_INPUT_ELEMENT_DESC>)
607        -> Result<ComPtr<d3d11::ID3D11InputLayout>, SlErr> {
608        let mut input_layout = ptr::null_mut();
609        let hr = unsafe {self.device.CreateInputLayout(
610            layout_desc.as_ptr(),
611            layout_desc.len() as u32,
612            vs.GetBufferPointer(),
613            vs.GetBufferSize(),
614            &mut input_layout as *mut *mut _
615        )};
616        if winerror::SUCCEEDED(hr) {
617            Ok(unsafe {ComPtr::from_raw(input_layout as *mut _)})
618        }
619        else {
620            Err(SlErr {msg: format!("create_input_layout failed {}", hr)})
621        }
622    }
623    
624    pub fn create_pixel_shader(&self, ps: &ComPtr<d3dcommon::ID3DBlob>)
625        -> Result<ComPtr<d3d11::ID3D11PixelShader>, SlErr> {
626        let mut pixel_shader = ptr::null_mut();
627        let hr = unsafe {self.device.CreatePixelShader(
628            ps.GetBufferPointer(),
629            ps.GetBufferSize(),
630            ptr::null_mut(),
631            &mut pixel_shader as *mut *mut _
632        )};
633        if winerror::SUCCEEDED(hr) {
634            Ok(unsafe {ComPtr::from_raw(pixel_shader as *mut _)})
635        }
636        else {
637            Err(SlErr {msg: format!("create_pixel_shader failed {}", hr)})
638        }
639    }
640    
641    
642    pub fn create_vertex_shader(&self, vs: &ComPtr<d3dcommon::ID3DBlob>)
643        -> Result<ComPtr<d3d11::ID3D11VertexShader>, SlErr> {
644        let mut vertex_shader = ptr::null_mut();
645        let hr = unsafe {self.device.CreateVertexShader(
646            vs.GetBufferPointer(),
647            vs.GetBufferSize(),
648            ptr::null_mut(),
649            &mut vertex_shader as *mut *mut _
650        )};
651        if winerror::SUCCEEDED(hr) {
652            Ok(unsafe {ComPtr::from_raw(vertex_shader as *mut _)})
653        }
654        else {
655            Err(SlErr {msg: format!("create_vertex_shader failed {}", hr)})
656        }
657    }
658    
659    
660    pub fn create_raster_state(&self)
661        -> Result<ComPtr<d3d11::ID3D11RasterizerState>, winerror::HRESULT> {
662        let mut raster_state = ptr::null_mut();
663        let raster_desc = d3d11::D3D11_RASTERIZER_DESC {
664            AntialiasedLineEnable: FALSE,
665            CullMode: d3d11::D3D11_CULL_NONE,
666            DepthBias: 0,
667            DepthBiasClamp: 0.0,
668            DepthClipEnable: TRUE,
669            FillMode: d3d11::D3D11_FILL_SOLID,
670            FrontCounterClockwise: FALSE,
671            MultisampleEnable: FALSE,
672            ScissorEnable: FALSE,
673            SlopeScaledDepthBias: 0.0,
674        };
675        let hr = unsafe {self.device.CreateRasterizerState(&raster_desc, &mut raster_state as *mut *mut _)};
676        if winerror::SUCCEEDED(hr) {
677            Ok(unsafe {ComPtr::from_raw(raster_state as *mut _)})
678        }
679        else {
680            Err(hr)
681        }
682    }
683    
684    pub fn create_blend_state(&self)
685        -> Result<ComPtr<d3d11::ID3D11BlendState>, winerror::HRESULT> {
686        let mut blend_state = ptr::null_mut();
687        let mut blend_desc: d3d11::D3D11_BLEND_DESC = unsafe {mem::zeroed()};
688        blend_desc.AlphaToCoverageEnable = FALSE;
689        blend_desc.RenderTarget[0] = d3d11::D3D11_RENDER_TARGET_BLEND_DESC {
690            BlendEnable: TRUE,
691            SrcBlend: d3d11::D3D11_BLEND_ONE,
692            SrcBlendAlpha: d3d11::D3D11_BLEND_ONE,
693            DestBlend: d3d11::D3D11_BLEND_INV_SRC_ALPHA,
694            DestBlendAlpha: d3d11::D3D11_BLEND_INV_SRC_ALPHA,
695            BlendOp: d3d11::D3D11_BLEND_OP_ADD,
696            BlendOpAlpha: d3d11::D3D11_BLEND_OP_ADD,
697            RenderTargetWriteMask: d3d11::D3D11_COLOR_WRITE_ENABLE_ALL as u8,
698        };
699        let hr = unsafe {self.device.CreateBlendState(&blend_desc, &mut blend_state as *mut *mut _)};
700        if winerror::SUCCEEDED(hr) {
701            Ok(unsafe {ComPtr::from_raw(blend_state as *mut _)})
702        }
703        else {
704            Err(hr)
705        }
706    }
707    
708    pub fn create_depth_stencil_view(&self, buffer: &ComPtr<d3d11::ID3D11Texture2D>)
709        -> Result<ComPtr<d3d11::ID3D11DepthStencilView>, winerror::HRESULT> {
710        let mut depth_stencil_view = ptr::null_mut();
711        let mut dsv_desc: d3d11::D3D11_DEPTH_STENCIL_VIEW_DESC = unsafe {mem::zeroed()};
712        dsv_desc.Format = dxgiformat::DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
713        dsv_desc.ViewDimension = d3d11::D3D11_DSV_DIMENSION_TEXTURE2D;
714        *unsafe {dsv_desc.u.Texture2D_mut()} = d3d11::D3D11_TEX2D_DSV {
715            MipSlice: 0,
716        };
717        let hr = unsafe {self.device.CreateDepthStencilView(buffer.as_raw() as *mut _, &dsv_desc, &mut depth_stencil_view as *mut *mut _)};
718        if winerror::SUCCEEDED(hr) {
719            Ok(unsafe {ComPtr::from_raw(depth_stencil_view as *mut _)})
720        }
721        else {
722            Err(hr)
723        }
724    }
725    
726    pub fn create_depth_stencil_state(&self)
727        -> Result<ComPtr<d3d11::ID3D11DepthStencilState>, winerror::HRESULT> {
728        let mut depth_stencil_state = ptr::null_mut();
729        let ds_desc = d3d11::D3D11_DEPTH_STENCIL_DESC {
730            DepthEnable: TRUE,
731            DepthWriteMask: d3d11::D3D11_DEPTH_WRITE_MASK_ALL,
732            DepthFunc: d3d11::D3D11_COMPARISON_LESS_EQUAL,
733            StencilEnable: FALSE,
734            StencilReadMask: 0xff,
735            StencilWriteMask: 0xff,
736            FrontFace: d3d11::D3D11_DEPTH_STENCILOP_DESC {
737                StencilFailOp: d3d11::D3D11_STENCIL_OP_REPLACE,
738                StencilDepthFailOp: d3d11::D3D11_STENCIL_OP_REPLACE,
739                StencilPassOp: d3d11::D3D11_STENCIL_OP_REPLACE,
740                StencilFunc: d3d11::D3D11_COMPARISON_ALWAYS,
741            },
742            BackFace: d3d11::D3D11_DEPTH_STENCILOP_DESC {
743                StencilFailOp: d3d11::D3D11_STENCIL_OP_REPLACE,
744                StencilDepthFailOp: d3d11::D3D11_STENCIL_OP_REPLACE,
745                StencilPassOp: d3d11::D3D11_STENCIL_OP_REPLACE,
746                StencilFunc: d3d11::D3D11_COMPARISON_ALWAYS,
747            },
748        };
749        
750        let hr = unsafe {self.device.CreateDepthStencilState(&ds_desc, &mut depth_stencil_state as *mut *mut _)};
751        if winerror::SUCCEEDED(hr) {
752            Ok(unsafe {ComPtr::from_raw(depth_stencil_state as *mut _)})
753        }
754        else {
755            Err(hr)
756        }
757    }
758    
759    pub fn create_render_target_view(&self, texture: &ComPtr<d3d11::ID3D11Texture2D>)
760        -> Result<ComPtr<d3d11::ID3D11RenderTargetView>, winerror::HRESULT> {
761        //let texture = D3d11Cx::get_swap_texture(swap_chain) ?;
762        let mut render_target_view = ptr::null_mut();
763        let hr = unsafe {self.device.CreateRenderTargetView(
764            texture.as_raw() as *mut _,
765            ptr::null(),
766            &mut render_target_view as *mut *mut _
767        )};
768        if winerror::SUCCEEDED(hr) {
769            Ok(unsafe {ComPtr::from_raw(render_target_view as *mut _)})
770        }
771        else {
772            Err(hr)
773        }
774    }
775    
776    pub fn get_swap_texture(swap_chain: &ComPtr<dxgi1_2::IDXGISwapChain1>)
777        -> Result<ComPtr<d3d11::ID3D11Texture2D>, winerror::HRESULT> {
778        let mut texture = ptr::null_mut();
779        let hr = unsafe {swap_chain.GetBuffer(
780            0,
781            &d3d11::ID3D11Texture2D::uuidof(),
782            &mut texture as *mut *mut _
783        )};
784        if winerror::SUCCEEDED(hr) {
785            Ok(unsafe {ComPtr::from_raw(texture as *mut _)})
786        }
787        else {
788            Err(hr)
789        }
790    }
791    
792    pub fn create_swap_chain_for_hwnd(
793        &self,
794        wg: &WindowGeom,
795        win32_window: &Win32Window,
796    )
797        -> Result<ComPtr<dxgi1_2::IDXGISwapChain1>, winerror::HRESULT> {
798        let mut swap_chain1 = ptr::null_mut();
799        let sc_desc = dxgi1_2::DXGI_SWAP_CHAIN_DESC1 {
800            AlphaMode: dxgi1_2::DXGI_ALPHA_MODE_IGNORE,
801            BufferCount: 2,
802            Width: (wg.inner_size.x * wg.dpi_factor) as u32,
803            Height: (wg.inner_size.y * wg.dpi_factor) as u32,
804            Format: dxgiformat::DXGI_FORMAT_B8G8R8A8_UNORM,
805            Flags: 0,
806            BufferUsage: dxgitype::DXGI_USAGE_RENDER_TARGET_OUTPUT,
807            SampleDesc: dxgitype::DXGI_SAMPLE_DESC {Count: 1, Quality: 0,},
808            Scaling: dxgi1_2::DXGI_SCALING_NONE,
809            Stereo: FALSE,
810            SwapEffect: dxgi::DXGI_SWAP_EFFECT_FLIP_DISCARD,
811        };
812        
813        let hr = unsafe {self.factory.CreateSwapChainForHwnd(
814            self.device.as_raw() as *mut _,
815            win32_window.hwnd.unwrap(),
816            &sc_desc,
817            ptr::null(),
818            ptr::null_mut(),
819            &mut swap_chain1 as *mut *mut _
820        )};
821        if winerror::SUCCEEDED(hr) {
822            Ok(unsafe {ComPtr::from_raw(swap_chain1 as *mut _)})
823        }
824        else {
825            Err(hr)
826        }
827    }
828    
829    pub fn resize_swap_chain(
830        &self,
831        wg: &WindowGeom,
832        swap_chain: &ComPtr<dxgi1_2::IDXGISwapChain1>,
833    ) {
834        unsafe {
835            let hr = swap_chain.ResizeBuffers(
836                2,
837                (wg.inner_size.x * wg.dpi_factor) as u32,
838                (wg.inner_size.y * wg.dpi_factor) as u32,
839                dxgiformat::DXGI_FORMAT_B8G8R8A8_UNORM,
840                0
841            );
842            if !winerror::SUCCEEDED(hr) {
843                panic!("Could not resize swapchain");
844            }
845        }
846    }
847    
848    pub fn create_d3d11_device(adapter: &ComPtr<dxgi::IDXGIAdapter>)
849        -> Result<(ComPtr<d3d11::ID3D11Device>, ComPtr<d3d11::ID3D11DeviceContext>), winerror::HRESULT> {
850        let mut device = ptr::null_mut();
851        let mut device_context = ptr::null_mut();
852        let hr = unsafe {d3d11::D3D11CreateDevice(
853            adapter.as_raw() as *mut _,
854            d3dcommon::D3D_DRIVER_TYPE_UNKNOWN,
855            ptr::null_mut(),
856            0,//d3d11::D3D11_CREATE_DEVICE_VIDEO_SUPPORT, //d3dcommonLLD3D11_CREATE_DEVICE_DEBUG,
857            [d3dcommon::D3D_FEATURE_LEVEL_11_0].as_ptr(),
858            1,
859            d3d11::D3D11_SDK_VERSION,
860            &mut device as *mut *mut _,
861            ptr::null_mut(),
862            &mut device_context as *mut *mut _,
863        )};
864        if winerror::SUCCEEDED(hr) {
865            Ok((unsafe {ComPtr::from_raw(device as *mut _)}, unsafe {ComPtr::from_raw(device_context as *mut _)}))
866        }
867        else {
868            Err(hr)
869        }
870    }
871    
872    pub fn create_dxgi_factory1(guid: &GUID)
873        -> Result<ComPtr<dxgi1_2::IDXGIFactory2>, winerror::HRESULT> {
874        let mut factory = ptr::null_mut();
875        let hr = unsafe {dxgi::CreateDXGIFactory1(
876            guid,
877            &mut factory as *mut *mut _
878        )};
879        if winerror::SUCCEEDED(hr) {
880            Ok(unsafe {ComPtr::from_raw(factory as *mut _)})
881        }
882        else {
883            Err(hr)
884        }
885    }
886    
887    
888    pub fn enum_adapters(factory: &ComPtr<dxgi1_2::IDXGIFactory2>)
889        -> Result<ComPtr<dxgi::IDXGIAdapter>, winerror::HRESULT> {
890        let mut adapter = ptr::null_mut();
891        let hr = unsafe {factory.EnumAdapters(
892            0,
893            &mut adapter as *mut *mut _
894        )};
895        if winerror::SUCCEEDED(hr) {
896            Ok(unsafe {ComPtr::from_raw(adapter as *mut _)})
897        }
898        else {
899            Err(hr)
900        }
901    }
902    
903    pub fn update_render_target(&self, cxtexture: &mut CxTexture, dpi_factor: f32, size: Vec2) -> bool {
904        
905        let width = if let Some(width) = cxtexture.desc.width {width as usize} else {(size.x * dpi_factor) as usize};
906        let height = if let Some(height) = cxtexture.desc.height {height as usize} else {(size.y * dpi_factor) as usize};
907        
908        if cxtexture.platform.width == width && cxtexture.platform.height == height {
909            return false
910        }
911        
912        let format;
913        match cxtexture.desc.format {
914            TextureFormat::Default | TextureFormat::RenderBGRA => {
915                format = dxgiformat::DXGI_FORMAT_R8G8B8A8_UNORM;
916            }
917            TextureFormat::RenderBGRAf16 => {
918                format = dxgiformat::DXGI_FORMAT_R32G32B32A32_FLOAT;
919            }
920            TextureFormat::RenderBGRAf32 => {
921                format = dxgiformat::DXGI_FORMAT_R32G32B32A32_FLOAT;
922            },
923            _ => {
924                panic!("Wrong format for update_render_target");
925            }
926        }
927        let texture_desc = d3d11::D3D11_TEXTURE2D_DESC {
928            Width: width as u32,
929            Height: height as u32,
930            MipLevels: 1,
931            ArraySize: 1,
932            Format: format,
933            SampleDesc: dxgitype::DXGI_SAMPLE_DESC {Count: 1, Quality: 0},
934            Usage: d3d11::D3D11_USAGE_DEFAULT,
935            BindFlags: d3d11::D3D11_BIND_RENDER_TARGET | d3d11::D3D11_BIND_SHADER_RESOURCE,
936            CPUAccessFlags: 0,
937            MiscFlags: 0,
938        };
939        
940        let mut texture = ptr::null_mut();
941        let hr = unsafe {self.device.CreateTexture2D(&texture_desc, ptr::null(), &mut texture as *mut *mut _)};
942        
943        if winerror::SUCCEEDED(hr) {
944            let mut shader_resource = ptr::null_mut();
945            unsafe {self.device.CreateShaderResourceView(texture as *mut _, ptr::null(), &mut shader_resource as *mut *mut _)};
946            cxtexture.platform.width = width;
947            cxtexture.platform.height = height;
948            cxtexture.platform.texture = Some(unsafe {ComPtr::from_raw(texture as *mut _)});
949            let mut shader_resource = ptr::null_mut();
950            unsafe {self.device.CreateShaderResourceView(texture as *mut _, ptr::null(), &mut shader_resource as *mut *mut _)};
951            cxtexture.platform.shader_resource = Some(unsafe {ComPtr::from_raw(shader_resource as *mut _)});
952            
953            cxtexture.platform.render_target_view = Some(
954                self.create_render_target_view(
955                    cxtexture.platform.texture.as_ref().unwrap()
956                ).expect("Cannot create_render_target_view")
957            );
958        }
959        else {
960            panic!("update_render_target failed");
961        }
962        return true
963    }
964    
965    pub fn update_depth_stencil(&self, cxtexture: &mut CxTexture, dpi_factor: f32, size: Vec2) -> bool {
966        
967        let width = if let Some(width) = cxtexture.desc.width {width as usize} else {(size.x * dpi_factor) as usize};
968        let height = if let Some(height) = cxtexture.desc.height {height as usize} else {(size.y * dpi_factor) as usize};
969        
970        if cxtexture.platform.width == width && cxtexture.platform.height == height {
971            return false
972        }
973        
974        let format;
975        match cxtexture.desc.format {
976            TextureFormat::Default | TextureFormat::Depth32Stencil8 => {
977                format = dxgiformat::DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
978            }
979            _ => {
980                panic!("Wrong format for update_depth_stencil");
981            }
982        }
983        let texture_desc = d3d11::D3D11_TEXTURE2D_DESC {
984            Width: width as u32,
985            Height: height as u32,
986            MipLevels: 1,
987            ArraySize: 1,
988            Format: format,
989            SampleDesc: dxgitype::DXGI_SAMPLE_DESC {Count: 1, Quality: 0},
990            Usage: d3d11::D3D11_USAGE_DEFAULT,
991            BindFlags: d3d11::D3D11_BIND_DEPTH_STENCIL, // | d3d11::D3D11_BIND_SHADER_RESOURCE,
992            CPUAccessFlags: 0,
993            MiscFlags: 0,
994        };
995        
996        let mut texture = ptr::null_mut();
997        let hr = unsafe {self.device.CreateTexture2D(&texture_desc, ptr::null(), &mut texture as *mut *mut _)};
998        
999        if winerror::SUCCEEDED(hr) {
1000            let mut shader_resource = ptr::null_mut();
1001            unsafe {self.device.CreateShaderResourceView(texture as *mut _, ptr::null(), &mut shader_resource as *mut *mut _)};
1002            cxtexture.platform.width = width;
1003            cxtexture.platform.height = height;
1004            cxtexture.platform.texture = Some(unsafe {ComPtr::from_raw(texture as *mut _)});
1005            
1006            //let mut shader_resource = ptr::null_mut();
1007            //unsafe {self.device.CreateShaderResourceView(texture as *mut _, ptr::null(), &mut shader_resource as *mut *mut _)};
1008            //cxtexture.platform.shader_resource = Some(unsafe {ComPtr::from_raw(shader_resource as *mut _)});
1009            
1010            // lets create the render target too
1011            if let Ok(dsview) = self.create_depth_stencil_view(cxtexture.platform.texture.as_ref().unwrap()) {
1012                cxtexture.platform.depth_stencil_view = Some(dsview);
1013            }
1014            else {
1015                panic!("create_depth_stencil_view failed");
1016            }
1017        }
1018        else {
1019            panic!("update_render_target failed");
1020        }
1021        return true
1022    }
1023    
1024    pub fn update_platform_texture_image_bgra(&self, res: &mut CxPlatformTexture, width: usize, height: usize, image_u32: &Vec<u32>) {
1025        
1026        if image_u32.len() != width * height {
1027            println!("update_platform_texture_image_bgra with wrong buffer_u32 size!");
1028            return;
1029        }
1030        
1031        let sub_data = d3d11::D3D11_SUBRESOURCE_DATA {
1032            pSysMem: image_u32.as_ptr() as *const _,
1033            SysMemPitch: (width * 4) as u32,
1034            SysMemSlicePitch: 0
1035        };
1036        
1037        let texture_desc = d3d11::D3D11_TEXTURE2D_DESC {
1038            Width: width as u32,
1039            Height: height as u32,
1040            MipLevels: 1,
1041            ArraySize: 1,
1042            Format: dxgiformat::DXGI_FORMAT_R8G8B8A8_UNORM,
1043            SampleDesc: dxgitype::DXGI_SAMPLE_DESC {
1044                Count: 1,
1045                Quality: 0
1046            },
1047            Usage: d3d11::D3D11_USAGE_DEFAULT,
1048            BindFlags: d3d11::D3D11_BIND_SHADER_RESOURCE,
1049            CPUAccessFlags: 0,
1050            MiscFlags: 0,
1051        };
1052        let mut texture = ptr::null_mut();
1053        let hr = unsafe {self.device.CreateTexture2D(&texture_desc, &sub_data, &mut texture as *mut *mut _)};
1054        if winerror::SUCCEEDED(hr) {
1055            let mut shader_resource = ptr::null_mut();
1056            unsafe {self.device.CreateShaderResourceView(
1057                texture as *mut _,
1058                ptr::null(),
1059                &mut shader_resource as *mut *mut _
1060            )};
1061            res.width = width;
1062            res.height = height;
1063            res.texture = Some(unsafe {ComPtr::from_raw(texture as *mut _)});
1064            res.shader_resource = Some(unsafe {ComPtr::from_raw(shader_resource as *mut _)});
1065        }
1066        else {
1067            panic!("update_platform_texture_image_bgra failed");
1068        }
1069    }
1070    
1071    /*
1072    
1073                            /*
1074                        TextureFormat::ImageBGRAf32 => {},
1075                        TextureFormat::ImageRf32 => {
1076                            if cxtexture.update_image {
1077                                cxtexture.update_image = false;
1078                                d3d11_cx.update_platform_texture_image_rf32(
1079                                    &mut cxtexture.platform.single,
1080                                    cxtexture.desc.width.unwrap(),
1081                                    cxtexture.desc.height.unwrap(),
1082                                    &cxtexture.image_f32,
1083                                );
1084                            }
1085                            d3d11_cx.set_shader_resource(i, &cxtexture.platform.single.shader_resource);
1086                        },
1087                        TextureFormat::ImageRGf32 => {
1088                            if cxtexture.update_image {
1089                                cxtexture.update_image = false;
1090                                d3d11_cx.update_platform_texture_image_rgf32(
1091                                    &mut cxtexture.platform.single,
1092                                    cxtexture.desc.width.unwrap(),
1093                                    cxtexture.desc.height.unwrap(),
1094                                    &cxtexture.image_f32,
1095                                );
1096                            }
1097                            d3d11_cx.set_shader_resource(i, &cxtexture.platform.single.shader_resource);
1098                        },
1099                        TextureFormat::MappedRGf32 | TextureFormat::MappedRf32 | TextureFormat::MappedBGRA | TextureFormat::MappedBGRAf32 => {
1100                            if let Ok(mut mapped) = cxtexture.platform.mapped.lock() {
1101                                if mapped.textures[0].texture.is_none() {
1102                                    d3d11_cx.init_mapped_textures(
1103                                        &mut *mapped,
1104                                        &cxtexture.desc.format,
1105                                        cxtexture.desc.width.unwrap(),
1106                                        cxtexture.desc.height.unwrap()
1107                                    );
1108                                }
1109                                if let Some(index) = d3d11_cx.flip_mapped_textures(&mut mapped, repaint_id) {
1110                                    d3d11_cx.set_shader_resource(i, &mapped.textures[index].shader_resource);
1111                                }
1112                            }
1113                        },*/
1114                        
1115    pub fn init_mapped_textures(&self, mapped: &mut CxPlatformTextureMapped, texture_format: &TextureFormat, width: usize, height: usize) {
1116        let slots_per_pixel;
1117        let format;
1118        match texture_format {
1119            TextureFormat::MappedRGf32 => {
1120                slots_per_pixel = 2;
1121                format = dxgiformat::DXGI_FORMAT_R32G32_FLOAT;
1122            }
1123            TextureFormat::MappedRf32 => {
1124                slots_per_pixel = 1;
1125                format = dxgiformat::DXGI_FORMAT_R32_FLOAT;
1126            }
1127            TextureFormat::MappedBGRA => {
1128                slots_per_pixel = 1;
1129                format = dxgiformat::DXGI_FORMAT_R8G8B8A8_UNORM;
1130            }
1131            TextureFormat::MappedBGRAf32 => {
1132                slots_per_pixel = 4;
1133                format = dxgiformat::DXGI_FORMAT_R32G32B32A32_FLOAT;
1134            },
1135            _ => {
1136                panic!("Wrong format for init_mapped_texures");
1137            }
1138        }
1139        let texture_desc = d3d11::D3D11_TEXTURE2D_DESC {
1140            Width: width as u32,
1141            Height: height as u32,
1142            MipLevels: 1,
1143            ArraySize: 1,
1144            Format: format,
1145            SampleDesc: dxgitype::DXGI_SAMPLE_DESC {Count: 1, Quality: 0},
1146            Usage: d3d11::D3D11_USAGE_DYNAMIC,
1147            BindFlags: d3d11::D3D11_BIND_SHADER_RESOURCE,
1148            CPUAccessFlags: d3d11::D3D11_CPU_ACCESS_WRITE,
1149            MiscFlags: 0,
1150        };
1151        for i in 0..MAPPED_TEXTURE_BUFFER_COUNT {
1152            let mut texture = ptr::null_mut();
1153            let hr = unsafe {self.device.CreateTexture2D(&texture_desc, ptr::null(), &mut texture as *mut *mut _)};
1154            if winerror::SUCCEEDED(hr) {
1155                let mut shader_resource = ptr::null_mut();
1156                unsafe {self.device.CreateShaderResourceView(texture as *mut _, ptr::null(), &mut shader_resource as *mut *mut _)};
1157                mapped.textures[i].slots_per_pixel = slots_per_pixel;
1158                mapped.textures[i].width = width;
1159                mapped.textures[i].height = height;
1160                mapped.textures[i].texture = Some(unsafe {ComPtr::from_raw(texture as *mut _)});
1161                let mut shader_resource = ptr::null_mut();
1162                unsafe {self.device.CreateShaderResourceView(texture as *mut _, ptr::null(), &mut shader_resource as *mut *mut _)};
1163                
1164                mapped.textures[i].shader_resource = Some(unsafe {ComPtr::from_raw(shader_resource as *mut _)});
1165                let mut d3d11_resource = ptr::null_mut();
1166                unsafe {mapped.textures[i].texture.as_ref().unwrap().QueryInterface(
1167                    &d3d11::ID3D11Resource::uuidof(),
1168                    &mut d3d11_resource as *mut *mut _
1169                )};
1170                mapped.textures[i].d3d11_resource = Some(unsafe {ComPtr::from_raw(d3d11_resource as *mut _)});
1171                // map them by default
1172                self.map_texture(&mut mapped.textures[i]);
1173            }
1174            else {
1175                panic!("init_mapped_textures failed");
1176            }
1177        }
1178    }
1179    
1180    pub fn flip_mapped_textures(&self, mapped: &mut CxPlatformTextureMapped, repaint_id: u64) -> Option<usize> {
1181        if mapped.repaint_id == repaint_id {
1182            return mapped.repaint_read
1183        }
1184        mapped.repaint_id = repaint_id;
1185        for i in 0..MAPPED_TEXTURE_BUFFER_COUNT {
1186            if mapped.write > mapped.read && i == mapped.read % MAPPED_TEXTURE_BUFFER_COUNT {
1187                if mapped.textures[i].locked {
1188                    panic!("Texture locked whilst unmapping, should never happen!")
1189                }
1190                self.unmap_texture(&mut mapped.textures[i]);
1191            }
1192            else if mapped.read == 0 || i != (mapped.read - 1) % MAPPED_TEXTURE_BUFFER_COUNT { // keep a safety for not stalling gpu
1193                self.map_texture(&mut mapped.textures[i]);
1194            }
1195        }
1196        if mapped.read != mapped.write && mapped.textures[mapped.read % MAPPED_TEXTURE_BUFFER_COUNT].map_ptr.is_none() {
1197            let read = mapped.read;
1198            if mapped.read != mapped.write && mapped.write > mapped.read {
1199                if mapped.write > mapped.read + 1 { // space ahead
1200                    mapped.read += 1;
1201                }
1202            }
1203            mapped.repaint_read = Some(read % MAPPED_TEXTURE_BUFFER_COUNT);
1204            return mapped.repaint_read;
1205        }
1206        mapped.repaint_read = None;
1207        return None
1208    }
1209    
1210    pub fn map_texture(&self, texture: &mut CxPlatformTextureResource) {
1211        if !texture.map_ptr.is_none() {
1212            return
1213        }
1214        unsafe {
1215            let mut mapped_resource = std::mem::zeroed();
1216            let d3d11_resource = texture.d3d11_resource.as_ref().unwrap();
1217            let hr = self.context.Map(d3d11_resource.as_raw(), 0, d3d11::D3D11_MAP_WRITE_DISCARD, 0, &mut mapped_resource);
1218            if winerror::SUCCEEDED(hr) {
1219                texture.map_ptr = Some(mapped_resource.pData);
1220            }
1221        }
1222    }
1223    
1224    pub fn unmap_texture(&self, texture: &mut CxPlatformTextureResource) {
1225        if texture.map_ptr.is_none() {
1226            return
1227        }
1228        let d3d11_resource = texture.d3d11_resource.as_ref().unwrap();
1229        unsafe {
1230            self.context.Unmap(d3d11_resource.as_raw(), 0);
1231        }
1232        texture.map_ptr = None;
1233    }*/
1234    
1235    /*
1236    pub fn update_platform_texture_image_rf32(&self, res: &mut CxPlatformTextureResource, width: usize, height: usize, image_f32: &Vec<f32>) {
1237        if image_f32.len() != width * height {
1238            println!("update_platform_texture_image_rf32 with wrong buffer_u32 size!");
1239            return;
1240        }
1241        
1242        let mut texture = ptr::null_mut();
1243        let sub_data = d3d11::D3D11_SUBRESOURCE_DATA {
1244            pSysMem: image_f32.as_ptr() as *const _,
1245            SysMemPitch: (width * 4) as u32,
1246            SysMemSlicePitch: 0
1247        };
1248        
1249        let texture_desc = d3d11::D3D11_TEXTURE2D_DESC {
1250            Width: width as u32,
1251            Height: height as u32,
1252            MipLevels: 1,
1253            ArraySize: 1,
1254            Format: dxgiformat::DXGI_FORMAT_R32_FLOAT,
1255            SampleDesc: dxgitype::DXGI_SAMPLE_DESC {
1256                Count: 1,
1257                Quality: 0
1258            },
1259            Usage: d3d11::D3D11_USAGE_DEFAULT,
1260            BindFlags: d3d11::D3D11_BIND_SHADER_RESOURCE,
1261            CPUAccessFlags: 0,
1262            MiscFlags: 0,
1263        };
1264        
1265        let hr = unsafe {self.device.CreateTexture2D(&texture_desc, &sub_data, &mut texture as *mut *mut _)};
1266        if winerror::SUCCEEDED(hr) {
1267            let mut shader_resource = ptr::null_mut();
1268            unsafe {self.device.CreateShaderResourceView(
1269                texture as *mut _,
1270                ptr::null(),
1271                &mut shader_resource as *mut *mut _
1272            )};
1273            res.width = width;
1274            res.height = height;
1275            res.texture = Some(unsafe {ComPtr::from_raw(texture as *mut _)});
1276            res.shader_resource = Some(unsafe {ComPtr::from_raw(shader_resource as *mut _)});
1277        }
1278        else {
1279            panic!("update_platform_texture_image_rf32 failed");
1280        }
1281    }
1282    
1283    
1284    pub fn update_platform_texture_image_rgf32(&self, res: &mut CxPlatformTextureResource, width: usize, height: usize, image_f32: &Vec<f32>) {
1285        if image_f32.len() != width * height * 2 {
1286            println!("update_platform_texture_image_rgf32 with wrong buffer_f32 size {} {}!", width * height * 2, image_f32.len());
1287            return;
1288        }
1289        
1290        let mut texture = ptr::null_mut();
1291        let sub_data = d3d11::D3D11_SUBRESOURCE_DATA {
1292            pSysMem: image_f32.as_ptr() as *const _,
1293            SysMemPitch: (width * 8) as u32,
1294            SysMemSlicePitch: 0
1295        };
1296        
1297        let texture_desc = d3d11::D3D11_TEXTURE2D_DESC {
1298            Width: width as u32,
1299            Height: height as u32,
1300            MipLevels: 1,
1301            ArraySize: 1,
1302            Format: dxgiformat::DXGI_FORMAT_R32G32_FLOAT,
1303            SampleDesc: dxgitype::DXGI_SAMPLE_DESC {
1304                Count: 1,
1305                Quality: 0
1306            },
1307            Usage: d3d11::D3D11_USAGE_DEFAULT,
1308            BindFlags: d3d11::D3D11_BIND_SHADER_RESOURCE,
1309            CPUAccessFlags: 0,
1310            MiscFlags: 0,
1311        };
1312        
1313        let hr = unsafe {self.device.CreateTexture2D(&texture_desc, &sub_data, &mut texture as *mut *mut _)};
1314        if winerror::SUCCEEDED(hr) {
1315            let mut shader_resource = ptr::null_mut();
1316            unsafe {self.device.CreateShaderResourceView(
1317                texture as *mut _,
1318                ptr::null(),
1319                &mut shader_resource as *mut *mut _
1320            )};
1321            res.texture = Some(unsafe {ComPtr::from_raw(texture as *mut _)});
1322            res.width = width;
1323            res.height = height;
1324            res.shader_resource = Some(unsafe {ComPtr::from_raw(shader_resource as *mut _)});
1325        }
1326        else {
1327            panic!("update_platform_texture_image_rgf32 failed");
1328        }
1329    }*/
1330}
1331
1332#[derive(Clone, Default)]
1333pub struct CxPlatformView {
1334    pub view_uniforms: D3d11Buffer
1335}
1336
1337#[derive(Default, Clone)]
1338pub struct CxPlatformDrawCall {
1339    pub draw_uniforms: D3d11Buffer,
1340    pub uniforms: D3d11Buffer,
1341    pub inst_vbuf: D3d11Buffer
1342}
1343
1344#[derive(Default, Clone)]
1345pub struct D3d11Buffer {
1346    pub last_size: usize,
1347    pub buffer: Option<ComPtr<d3d11::ID3D11Buffer>>
1348}
1349
1350impl D3d11Buffer {
1351    pub fn update_with_data(&mut self, d3d11_cx: &D3d11Cx, bind_flags: u32, len_slots: usize, data: *const std::ffi::c_void) {
1352        let mut buffer = ptr::null_mut();
1353        
1354        let buffer_desc = d3d11::D3D11_BUFFER_DESC {
1355            Usage: d3d11::D3D11_USAGE_DEFAULT,
1356            ByteWidth: (len_slots * 4) as u32,
1357            BindFlags: bind_flags,
1358            CPUAccessFlags: 0,
1359            MiscFlags: 0,
1360            StructureByteStride: 0
1361        };
1362        
1363        let sub_data = d3d11::D3D11_SUBRESOURCE_DATA {
1364            pSysMem: data,
1365            SysMemPitch: 0,
1366            SysMemSlicePitch: 0
1367        };
1368        
1369        let hr = unsafe {d3d11_cx.device.CreateBuffer(&buffer_desc, &sub_data, &mut buffer as *mut *mut _)};
1370        if winerror::SUCCEEDED(hr) {
1371            self.last_size = len_slots;
1372            self.buffer = Some(unsafe {ComPtr::from_raw(buffer as *mut _)});
1373        }
1374        else {
1375            panic!("Buffer create failed {}", len_slots);
1376        }
1377    }
1378    
1379    pub fn update_with_u32_index_data(&mut self, d3d11_cx: &D3d11Cx, data: &[u32]) {
1380        self.update_with_data(d3d11_cx, d3d11::D3D11_BIND_INDEX_BUFFER, data.len(), data.as_ptr() as *const _);
1381    }
1382    
1383    pub fn update_with_f32_vertex_data(&mut self, d3d11_cx: &D3d11Cx, data: &[f32]) {
1384        self.update_with_data(d3d11_cx, d3d11::D3D11_BIND_VERTEX_BUFFER, data.len(), data.as_ptr() as *const _);
1385    }
1386    
1387    pub fn update_with_f32_constant_data(&mut self, d3d11_cx: &D3d11Cx, data: &[f32]) {
1388        let mut buffer = ptr::null_mut();
1389        if (data.len() & 3) != 0 { // we have to align the data at the end
1390            let mut new_data = data.to_vec();
1391            let steps = 4 - (data.len() & 3);
1392            for _ in 0..steps {
1393                new_data.push(0.0);
1394            };
1395            return self.update_with_f32_constant_data(d3d11_cx, &new_data);
1396        }
1397        let sub_data = d3d11::D3D11_SUBRESOURCE_DATA {
1398            pSysMem: data.as_ptr() as *const _,
1399            SysMemPitch: 0,
1400            SysMemSlicePitch: 0
1401        };
1402        let len_slots = data.len();
1403        
1404        let buffer_desc = d3d11::D3D11_BUFFER_DESC {
1405            Usage: d3d11::D3D11_USAGE_DEFAULT,
1406            ByteWidth: (len_slots * 4) as u32,
1407            BindFlags: d3d11::D3D11_BIND_CONSTANT_BUFFER,
1408            CPUAccessFlags: 0,
1409            MiscFlags: 0,
1410            StructureByteStride: 0
1411        };
1412        
1413        let hr = unsafe {d3d11_cx.device.CreateBuffer(&buffer_desc, &sub_data, &mut buffer as *mut *mut _)};
1414        if winerror::SUCCEEDED(hr) {
1415            // println!("Buffer create OK! {} {}",  len_bytes, bind_flags);
1416            self.last_size = len_slots;
1417            self.buffer = Some(unsafe {ComPtr::from_raw(buffer as *mut _)});
1418        }
1419        else {
1420            panic!("Buffer create failed {}", len_slots);
1421        }
1422    }
1423}
1424
1425
1426
1427#[derive(Default)]
1428pub struct CxPlatformTexture {
1429    width: usize,
1430    height: usize,
1431    slots_per_pixel: usize,
1432    texture: Option<ComPtr<d3d11::ID3D11Texture2D>>,
1433    shader_resource: Option<ComPtr<d3d11::ID3D11ShaderResourceView>>,
1434    d3d11_resource: Option<ComPtr<d3d11::ID3D11Resource>>,
1435    //single: CxPlatformTextureResource,
1436    //mapped: Mutex<CxPlatformTextureMapped>,
1437    render_target_view: Option<ComPtr<d3d11::ID3D11RenderTargetView>>,
1438    depth_stencil_view: Option<ComPtr<d3d11::ID3D11DepthStencilView>>
1439}
1440
1441#[derive(Default, Clone)]
1442pub struct CxPlatformPass {
1443    pass_uniforms: D3d11Buffer,
1444    blend_state: Option<ComPtr<d3d11::ID3D11BlendState>>,
1445    raster_state: Option<ComPtr<d3d11::ID3D11RasterizerState>>,
1446    depth_stencil_state: Option<ComPtr<d3d11::ID3D11DepthStencilState>>
1447}
1448
1449/*pub const MAPPED_TEXTURE_BUFFER_COUNT: usize = 4;
1450
1451    /*
1452    pub fn create_depth_stencil_buffer(&self, wg: &WindowGeom)
1453        -> Result<ComPtr<d3d11::ID3D11Texture2D>, winerror::HRESULT> {
1454        let mut depth_stencil_buffer = ptr::null_mut();
1455        let texture2d_desc = d3d11::D3D11_TEXTURE2D_DESC {
1456            Width: (wg.inner_size.x * wg.dpi_factor) as u32,
1457            Height: (wg.inner_size.y * wg.dpi_factor) as u32,
1458            MipLevels: 1,
1459            ArraySize: 1,
1460            Format: dxgiformat::DXGI_FORMAT_D24_UNORM_S8_UINT,
1461            SampleDesc: dxgitype::DXGI_SAMPLE_DESC {
1462                Count: 1,
1463                Quality: 0
1464            },
1465            Usage: d3d11::D3D11_USAGE_DEFAULT,
1466            BindFlags: d3d11::D3D11_BIND_DEPTH_STENCIL,
1467            CPUAccessFlags: 0,
1468            MiscFlags: 0
1469        };
1470        let hr = unsafe {self.device.CreateTexture2D(&texture2d_desc, ptr::null_mut(), &mut depth_stencil_buffer as *mut *mut _)};
1471        if winerror::SUCCEEDED(hr) {
1472            Ok(unsafe {ComPtr::from_raw(depth_stencil_buffer as *mut _)})
1473        }
1474        else {
1475            Err(hr)
1476        }
1477    }*/
1478    
1479
1480#[derive(Default, Clone)]
1481pub struct CxPlatformTextureResource {
1482    map_ptr: Option<*mut c_void>,
1483    locked: bool,
1484    user_data: Option<usize>,
1485}
1486#[derive(Default)]
1487pub struct CxPlatformTextureMapped {
1488    read: usize,
1489    write: usize,
1490    repaint_read: Option<usize>,
1491    repaint_id: u64,
1492    textures: [CxPlatformTextureResource; MAPPED_TEXTURE_BUFFER_COUNT],
1493}
1494pub struct CxThread {
1495    cx: u64
1496}
1497pub fn new_cxthread(&mut self) -> CxThread {
1498        CxThread {cx: self as *mut _ as u64}
1499    }
1500    
1501    pub fn get_mapped_texture_user_data(&mut self, texture: &Texture) -> Option<usize> {
1502        if let Some(texture_id) = texture.texture_id {
1503            let cxtexture = &self.textures[texture_id];
1504            if let Ok(mapped) = cxtexture.platform.mapped.lock() {
1505                return mapped.textures[mapped.read % MAPPED_TEXTURE_BUFFER_COUNT].user_data;
1506            }
1507        }
1508        None
1509    }
1510    
1511impl CxThread {
1512    
1513    pub fn lock_mapped_texture_f32(&mut self, texture: &Texture, user_data: usize) -> Option<&mut [f32]> {
1514        if let Some(texture_id) = texture.texture_id {
1515            let cx = unsafe {&mut *(self.cx as *mut Cx)};
1516            let cxtexture = &mut cx.textures[texture_id];
1517            if let Ok(mut mapped) = cxtexture.platform.mapped.lock() {
1518                let write = mapped.write;
1519                let texture = &mut mapped.textures[write % MAPPED_TEXTURE_BUFFER_COUNT];
1520                if let Some(ptr) = texture.map_ptr {
1521                    texture.user_data = Some(user_data);
1522                    if texture.locked == true {
1523                        panic!("lock_mapped_texture_f32 ran twice for the same texture, pair with unlock_mapped_texture!")
1524                    }
1525                    texture.locked = true;
1526                    return Some(unsafe {std::slice::from_raw_parts_mut(
1527                        ptr as *mut f32,
1528                        texture.width * texture.height * texture.slots_per_pixel
1529                    )});
1530                }
1531            };
1532        }
1533        None
1534    }
1535    
1536    pub fn lock_mapped_texture_u32(&mut self, texture: &Texture, user_data: usize) -> Option<&mut [u32]> {
1537        if let Some(texture_id) = texture.texture_id {
1538            let cx = unsafe {&mut *(self.cx as *mut Cx)};
1539            let cxtexture = &mut cx.textures[texture_id];
1540            if let Ok(mut mapped) = cxtexture.platform.mapped.lock() {
1541                let write = mapped.write;
1542                let texture = &mut mapped.textures[write % MAPPED_TEXTURE_BUFFER_COUNT];
1543                if let Some(ptr) = texture.map_ptr {
1544                    texture.user_data = Some(user_data);
1545                    if texture.locked == true {
1546                        panic!("lock_mapped_texture_u32 ran twice for the same texture, pair with unlock_mapped_texture!")
1547                    }
1548                    texture.locked = true;
1549                    return Some(unsafe {std::slice::from_raw_parts_mut(
1550                        ptr as *mut u32,
1551                        texture.width * texture.height * texture.slots_per_pixel
1552                    )});
1553                }
1554            };
1555        }
1556        None
1557    }
1558    
1559    pub fn unlock_mapped_texture(&mut self, texture: &Texture) {
1560        if let Some(texture_id) = texture.texture_id {
1561            let cx = unsafe {&mut *(self.cx as *mut Cx)};
1562            let cxtexture = &mut cx.textures[texture_id];
1563            if let Ok(mut mapped) = cxtexture.platform.mapped.lock() {
1564                // lets try to get the texture at mapped.write
1565                let write = mapped.write;
1566                let texture = &mut mapped.textures[write % MAPPED_TEXTURE_BUFFER_COUNT];
1567                if !texture.locked { // no-op
1568                    return
1569                }
1570                texture.locked = false;
1571                mapped.write += 1; // increase the write pointer
1572            };
1573        }
1574    }
1575}*/