A shaders/shaders.hlsl => shaders/shaders.hlsl +9 -0
@@ 0,0 1,9 @@
+float4 vs_main( float4 pos : POSITION ) : SV_POSITION
+{
+ return pos;
+}
+
+float4 ps_main() : SV_TARGET
+{
+ return float4(1.0f, 1.0f, 1.0f, 1.0f);
+}
M src/d3d11.rs => src/d3d11.rs +22 -9
@@ 1,3 1,4 @@
+use std::ops::Deref;
use std::ptr::{null, null_mut};
use winapi::um::{d3d11, d3dcommon, d3dcompiler};
@@ 95,12 96,12 @@ impl D3D11Device {
}
}
- pub fn create_vertex_shader(&self, shader: &D3DBlob) -> Result<D3D11VertexShader, Error> {
+ pub fn create_vertex_shader(&self, shader: &[u8]) -> Result<D3D11VertexShader, Error> {
unsafe {
let mut ptr = null_mut();
let hr = self.0.CreateVertexShader(
- shader.0.GetBufferPointer(),
- shader.0.GetBufferSize(),
+ shader.as_ptr() as *const _,
+ shader.len(),
null_mut(),
&mut ptr,
);
@@ 108,12 109,12 @@ impl D3D11Device {
}
}
- pub fn create_pixel_shader(&self, shader: &D3DBlob) -> Result<D3D11PixelShader, Error> {
+ pub fn create_pixel_shader(&self, shader: &[u8]) -> Result<D3D11PixelShader, Error> {
unsafe {
let mut ptr = null_mut();
let hr = self.0.CreatePixelShader(
- shader.0.GetBufferPointer(),
- shader.0.GetBufferSize(),
+ shader.as_ptr() as *const _,
+ shader.len(),
null_mut(),
&mut ptr,
);
@@ 124,7 125,7 @@ impl D3D11Device {
pub fn create_input_layout(
&self,
descs: &[d3d11::D3D11_INPUT_ELEMENT_DESC],
- bytecode: &D3DBlob,
+ bytecode: &[u8],
) -> Result<D3D11InputLayout, Error> {
unsafe {
assert!(descs.len() <= 0xffff_ffff);
@@ 132,8 133,8 @@ impl D3D11Device {
let hr = self.0.CreateInputLayout(
descs.as_ptr(),
descs.len() as u32,
- bytecode.0.GetBufferPointer(),
- bytecode.0.GetBufferSize(),
+ bytecode.as_ptr() as *const _,
+ bytecode.len(),
&mut ptr,
);
wrap(hr, ptr, D3D11InputLayout)
@@ 234,3 235,15 @@ impl D3DBlob {
}
}
}
+
+impl Deref for D3DBlob {
+ type Target = [u8];
+
+ fn deref(&self) -> &[u8] {
+ unsafe {
+ let ptr = self.0.GetBufferPointer();
+ let size = self.0.GetBufferSize();
+ std::slice::from_raw_parts(ptr as *const _, size as usize)
+ }
+ }
+}
M src/main.rs => src/main.rs +16 -20
@@ 1,6 1,7 @@
use std::ptr::{null, null_mut};
-use winapi::shared::dxgi::DXGI_SWAP_EFFECT_FLIP_DISCARD;
+use winapi::shared::dxgi::DXGI_SWAP_EFFECT_SEQUENTIAL;
+// compatibility is good.
use winapi::shared::{dxgi1_2, dxgiformat, dxgitype, minwindef};
use winapi::shared::dxgiformat::DXGI_FORMAT_R32G32B32_FLOAT;
use winapi::um::d3dcommon::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
@@ 15,19 16,8 @@ mod util;
use d3d11::D3DBlob;
-const VERTEX_SHADER_HLSL: &str = r#"
-float4 main( float4 pos : POSITION ) : SV_POSITION
-{
- return pos;
-}
-"#;
+const SHADER_HLSL: &str = include_str!("../shaders/shaders.hlsl");
-const PIXEL_SHADER_HLSL: &str = r#"
-float4 main() : SV_TARGET
-{
- return float4(1.0f, 1.0f, 1.0f, 1.0f);
-}
-"#;
fn main() {
unsafe {
@@ 79,18 69,19 @@ fn main() {
},
Scaling: dxgi1_2::DXGI_SCALING_STRETCH,
Stereo: minwindef::FALSE,
- // Note: FLIP_DISCARD is Windows 8 only; negotiate
- SwapEffect: DXGI_SWAP_EFFECT_FLIP_DISCARD,
+ // Note: consider using flip-mode for higher performance. However,
+ // compatibility is good.
+ SwapEffect: DXGI_SWAP_EFFECT_SEQUENTIAL,
};
let mut swap_chain = dxgi_factory
.create_swapchain_for_hwnd(&d3d_device, hwnd, &desc)
.unwrap();
let vertex_shader_bc =
- D3DBlob::compile_shader(VERTEX_SHADER_HLSL, "vs_5_0", "main", 0).unwrap();
+ D3DBlob::compile_shader(SHADER_HLSL, "vs_5_0", "vs_main", 0).unwrap();
let vertex_shader = d3d_device.create_vertex_shader(&vertex_shader_bc).unwrap();
let pixel_shader_bc =
- D3DBlob::compile_shader(PIXEL_SHADER_HLSL, "ps_5_0", "main", 0).unwrap();
+ D3DBlob::compile_shader(SHADER_HLSL, "ps_5_0", "ps_main", 0).unwrap();
let pixel_shader = d3d_device.create_pixel_shader(&pixel_shader_bc).unwrap();
let ieds = [
@@ 144,15 135,20 @@ fn main() {
device_context.ia_set_primitive_topology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
device_context.draw(3, 0);
- swap_chain.present(1, 0).unwrap();
- // Show window after first present to avoid flash of background color.
+ // Defer window show to avoid flash of background color.
+ //
+ // With blit-model, the show has to happen before the present, otherwise
+ // the contents will be missing. With flip-model, it can happen after. The
+ // range of locations with no flash seems broad, so this seems like a good
+ // and simple compromise.
//
// I did some research and found that this is very conservative, lots of
// other combinations eliminate the flash, including just creating the
// d3d11 factory before creating the window (and using WS_VISIBLE). But
// this seems robust and doesn't seem to have a significant downside.
winuser::ShowWindow(hwnd, winuser::SW_SHOWNORMAL);
-
+ swap_chain.present(1, 0).unwrap();
+
loop {
let mut msg = std::mem::zeroed();
// Note: we filter on hwnd so we get an error when the window is closed.