Skip to content

Geometry shader support #10

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 16 additions & 45 deletions ext/update_shaderc_sources.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env python

# Copyright 2016 The Shaderc Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -13,33 +12,23 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Get source files for Shaderc and its dependencies from public repositories.
"""

from __future__ import print_function

"""Get source files for Shaderc and its dependencies from public
repositories."""
from operator import attrgetter
import argparse
import json
import distutils.dir_util
import os.path
import subprocess
import sys

KNOWN_GOOD_FILE = 'known_good.json'

# Maps a site name to its hostname.
SITE_TO_HOST = { 'github' : 'github.com',
'gitlab' : 'gitlab.com'}

SITE_TO_HOST = {'github': 'github.com',
'gitlab': 'gitlab.com'}
VERBOSE = True


def command_output(cmd, directory, fail_ok=False):
"""Runs a command in a directory and returns its standard output stream.

Captures the standard error stream.

Raises a RuntimeError if the command fails to launch or otherwise fails.
"""
if VERBOSE:
Expand All @@ -53,14 +42,10 @@ def command_output(cmd, directory, fail_ok=False):
if VERBOSE:
print(stdout)
return stdout


class GoodCommit(object):
"""Represents a good commit for a repository."""

def __init__(self, json):
"""Initializes this good commit object.

Args:
'json': A fully populated JSON object describing the commit.
"""
Expand All @@ -70,72 +55,58 @@ def __init__(self, json):
self.subrepo = json['subrepo']
self.subdir = json['subdir'] if ('subdir' in json) else '.'
self.commit = json['commit']

def GetUrl(self, style='https'):
"""Returns the URL for the repository."""
host = SITE_TO_HOST[self.site]
sep = '/' if (style is 'https') else ':'
return '{style}://{host}{sep}{subrepo}'.format(
style=style,
host=host,
sep=sep,
subrepo=self.subrepo)

style=style,
host=host,
sep=sep,
subrepo=self.subrepo)
def AddRemote(self):
"""Add the remote 'known-good' if it does not exist."""
if len(command_output(['git', 'remote', 'get-url', 'known-good'], self.subdir, fail_ok=True)) == 0:
command_output(['git', 'remote', 'add', 'known-good', self.GetUrl()], self.subdir)

command_output(
['git', 'remote', 'add', 'known-good', self.GetUrl()], self.subdir)
def HasCommit(self):
"""Check if the repository contains the known-good commit."""
return 0 == subprocess.call(['git', 'rev-parse', '--verify', '--quiet',
self.commit + "^{commit}"],
self.commit + '^{commit}'],
cwd=self.subdir)

def Clone(self):
distutils.dir_util.mkpath(self.subdir)
command_output(['git', 'clone', self.GetUrl(), '.'], self.subdir)

def Fetch(self):
command_output(['git', 'fetch', 'known-good'], self.subdir)

def Checkout(self):
if not os.path.exists(os.path.join(self.subdir,'.git')):
if not os.path.exists(os.path.join(self.subdir, '.git')):
self.Clone()
self.AddRemote()
if not self.HasCommit():
self.Fetch()
command_output(['git', 'checkout', self.commit], self.subdir)


def GetGoodCommits(known_good_file):
"""Returns the latest list of GoodCommit objects."""
with open(known_good_file) as known_good:
return [GoodCommit(c) for c in json.loads(known_good.read())['commits']]


def main():
parser = argparse.ArgumentParser(description='Get Shaderc source dependencies at a known-good commit')
parser = argparse.ArgumentParser(
description='Get Shaderc source dependencies at a known-good commit')
parser.add_argument('--dir', dest='dir', default='src',
help="Set target directory for Shaderc source root. Default is \'src\'.")
parser.add_argument('--file', dest='known_good_file', default=KNOWN_GOOD_FILE,
help="The file containing known-good commits. Default is \'' + KNOWN_GOOD_FILE + '\'.")

args = parser.parse_args()

commits = GetGoodCommits(args.known_good_file)

distutils.dir_util.mkpath(args.dir)
print('Change directory to {d}'.format(d=args.dir))
os.chdir(args.dir)

# Create the subdirectories in sorted order so that parent git repositories
# are created first.
for c in sorted(commits, cmp=lambda x,y: cmp(x.subdir, y.subdir)):
for c in sorted(commits, key=attrgetter('subdir')):
print('Get {n}\n'.format(n=c.name))
c.Checkout()
sys.exit(0)


if __name__ == '__main__':
main()
16 changes: 16 additions & 0 deletions src/Veldrid.SPIRV.Tests/CompilationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,22 @@ public void ComputeSucceeds(string cs, CrossCompileTarget target)
Assert.NotNull(result.ComputeShader);
}

[Theory]
//[InlineData("empty.geom", CrossCompileTarget.HLSL)]
[InlineData("empty.geom", CrossCompileTarget.GLSL)]
[InlineData("empty.geom", CrossCompileTarget.ESSL)]
[InlineData("empty.geom", CrossCompileTarget.MSL)]
//[InlineData("simple.geom", CrossCompileTarget.HLSL)]
[InlineData("simple.geom", CrossCompileTarget.GLSL)]
[InlineData("simple.geom", CrossCompileTarget.ESSL)]
[InlineData("simple.geom", CrossCompileTarget.MSL)]
public void GeometrySucceeds(string cs, CrossCompileTarget target)
{
byte[] csBytes = TestUtil.LoadBytes(cs);
ComputeCompilationResult result = SpirvCompilation.CompileGeometry(csBytes, target);
Assert.NotNull(result.ComputeShader);
}

[Theory]
[InlineData("overlapping-resources.vert.spv", "overlapping-resources.frag.spv", CrossCompileTarget.HLSL)]
[InlineData("overlapping-resources.vert", "overlapping-resources.frag.spv", CrossCompileTarget.HLSL)]
Expand Down
9 changes: 9 additions & 0 deletions src/Veldrid.SPIRV.Tests/TestShaders/empty.geom
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#version 450

layout(triangles) in;
layout(triangle_strip, max_vertices=3) out;

void main()
{
EndPrimitive();
}
14 changes: 14 additions & 0 deletions src/Veldrid.SPIRV.Tests/TestShaders/simple.geom
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#version 400
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;

void main()
{
for (int i = 0; i<gl_in.length(); i++)
{
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}

EndPrimitive();
}
4 changes: 3 additions & 1 deletion src/Veldrid.SPIRV.Tests/Veldrid.SPIRV.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
Expand All @@ -22,6 +22,8 @@

<ItemGroup>
<Content Include="TestShaders/*" CopyToOutputDirectory="PreserveNewest" />
<None Remove="TestShaders\empty.geom" />
<None Remove="TestShaders\simple.geom" />
<Content Include="$(RepositoryRootDirectory)/build/win-x64/$(Configuration)/libveldrid-spirv.dll" Condition="Exists('$(RepositoryRootDirectory)/build/win-x64/$(Configuration)/libveldrid-spirv.dll')" CopyToOutputDirectory="PreserveNewest" />
<Content Include="$(RepositoryRootDirectory)/build/$(Configuration)/libveldrid-spirv.dylib" Condition="Exists('$(RepositoryRootDirectory)/build/$(Configuration)/libveldrid-spirv.dylib')" CopyToOutputDirectory="PreserveNewest" />
<Content Include="$(RepositoryRootDirectory)/build/$(Configuration)/libveldrid-spirv.so" Condition="Exists('$(RepositoryRootDirectory)/build/$(Configuration)/libveldrid-spirv.so')" CopyToOutputDirectory="PreserveNewest" />
Expand Down
46 changes: 46 additions & 0 deletions src/Veldrid.SPIRV.VariantCompiler/CompilationSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public string[] Compile(ShaderVariantDescription variant)
{
if (variant.Shaders[0].Stage == ShaderStages.Vertex) { return CompileVertexFragment(variant); }
if (variant.Shaders[0].Stage == ShaderStages.Compute) { return CompileCompute(variant); }
if (variant.Shaders[0].Stage == ShaderStages.Geometry) { return CompileGeometry(variant); }
}
if (variant.Shaders.Length == 2)
{
Expand Down Expand Up @@ -285,5 +286,50 @@ private string[] CompileCompute(ShaderVariantDescription variant)

return generatedFiles.ToArray();
}

private string[] CompileGeometry(ShaderVariantDescription variant)
{
List<string> generatedFiles = new List<string>();
byte[] csBytes = CompileToSpirv(variant, variant.Shaders[0].FileName, ShaderStages.Geometry);
string spvPath = Path.Combine(_outputPath, $"{variant.Name}_{ShaderStages.Geometry.ToString()}.spv");
File.WriteAllBytes(spvPath, csBytes);
generatedFiles.Add(spvPath);

List<Exception> compilationExceptions = new List<Exception>();
foreach (CrossCompileTarget target in variant.Targets)
{
try
{
GeometryCompilationResult result = SpirvCompilation.CompileGeometry(csBytes, target, variant.CrossCompileOptions);
string csPath = Path.Combine(_outputPath, $"{variant.Name}_Geometry.{GetExtension(target)}");
File.WriteAllText(csPath, result.GeometryShader);
generatedFiles.Add(csPath);

string reflectionPath = Path.Combine(_outputPath, $"{variant.Name}_ReflectionInfo.json");

JsonSerializer serializer = new JsonSerializer();
serializer.Formatting = Formatting.Indented;
StringEnumConverter enumConverter = new StringEnumConverter();
serializer.Converters.Add(enumConverter);
using (StreamWriter sw = File.CreateText(reflectionPath))
using (JsonTextWriter jtw = new JsonTextWriter(sw))
{
serializer.Serialize(jtw, result.Reflection);
}
generatedFiles.Add(reflectionPath);
}
catch (Exception e)
{
compilationExceptions.Add(e);
}
}

if (compilationExceptions.Count > 0)
{
throw new AggregateException($"Errors were encountered when compiling shader variant(s).", compilationExceptions);
}

return generatedFiles.ToArray();
}
}
}
1 change: 1 addition & 0 deletions src/Veldrid.SPIRV/CrossCompileInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ internal struct CrossCompileInfo
public InteropArray VertexShader;
public InteropArray FragmentShader;
public InteropArray ComputeShader;
public InteropArray GeometryShader;
}
}
Loading