mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-27 01:03:41 +00:00
[hlsl-out] Return entry points name to users
This commit is contained in:
parent
391983459a
commit
e28344edbb
@ -304,9 +304,12 @@ fn main() {
|
||||
}
|
||||
"hlsl" => {
|
||||
use naga::back::hlsl;
|
||||
let hlsl = hlsl::write_string(&module, info.as_ref().unwrap(), ¶ms.hlsl)
|
||||
let mut buffer = String::new();
|
||||
let mut writer = hlsl::Writer::new(&mut buffer, ¶ms.hlsl);
|
||||
writer
|
||||
.write(&module, info.as_ref().unwrap())
|
||||
.unwrap_pretty();
|
||||
fs::write(output_path, hlsl).unwrap();
|
||||
fs::write(output_path, buffer).unwrap();
|
||||
}
|
||||
"wgsl" => {
|
||||
use naga::back::wgsl;
|
||||
|
@ -15,30 +15,45 @@ pub enum ShaderModel {
|
||||
V6_0,
|
||||
}
|
||||
|
||||
impl ShaderModel {
|
||||
pub fn to_profile_string(self, stage: crate::ShaderStage) -> String {
|
||||
let stage_prefix = match stage {
|
||||
crate::ShaderStage::Vertex => "vs_",
|
||||
crate::ShaderStage::Fragment => "ps_",
|
||||
crate::ShaderStage::Compute => "cs_",
|
||||
};
|
||||
|
||||
let version = match self {
|
||||
Self::V5_0 => "5_0",
|
||||
Self::V5_1 => "5_1",
|
||||
Self::V6_0 => "6_0",
|
||||
};
|
||||
|
||||
format!("{}{}", stage_prefix, version)
|
||||
}
|
||||
}
|
||||
|
||||
/// Structure that contains the configuration used in the [`Writer`](Writer)
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Options {
|
||||
/// The hlsl shader model to be used
|
||||
pub shader_model: ShaderModel,
|
||||
/// The vertex entry point name in generated shader
|
||||
pub vertex_entry_point_name: String,
|
||||
/// The fragment entry point name in generated shader
|
||||
pub fragment_entry_point_name: String,
|
||||
/// The comput entry point name in generated shader
|
||||
pub compute_entry_point_name: String,
|
||||
}
|
||||
|
||||
impl Default for Options {
|
||||
fn default() -> Self {
|
||||
Options {
|
||||
shader_model: ShaderModel::V5_0,
|
||||
vertex_entry_point_name: String::from("vert_main"),
|
||||
fragment_entry_point_name: String::from("frag_main"),
|
||||
compute_entry_point_name: String::from("comp_main"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReflectionInfo {
|
||||
/// Information about all entry points (stage, name).
|
||||
pub entry_points: Vec<(crate::ShaderStage, String)>,
|
||||
// TODO: locations
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error {
|
||||
#[error(transparent)]
|
||||
@ -50,14 +65,3 @@ pub enum Error {
|
||||
#[error("{0}")]
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
pub fn write_string(
|
||||
module: &crate::Module,
|
||||
info: &crate::valid::ModuleInfo,
|
||||
options: &Options,
|
||||
) -> Result<String, Error> {
|
||||
let mut w = Writer::new(String::new(), options);
|
||||
w.write(module, info)?;
|
||||
let output = w.finish();
|
||||
Ok(output)
|
||||
}
|
||||
|
@ -13,9 +13,14 @@ const LOCATION_SEMANTIC: &str = "LOC";
|
||||
/// Shorthand result used internally by the backend
|
||||
type BackendResult = Result<(), Error>;
|
||||
|
||||
/// Structure contains information required for generating
|
||||
/// wrapped structure of all entry points arguments
|
||||
struct EntryPointBinding {
|
||||
/// Associated shader stage
|
||||
stage: ShaderStage,
|
||||
/// Generated structure name
|
||||
name: String,
|
||||
/// Members of generated structure
|
||||
members: Vec<EpStructMember>,
|
||||
}
|
||||
|
||||
@ -29,8 +34,11 @@ pub struct Writer<'a, W> {
|
||||
out: W,
|
||||
names: crate::FastHashMap<NameKey, String>,
|
||||
namer: proc::Namer,
|
||||
/// HLSL backend options
|
||||
options: &'a Options,
|
||||
/// Information about entry point arguments wrapped into structure
|
||||
ep_inputs: Vec<Option<EntryPointBinding>>,
|
||||
/// Set of expressions that have associated temporary variables
|
||||
named_expressions: crate::NamedExpressions,
|
||||
}
|
||||
|
||||
@ -54,7 +62,11 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
self.ep_inputs.clear();
|
||||
}
|
||||
|
||||
pub fn write(&mut self, module: &Module, info: &valid::ModuleInfo) -> BackendResult {
|
||||
pub fn write(
|
||||
&mut self,
|
||||
module: &Module,
|
||||
info: &valid::ModuleInfo,
|
||||
) -> Result<super::ReflectionInfo, Error> {
|
||||
self.reset(module);
|
||||
|
||||
// Write all constants
|
||||
@ -102,7 +114,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
|
||||
// Write all entry points wrapped structs
|
||||
for (index, ep) in module.entry_points.iter().enumerate() {
|
||||
self.write_ep_input_struct(module, &ep.function, ep.stage, index)?;
|
||||
self.write_ep_input_struct(module, &ep.function, ep.stage, &ep.name, index)?;
|
||||
}
|
||||
|
||||
// Write all regular functions
|
||||
@ -121,6 +133,8 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
writeln!(self.out)?;
|
||||
}
|
||||
|
||||
let mut entry_points_info = Vec::with_capacity(module.entry_points.len());
|
||||
|
||||
// Write all entry points
|
||||
for (index, ep) in module.entry_points.iter().enumerate() {
|
||||
let ctx = back::FunctionCtx {
|
||||
@ -140,20 +154,20 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
)?;
|
||||
}
|
||||
|
||||
let name = match ep.stage {
|
||||
ShaderStage::Vertex => &self.options.vertex_entry_point_name,
|
||||
ShaderStage::Fragment => &self.options.fragment_entry_point_name,
|
||||
ShaderStage::Compute => &self.options.compute_entry_point_name,
|
||||
};
|
||||
let name = self.names[&NameKey::EntryPoint(index as u16)].clone();
|
||||
|
||||
self.write_function(module, name, &ep.function, &ctx)?;
|
||||
self.write_function(module, &name, &ep.function, &ctx)?;
|
||||
|
||||
if index < module.entry_points.len() - 1 {
|
||||
writeln!(self.out)?;
|
||||
}
|
||||
|
||||
entry_points_info.push((ep.stage, name))
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(super::ReflectionInfo {
|
||||
entry_points: entry_points_info,
|
||||
})
|
||||
}
|
||||
|
||||
fn write_binding(&mut self, binding: &crate::Binding) -> BackendResult {
|
||||
@ -174,14 +188,16 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
module: &Module,
|
||||
func: &crate::Function,
|
||||
stage: ShaderStage,
|
||||
entry_point_name: &str,
|
||||
index: usize,
|
||||
) -> BackendResult {
|
||||
if !func.arguments.is_empty() {
|
||||
let struct_name = self.namer.call_unique(match stage {
|
||||
let struct_name_prefix = match stage {
|
||||
ShaderStage::Vertex => "VertexInput",
|
||||
ShaderStage::Fragment => "FragmentInput",
|
||||
ShaderStage::Compute => "ComputeInput",
|
||||
});
|
||||
};
|
||||
let struct_name = format!("{}_{}", struct_name_prefix, entry_point_name);
|
||||
|
||||
let mut members = Vec::with_capacity(func.arguments.len());
|
||||
|
||||
@ -1058,10 +1074,6 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn finish(self) -> W {
|
||||
self.out
|
||||
}
|
||||
}
|
||||
|
||||
fn image_dimension_str(dim: crate::ImageDimension) -> &'static str {
|
||||
|
@ -29,3 +29,10 @@ fn main([[location(0)]] uv : vec2<f32>) -> [[location(0)]] vec4<f32> {
|
||||
let premultiplied = color.a * color;
|
||||
return premultiplied;
|
||||
}
|
||||
|
||||
|
||||
// We need to make sure that backends are successfully handling multiple entry points for the same shader stage.
|
||||
//[[stage(fragment)]]
|
||||
//fn fs_extra() -> [[location(0)]] vec4<f32> {
|
||||
// return vec4<f32>(0.0, 0.5, 0.0, 0.5);
|
||||
//}
|
||||
|
@ -1,5 +1,5 @@
|
||||
[numthreads(1, 1, 1)]
|
||||
void comp_main()
|
||||
void main()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
compute=cs_5_0
|
||||
compute_name=comp_main
|
||||
compute_name=main
|
||||
|
@ -18,7 +18,7 @@ static float2 a_uv1;
|
||||
static gl_PerVertex perVertexStruct = { float4(0.0, 0.0, 0.0, 1.0), 1.0, float(0.0), float(0.0) };
|
||||
static float2 a_pos1;
|
||||
|
||||
struct VertexInput {
|
||||
struct VertexInput_main {
|
||||
float2 a_uv2 : LOC1;
|
||||
float2 a_pos2 : LOC0;
|
||||
};
|
||||
@ -32,10 +32,10 @@ void main1()
|
||||
return;
|
||||
}
|
||||
|
||||
type10 vert_main(VertexInput vertexinput)
|
||||
type10 main(VertexInput_main vertexinput_main)
|
||||
{
|
||||
a_uv1 = vertexinput.a_uv2;
|
||||
a_pos1 = vertexinput.a_pos2;
|
||||
a_uv1 = vertexinput_main.a_uv2;
|
||||
a_pos1 = vertexinput_main.a_pos2;
|
||||
main1();
|
||||
float2 _expr10 = v_uv;
|
||||
float4 _expr11 = perVertexStruct.gl_Position;
|
||||
|
@ -1,2 +1,2 @@
|
||||
vertex=vs_5_0
|
||||
vertex_name=vert_main
|
||||
vertex_name=main
|
||||
|
@ -8,24 +8,24 @@ struct VertexOutput {
|
||||
Texture2D<float4> u_texture : register(t0);
|
||||
SamplerState u_sampler : register(s1);
|
||||
|
||||
struct VertexInput {
|
||||
struct VertexInput_main {
|
||||
float2 pos1 : LOC0;
|
||||
float2 uv2 : LOC1;
|
||||
};
|
||||
|
||||
struct FragmentInput {
|
||||
struct FragmentInput_main {
|
||||
float2 uv3 : LOC0;
|
||||
};
|
||||
|
||||
VertexOutput vert_main(VertexInput vertexinput)
|
||||
VertexOutput main(VertexInput_main vertexinput_main)
|
||||
{
|
||||
const VertexOutput vertexoutput1 = { vertexinput.uv2, float4((c_scale * vertexinput.pos1), 0.0, 1.0) };
|
||||
const VertexOutput vertexoutput1 = { vertexinput_main.uv2, float4((c_scale * vertexinput_main.pos1), 0.0, 1.0) };
|
||||
return vertexoutput1;
|
||||
}
|
||||
|
||||
float4 frag_main(FragmentInput fragmentinput) : SV_Target0
|
||||
float4 main1(FragmentInput_main fragmentinput_main) : SV_Target0
|
||||
{
|
||||
float4 color = u_texture.Sample(u_sampler, fragmentinput.uv3);
|
||||
float4 color = u_texture.Sample(u_sampler, fragmentinput_main.uv3);
|
||||
if ((color.w == 0.0)) {
|
||||
discard;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
vertex=vs_5_0
|
||||
vertex_name=vert_main
|
||||
vertex_name=main
|
||||
fragment=ps_5_0
|
||||
fragment_name=frag_main
|
||||
fragment_name=main1
|
||||
|
@ -261,26 +261,30 @@ fn write_output_hlsl(
|
||||
file_name: &str,
|
||||
) {
|
||||
use naga::back::hlsl;
|
||||
let mut buffer = String::new();
|
||||
let options = hlsl::Options::default();
|
||||
let string = hlsl::write_string(module, info, &options).unwrap();
|
||||
let mut writer = hlsl::Writer::new(&mut buffer, &options);
|
||||
let reflection_info = writer.write(module, info).unwrap();
|
||||
|
||||
fs::write(destination.join(format!("hlsl/{}.hlsl", file_name)), string).unwrap();
|
||||
fs::write(destination.join(format!("hlsl/{}.hlsl", file_name)), buffer).unwrap();
|
||||
|
||||
// We need a config file for validation script
|
||||
// This file contains an info about profiles (shader stages) contains inside generated shader
|
||||
// This info will be passed to dxc
|
||||
let mut config_str = String::from("");
|
||||
for ep in module.entry_points.iter() {
|
||||
let (stage_str, profile, ep_name) = match ep.stage {
|
||||
naga::ShaderStage::Vertex => ("vertex", "vs_5_0", &options.vertex_entry_point_name),
|
||||
naga::ShaderStage::Fragment => {
|
||||
("fragment", "ps_5_0", &options.fragment_entry_point_name)
|
||||
}
|
||||
naga::ShaderStage::Compute => ("compute", "cs_5_0", &options.compute_entry_point_name),
|
||||
for (stage, name) in reflection_info.entry_points.iter() {
|
||||
let stage_str = match stage {
|
||||
naga::ShaderStage::Vertex => "vertex",
|
||||
naga::ShaderStage::Fragment => "fragment",
|
||||
naga::ShaderStage::Compute => "compute",
|
||||
};
|
||||
config_str = format!(
|
||||
"{}{}={}\n{}_name={}\n",
|
||||
config_str, stage_str, profile, stage_str, ep_name
|
||||
config_str,
|
||||
stage_str,
|
||||
options.shader_model.to_profile_string(*stage),
|
||||
stage_str,
|
||||
name
|
||||
);
|
||||
}
|
||||
fs::write(
|
||||
|
Loading…
Reference in New Issue
Block a user