mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 06:45:23 +00:00
Add push constants example (#1072)
This commit is contained in:
parent
37de51eeef
commit
4633c72bab
@ -77,7 +77,7 @@ fn main() {
|
|||||||
// We need to create the compute pipeline that describes our operation.
|
// We need to create the compute pipeline that describes our operation.
|
||||||
//
|
//
|
||||||
// If you are familiar with graphics pipeline, the principle is the same except that compute
|
// If you are familiar with graphics pipeline, the principle is the same except that compute
|
||||||
// pipelines are much more simple to create.
|
// pipelines are much simpler to create.
|
||||||
let pipeline = Arc::new({
|
let pipeline = Arc::new({
|
||||||
// TODO: explain
|
// TODO: explain
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
111
examples/src/bin/push-constants.rs
Normal file
111
examples/src/bin/push-constants.rs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
// Copyright (c) 2017 The vulkano developers
|
||||||
|
// Licensed under the Apache License, Version 2.0
|
||||||
|
// <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
|
||||||
|
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||||
|
// at your option. All files in the project carrying such
|
||||||
|
// notice may not be copied, modified, or distributed except
|
||||||
|
// according to those terms.
|
||||||
|
|
||||||
|
// TODO: Give a paragraph about what push constants are and what problems they solve
|
||||||
|
extern crate vulkano;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate vulkano_shader_derive;
|
||||||
|
|
||||||
|
use vulkano::buffer::BufferUsage;
|
||||||
|
use vulkano::buffer::CpuAccessibleBuffer;
|
||||||
|
use vulkano::command_buffer::AutoCommandBufferBuilder;
|
||||||
|
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
|
||||||
|
use vulkano::device::Device;
|
||||||
|
use vulkano::device::DeviceExtensions;
|
||||||
|
use vulkano::instance::Instance;
|
||||||
|
use vulkano::instance::InstanceExtensions;
|
||||||
|
use vulkano::pipeline::ComputePipeline;
|
||||||
|
use vulkano::sync::now;
|
||||||
|
use vulkano::sync::GpuFuture;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
|
||||||
|
let physical = vulkano::instance::PhysicalDevice::enumerate(&instance).next().unwrap();
|
||||||
|
let queue_family = physical.queue_families().find(|&q| q.supports_compute()).unwrap();
|
||||||
|
let (device, mut queues) = {
|
||||||
|
Device::new(physical, physical.supported_features(), &DeviceExtensions::none(),
|
||||||
|
[(queue_family, 0.5)].iter().cloned()).expect("failed to create device")
|
||||||
|
};
|
||||||
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
|
mod cs {
|
||||||
|
#[derive(VulkanoShader)]
|
||||||
|
#[ty = "compute"]
|
||||||
|
#[src = "
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
|
||||||
|
layout(push_constant) uniform PushConstantData {
|
||||||
|
int multiple;
|
||||||
|
float addend;
|
||||||
|
bool enable;
|
||||||
|
} pc;
|
||||||
|
|
||||||
|
layout(set = 0, binding = 0) buffer Data {
|
||||||
|
uint data[];
|
||||||
|
} data;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
uint idx = gl_GlobalInvocationID.x;
|
||||||
|
if (pc.enable) {
|
||||||
|
data.data[idx] *= pc.multiple;
|
||||||
|
data.data[idx] += uint(pc.addend);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
struct Dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
let shader = cs::Shader::load(device.clone())
|
||||||
|
.expect("failed to create shader module");
|
||||||
|
let pipeline = Arc::new(ComputePipeline::new(device.clone(), &shader.main_entry_point(), &()).unwrap());
|
||||||
|
|
||||||
|
let data_buffer = {
|
||||||
|
let data_iter = (0 .. 65536u32).map(|n| n);
|
||||||
|
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(),
|
||||||
|
data_iter).expect("failed to create buffer")
|
||||||
|
};
|
||||||
|
|
||||||
|
let set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0)
|
||||||
|
.add_buffer(data_buffer.clone()).unwrap()
|
||||||
|
.build().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
// The `vulkano_shaders!` macro generates a struct with the correct representation of the push constants struct specified in the shader.
|
||||||
|
// Here we create an instance of the generated struct.
|
||||||
|
let push_constants = cs::ty::PushConstantData {
|
||||||
|
multiple: 1,
|
||||||
|
addend: 1.0,
|
||||||
|
enable: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// For a compute pipeline, push constants are passed to the `dispatch` method.
|
||||||
|
// For a graphics pipeline, push constants are passed to the `draw` and `draw_indexed` methods.
|
||||||
|
// Note that there is no type safety for the push constants argument.
|
||||||
|
// So be careful to only pass an instance of the struct generated by the `vulkano_shaders!` macro.
|
||||||
|
let command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap()
|
||||||
|
.dispatch([1024, 1, 1], pipeline.clone(), set.clone(), push_constants).unwrap()
|
||||||
|
.build().unwrap();
|
||||||
|
|
||||||
|
let future = now(device.clone())
|
||||||
|
.then_execute(queue.clone(), command_buffer).unwrap()
|
||||||
|
.then_signal_fence_and_flush().unwrap();
|
||||||
|
|
||||||
|
future.wait(None).unwrap();
|
||||||
|
|
||||||
|
let data_buffer_content = data_buffer.read().expect("failed to lock buffer for reading");
|
||||||
|
for n in 0 .. 65536u32 {
|
||||||
|
assert_eq!(data_buffer_content[n as usize], n * 1 + 1);
|
||||||
|
}
|
||||||
|
println!("Success");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user