Finished first version of shader compiler. HLSL -> DXIL.

Submitting vertex and frag shader needed to display a triangle.
This commit is contained in:
2025-03-08 22:36:15 -05:00
parent f9f292b6d6
commit da203c80f3
27 changed files with 837 additions and 173 deletions

View File

@@ -1,56 +1,229 @@
#include <Core/Common/EnumUtils.h>
#include <Core/Common/String.h>
#include <Core/HAL/IO/IOStream.h>
#include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h>
// Must be before everything else.
// Cannot include DX12Includes because we redefine everything.
// TODO : Separate lib
// TODO : Only when not shipping
// Check if we just load the dll and not link against?
#include <DXCompiler.h>
#pragma comment(lib, "dxcompiler.lib")
#include <Core/Memory/Allocator.h>
#include <ShaderCompiler.h>
using namespace Juliet;
void Compile()
void PrintHelp()
{
IDxcCompiler3* compiler = nullptr;
DxcCreateInstance(&CLSID_DxcCompiler, IID_IDxcCompiler3, reinterpret_cast<void**>(&compiler));
IDxcUtils* utils = nullptr;
DxcCreateInstance(&CLSID_DxcUtils, &IID_IDxcUtils, reinterpret_cast<void**>(&utils));
if (compiler == nullptr)
{
Juliet::Log(LogLevel::Error, LogCategory::Graphics, "Cannot create DXCompiler instance");
}
if (utils == nullptr)
{
Log(LogLevel::Error, LogCategory::Graphics, "Cannot create IDxcUtils instance");
compiler->lpVtbl->Release(compiler);
}
IDxcIncludeHandler* includeHandler;
utils->lpVtbl->CreateDefaultIncludeHandler(utils, &includeHandler);
if (includeHandler == nullptr)
{
compiler->lpVtbl->Release(compiler);
utils->lpVtbl->Release(utils);
}
LogMessage(LogCategory::Tool, "Usage: JulietShaderCompiler.exe <input> [options]");
LogMessage(LogCategory::Tool, "Required Parameters:");
static constexpr int kColumnWdith = 32;
LogMessage(LogCategory::Tool, " %-*s %s", kColumnWdith, "-o | --output <value>", "Output file.");
// LogMessage(LogCategory::Tool, "\n");
// LogMessage(LogCategory::Tool, "Required Parameters that can be inferred from filename:");
// LogMessage(LogCategory::Tool, " %-*s %s", kColumnWdith, "-s | --src <value>", "Source Language. Values: [HLSL*] | * Default");
// LogMessage(LogCategory::Tool, " %-*s %s", kColumnWdith, "-d | --dest <value>", "Destination Format. Values: [DXIL*] | * Default");
}
int main(int argc, char* argv[])
{
// auto* stream = IOFromFile(ConstString("XF"), ConstString("w"));
String filename = {};
ByteBuffer fileData = {};
String outputFilename = {};
String entryPoint = WrapString("main");
bool sourceLangDetected = false;
auto srcLanguage = SourceLanguage::Invalid;
bool dstShaderFormatDetected = false;
auto dstShaderFormat = ShaderFormat::Invalid;
bool shaderStageDetected = false;
auto shaderStage = ShaderStage::Invalid;
IOStream* outStream = nullptr;
auto deferred = Defer(
[&]()
{
if (IsValid(fileData))
{
Free(fileData);
}
if (outStream)
{
IOClose(outStream);
}
// Pause here to not close the console window immediately on stop
system("PAUSE");
});
for (int idx = 1; idx < argc; ++idx)
{
String arg = WrapString(argv[idx]);
if (CStr(arg)[0] == '-')
{
if (StringCompareCaseInsensitive(arg, ConstString("-h")) == 0 ||
StringCompareCaseInsensitive(arg, ConstString("--help")) == 0)
{
PrintHelp();
return 1;
}
if (StringCompareCaseInsensitive(arg, ConstString("-o")) == 0 ||
StringCompareCaseInsensitive(arg, ConstString("--output")) == 0)
{
if (idx + 1 >= argc)
{
LogError(LogCategory::Tool, "%s requires an argument", argv);
PrintHelp();
return 1;
}
idx += 1;
outputFilename = WrapString(argv[idx]);
}
}
else if (IsValid(filename) == false)
{
filename = arg;
}
else
{
LogError(LogCategory::Tool, "%s: Unknown parameter: %s", argv[0], CStr(arg));
PrintHelp();
return 1;
}
}
if (!IsValid(filename))
{
LogError(LogCategory::Tool, "%s: missing input filename path", argv[0]);
PrintHelp();
return 1;
}
if (!IsValid(outputFilename))
{
LogError(LogCategory::Tool, "%s: missing output path", argv[0]);
PrintHelp();
return 1;
}
fileData = LoadFile(filename);
if (!IsValid(fileData))
{
LogError(LogCategory::Tool, "Invalid file: %s", CStr(filename));
return 1;
}
// Find the source language from filename
{
if (!sourceLangDetected)
{
if (IsValid(FindString(filename, WrapString("hlsl"))))
{
srcLanguage = SourceLanguage::HLSL;
}
static_assert(ToUnderlying(SourceLanguage::Count) == 1, "SourceLanguage must be one of: HLSL");
}
if (srcLanguage == SourceLanguage::Invalid)
{
LogError(LogCategory::Tool,
"%s: Invalid source language. Please either have a valid file extension or use -s/--src", argv[0]);
PrintHelp();
return 1;
}
}
// Find the destination format from output file name
{
if (!dstShaderFormatDetected)
{
if (IsValid(FindString(outputFilename, WrapString("dxil"))))
{
dstShaderFormat = ShaderFormat::DXIL;
}
static_assert(ToUnderlying(ShaderFormat::Count) == 1, "ShaderFormat must be one of: DXIL");
if (dstShaderFormat == ShaderFormat::Invalid)
{
LogError(LogCategory::Tool,
"%s: Invalid shader format. Please either have a valid file extension or use -d/--dest", argv[0]);
PrintHelp();
return 1;
}
}
}
// Find shader stage from filename
{
if (!shaderStageDetected)
{
// TODO Need a case insensitive FindString
if (IsValid(FindString(filename, WrapString("vert"))))
{
shaderStage = ShaderStage::Vertex;
}
else if (IsValid(FindString(filename, WrapString("frag"))))
{
shaderStage = ShaderStage::Fragment;
}
else if (IsValid(FindString(filename, WrapString("comp"))))
{
shaderStage = ShaderStage::Compute;
}
static_assert(ToUnderlying(ShaderFormat::Count) == 1, "ShaderStage must be one of: vert, frag, comp");
if (shaderStage == ShaderStage::Invalid)
{
LogError(LogCategory::Tool, "%s: Invalid shader stage. Please include it in the filename", argv[0]);
PrintHelp();
return 1;
}
}
}
outStream = IOFromFile(outputFilename, WrapString("w"));
if (!outStream)
{
LogError(LogCategory::Tool, "%s: Failed to open %s for writing", argv[0], CStr(outputFilename));
return 1;
}
switch (srcLanguage)
{
case SourceLanguage::HLSL:
{
HLSLShaderInfo hlslInfo = {};
hlslInfo.ByteCodeBuffer = fileData;
hlslInfo.EntryPoint = entryPoint;
hlslInfo.Name = filename;
hlslInfo.Stage = shaderStage;
switch (dstShaderFormat)
{
case ShaderFormat::DXIL:
{
ByteBuffer compiledBuffer = CompileDXIL(hlslInfo);
if (!IsValid(compiledBuffer))
{
LogError(LogCategory::Tool, "Failed to compile DXBC from HLSL. Error: %s", "Unknown");
}
else
{
IOWrite(outStream, compiledBuffer);
Free(compiledBuffer);
}
break;
}
case ShaderFormat::Invalid: Assert(false && "Shader format is invalid"); return 1;
}
break;
}
case SourceLanguage::Invalid: Assert(false && "Source Language is invalid"); return 1;
}
//
// IOPrintf(stream, ":)");
// IOPrintf(stream, "%d%s", 1234, "Hello World!");
size_t bytesRead = 0;
auto* data = LoadFile(ConstString("XF"),bytesRead );
return 0;
}