Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for win32 array parameters #479

Closed
Nerixyz opened this issue Jan 31, 2021 · 3 comments · Fixed by #1562
Closed

Support for win32 array parameters #479

Nerixyz opened this issue Jan 31, 2021 · 3 comments · Fixed by #1562
Labels
enhancement New feature or request

Comments

@Nerixyz
Copy link
Contributor

Nerixyz commented Jan 31, 2021

Hi, I'm trying out the Direct 3D Api in conjunction with VLC. I'm pretty much following an example provided by VLC here.

When creating the Direct 3D related things, I need to use the method/function ID3D11DeviceContext::OMSetRenderTargets. In the documentation from Microsoft in C++, the second parameter ppRenderTargetViews is a pointer to an array.

This is the generated documentation for this method.

Generated bindings
pub fn OMSetRenderTargets<
    'a,
    T1__: ::std::convert::Into<::windows::Param<'a, ID3D11RenderTargetView>>,
    T2__: ::std::convert::Into<::windows::Param<'a, ID3D11DepthStencilView>>,
>(
    &self,
    num_views: u32,
    pp_render_target_views: T1__,
    p_depth_stencil_view: T2__,
) {
    unsafe {
        (::windows::Interface::vtable(self).33)(
            ::windows::Abi::abi(self),
            num_views,
            pp_render_target_views.into().abi(),
            p_depth_stencil_view.into().abi(),
        )
    }
}

In the C++ version, the method is called like this:

// swapchainRenderTarget is declared like this: ID3D11RenderTargetView *swapchainRenderTarget
 ctx->d3dctx->OMSetRenderTargets(1, &ctx->swapchainRenderTarget, NULL);

Now when I try to call the method like in the following example, the program just sleeps/waits until it's stopped. So there's something wrong.

// swapchain_render_target: ID3D11RenderTargetView
device_context.OMSetRenderTargets(1, &swapchain_render_target, None);

How do I call the method with the correct argument?

My code
let scd = DXGI_SWAP_CHAIN_DESC {
    buffer_count: 1,
    buffer_desc: DXGI_MODE_DESC {
        width: dimensions.x as u32,
        height: dimensions.y as u32,
        format: DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM,
        ..Default::default()
    },
    buffer_usage: DXGI_USAGE_RENDER_TARGET_OUTPUT,
    output_window: hwnd,
    sample_desc: DXGI_SAMPLE_DESC {
        count: 1,
        ..Default::default()
    },
    windowed: true.into(),
    flags: DXGI_SWAP_CHAIN_FLAG::DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH.0 as u32,
    ..Default::default()
};

let (device, device_context, swapchain) = unsafe {
    let mut device = None;
    let mut swapchain = None;
    let mut device_context = None;
    let hr = D3D11CreateDeviceAndSwapChain(
        None,
        D3D_DRIVER_TYPE::D3D_DRIVER_TYPE_HARDWARE,
        0,
         D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_DEBUG.0 as u32,
        ptr::null(),
        0,
        D3D11_SDK_VERSION as u32,
        &scd,
        &mut swapchain,
        &mut device,
        ptr::null_mut(),
        &mut device_context,
    );
    match (device, device_context, swapchain) {
        (Some(device), Some(ctx), Some(swap)) => (device, ctx, swap),
        _ => return Err(bindings::windows::Error::new(
            hr,
            "Failed to create device/ctx/swapchain",
        ))
    }
};
println!("Created Device & Ctx & Swapchain");

if let Ok(mt) = device.cast::<ID3D10Multithread>() {
    mt.SetMultithreadProtected(true.into());
}
println!("Set Multithread protection");

let viewport = D3D11_VIEWPORT {
    width: dimensions.x,
    height: dimensions.y,
    max_depth: 0.0,
    min_depth: 0.0,
    top_leftx: 0.0,
    top_lefty: 0.0,
};

device_context.RSSetViewports(1, &viewport);
println!("Set Viewport");

let mut back_buffer: Option<ID3D11Texture2D> = None;
let hr = swapchain.GetBuffer(0, &ID3D11Texture2D::IID, &mut back_buffer as *mut _ as _);
let back_buffer = back_buffer.ok_or_else(|| bindings::windows::Error::new(
    hr,
    "Failed to create back buffer",
))?;
println!("Created BackBuffer");

let mut swapchain_render_target = None;
let hr = device.CreateRenderTargetView(back_buffer, ptr::null(), &mut swapchain_render_target);
let swapchain_render_target = swapchain_render_target.ok_or_else(|| bindings::windows::Error::new(
    hr,
    "Failed to create render target",
))?;
println!("Created RenderTarget");

device_context.OMSetRenderTargets(1, &swapchain_render_target, None);

// This is never logged
println!("Set RenderTarget");
@kennykerr kennykerr added the question Further information is requested label Feb 1, 2021
@kennykerr
Copy link
Collaborator

Sorry for the delay in responding. Array support is coming soon. That should address this issue.

@kennykerr kennykerr changed the title [Question] Pointer to Array - OMSetRenderTargets Support for win32 array parameters Mar 16, 2021
@kennykerr kennykerr added enhancement New feature or request and removed question Further information is requested labels Jun 23, 2021
@kennykerr
Copy link
Collaborator

Windows::Win32::Graphics::Imaging::IWICBitmapSource's CopyPixels is another example.

@kennykerr
Copy link
Collaborator

Sorry for the delay, #1562 adds support for Win32 array parameters and fixes this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants