larvyde
larvyde

Reputation: 811

gfx-rs assertion failure when trying to draw to a texture render target

I'm trying to draw to an offscreen render target

type ColorFormat = gfx::format::Rgba8;

gfx_defines! {
    pipeline terrain {
        // snip vbuffer / uniforms
        out: gfx::RenderTarget<ColorFormat> = "f_color",
        selection: gfx::RenderTarget<ColorFormat> = "f_selection",
    }
}

with a texture render target set to the same size as my window

let builder = glutin::WindowBuilder::new()
    .with_dimensions(1024, 768);

let (_, _, selection_target) = factory.create_render_target(1024, 768).unwrap();

let mut pd_terrain = terrain::Data {
    // snip
    out: color_view.clone(),
    selection: selection_target.clone(),
};

The code compiles fine, but at runtime I get a panic message that says something about dimensions

thread 'main' panicked at 'assertion failed: self.dimensions.map(|d| d == dim).unwrap_or(true)', /home/larvyde/.cargo/registry/src/github.com-1ecc6299db9ec823/gfx_core-0.8.2/src/pso.rs:293:8

The code works if I leave the selection target out of the pipeline.

My understanding is that it's complaining that the selection render target's dimensions don't match the color buffer's, but since both are set to the window dimensions, they should have been the same. So what is wrong here? Am I missing an initialization step or is my problem something else entirely?

EDIT: the libraries and versions I'm using are as follows

[dependencies]
cgmath = "0.16"
gfx = "0.17"
gfx_window_glutin = "0.20"
glutin = "0.12"

running with RUST_BACKTRACE=1 gives this:

   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
             at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at /checkout/src/libstd/sys_common/backtrace.rs:69
   2: std::panicking::default_hook::{{closure}}
             at /checkout/src/libstd/sys_common/backtrace.rs:58
             at /checkout/src/libstd/panicking.rs:381
   3: std::panicking::default_hook
             at /checkout/src/libstd/panicking.rs:397
   4: std::panicking::rust_panic_with_hook
             at /checkout/src/libstd/panicking.rs:577
   5: std::panicking::begin_panic
             at /checkout/src/libstd/panicking.rs:538
   6: <gfx_core::pso::PixelTargetSet<R>>::set_dimensions
             at ./<panic macros>:3
   7: <gfx_core::pso::PixelTargetSet<R>>::add_color
             at /home/larvyde/.cargo/registry/src/github.com-1ecc6299db9ec823/gfx_core-0.8.2/src/pso.rs:274
   8: <gfx::pso::target::RenderTarget<T> as gfx::pso::DataBind<R>>::bind_to
             at /home/larvyde/.cargo/registry/src/github.com-1ecc6299db9ec823/gfx-0.17.1/src/pso/target.rs:130
   9: <thera::terrain::Data<R> as gfx::pso::PipelineData<R>>::bake_to
             at ./<gfx_pipeline_inner macros>:99
  10: <gfx::encoder::Encoder<R, C>>::draw
             at /home/larvyde/.cargo/registry/src/github.com-1ecc6299db9ec823/gfx-0.17.1/src/encoder.rs:537
  11: thera::main
             at src/main.rs:155
  12: __rust_maybe_catch_panic
             at /checkout/src/libpanic_unwind/lib.rs:99
  13: std::rt::lang_start
             at /checkout/src/libstd/panicking.rs:459
             at /checkout/src/libstd/panic.rs:361
             at /checkout/src/libstd/rt.rs:59
  14: main
  15: __libc_start_main
  16: _start

Upvotes: 3

Views: 314

Answers (1)

Smasher816
Smasher816

Reputation: 31

The dimension is more than just a width and height, it also includes a depth. See https://docs.rs/gfx/0.17.1/gfx/handle/struct.DepthStencilView.html#method.get_dimensions. This must also be the same between the texture and target.

For reference, I hit the same assert in my code when using gfx_glpyh's draw_queued function. The function has the following signature

pub fn draw_queued<C, T, D>(
    &mut self, 
    encoder: &mut Encoder<R, C>, 
    target: &RenderTargetView<R, T>, 
    depth_target: &DepthStencilView<R, D>
) -> Result<(), String> 

The issue in my case was the render target (texture) had a depth of 0, but the depth_target (from my screen) had a depth of 1. To fix the issue I added the following to my pipeline definition

depth: gfx::DepthTarget<Depth> = gfx::preset::depth::PASS_TEST,

and created the following in my initialization passed to ::Data

let _depth = renderer.factory.create_depth_stencil_view_only(w as u16, h as u16).unwrap();

Using this depth instead of the one from gfx_window_glutin::init fixed the crash. I hope this guides you to a similar solution.

Upvotes: 1

Related Questions