Skip to content

Commit

Permalink
gpu-dawn: build Dawn & DirectXShaderCompiler for windows
Browse files Browse the repository at this point in the history
Helps hexops/mach#86

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
  • Loading branch information
slimsag committed Mar 5, 2022
1 parent 70f18d8 commit f993d09
Show file tree
Hide file tree
Showing 2 changed files with 214 additions and 4 deletions.
162 changes: 158 additions & 4 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ fn linkFromSource(b: *Builder, step: *std.build.LibExeObjStep, options: Options)
const lib_dawn_native = buildLibDawnNative(b, step, options);
step.linkLibrary(lib_dawn_native);

if (options.d3d12.?) {
const lib_dxcompiler = buildLibDxcompiler(b, step, options);
step.linkLibrary(lib_dxcompiler);
}

const lib_dawn_wire = buildLibDawnWire(b, step, options);
step.linkLibrary(lib_dawn_wire);

Expand Down Expand Up @@ -168,6 +173,7 @@ fn linkFromSource(b: *Builder, step: *std.build.LibExeObjStep, options: Options)
_ = buildLibDawnUtils(b, lib_dawn, options);
_ = buildLibSPIRVTools(b, lib_dawn, options);
_ = buildLibTint(b, lib_dawn, options);
if (options.d3d12.?) _ = buildLibDxcompiler(b, lib_dawn, options);
}

fn ensureSubmodules(allocator: std.mem.Allocator) !void {
Expand Down Expand Up @@ -435,6 +441,14 @@ fn buildLibMachDawnNative(b: *Builder, step: *std.build.LibExeObjStep, options:
include("libs/dawn/include"),
include("libs/dawn/src"),
}) catch unreachable;
const target = (std.zig.system.NativeTargetInfo.detect(b.allocator, step.target) catch unreachable).target;
if (target.os.tag == .windows) {
cpp_flags.appendSlice(&.{
"-D_DEBUG",
"-D_MT",
"-D_DLL",
}) catch unreachable;
}

lib.addCSourceFile("src/dawn/dawn_native_mach.cpp", cpp_flags.items);
return lib;
Expand Down Expand Up @@ -474,6 +488,10 @@ fn buildLibDawnCommon(b: *Builder, step: *std.build.LibExeObjStep, options: Opti
var abs_path = std.fs.path.join(b.allocator, &.{ thisDir(), "libs/dawn/src/dawn/common/SystemUtils_mac.mm" }) catch unreachable;
cpp_sources.append(abs_path) catch unreachable;
}
if (target.os.tag == .windows) {
var abs_path = std.fs.path.join(b.allocator, &.{ thisDir(), "libs/dawn/src/dawn/common/WindowsUtils.cpp" }) catch unreachable;
cpp_sources.append(abs_path) catch unreachable;
}

var cpp_flags = std.ArrayList([]const u8).init(b.allocator);
cpp_flags.appendSlice(flags.items) catch unreachable;
Expand Down Expand Up @@ -534,6 +552,25 @@ fn appendDawnEnableBackendTypeFlags(flags: *std.ArrayList([]const u8), options:
if (options.opengl_es.?) try flags.appendSlice(&.{ opengl, opengl_es });
}

const dawn_d3d12_flags = &[_][]const u8{
"-DDAWN_NO_WINDOWS_UI",
"-D__EMULATE_UUID=1",
"-Wno-nonportable-include-path",
"-Wno-extern-c-compat",
"-Wno-invalid-noreturn",
"-Wno-pragma-pack",
"-Wno-microsoft-template-shadow",
"-Wno-unused-command-line-argument",
"-Wno-microsoft-exception-spec",
"-Wno-implicit-exception-spec-mismatch",
"-Wno-unknown-attributes",
"-Wno-c++20-extensions",
"-D_CRT_SECURE_NO_WARNINGS",
"-DWIN32_LEAN_AND_MEAN",
"-DD3D10_ARBITRARY_HEADER_ORDERING",
"-DNOMINMAX",
};

// Builds dawn native sources; derived from src/dawn/native/BUILD.gn
fn buildLibDawnNative(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep {
const lib = if (!options.separate_libs) step else blk: {
Expand Down Expand Up @@ -572,6 +609,7 @@ fn buildLibDawnNative(b: *Builder, step: *std.build.LibExeObjStep, options: Opti
include("libs/dawn/out/Debug/gen/include"),
include("libs/dawn/out/Debug/gen/src"),
}) catch unreachable;
if (options.d3d12.?) flags.appendSlice(dawn_d3d12_flags) catch unreachable;

appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{
Expand Down Expand Up @@ -602,9 +640,18 @@ fn buildLibDawnNative(b: *Builder, step: *std.build.LibExeObjStep, options: Opti
// TODO(build-system): allow use_angle here. See src/dawn/native/BUILD.gn
// TODO(build-system): could allow use_swiftshader here. See src/dawn/native/BUILD.gn

var cpp_sources = std.ArrayList([]const u8).init(b.allocator);
if (options.d3d12.?) {
// TODO(build-system): windows
// libs += [ "dxguid.lib" ]
lib.linkSystemLibrary("dxgi");
lib.linkSystemLibrary("dxguid");

for ([_][]const u8{
"src/dawn/mingw_helpers.cpp",
}) |path| {
var abs_path = std.fs.path.join(b.allocator, &.{ thisDir(), path }) catch unreachable;
cpp_sources.append(abs_path) catch unreachable;
}

appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{
"libs/dawn/src/dawn/native/d3d12/",
Expand Down Expand Up @@ -632,7 +679,6 @@ fn buildLibDawnNative(b: *Builder, step: *std.build.LibExeObjStep, options: Opti
}) catch unreachable;
}

var cpp_sources = std.ArrayList([]const u8).init(b.allocator);
if (options.linux_window_manager != null and options.linux_window_manager.? == .X11) {
lib.linkSystemLibrary("X11");
for ([_][]const u8{
Expand Down Expand Up @@ -1031,13 +1077,20 @@ fn buildLibAbseilCpp(b: *Builder, step: *std.build.LibExeObjStep, options: Optio

const target = (std.zig.system.NativeTargetInfo.detect(b.allocator, step.target) catch unreachable).target;
if (target.os.tag == .macos) lib.linkFramework("CoreFoundation");
if (target.os.tag == .windows) lib.linkSystemLibrary("bcrypt");

var flags = std.ArrayList([]const u8).init(b.allocator);
flags.appendSlice(&.{
include("libs/dawn"),
include("libs/dawn/third_party/abseil-cpp"),
}) catch unreachable;
if (target.os.tag == .windows) flags.append("-DABSL_FORCE_THREAD_IDENTITY_MODE=2") catch unreachable;
if (target.os.tag == .windows) flags.appendSlice(&.{
"-DABSL_FORCE_THREAD_IDENTITY_MODE=2",
"-DWIN32_LEAN_AND_MEAN",
"-DD3D10_ARBITRARY_HEADER_ORDERING",
"-D_CRT_SECURE_NO_WARNINGS",
"-DNOMINMAX",
}) catch unreachable;

// absl
appendLangScannedSources(b, lib, options, .{
Expand Down Expand Up @@ -1143,6 +1196,7 @@ fn buildLibDawnUtils(b: *Builder, step: *std.build.LibExeObjStep, options: Optio
var abs_path = std.fs.path.join(b.allocator, &.{ thisDir(), "libs/dawn", path }) catch unreachable;
cpp_sources.append(abs_path) catch unreachable;
}
flags.appendSlice(dawn_d3d12_flags) catch unreachable;
}
if (options.metal.?) {
for ([_][]const u8{
Expand Down Expand Up @@ -1178,6 +1232,106 @@ fn buildLibDawnUtils(b: *Builder, step: *std.build.LibExeObjStep, options: Optio
return lib;
}

// Buids dxcompiler sources; derived from libs/DirectXShaderCompiler/CMakeLists.txt
fn buildLibDxcompiler(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep {
const lib = if (!options.separate_libs) step else blk: {
var main_abs = std.fs.path.join(b.allocator, &.{ thisDir(), "src/dawn/dummy.zig" }) catch unreachable;
const separate_lib = b.addStaticLibrary("dxcompiler", main_abs);
separate_lib.install();
separate_lib.setBuildMode(step.build_mode);
separate_lib.setTarget(step.target);
separate_lib.linkLibCpp();
break :blk separate_lib;
};
system_sdk.include(b, lib, .{});

lib.linkSystemLibrary("oleaut32");
lib.linkSystemLibrary("ole32");
lib.linkSystemLibrary("dbghelp");
lib.linkSystemLibrary("dxguid");
lib.linkLibCpp();

var flags = std.ArrayList([]const u8).init(b.allocator);
flags.appendSlice(&.{
include("libs/"),
include("libs/DirectXShaderCompiler/include/llvm/llvm_assert"),
include("libs/DirectXShaderCompiler/include"),
include("libs/DirectXShaderCompiler/build/include"),
include("libs/DirectXShaderCompiler/build/lib/HLSL"),
include("libs/DirectXShaderCompiler/build/lib/DxilPIXPasses"),
include("libs/DirectXShaderCompiler/build/include"),
"-DUNREFERENCED_PARAMETER(x)=",
"-Wno-inconsistent-missing-override",
"-Wno-missing-exception-spec",
"-Wno-switch",
"-Wno-deprecated-declarations",
"-Wno-macro-redefined", // regex2.h and regcomp.c requires this for OUT redefinition
"-DMSFT_SUPPORTS_CHILD_PROCESSES=1",
"-DHAVE_LIBPSAPI=1",
"-DHAVE_LIBSHELL32=1",
"-DLLVM_ON_WIN32=1",
}) catch unreachable;

appendLangScannedSources(b, lib, options, .{
.zero_debug_symbols = true,
.rel_dirs = &.{
"libs/DirectXShaderCompiler/lib/Analysis/IPA",
"libs/DirectXShaderCompiler/lib/Analysis",
"libs/DirectXShaderCompiler/lib/AsmParser",
"libs/DirectXShaderCompiler/lib/Bitcode/Writer",
"libs/DirectXShaderCompiler/lib/DxcBindingTable",
"libs/DirectXShaderCompiler/lib/DxcSupport",
"libs/DirectXShaderCompiler/lib/DxilContainer",
"libs/DirectXShaderCompiler/lib/DxilPIXPasses",
"libs/DirectXShaderCompiler/lib/DxilRootSignature",
"libs/DirectXShaderCompiler/lib/DXIL",
"libs/DirectXShaderCompiler/lib/DxrFallback",
"libs/DirectXShaderCompiler/lib/HLSL",
"libs/DirectXShaderCompiler/lib/IRReader",
"libs/DirectXShaderCompiler/lib/IR",
"libs/DirectXShaderCompiler/lib/Linker",
"libs/DirectXShaderCompiler/lib/miniz",
"libs/DirectXShaderCompiler/lib/Option",
"libs/DirectXShaderCompiler/lib/PassPrinters",
"libs/DirectXShaderCompiler/lib/Passes",
"libs/DirectXShaderCompiler/lib/ProfileData",
"libs/DirectXShaderCompiler/lib/Target",
"libs/DirectXShaderCompiler/lib/Transforms/InstCombine",
"libs/DirectXShaderCompiler/lib/Transforms/IPO",
"libs/DirectXShaderCompiler/lib/Transforms/Scalar",
"libs/DirectXShaderCompiler/lib/Transforms/Utils",
"libs/DirectXShaderCompiler/lib/Transforms/Vectorize",
},
.flags = flags.items,
}) catch unreachable;

appendLangScannedSources(b, lib, options, .{
.zero_debug_symbols = true,
.rel_dirs = &.{
"libs/DirectXShaderCompiler/lib/Support",
},
.flags = flags.items,
.excluding_contains = &.{
"DynamicLibrary.cpp", // ignore, HLSL_IGNORE_SOURCES
"PluginLoader.cpp", // ignore, HLSL_IGNORE_SOURCES
"Path.cpp", // ignore, LLVM_INCLUDE_TESTS
"DynamicLibrary.cpp", // ignore
},
}) catch unreachable;

appendLangScannedSources(b, lib, options, .{
.zero_debug_symbols = true,
.rel_dirs = &.{
"libs/DirectXShaderCompiler/lib/Bitcode/Reader",
},
.flags = flags.items,
.excluding_contains = &.{
"BitReader.cpp", // ignore
},
}) catch unreachable;
return lib;
}

fn include(comptime rel: []const u8) []const u8 {
return "-I" ++ thisDir() ++ "/" ++ rel;
}
Expand Down
56 changes: 56 additions & 0 deletions src/dawn/mingw_helpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#ifdef __MINGW32__
#include <guiddef.h>
#include <stdint.h>

#define MINGW_UUIDOF(type, spec) \
extern "C++" { \
struct __declspec(uuid(spec)) type; \
template<> const GUID &__mingw_uuidof<type>() { \
static constexpr IID __uuid_inst = guid_from_string(spec); \
return __uuid_inst; \
} \
template<> const GUID &__mingw_uuidof<type*>() { \
return __mingw_uuidof<type>(); \
} \
}

constexpr uint8_t nybble_from_hex(char c) {
return ((c >= '0' && c <= '9')
? (c - '0')
: ((c >= 'a' && c <= 'f')
? (c - 'a' + 10)
: ((c >= 'A' && c <= 'F') ? (c - 'A' + 10)
: /* Should be an error */ -1)));
}

constexpr uint8_t byte_from_hex(char c1, char c2) {
return nybble_from_hex(c1) << 4 | nybble_from_hex(c2);
}

constexpr uint8_t byte_from_hexstr(const char str[2]) {
return nybble_from_hex(str[0]) << 4 | nybble_from_hex(str[1]);
}

constexpr GUID guid_from_string(const char str[37]) {
return GUID{static_cast<uint32_t>(byte_from_hexstr(str)) << 24 |
static_cast<uint32_t>(byte_from_hexstr(str + 2)) << 16 |
static_cast<uint32_t>(byte_from_hexstr(str + 4)) << 8 |
byte_from_hexstr(str + 6),
static_cast<uint16_t>(
static_cast<uint16_t>(byte_from_hexstr(str + 9)) << 8 |
byte_from_hexstr(str + 11)),
static_cast<uint16_t>(
static_cast<uint16_t>(byte_from_hexstr(str + 14)) << 8 |
byte_from_hexstr(str + 16)),
{byte_from_hexstr(str + 19), byte_from_hexstr(str + 21),
byte_from_hexstr(str + 24), byte_from_hexstr(str + 26),
byte_from_hexstr(str + 28), byte_from_hexstr(str + 30),
byte_from_hexstr(str + 32), byte_from_hexstr(str + 34)}};
}

#endif // __MINGW32__

// The point of this helper file is to export the specializations for MINGW_UUIDOF
// below, since MinGW does not have these as part of dxguid yet (not completely up
// to date.)
MINGW_UUIDOF(IDXGraphicsAnalysis, "9f251514-9d4d-4902-9d60-18988ab7d4b5")

0 comments on commit f993d09

Please sign in to comment.