~raph/dx11-toy

f1702b8acec835414316447b13ea845584f7c5e6 — Raph Levien 2 years ago 9660d37
Clear the buffer to a solid color
4 files changed, 111 insertions(+), 6 deletions(-)

M src/d3d11.rs
M src/dxgi.rs
M src/main.rs
M src/util.rs
M src/d3d11.rs => src/d3d11.rs +28 -1
@@ 1,4 1,4 @@
use std::ptr::null_mut;
use std::ptr::{null, null_mut};

use winapi::um::{d3d11, d3dcommon};



@@ 8,6 8,8 @@ use crate::util::{wrap, Error};

pub struct D3D11Device(ComPtr<d3d11::ID3D11Device>);
pub struct D3D11DeviceContext(ComPtr<d3d11::ID3D11DeviceContext>);
pub struct D3D11Texture2D(pub ComPtr<d3d11::ID3D11Texture2D>);
pub struct D3D11RenderTargetView(pub ComPtr<d3d11::ID3D11RenderTargetView>);

impl D3D11Device {
    // This function only supports a fraction of available options.


@@ 32,4 34,29 @@ impl D3D11Device {
            Ok((device, device_ctx))
        }
    }

    pub fn as_raw(&self) -> *mut d3d11::ID3D11Device {
        self.0.as_raw()
    }

    pub fn create_render_target_view(
        &self,
        resource: &D3D11Texture2D,
    ) -> Result<D3D11RenderTargetView, Error> {
        unsafe {
            let mut ptr = null_mut();
            let hr = self
                .0
                .CreateRenderTargetView(resource.0.as_raw() as *mut _, null(), &mut ptr);
            wrap(hr, ptr, D3D11RenderTargetView)
        }
    }
}

impl D3D11DeviceContext {
    pub fn clear_render_target_view(&mut self, rtv: &mut D3D11RenderTargetView, color: &[f32; 4]) {
        unsafe {
            self.0.ClearRenderTargetView(rtv.0.as_raw(), color);
        }
    }
}

M src/dxgi.rs => src/dxgi.rs +45 -3
@@ 1,13 1,16 @@
use std::ptr::null_mut;
use std::ptr::{null, null_mut};

use winapi::shared::{dxgi, dxgi1_2};
use winapi::shared::{dxgi, dxgi1_2, windef};
use winapi::um::d3d11;
use winapi::Interface;

use wio::com::ComPtr;

use crate::util::{wrap, Error};
use crate::d3d11::{D3D11Device, D3D11Texture2D};
use crate::util::{wrap, wrap_unit, Error};

pub struct DXGIFactory2(ComPtr<dxgi1_2::IDXGIFactory2>);
pub struct DXGISwapChain1(ComPtr<dxgi1_2::IDXGISwapChain1>);

impl DXGIFactory2 {
    pub fn create() -> Result<DXGIFactory2, Error> {


@@ 20,4 23,43 @@ impl DXGIFactory2 {
            wrap(hr, ptr, DXGIFactory2)
        }
    }

    pub unsafe fn create_swapchain_for_hwnd(
        &self,
        device: &D3D11Device,
        hwnd: windef::HWND,
        desc: &dxgi1_2::DXGI_SWAP_CHAIN_DESC1,
    ) -> Result<DXGISwapChain1, Error> {
        let mut ptr = null_mut();
        let hr = self.0.CreateSwapChainForHwnd(
            device.as_raw() as *mut _,
            hwnd,
            desc,
            null(),
            null_mut(),
            &mut ptr as *mut _ as *mut _,
        );
        wrap(hr, ptr, DXGISwapChain1)
    }
}

impl DXGISwapChain1 {
    pub fn present(&self, sync_interval: u32, flags: u32) -> Result<(), Error> {
        unsafe {
            let hr = self.0.Present(sync_interval, flags);
            wrap_unit(hr)
        }
    }

    pub fn get_buffer(&mut self, buffer: u32) -> Result<D3D11Texture2D, Error> {
        unsafe {
            let mut ptr = null_mut();
            let hr = self.0.GetBuffer(
                buffer,
                &d3d11::ID3D11Texture2D::uuidof(),
                &mut ptr as *mut _ as *mut _,
            );
            wrap(hr, ptr, D3D11Texture2D)
        }
    }
}

M src/main.rs => src/main.rs +30 -2
@@ 1,6 1,8 @@
use std::ptr::{null, null_mut};

use winapi::um::{errhandlingapi, wingdi, winuser};
use winapi::shared::dxgi::DXGI_SWAP_EFFECT_FLIP_DISCARD;
use winapi::shared::{dxgi1_2, dxgiformat, dxgitype, minwindef};
use winapi::um::{wingdi, winuser};

use wio::wide::ToWide;



@@ 42,8 44,34 @@ fn main() {
            null_mut(),
        );

        let (d3d_device, d3d_device_context) = d3d11::D3D11Device::create().unwrap();
        let (d3d_device, mut d3d_device_context) = d3d11::D3D11Device::create().unwrap();
        let dxgi_factory = dxgi::DXGIFactory2::create().unwrap();
        let desc = dxgi1_2::DXGI_SWAP_CHAIN_DESC1 {
            Width: 0,
            Height: 0,
            AlphaMode: dxgi1_2::DXGI_ALPHA_MODE_IGNORE,
            BufferCount: 2,
            Format: dxgiformat::DXGI_FORMAT_B8G8R8A8_UNORM,
            Flags: 0,
            BufferUsage: dxgitype::DXGI_USAGE_RENDER_TARGET_OUTPUT,
            SampleDesc: dxgitype::DXGI_SAMPLE_DESC {
                Count: 1,
                Quality: 0,
            },
            Scaling: dxgi1_2::DXGI_SCALING_STRETCH,
            Stereo: minwindef::FALSE,
            // Note: FLIP_DISCARD is Windows 8 only; negotiate
            SwapEffect: DXGI_SWAP_EFFECT_FLIP_DISCARD,
        };
        let mut swap_chain = dxgi_factory
            .create_swapchain_for_hwnd(&d3d_device, hwnd, &desc)
            .unwrap();

        let buf = swap_chain.get_buffer(0).unwrap();
        let mut rtv = d3d_device.create_render_target_view(&buf).unwrap();
        d3d_device_context.clear_render_target_view(&mut rtv, &[0.0, 0.2, 0.4, 1.0]);

        swap_chain.present(1, 0).unwrap();

        loop {
            let mut msg = std::mem::zeroed();

M src/util.rs => src/util.rs +8 -0
@@ 17,3 17,11 @@ where
        Err(Error(hr))
    }
}

pub fn wrap_unit(hr: HRESULT) -> Result<(), Error> {
    if SUCCEEDED(hr) {
        Ok(())
    } else {
        Err(Error(hr))
    }
}