Skip to content

Commit 930bda7

Browse files
committed
Merge #1620
1620: Pipeline deriving r=kvark a=msiglreith - Add support for deriving pipelines from other pipelines as supported in Vulkan. - Additional pipeline flag (ie disable optimizations) - Refactor pipeline descriptors a bit for compute and graphics Only HAL and Vulkan implemented so far, others require a few adjustment due to the new API. cc #1610
2 parents 342b4f9 + 8b66735 commit 930bda7

File tree

14 files changed

+278
-146
lines changed

14 files changed

+278
-146
lines changed

examples/hal/compute/main.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ fn main() {
6363
let pipeline_layout = gpu.device.create_pipeline_layout(&[&set_layout]);
6464
let entry_point = pso::EntryPoint { entry: "main", module: &shader };
6565
let pipeline = gpu.device
66-
.create_compute_pipelines(&[(entry_point, &pipeline_layout)])
66+
.create_compute_pipelines(&[
67+
pso::ComputePipelineDesc::new(entry_point, &pipeline_layout)
68+
])
6769
.remove(0)
6870
.expect("Error creating compute pipeline!");
6971

examples/hal/quad/main.rs

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -205,37 +205,6 @@ fn main() {
205205
device.create_render_pass(&[attachment], &[subpass], &[dependency])
206206
};
207207

208-
//
209-
let mut pipeline_desc = pso::GraphicsPipelineDesc::new(
210-
Primitive::TriangleList,
211-
pso::Rasterizer::FILL,
212-
);
213-
pipeline_desc.blender.targets.push(pso::ColorBlendDesc(
214-
pso::ColorMask::ALL,
215-
pso::BlendState::ALPHA,
216-
));
217-
pipeline_desc.vertex_buffers.push(pso::VertexBufferDesc {
218-
stride: std::mem::size_of::<Vertex>() as u32,
219-
rate: 0,
220-
});
221-
222-
pipeline_desc.attributes.push(pso::AttributeDesc {
223-
location: 0,
224-
binding: 0,
225-
element: pso::Element {
226-
format: Vec2::<f32>::SELF,
227-
offset: 0,
228-
},
229-
});
230-
pipeline_desc.attributes.push(pso::AttributeDesc {
231-
location: 1,
232-
binding: 0,
233-
element: pso::Element {
234-
format: Vec2::<f32>::SELF,
235-
offset: 8
236-
},
237-
});
238-
239208
//
240209
let pipelines = {
241210
//TODO: remove the type annotations when we have support for
@@ -259,10 +228,44 @@ fn main() {
259228
geometry: None,
260229
fragment: Some(fs_entry),
261230
};
231+
262232
let subpass = Subpass { index: 0, main_pass: &render_pass };
263-
device.create_graphics_pipelines(&[
264-
(shader_entries, &pipeline_layout, subpass, &pipeline_desc)
265-
])
233+
234+
let mut pipeline_desc = pso::GraphicsPipelineDesc::new(
235+
shader_entries,
236+
Primitive::TriangleList,
237+
pso::Rasterizer::FILL,
238+
&pipeline_layout,
239+
subpass,
240+
);
241+
pipeline_desc.blender.targets.push(pso::ColorBlendDesc(
242+
pso::ColorMask::ALL,
243+
pso::BlendState::ALPHA,
244+
));
245+
pipeline_desc.vertex_buffers.push(pso::VertexBufferDesc {
246+
stride: std::mem::size_of::<Vertex>() as u32,
247+
rate: 0,
248+
});
249+
250+
pipeline_desc.attributes.push(pso::AttributeDesc {
251+
location: 0,
252+
binding: 0,
253+
element: pso::Element {
254+
format: Vec2::<f32>::SELF,
255+
offset: 0,
256+
},
257+
});
258+
pipeline_desc.attributes.push(pso::AttributeDesc {
259+
location: 1,
260+
binding: 0,
261+
element: pso::Element {
262+
format: Vec2::<f32>::SELF,
263+
offset: 8
264+
},
265+
});
266+
267+
268+
device.create_graphics_pipelines(&[pipeline_desc])
266269
};
267270

268271
println!("pipelines: {:?}", pipelines);

src/backend/dx12/src/device.rs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -765,9 +765,9 @@ impl d::Device<B> for Device {
765765

766766
fn create_graphics_pipelines<'a>(
767767
&self,
768-
descs: &[(pso::GraphicsShaderSet<'a, B>, &n::PipelineLayout, pass::Subpass<'a, B>, &pso::GraphicsPipelineDesc)],
768+
descs: &[pso::GraphicsPipelineDesc<'a, B>],
769769
) -> Vec<Result<n::GraphicsPipeline, pso::CreationError>> {
770-
descs.iter().map(|&(shaders, ref signature, ref subpass, ref desc)| {
770+
descs.iter().map(|desc| {
771771
let build_shader = |source: Option<pso::EntryPoint<'a, B>>| {
772772
// TODO: better handle case where looking up shader fails
773773
let shader = source.and_then(|src| src.module.shaders.get(src.entry));
@@ -787,11 +787,11 @@ impl d::Device<B> for Device {
787787
}
788788
};
789789

790-
let vs = build_shader(Some(shaders.vertex));
791-
let fs = build_shader(shaders.fragment);
792-
let gs = build_shader(shaders.geometry);
793-
let ds = build_shader(shaders.domain);
794-
let hs = build_shader(shaders.hull);
790+
let vs = build_shader(Some(desc.shaders.vertex));
791+
let fs = build_shader(desc.shaders.fragment);
792+
let gs = build_shader(desc.shaders.geometry);
793+
let ds = build_shader(desc.shaders.domain);
794+
let hs = build_shader(desc.shaders.hull);
795795

796796
// Define input element descriptions
797797
let mut vs_reflect = shade::reflect_shader(&vs);
@@ -842,9 +842,12 @@ impl d::Device<B> for Device {
842842

843843
// TODO: check maximum number of rtvs
844844
// Get associated subpass information
845-
let pass = match subpass.main_pass.subpasses.get(subpass.index) {
846-
Some(subpass) => subpass,
847-
None => return Err(pso::CreationError::InvalidSubpass(subpass.index)),
845+
let pass = {
846+
let subpass = &desc.subpass;
847+
match subpass.main_pass.subpasses.get(subpass.index) {
848+
Some(subpass) => subpass,
849+
None => return Err(pso::CreationError::InvalidSubpass(subpass.index)),
850+
}
848851
};
849852

850853
// Get color attachment formats from subpass
@@ -854,7 +857,7 @@ impl d::Device<B> for Device {
854857
for (rtv, target) in rtvs.iter_mut()
855858
.zip(pass.color_attachments.iter())
856859
{
857-
let format = subpass.main_pass.attachments[target.0].format;
860+
let format = desc.subpass.main_pass.attachments[target.0].format;
858861
*rtv = conv::map_format(format).unwrap_or(winapi::DXGI_FORMAT_UNKNOWN);
859862
num_rtvs += 1;
860863
}
@@ -863,7 +866,7 @@ impl d::Device<B> for Device {
863866

864867
// Setup pipeline description
865868
let pso_desc = winapi::D3D12_GRAPHICS_PIPELINE_STATE_DESC {
866-
pRootSignature: signature.raw,
869+
pRootSignature: desc.layout.raw,
867870
VS: vs, PS: fs, GS: gs, DS: ds, HS: hs,
868871
StreamOutput: winapi::D3D12_STREAM_OUTPUT_DESC {
869872
pSODeclaration: ptr::null(),
@@ -889,7 +892,16 @@ impl d::Device<B> for Device {
889892
NumRenderTargets: num_rtvs,
890893
RTVFormats: rtvs,
891894
DSVFormat: pass.depth_stencil_attachment
892-
.and_then(|att_ref| conv::map_format_dsv(subpass.main_pass.attachments[att_ref.0].format.0))
895+
.and_then(|att_ref|
896+
conv::map_format_dsv(
897+
desc
898+
.subpass
899+
.main_pass
900+
.attachments[att_ref.0]
901+
.format
902+
.0
903+
)
904+
)
893905
.unwrap_or(winapi::DXGI_FORMAT_UNKNOWN),
894906
SampleDesc: winapi::DXGI_SAMPLE_DESC {
895907
Count: 1, // TODO
@@ -924,12 +936,12 @@ impl d::Device<B> for Device {
924936

925937
fn create_compute_pipelines<'a>(
926938
&self,
927-
descs: &[(pso::EntryPoint<'a, B>, &n::PipelineLayout)],
939+
descs: &[pso::ComputePipelineDesc<'a, B>],
928940
) -> Vec<Result<n::ComputePipeline, pso::CreationError>> {
929-
descs.iter().map(|&(shader, ref signature)| {
941+
descs.iter().map(|desc| {
930942
let cs = {
931943
// TODO: better handle case where looking up shader fails
932-
match shader.module.shaders.get(shader.entry) {
944+
match desc.shader.module.shaders.get(desc.shader.entry) {
933945
Some(shader) => {
934946
winapi::D3D12_SHADER_BYTECODE {
935947
pShaderBytecode: unsafe { (**shader).GetBufferPointer() as *const _ },
@@ -946,7 +958,7 @@ impl d::Device<B> for Device {
946958
};
947959

948960
let pso_desc = winapi::D3D12_COMPUTE_PIPELINE_STATE_DESC {
949-
pRootSignature: signature.raw,
961+
pRootSignature: desc.layout.raw,
950962
CS: cs,
951963
NodeMask: 0,
952964
CachedPSO: winapi::D3D12_CACHED_PIPELINE_STATE {

src/backend/empty/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,14 @@ impl hal::Device<Backend> for Device {
9797

9898
fn create_graphics_pipelines<'a>(
9999
&self,
100-
_: &[(pso::GraphicsShaderSet<'a, Backend>, &(), pass::Subpass<'a, Backend>, &pso::GraphicsPipelineDesc)],
100+
_: &[pso::GraphicsPipelineDesc<'a, Backend>],
101101
) -> Vec<Result<(), pso::CreationError>> {
102102
unimplemented!()
103103
}
104104

105105
fn create_compute_pipelines<'a>(
106106
&self,
107-
_: &[(pso::EntryPoint<'a, Backend>, &())],
107+
_: &[pso::ComputePipelineDesc<'a, Backend>],
108108
) -> Vec<Result<(), pso::CreationError>> {
109109
unimplemented!()
110110
}

src/backend/gl/src/device.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -233,16 +233,19 @@ impl d::Device<B> for Device {
233233

234234
fn create_graphics_pipelines<'a>(
235235
&self,
236-
descs: &[(pso::GraphicsShaderSet<'a, B>, &n::PipelineLayout, pass::Subpass<'a, B>, &pso::GraphicsPipelineDesc)],
236+
descs: &[pso::GraphicsPipelineDesc<'a, B>],
237237
) -> Vec<Result<n::GraphicsPipeline, pso::CreationError>> {
238238
let gl = &self.share.context;
239239
let priv_caps = &self.share.private_caps;
240240
let share = &self.share;
241241
descs.iter()
242-
.map(|&(shaders, _layout, subpass, _desc)| {
243-
let subpass = match subpass.main_pass.subpasses.get(subpass.index) {
244-
Some(sp) => sp,
245-
None => return Err(pso::CreationError::InvalidSubpass(subpass.index)),
242+
.map(|desc| {
243+
let subpass = {
244+
let subpass = desc.subpass;
245+
match subpass.main_pass.subpasses.get(subpass.index) {
246+
Some(sp) => sp,
247+
None => return Err(pso::CreationError::InvalidSubpass(subpass.index)),
248+
}
246249
};
247250

248251
let program = {
@@ -256,11 +259,11 @@ impl d::Device<B> for Device {
256259
};
257260

258261
// Attach shaders to program
259-
attach_shader(Some(shaders.vertex));
260-
attach_shader(shaders.hull);
261-
attach_shader(shaders.domain);
262-
attach_shader(shaders.geometry);
263-
attach_shader(shaders.fragment);
262+
attach_shader(Some(desc.shaders.vertex));
263+
attach_shader(desc.shaders.hull);
264+
attach_shader(desc.shaders.domain);
265+
attach_shader(desc.shaders.geometry);
266+
attach_shader(desc.shaders.fragment);
264267

265268
if !priv_caps.program_interface && priv_caps.frag_data_location {
266269
for i in 0..subpass.color_attachments.len() {
@@ -299,7 +302,7 @@ impl d::Device<B> for Device {
299302

300303
fn create_compute_pipelines<'a>(
301304
&self,
302-
_descs: &[(pso::EntryPoint<'a, B>, &n::PipelineLayout)],
305+
_descs: &[pso::ComputePipelineDesc<'a, B>],
303306
) -> Vec<Result<n::ComputePipeline, pso::CreationError>> {
304307
unimplemented!()
305308
}

src/backend/metal/src/device.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,11 @@ impl Device {
257257

258258
fn create_graphics_pipeline<'a>(
259259
&self,
260-
&(ref shader_set, pipeline_layout, ref pass_descriptor, pipeline_desc):
261-
&(pso::GraphicsShaderSet<'a, Backend>, &n::PipelineLayout, Subpass<'a, Backend>, &pso::GraphicsPipelineDesc),
260+
pipeline_desc: &pso::GraphicsPipelineDesc<'a, Backend>,
262261
) -> Result<n::GraphicsPipeline, pso::CreationError> {
263-
let pipeline = metal::RenderPipelineDescriptor::new();
262+
let pipeline = metal::RenderPipelineDescriptor::new();
263+
let pipeline_layout = &pipeline_desc.layout;
264+
let pass_descriptor = &pipeline_desc.subpass;
264265

265266
// FIXME: lots missing
266267

@@ -275,21 +276,21 @@ impl Device {
275276
pipeline.set_input_primitive_topology(primitive_class);
276277

277278
// Shaders
278-
let vs_lib = match shader_set.vertex.module {
279+
let vs_lib = match pipeline_desc.shaders.vertex.module {
279280
&n::ShaderModule::Compiled(ref lib) => lib.to_owned(),
280281
&n::ShaderModule::Raw(ref data) => {
281282
//TODO: cache them all somewhere!
282283
self.compile_shader_library(data, &pipeline_layout.res_overrides).unwrap()
283284
},
284285
};
285286
let mtl_vertex_function = vs_lib
286-
.get_function(shader_set.vertex.entry)
287+
.get_function(pipeline_desc.shaders.vertex.entry)
287288
.ok_or_else(|| {
288289
error!("invalid vertex shader entry point");
289290
pso::CreationError::Other
290291
})?;
291292
pipeline.set_vertex_function(Some(&mtl_vertex_function));
292-
let fs_lib = if let Some(fragment_entry) = shader_set.fragment {
293+
let fs_lib = if let Some(fragment_entry) = pipeline_desc.shaders.fragment {
293294
let fs_lib = match fragment_entry.module {
294295
&n::ShaderModule::Compiled(ref lib) => lib.to_owned(),
295296
&n::ShaderModule::Raw(ref data) => {
@@ -307,15 +308,15 @@ impl Device {
307308
} else {
308309
None
309310
};
310-
if shader_set.hull.is_some() {
311+
if pipeline_desc.shaders.hull.is_some() {
311312
error!("Metal tesselation shaders are not supported");
312313
return Err(pso::CreationError::Other);
313314
}
314-
if shader_set.domain.is_some() {
315+
if pipeline_desc.shaders.domain.is_some() {
315316
error!("Metal tesselation shaders are not supported");
316317
return Err(pso::CreationError::Other);
317318
}
318-
if shader_set.geometry.is_some() {
319+
if pipeline_desc.shaders.geometry.is_some() {
319320
error!("Metal geometry shaders are not supported");
320321
return Err(pso::CreationError::Other);
321322
}
@@ -542,7 +543,7 @@ impl hal::Device<Backend> for Device {
542543

543544
fn create_graphics_pipelines<'a>(
544545
&self,
545-
params: &[(pso::GraphicsShaderSet<'a, Backend>, &n::PipelineLayout, Subpass<'a, Backend>, &pso::GraphicsPipelineDesc)],
546+
params: &[pso::GraphicsPipelineDesc<'a, Backend>],
546547
) -> Vec<Result<n::GraphicsPipeline, pso::CreationError>> {
547548
let mut output = Vec::with_capacity(params.len());
548549
for param in params {
@@ -553,7 +554,7 @@ impl hal::Device<Backend> for Device {
553554

554555
fn create_compute_pipelines<'a>(
555556
&self,
556-
_pipelines: &[(pso::EntryPoint<'a, Backend>, &n::PipelineLayout)],
557+
_pipelines: &[pso::ComputePipelineDesc<'a, Backend>],
557558
) -> Vec<Result<n::ComputePipeline, pso::CreationError>> {
558559
unimplemented!()
559560
}

0 commit comments

Comments
 (0)