Skip to content

Commit

Permalink
Add RGA. Fixes #5.
Browse files Browse the repository at this point in the history
  • Loading branch information
tgjones committed Aug 25, 2018
1 parent b7fd1d7 commit 83674af
Show file tree
Hide file tree
Showing 9 changed files with 259 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog

## 2018-08-25

* New compiler - [RGA](https://github.com/GPUOpen-Tools/RGA)

## 2018-07-02

* Fixed ISPC interface name (#36)
Expand Down
40 changes: 37 additions & 3 deletions build.cake
@@ -1,6 +1,6 @@
#addin nuget:?package=SharpZipLib
#addin nuget:?package=Cake.Compression
#addin nuget:?package=Cake.Git
#addin nuget:?package=SharpZipLib&version=1.0.0
#addin nuget:?package=Cake.Compression&version=0.2.1
#addin nuget:?package=Cake.Git&version=0.18.0

var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
Expand Down Expand Up @@ -223,6 +223,39 @@ Task("Download-LZMA")
DownloadLzma("1805", "18.05");
});

Task("Download-RGA")
.Does(() => {
var amdDriverExePath = DownloadCompiler(
"https://www2.ati.com/drivers/win10-64bit-radeon-software-adrenalin-edition-18.5.1-may23.exe",
"amd-driver",
"18.5.1",
true);
var amdDriverFolder = "./build/amd-driver/18.5.1";
EnsureDirectoryExists(amdDriverFolder);
CleanDirectory(amdDriverFolder);
StartProcess(
@"C:\Program Files\7-Zip\7z.exe",
$@"e -o""{amdDriverFolder}"" ""{amdDriverExePath}"" Packages\Drivers\Display\WT6A_INF\B328940\atidxx64.dll");
var driverDllPath = amdDriverFolder + "/atidxx64.dll";
void DownloadRga(string version)
{
var binariesFolder = DownloadAndUnzipCompiler(
$"https://github.com/GPUOpen-Tools/RGA/releases/download/{version}/rga-windows-x64-{version}.zip",
"rga",
version,
true,
"bin/**/*.*");
CopyFiles(driverDllPath, binariesFolder);
}
DownloadRga("2.0.1");
});

Task("Build-ANGLE")
.Does(() => {
StartProcess(MakeAbsolute(File("./external/angle/build.bat")), new ProcessSettings {
Expand Down Expand Up @@ -403,6 +436,7 @@ Task("Default")
.IsDependentOn("Download-HLSLParser")
.IsDependentOn("Download-zstd")
.IsDependentOn("Download-LZMA")
.IsDependentOn("Download-RGA")
.IsDependentOn("Build-ANGLE")
.IsDependentOn("Build")
.IsDependentOn("Test");
Expand Down
2 changes: 2 additions & 0 deletions src/ShaderPlayground.Core/Compiler.cs
Expand Up @@ -12,6 +12,7 @@
using ShaderPlayground.Core.Compilers.Lzma;
using ShaderPlayground.Core.Compilers.Mali;
using ShaderPlayground.Core.Compilers.Miniz;
using ShaderPlayground.Core.Compilers.Rga;
using ShaderPlayground.Core.Compilers.Slang;
using ShaderPlayground.Core.Compilers.Smolv;
using ShaderPlayground.Core.Compilers.SpirVCross;
Expand Down Expand Up @@ -45,6 +46,7 @@ public static class Compiler
new LzmaCompiler(),
new MaliCompiler(),
new MinizCompiler(),
new RgaCompiler(),
new SlangCompiler(),
new SmolvToSpirvCompiler(),
new SpirvAssemblerCompiler(),
Expand Down
1 change: 1 addition & 0 deletions src/ShaderPlayground.Core/CompilerNames.cs
Expand Up @@ -7,6 +7,7 @@ public static class CompilerNames
public const string Fxc = "fxc";
public const string Mali = "mali";
public const string Glslang = "glslang";
public const string Rga = "rga";
public const string SpirvAssembler = "spirv-as";
public const string SpirVCross = "spirv-cross";
public const string SpirVCrossIspc = "spirv-cross-ispc";
Expand Down
Expand Up @@ -20,7 +20,7 @@ internal sealed class GlslangCompiler : IShaderCompiler
CommonParameters.CreateVersionParameter("glslang"),
CommonParameters.GlslShaderStage,
new ShaderCompilerParameter("Target", "Target", ShaderCompilerParameterType.ComboBox, TargetOptions, SpirVVulkan1_0),
CommonParameters.HlslEntryPoint, // TODO: Only visible when input language is HLSL?
CommonParameters.HlslEntryPoint.WithOnlyForInputLanguage(LanguageNames.Hlsl),
CommonParameters.CreateOutputParameter(new[] { LanguageNames.SpirV })
};

Expand Down
177 changes: 177 additions & 0 deletions src/ShaderPlayground.Core/Compilers/Rga/RgaCompiler.cs
@@ -0,0 +1,177 @@
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using ShaderPlayground.Core.Util;

namespace ShaderPlayground.Core.Compilers.Rga
{
internal sealed class RgaCompiler : IShaderCompiler
{
static RgaCompiler()
{
ProcessHelper.Run(
Path.Combine(AppContext.BaseDirectory, "Binaries", "rga", "2.0.1", "rga.exe"),
"-s hlsl --list-asics",
out var stdOutput,
out var _);

// Extract ASICs from output.
var coreRegex = new Regex(@"\n([a-zA-Z0-9 ]+) \(");
var matches = coreRegex.Matches(stdOutput);

AsicOptions = matches
.Cast<Match>()
.Select(x => x.Groups[1].Value)
.ToArray();
}

public string Name { get; } = CompilerNames.Rga;
public string DisplayName { get; } = "Radeon GPU Analyzer";
public string Url { get; } = "https://github.com/GPUOpen-Tools/RGA";
public string Description { get; } = "The Radeon GPU Analyzer (RGA) is an offline compiler and code analysis tool for DirectX shaders, OpenGL shaders, Vulkan shaders and OpenCL kernels.";

public string[] InputLanguages { get; } = { LanguageNames.Hlsl, LanguageNames.Glsl, LanguageNames.SpirvAssembly };

public ShaderCompilerParameter[] Parameters { get; } = new[]
{
CommonParameters.CreateVersionParameter("rga"),
new ShaderCompilerParameter("Asic", "ASIC", ShaderCompilerParameterType.ComboBox, AsicOptions, "gfx900"),

// HLSL
CommonParameters.HlslEntryPoint.WithOnlyForInputLanguage(LanguageNames.Hlsl),
new ShaderCompilerParameter("TargetProfile", "Target profile", ShaderCompilerParameterType.ComboBox, TargetProfileOptions, "ps_5_0", onlyForInputLanguage: LanguageNames.Hlsl),

// GLSL
new ShaderCompilerParameter("GlslTarget", "Target", ShaderCompilerParameterType.ComboBox, TargetOptions, TargetOpenGL, onlyForInputLanguage: LanguageNames.Glsl),
CommonParameters.GlslShaderStage.WithOnlyForInputLanguage(LanguageNames.Glsl)
};

private static readonly string[] AsicOptions;

private static readonly string[] TargetProfileOptions =
{
"cs_4_0",
"cs_4_1",
"cs_5_0",
"ds_5_0",
"gs_4_0",
"gs_4_1",
"gs_5_0",
"hs_5_0",
"ps_4_0",
"ps_4_1",
"ps_5_0",
"vs_4_0",
"vs_4_1",
"vs_5_0",
};

private const string TargetOpenGL = "OpenGL";
private const string TargetVulkan = "Vulkan";

private static readonly string[] TargetOptions =
{
TargetOpenGL,
TargetVulkan
};

public ShaderCompilerResult Compile(ShaderCode shaderCode, ShaderCompilerArguments arguments)
{
var asic = arguments.GetString("Asic");
var entryPoint = arguments.GetString("EntryPoint");
var targetProfile = arguments.GetString("TargetProfile");
var shaderStage = arguments.GetString(CommonParameters.GlslShaderStage.Name);

using (var tempFile = TempFile.FromShaderCode(shaderCode))
{
var outputAnalysisPath = $"{tempFile.FilePath}.analysis";
var isaPath = $"{tempFile.FilePath}.isa";
var liveRegPath = $"{tempFile.FilePath}.livereg";
var cfgPath = $"{tempFile.FilePath}.cfg";

var args = $"--asic \"{asic}\" --analysis \"{outputAnalysisPath}\" --isa \"{isaPath}\" --livereg \"{liveRegPath}\" --cfg \"{cfgPath}\"";

switch (shaderCode.Language)
{
case LanguageNames.Hlsl:
args += $" -s hlsl --profile {targetProfile} --function {entryPoint}";
break;

case LanguageNames.Glsl:
switch (arguments.GetString("GlslTarget"))
{
case TargetOpenGL:
args += $" -s opengl --{shaderStage}";
break;

case TargetVulkan:
args += $" -s vulkan --{shaderStage}";
break;
}
break;

case LanguageNames.SpirvAssembly:
args += $" -s vulkan-spv-txt --{shaderStage}";
break;
}

args += $" \"{tempFile.FilePath}\"";

var rgaPath = CommonParameters.GetBinaryPath("rga", arguments, "rga.exe");
ProcessHelper.Run(
rgaPath,
args,
out var stdOutput,
out _);

string GetActualOutputPath(string extension)
{
if (extension == "analysis" && shaderCode.Language == LanguageNames.Hlsl)
{
return Path.Combine(
Path.GetDirectoryName(tempFile.FilePath),
$"{entryPoint}_{Path.GetFileName(tempFile.FilePath)}.analysis");
}

var name = shaderCode.Language == LanguageNames.Hlsl
? entryPoint
: shaderStage;

return Path.Combine(
Path.GetDirectoryName(tempFile.FilePath),
$"{asic}_{name}_{Path.GetFileName(tempFile.FilePath)}.{extension}");
}

outputAnalysisPath = GetActualOutputPath("analysis");
isaPath = GetActualOutputPath("isa");
liveRegPath = GetActualOutputPath("livereg");
cfgPath = GetActualOutputPath("cfg");

var outputAnalysis = FileHelper.ReadAllTextIfExists(outputAnalysisPath);
var isa = FileHelper.ReadAllTextIfExists(isaPath);
var liveReg = FileHelper.ReadAllTextIfExists(liveRegPath);
var cfg = FileHelper.ReadAllTextIfExists(cfgPath);

FileHelper.DeleteIfExists(outputAnalysisPath);
FileHelper.DeleteIfExists(isaPath);
FileHelper.DeleteIfExists(liveRegPath);
FileHelper.DeleteIfExists(cfgPath);

var selectedOutputIndex = stdOutput.Contains("\nError: ") || stdOutput.Contains("... failed.")
? 3
: (int?) null;

return new ShaderCompilerResult(
selectedOutputIndex == null,
null,
selectedOutputIndex,
new ShaderCompilerOutput("Disassembly", null, isa),
//new ShaderCompilerOutput("Analysis", null, outputAnalysis),
new ShaderCompilerOutput("Live register analysis", null, liveReg),
new ShaderCompilerOutput("Control flow graph", "graphviz", cfg),
new ShaderCompilerOutput("Build output", null, stdOutput));
}
}
}
}
24 changes: 23 additions & 1 deletion src/ShaderPlayground.Core/ShaderCompilerParameter.cs
Expand Up @@ -17,14 +17,36 @@ public sealed class ShaderCompilerParameter

public string Description { get; }

internal ShaderCompilerParameter(string name, string displayName, ShaderCompilerParameterType parameterType, string[] options = null, string defaultValue = null, string description = null)
public string OnlyForInputLanguage { get; }

internal ShaderCompilerParameter(
string name,
string displayName,
ShaderCompilerParameterType parameterType,
string[] options = null,
string defaultValue = null,
string description = null,
string onlyForInputLanguage = null)
{
Name = name;
DisplayName = displayName;
ParameterType = parameterType;
Options = options ?? Array.Empty<string>();
DefaultValue = defaultValue;
Description = description;
OnlyForInputLanguage = onlyForInputLanguage;
}

public ShaderCompilerParameter WithOnlyForInputLanguage(string language)
{
return new ShaderCompilerParameter(
Name,
DisplayName,
ParameterType,
Options,
DefaultValue,
Description,
language);
}
}
}
8 changes: 7 additions & 1 deletion src/ShaderPlayground.Web/wwwroot/js/site.js
Expand Up @@ -10,6 +10,8 @@
* @property {ShaderCompilerParameterType} parameterType
* @property {string[]} options
* @property {string} defaultValue
* @property {string} description
* @property {string} onlyForInputLanguage
*/

/**
Expand Down Expand Up @@ -570,6 +572,8 @@
* @param {ShaderLanguage} inputLanguage
*/
constructor(inputLanguage) {
this.inputLanguage = inputLanguage;

/** @type {HTMLTemplateElement} */
let template = document.getElementById("compiler-editor-template");

Expand Down Expand Up @@ -641,7 +645,9 @@
this.versionSelect.innerHTML = '';
this.versionSelect.appendChild(parameterEditor.element.querySelector("select"));
} else {
this.argumentsDiv.appendChild(parameterEditor.element);
if (parameter.onlyForInputLanguage === null || parameter.onlyForInputLanguage === this.inputLanguage.name) {
this.argumentsDiv.appendChild(parameterEditor.element);
}
}
}

Expand Down
8 changes: 7 additions & 1 deletion src/ShaderPlayground.Web/wwwroot/js/site.min.js
Expand Up @@ -10,6 +10,8 @@ $(function () {
* @property {ShaderCompilerParameterType} parameterType
* @property {string[]} options
* @property {string} defaultValue
* @property {string} description
* @property {string} onlyForInputLanguage
*/

/**
Expand Down Expand Up @@ -570,6 +572,8 @@ $(function () {
* @param {ShaderLanguage} inputLanguage
*/
constructor(inputLanguage) {
this.inputLanguage = inputLanguage;

/** @type {HTMLTemplateElement} */
let template = document.getElementById("compiler-editor-template");

Expand Down Expand Up @@ -641,7 +645,9 @@ $(function () {
this.versionSelect.innerHTML = '';
this.versionSelect.appendChild(parameterEditor.element.querySelector("select"));
} else {
this.argumentsDiv.appendChild(parameterEditor.element);
if (parameter.onlyForInputLanguage === null || parameter.onlyForInputLanguage === this.inputLanguage.name) {
this.argumentsDiv.appendChild(parameterEditor.element);
}
}
}

Expand Down

0 comments on commit 83674af

Please sign in to comment.