webgpu: begin building Dawn with Zig
* MacOS support functional * C shims for dawn_native functionality, e.g. required utilities for binding to a GLFW window. * Fully building with Zig, but depends on ziglang/zig#10096 for Obj-C++ support. Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
564248c09b
commit
b2aca7fdde
8 changed files with 2251 additions and 0 deletions
|
|
@ -1,14 +1,38 @@
|
||||||
const Builder = @import("std").build.Builder;
|
const Builder = @import("std").build.Builder;
|
||||||
|
const dawn = @import("build_dawn.zig");
|
||||||
|
|
||||||
|
const glfw = @import("./libs/dawn/mach-old/glfw/build.zig"); // TODO: mach-old path
|
||||||
|
|
||||||
pub fn build(b: *Builder) void {
|
pub fn build(b: *Builder) void {
|
||||||
const mode = b.standardReleaseOptions();
|
const mode = b.standardReleaseOptions();
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
|
||||||
const lib = b.addStaticLibrary("webgpu", "src/main.zig");
|
const lib = b.addStaticLibrary("webgpu", "src/main.zig");
|
||||||
lib.setBuildMode(mode);
|
lib.setBuildMode(mode);
|
||||||
|
lib.setTarget(target);
|
||||||
lib.install();
|
lib.install();
|
||||||
|
dawn.link(b, lib, .{});
|
||||||
|
|
||||||
var main_tests = b.addTest("src/main.zig");
|
var main_tests = b.addTest("src/main.zig");
|
||||||
main_tests.setBuildMode(mode);
|
main_tests.setBuildMode(mode);
|
||||||
|
|
||||||
const test_step = b.step("test", "Run library tests");
|
const test_step = b.step("test", "Run library tests");
|
||||||
test_step.dependOn(&main_tests.step);
|
test_step.dependOn(&main_tests.step);
|
||||||
|
|
||||||
|
const dawn_example = b.addExecutable("dawn-example", "src/dawn/hello_triangle.zig");
|
||||||
|
dawn_example.setBuildMode(mode);
|
||||||
|
dawn_example.setTarget(target);
|
||||||
|
dawn.link(b, dawn_example, .{});
|
||||||
|
glfw.link(b, dawn_example, .{.system_sdk = .{.set_sysroot = false}});
|
||||||
|
dawn_example.addPackagePath("glfw", "./libs/dawn/mach-old/glfw/src/main.zig"); // TODO: mach-old path
|
||||||
|
dawn_example.addIncludeDir("libs/dawn/out/Debug/gen/src/include");
|
||||||
|
dawn_example.addIncludeDir("libs/dawn/out/Debug/gen/src");
|
||||||
|
dawn_example.addIncludeDir("libs/dawn/src/include");
|
||||||
|
dawn_example.addIncludeDir("src/dawn");
|
||||||
|
dawn_example.install();
|
||||||
|
|
||||||
|
const dawn_example_run_cmd = dawn_example.run();
|
||||||
|
dawn_example_run_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
const dawn_example_run_step = b.step("run-dawn-example", "Run the dawn example");
|
||||||
|
dawn_example_run_step.dependOn(&dawn_example_run_cmd.step);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1295
webgpu/build_dawn.zig
Normal file
1295
webgpu/build_dawn.zig
Normal file
File diff suppressed because it is too large
Load diff
5
webgpu/src/dawn/c.zig
Normal file
5
webgpu/src/dawn/c.zig
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
pub const c = @cImport({
|
||||||
|
@cInclude("dawn/webgpu.h");
|
||||||
|
@cInclude("dawn/dawn_proc.h");
|
||||||
|
@cInclude("dawn_native_c.h");
|
||||||
|
});
|
||||||
388
webgpu/src/dawn/dawn_native_c.cpp
Normal file
388
webgpu/src/dawn/dawn_native_c.cpp
Normal file
|
|
@ -0,0 +1,388 @@
|
||||||
|
#include <dawn_native/DawnNative.h>
|
||||||
|
#include <dawn_native/wgpu_structs_autogen.h>
|
||||||
|
#include "utils/BackendBinding.h"
|
||||||
|
|
||||||
|
#include "dawn_native_c.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// wgpu::AdapterProperties wrappers
|
||||||
|
MACH_EXPORT void machDawnNativeAdapterProperties_deinit(MachDawnNativeAdapterProperties properties) {
|
||||||
|
auto self = reinterpret_cast<wgpu::AdapterProperties*>(properties);
|
||||||
|
delete self;
|
||||||
|
}
|
||||||
|
MACH_EXPORT uint32_t machDawnNativeAdapterProperties_getVendorID(MachDawnNativeAdapterProperties properties) {
|
||||||
|
auto self = reinterpret_cast<wgpu::AdapterProperties*>(properties);
|
||||||
|
return self->vendorID;
|
||||||
|
}
|
||||||
|
MACH_EXPORT uint32_t machDawnNativeAdapterProperties_getDeviceID(MachDawnNativeAdapterProperties properties) {
|
||||||
|
auto self = reinterpret_cast<wgpu::AdapterProperties*>(properties);
|
||||||
|
return self->deviceID;
|
||||||
|
}
|
||||||
|
MACH_EXPORT char const* machDawnNativeAdapterProperties_getName(MachDawnNativeAdapterProperties properties) {
|
||||||
|
auto self = reinterpret_cast<wgpu::AdapterProperties*>(properties);
|
||||||
|
return self->name;
|
||||||
|
}
|
||||||
|
MACH_EXPORT char const* machDawnNativeAdapterProperties_getDriverDescription(MachDawnNativeAdapterProperties properties) {
|
||||||
|
auto self = reinterpret_cast<wgpu::AdapterProperties*>(properties);
|
||||||
|
return self->driverDescription;
|
||||||
|
}
|
||||||
|
MACH_EXPORT WGPUAdapterType machDawnNativeAdapterProperties_getAdapterType(MachDawnNativeAdapterProperties properties) {
|
||||||
|
auto self = reinterpret_cast<wgpu::AdapterProperties*>(properties);
|
||||||
|
switch (self->adapterType) {
|
||||||
|
case wgpu::AdapterType::DiscreteGPU: return WGPUAdapterType_DiscreteGPU;
|
||||||
|
case wgpu::AdapterType::IntegratedGPU: return WGPUAdapterType_IntegratedGPU;
|
||||||
|
case wgpu::AdapterType::CPU: return WGPUAdapterType_CPU;
|
||||||
|
case wgpu::AdapterType::Unknown: return WGPUAdapterType_Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MACH_EXPORT WGPUBackendType machDawnNativeAdapterProperties_getBackendType(MachDawnNativeAdapterProperties properties) {
|
||||||
|
auto self = reinterpret_cast<wgpu::AdapterProperties*>(properties);
|
||||||
|
switch (self->backendType) {
|
||||||
|
case wgpu::BackendType::WebGPU: return WGPUBackendType_WebGPU;
|
||||||
|
case wgpu::BackendType::D3D11: return WGPUBackendType_D3D11;
|
||||||
|
case wgpu::BackendType::D3D12: return WGPUBackendType_D3D12;
|
||||||
|
case wgpu::BackendType::Metal: return WGPUBackendType_Metal;
|
||||||
|
case wgpu::BackendType::Null: return WGPUBackendType_Null;
|
||||||
|
case wgpu::BackendType::OpenGL: return WGPUBackendType_OpenGL;
|
||||||
|
case wgpu::BackendType::OpenGLES: return WGPUBackendType_OpenGLES;
|
||||||
|
case wgpu::BackendType::Vulkan: return WGPUBackendType_Vulkan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dawn_native::Adapter wrappers
|
||||||
|
MACH_EXPORT MachDawnNativeAdapterProperties machDawnNativeAdapter_getProperties(MachDawnNativeAdapter adapter) {
|
||||||
|
auto self = reinterpret_cast<dawn_native::Adapter*>(adapter);
|
||||||
|
auto cppProperties = new wgpu::AdapterProperties();
|
||||||
|
self->GetProperties(cppProperties);
|
||||||
|
return reinterpret_cast<MachDawnNativeAdapterProperties>(cppProperties);
|
||||||
|
}
|
||||||
|
// TODO(mach-dawn-shims):
|
||||||
|
// std::vector<const char*> GetSupportedExtensions() const;
|
||||||
|
// WGPUDeviceProperties GetAdapterProperties() const;
|
||||||
|
// bool GetLimits(WGPUSupportedLimits* limits) const;
|
||||||
|
// void SetUseTieredLimits(bool useTieredLimits);
|
||||||
|
// // Check that the Adapter is able to support importing external images. This is necessary
|
||||||
|
// // to implement the swapchain and interop APIs in Chromium.
|
||||||
|
// bool SupportsExternalImages() const;
|
||||||
|
// explicit operator bool() const;
|
||||||
|
MACH_EXPORT WGPUDevice machDawnNativeAdapter_createDevice(MachDawnNativeAdapter adapter, MachDawnNativeDeviceDescriptor* deviceDescriptor) {
|
||||||
|
auto self = reinterpret_cast<dawn_native::Adapter*>(adapter);
|
||||||
|
|
||||||
|
if (deviceDescriptor == nullptr) {
|
||||||
|
return self->CreateDevice(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const char*> cppRequiredExtensions;
|
||||||
|
for (int i = 0; i < deviceDescriptor->requiredExtensionsLength; i++)
|
||||||
|
cppRequiredExtensions.push_back(deviceDescriptor->requiredExtensions[i]);
|
||||||
|
|
||||||
|
std::vector<const char*> cppForceEnabledToggles;
|
||||||
|
for (int i = 0; i < deviceDescriptor->forceEnabledTogglesLength; i++)
|
||||||
|
cppForceEnabledToggles.push_back(deviceDescriptor->forceEnabledToggles[i]);
|
||||||
|
|
||||||
|
std::vector<const char*> cppForceDisabledToggles;
|
||||||
|
for (int i = 0; i < deviceDescriptor->forceDisabledTogglesLength; i++)
|
||||||
|
cppForceDisabledToggles.push_back(deviceDescriptor->forceDisabledToggles[i]);
|
||||||
|
|
||||||
|
auto cppDeviceDescriptor = dawn_native::DeviceDescriptor{
|
||||||
|
.requiredExtensions = cppRequiredExtensions,
|
||||||
|
.forceEnabledToggles = cppForceEnabledToggles,
|
||||||
|
.forceDisabledToggles = cppForceDisabledToggles,
|
||||||
|
.requiredLimits = deviceDescriptor->requiredLimits,
|
||||||
|
};
|
||||||
|
return self->CreateDevice(&cppDeviceDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(mach-dawn-shims):
|
||||||
|
// // An optional parameter of Adapter::CreateDevice() to send additional information when creating
|
||||||
|
// // a Device. For example, we can use it to enable a workaround, optimization or feature.
|
||||||
|
// struct DAWN_NATIVE_EXPORT DeviceDescriptor {
|
||||||
|
// std::vector<const char*> requiredExtensions;
|
||||||
|
// std::vector<const char*> forceEnabledToggles;
|
||||||
|
// std::vector<const char*> forceDisabledToggles;
|
||||||
|
|
||||||
|
// const WGPURequiredLimits* requiredLimits = nullptr;
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
// TODO(mach-dawn-shims):
|
||||||
|
// // Create a device on this adapter, note that the interface will change to include at least
|
||||||
|
// // a device descriptor and a pointer to backend specific options.
|
||||||
|
// // On an error, nullptr is returned.
|
||||||
|
// WGPUDevice CreateDevice(const DeviceDescriptor* deviceDescriptor = nullptr);
|
||||||
|
|
||||||
|
// TODO(mach-dawn-shims):
|
||||||
|
// void RequestDevice(const DeviceDescriptor* descriptor,
|
||||||
|
// WGPURequestDeviceCallback callback,
|
||||||
|
// void* userdata);
|
||||||
|
|
||||||
|
// TODO(mach-dawn-shims):
|
||||||
|
// // Reset the backend device object for testing purposes.
|
||||||
|
// void ResetInternalDeviceForTesting();
|
||||||
|
|
||||||
|
// std::vector<Adapter> wrapper
|
||||||
|
typedef struct MachDawnNativeAdaptersImpl* MachDawnNativeAdapters;
|
||||||
|
MACH_EXPORT MachDawnNativeAdapter machDawnNativeAdapters_index(MachDawnNativeAdapters adapters, uintptr_t index) {
|
||||||
|
auto self = reinterpret_cast<std::vector<dawn_native::Adapter>*>(adapters);
|
||||||
|
return reinterpret_cast<MachDawnNativeAdapter>(&(*self)[index]);
|
||||||
|
}
|
||||||
|
MACH_EXPORT uintptr_t machDawnNativeAdapters_length(MachDawnNativeAdapters adapters) {
|
||||||
|
auto self = reinterpret_cast<std::vector<dawn_native::Adapter>*>(adapters);
|
||||||
|
return self->size();
|
||||||
|
};
|
||||||
|
|
||||||
|
// dawn_native::Instance wrappers
|
||||||
|
MACH_EXPORT MachDawnNativeInstance machDawnNativeInstance_init(void) {
|
||||||
|
return reinterpret_cast<MachDawnNativeInstance>(new dawn_native::Instance());
|
||||||
|
}
|
||||||
|
MACH_EXPORT void machDawnNativeInstance_deinit(MachDawnNativeInstance instance) {
|
||||||
|
delete reinterpret_cast<dawn_native::Instance*>(instance);
|
||||||
|
}
|
||||||
|
MACH_EXPORT void machDawnNativeInstance_discoverDefaultAdapters(MachDawnNativeInstance instance) {
|
||||||
|
dawn_native::Instance* self = reinterpret_cast<dawn_native::Instance*>(instance);
|
||||||
|
self->DiscoverDefaultAdapters();
|
||||||
|
}
|
||||||
|
// TODO(mach-dawn-shims):
|
||||||
|
// // Adds adapters that can be discovered with the options provided (like a getProcAddress).
|
||||||
|
// // The backend is chosen based on the type of the options used. Returns true on success.
|
||||||
|
// bool DiscoverAdapters(const AdapterDiscoveryOptionsBase* options);
|
||||||
|
MACH_EXPORT MachDawnNativeAdapters machDawnNativeInstance_getAdapters(MachDawnNativeInstance instance) {
|
||||||
|
dawn_native::Instance* self = reinterpret_cast<dawn_native::Instance*>(instance);
|
||||||
|
auto cppAdapters = self->GetAdapters();
|
||||||
|
auto heapAllocated = new std::vector<dawn_native::Adapter>();
|
||||||
|
for (int i=0; i<cppAdapters.size(); i++) heapAllocated->push_back(cppAdapters[i]);
|
||||||
|
return reinterpret_cast<MachDawnNativeAdapters>(heapAllocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
MACH_EXPORT const DawnProcTable* machDawnNativeGetProcs() {
|
||||||
|
return &dawn_native::GetProcs();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(mach-dawn-shims):
|
||||||
|
// const ToggleInfo* GetToggleInfo(const char* toggleName);
|
||||||
|
|
||||||
|
// TODO(mach-dawn-shims):
|
||||||
|
// // Enables backend validation layers
|
||||||
|
// void EnableBackendValidation(bool enableBackendValidation);
|
||||||
|
// void SetBackendValidationLevel(BackendValidationLevel validationLevel);
|
||||||
|
|
||||||
|
// TODO(mach-dawn-shims):
|
||||||
|
// // Enable debug capture on Dawn startup
|
||||||
|
// void EnableBeginCaptureOnStartup(bool beginCaptureOnStartup);
|
||||||
|
|
||||||
|
// TODO(mach-dawn-shims):
|
||||||
|
// void SetPlatform(dawn_platform::Platform* platform);
|
||||||
|
|
||||||
|
// TODO(mach-dawn-shims):
|
||||||
|
// // Returns the underlying WGPUInstance object.
|
||||||
|
// WGPUInstance Get() const;
|
||||||
|
|
||||||
|
|
||||||
|
// typedef struct MachUtilsBackendBindingImpl* MachUtilsBackendBinding;
|
||||||
|
#include <stdio.h>
|
||||||
|
MACH_EXPORT MachUtilsBackendBinding machUtilsCreateBinding(WGPUBackendType backendType, GLFWwindow* window, WGPUDevice device) {
|
||||||
|
wgpu::BackendType cppBackendType;
|
||||||
|
printf("here with backendType=%d, expecting %d\n", backendType, WGPUBackendType_Metal);
|
||||||
|
switch (backendType) {
|
||||||
|
case WGPUBackendType_WebGPU:
|
||||||
|
cppBackendType = wgpu::BackendType::WebGPU;
|
||||||
|
break;
|
||||||
|
case WGPUBackendType_D3D11:
|
||||||
|
cppBackendType = wgpu::BackendType::D3D11;
|
||||||
|
break;
|
||||||
|
case WGPUBackendType_D3D12:
|
||||||
|
cppBackendType = wgpu::BackendType::D3D12;
|
||||||
|
break;
|
||||||
|
case WGPUBackendType_Metal:
|
||||||
|
cppBackendType = wgpu::BackendType::Metal;
|
||||||
|
break;
|
||||||
|
case WGPUBackendType_Null:
|
||||||
|
cppBackendType = wgpu::BackendType::Null;
|
||||||
|
break;
|
||||||
|
case WGPUBackendType_OpenGL:
|
||||||
|
cppBackendType = wgpu::BackendType::OpenGL;
|
||||||
|
break;
|
||||||
|
case WGPUBackendType_OpenGLES:
|
||||||
|
cppBackendType = wgpu::BackendType::OpenGLES;
|
||||||
|
break;
|
||||||
|
case WGPUBackendType_Vulkan:
|
||||||
|
cppBackendType = wgpu::BackendType::Vulkan;
|
||||||
|
break;
|
||||||
|
case WGPUBackendType_Force32:
|
||||||
|
// TODO: what would this indicate?
|
||||||
|
cppBackendType = wgpu::BackendType::Null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("created cppBackendType=%d, expected %d\n", cppBackendType, wgpu::BackendType::Metal);
|
||||||
|
return reinterpret_cast<MachUtilsBackendBinding>(utils::CreateBinding(cppBackendType, window, device));
|
||||||
|
}
|
||||||
|
|
||||||
|
MACH_EXPORT uint64_t machUtilsBackendBinding_getSwapChainImplementation(MachUtilsBackendBinding binding) {
|
||||||
|
auto self = reinterpret_cast<utils::BackendBinding*>(binding);
|
||||||
|
return self->GetSwapChainImplementation();
|
||||||
|
}
|
||||||
|
MACH_EXPORT WGPUTextureFormat machUtilsBackendBinding_getPreferredSwapChainTextureFormat(MachUtilsBackendBinding binding) {
|
||||||
|
auto self = reinterpret_cast<utils::BackendBinding*>(binding);
|
||||||
|
return self->GetPreferredSwapChainTextureFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO(mach-dawn-shims): everything below here is not wrapped
|
||||||
|
|
||||||
|
// #ifndef DAWNNATIVE_DAWNNATIVE_H_
|
||||||
|
// #define DAWNNATIVE_DAWNNATIVE_H_
|
||||||
|
|
||||||
|
// #include <dawn/dawn_proc_table.h>
|
||||||
|
// #include <dawn/webgpu.h>
|
||||||
|
// #include <dawn_native/dawn_native_export.h>
|
||||||
|
|
||||||
|
// #include <string>
|
||||||
|
// #include <vector>
|
||||||
|
|
||||||
|
// namespace dawn_platform {
|
||||||
|
// class Platform;
|
||||||
|
// } // namespace dawn_platform
|
||||||
|
|
||||||
|
// namespace wgpu {
|
||||||
|
// struct AdapterProperties;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// namespace dawn_native {
|
||||||
|
|
||||||
|
// // DEPRECATED: use WGPUAdapterProperties instead.
|
||||||
|
// struct PCIInfo {
|
||||||
|
// uint32_t deviceId = 0;
|
||||||
|
// uint32_t vendorId = 0;
|
||||||
|
// std::string name;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // DEPRECATED: use WGPUBackendType instead.
|
||||||
|
// enum class BackendType {
|
||||||
|
// D3D12,
|
||||||
|
// Metal,
|
||||||
|
// Null,
|
||||||
|
// OpenGL,
|
||||||
|
// OpenGLES,
|
||||||
|
// Vulkan,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // DEPRECATED: use WGPUAdapterType instead.
|
||||||
|
// enum class DeviceType {
|
||||||
|
// DiscreteGPU,
|
||||||
|
// IntegratedGPU,
|
||||||
|
// CPU,
|
||||||
|
// Unknown,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// class InstanceBase;
|
||||||
|
// class AdapterBase;
|
||||||
|
|
||||||
|
// // A struct to record the information of a toggle. A toggle is a code path in Dawn device that
|
||||||
|
// // can be manually configured to run or not outside Dawn, including workarounds, special
|
||||||
|
// // features and optimizations.
|
||||||
|
// struct ToggleInfo {
|
||||||
|
// const char* name;
|
||||||
|
// const char* description;
|
||||||
|
// const char* url;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // A struct to record the information of an extension. An extension is a GPU feature that is not
|
||||||
|
// // required to be supported by all Dawn backends and can only be used when it is enabled on the
|
||||||
|
// // creation of device.
|
||||||
|
// using ExtensionInfo = ToggleInfo;
|
||||||
|
|
||||||
|
// // Base class for options passed to Instance::DiscoverAdapters.
|
||||||
|
// struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptionsBase {
|
||||||
|
// public:
|
||||||
|
// const WGPUBackendType backendType;
|
||||||
|
|
||||||
|
// protected:
|
||||||
|
// AdapterDiscoveryOptionsBase(WGPUBackendType type);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// enum BackendValidationLevel { Full, Partial, Disabled };
|
||||||
|
|
||||||
|
// class DAWN_NATIVE_EXPORT Instance {
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Query the names of all the toggles that are enabled in device
|
||||||
|
// DAWN_NATIVE_EXPORT std::vector<const char*> GetTogglesUsed(WGPUDevice device);
|
||||||
|
|
||||||
|
// // Backdoor to get the number of lazy clears for testing
|
||||||
|
// DAWN_NATIVE_EXPORT size_t GetLazyClearCountForTesting(WGPUDevice device);
|
||||||
|
|
||||||
|
// // Backdoor to get the number of deprecation warnings for testing
|
||||||
|
// DAWN_NATIVE_EXPORT size_t GetDeprecationWarningCountForTesting(WGPUDevice device);
|
||||||
|
|
||||||
|
// // Query if texture has been initialized
|
||||||
|
// DAWN_NATIVE_EXPORT bool IsTextureSubresourceInitialized(
|
||||||
|
// WGPUTexture texture,
|
||||||
|
// uint32_t baseMipLevel,
|
||||||
|
// uint32_t levelCount,
|
||||||
|
// uint32_t baseArrayLayer,
|
||||||
|
// uint32_t layerCount,
|
||||||
|
// WGPUTextureAspect aspect = WGPUTextureAspect_All);
|
||||||
|
|
||||||
|
// // Backdoor to get the order of the ProcMap for testing
|
||||||
|
// DAWN_NATIVE_EXPORT std::vector<const char*> GetProcMapNamesForTesting();
|
||||||
|
|
||||||
|
// DAWN_NATIVE_EXPORT bool DeviceTick(WGPUDevice device);
|
||||||
|
|
||||||
|
// // ErrorInjector functions used for testing only. Defined in dawn_native/ErrorInjector.cpp
|
||||||
|
// DAWN_NATIVE_EXPORT void EnableErrorInjector();
|
||||||
|
// DAWN_NATIVE_EXPORT void DisableErrorInjector();
|
||||||
|
// DAWN_NATIVE_EXPORT void ClearErrorInjector();
|
||||||
|
// DAWN_NATIVE_EXPORT uint64_t AcquireErrorInjectorCallCount();
|
||||||
|
// DAWN_NATIVE_EXPORT void InjectErrorAt(uint64_t index);
|
||||||
|
|
||||||
|
// // The different types of external images
|
||||||
|
// enum ExternalImageType {
|
||||||
|
// OpaqueFD,
|
||||||
|
// DmaBuf,
|
||||||
|
// IOSurface,
|
||||||
|
// DXGISharedHandle,
|
||||||
|
// EGLImage,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Common properties of external images
|
||||||
|
// struct DAWN_NATIVE_EXPORT ExternalImageDescriptor {
|
||||||
|
// public:
|
||||||
|
// const ExternalImageType type;
|
||||||
|
// const WGPUTextureDescriptor* cTextureDescriptor; // Must match image creation params
|
||||||
|
// bool isInitialized; // Whether the texture is initialized on import
|
||||||
|
|
||||||
|
// protected:
|
||||||
|
// ExternalImageDescriptor(ExternalImageType type);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// struct DAWN_NATIVE_EXPORT ExternalImageAccessDescriptor {
|
||||||
|
// public:
|
||||||
|
// bool isInitialized; // Whether the texture is initialized on import
|
||||||
|
// WGPUTextureUsageFlags usage;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// struct DAWN_NATIVE_EXPORT ExternalImageExportInfo {
|
||||||
|
// public:
|
||||||
|
// const ExternalImageType type;
|
||||||
|
// bool isInitialized; // Whether the texture is initialized after export
|
||||||
|
|
||||||
|
// protected:
|
||||||
|
// ExternalImageExportInfo(ExternalImageType type);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// DAWN_NATIVE_EXPORT const char* GetObjectLabelForTesting(void* objectHandle);
|
||||||
|
|
||||||
|
// DAWN_NATIVE_EXPORT uint64_t GetAllocatedSizeForTesting(WGPUBuffer buffer);
|
||||||
|
|
||||||
|
// DAWN_NATIVE_EXPORT bool BindGroupLayoutBindingsEqualForTesting(WGPUBindGroupLayout a,
|
||||||
|
// WGPUBindGroupLayout b);
|
||||||
|
|
||||||
|
// } // namespace dawn_native
|
||||||
|
|
||||||
|
// #endif // DAWNNATIVE_DAWNNATIVE_H_
|
||||||
102
webgpu/src/dawn/dawn_native_c.h
Normal file
102
webgpu/src/dawn/dawn_native_c.h
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
#ifndef MACH_DAWNNATIVE_C_H_
|
||||||
|
#define MACH_DAWNNATIVE_C_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MACH_DAWNNATIVE_C_SHARED_LIBRARY)
|
||||||
|
# if defined(_WIN32)
|
||||||
|
# if defined(MACH_DAWNNATIVE_C_IMPLEMENTATION)
|
||||||
|
# define MACH_EXPORT __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define MACH_EXPORT __declspec(dllimport)
|
||||||
|
# endif
|
||||||
|
# else // defined(_WIN32)
|
||||||
|
# if defined(MACH_DAWNNATIVE_C_IMPLEMENTATION)
|
||||||
|
# define MACH_EXPORT __attribute__((visibility("default")))
|
||||||
|
# else
|
||||||
|
# define MACH_EXPORT
|
||||||
|
# endif
|
||||||
|
# endif // defined(_WIN32)
|
||||||
|
#else // defined(MACH_DAWNNATIVE_C_SHARED_LIBRARY)
|
||||||
|
# define MACH_EXPORT
|
||||||
|
#endif // defined(MACH_DAWNNATIVE_C_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
#include <dawn/webgpu.h>
|
||||||
|
#include <dawn/dawn_proc_table.h>
|
||||||
|
|
||||||
|
// TODO(slimsag): future: Dawn authors want dawn_native::AdapterProperties to eventually be in webgpu.h,
|
||||||
|
// and there is a corresponding WGPUAdapterProperties struct today, but there aren't corresponding methods
|
||||||
|
// to actually use / work with it today.
|
||||||
|
typedef struct MachDawnNativeAdapterPropertiesImpl* MachDawnNativeAdapterProperties;
|
||||||
|
|
||||||
|
MACH_EXPORT void machDawnNativeAdapterProperties_deinit(MachDawnNativeAdapterProperties properties);
|
||||||
|
MACH_EXPORT uint32_t machDawnNativeAdapterProperties_getVendorID(MachDawnNativeAdapterProperties properties);
|
||||||
|
MACH_EXPORT uint32_t machDawnNativeAdapterProperties_getDeviceID(MachDawnNativeAdapterProperties properties);
|
||||||
|
MACH_EXPORT char const* machDawnNativeAdapterProperties_getName(MachDawnNativeAdapterProperties properties);
|
||||||
|
MACH_EXPORT char const* machDawnNativeAdapterProperties_getDriverDescription(MachDawnNativeAdapterProperties properties);
|
||||||
|
MACH_EXPORT WGPUAdapterType machDawnNativeAdapterProperties_getAdapterType(MachDawnNativeAdapterProperties properties);
|
||||||
|
MACH_EXPORT WGPUBackendType machDawnNativeAdapterProperties_getBackendType(MachDawnNativeAdapterProperties properties);
|
||||||
|
|
||||||
|
// An adapter is an object that represent on possibility of creating devices in the system.
|
||||||
|
// Most of the time it will represent a combination of a physical GPU and an API. Not that the
|
||||||
|
// same GPU can be represented by multiple adapters but on different APIs.
|
||||||
|
//
|
||||||
|
// The underlying Dawn adapter is owned by the Dawn instance so this is just a reference to an
|
||||||
|
// underlying adapter.
|
||||||
|
typedef struct MachDawnNativeAdapterImpl* MachDawnNativeAdapter;
|
||||||
|
|
||||||
|
MACH_EXPORT MachDawnNativeAdapterProperties machDawnNativeAdapter_getProperties(MachDawnNativeAdapter adapter);
|
||||||
|
|
||||||
|
// An optional parameter of Adapter::CreateDevice() to send additional information when creating
|
||||||
|
// a Device. For example, we can use it to enable a workaround, optimization or feature.
|
||||||
|
typedef struct MachDawnNativeDeviceDescriptor {
|
||||||
|
char** requiredExtensions;
|
||||||
|
uintptr_t requiredExtensionsLength;
|
||||||
|
|
||||||
|
char** forceEnabledToggles;
|
||||||
|
uintptr_t forceEnabledTogglesLength;
|
||||||
|
|
||||||
|
char** forceDisabledToggles;
|
||||||
|
uintptr_t forceDisabledTogglesLength;
|
||||||
|
|
||||||
|
// default null
|
||||||
|
WGPURequiredLimits* requiredLimits;
|
||||||
|
} MachDawnNativeDeviceDescriptor;
|
||||||
|
MACH_EXPORT WGPUDevice machDawnNativeAdapter_createDevice(MachDawnNativeAdapter adapter, MachDawnNativeDeviceDescriptor* deviceDescriptor);
|
||||||
|
|
||||||
|
typedef struct MachDawnNativeAdaptersImpl* MachDawnNativeAdapters;
|
||||||
|
MACH_EXPORT MachDawnNativeAdapter machDawnNativeAdapters_index(MachDawnNativeAdapters adapters, uintptr_t index);
|
||||||
|
MACH_EXPORT uintptr_t machDawnNativeAdapters_length(MachDawnNativeAdapters adapters);
|
||||||
|
|
||||||
|
// Represents a connection to dawn_native and is used for dependency injection, discovering
|
||||||
|
// system adapters and injecting custom adapters (like a Swiftshader Vulkan adapter).
|
||||||
|
//
|
||||||
|
// This can be initialized via machDawnNativeInstanceInit and destroyed via
|
||||||
|
// machDawnNativeInstanceDeinit. The instance controls the lifetime of all adapters for the
|
||||||
|
// instance.
|
||||||
|
typedef struct MachDawnNativeInstanceImpl* MachDawnNativeInstance;
|
||||||
|
|
||||||
|
MACH_EXPORT MachDawnNativeInstance machDawnNativeInstance_init(void);
|
||||||
|
MACH_EXPORT void machDawnNativeInstance_deinit(MachDawnNativeInstance);
|
||||||
|
MACH_EXPORT void machDawnNativeInstance_discoverDefaultAdapters(MachDawnNativeInstance);
|
||||||
|
MACH_EXPORT MachDawnNativeAdapters machDawnNativeInstance_getAdapters(MachDawnNativeInstance instance);
|
||||||
|
|
||||||
|
// Backend-agnostic API for dawn_native
|
||||||
|
MACH_EXPORT const DawnProcTable* machDawnNativeGetProcs();
|
||||||
|
|
||||||
|
|
||||||
|
// utils
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
typedef struct MachUtilsBackendBindingImpl* MachUtilsBackendBinding;
|
||||||
|
MACH_EXPORT MachUtilsBackendBinding machUtilsCreateBinding(WGPUBackendType backendType, GLFWwindow* window, WGPUDevice device);
|
||||||
|
MACH_EXPORT uint64_t machUtilsBackendBinding_getSwapChainImplementation(MachUtilsBackendBinding binding);
|
||||||
|
MACH_EXPORT WGPUTextureFormat machUtilsBackendBinding_getPreferredSwapChainTextureFormat(MachUtilsBackendBinding binding);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // MACH_DAWNNATIVE_C_H_
|
||||||
0
webgpu/src/dawn/dummy.zig
Normal file
0
webgpu/src/dawn/dummy.zig
Normal file
167
webgpu/src/dawn/hello_triangle.zig
Normal file
167
webgpu/src/dawn/hello_triangle.zig
Normal file
|
|
@ -0,0 +1,167 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const sample_utils = @import("sample_utils.zig");
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
const glfw = @import("glfw");
|
||||||
|
|
||||||
|
// #include "utils/SystemUtils.h"
|
||||||
|
// #include "utils/WGPUHelpers.h"
|
||||||
|
|
||||||
|
// WGPUSwapChain swapchain;
|
||||||
|
// WGPURenderPipeline pipeline;
|
||||||
|
|
||||||
|
// WGPUTextureFormat swapChainFormat;
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
var allocator = &gpa.allocator;
|
||||||
|
|
||||||
|
const setup = try sample_utils.setup();
|
||||||
|
const queue = c.wgpuDeviceGetQueue(setup.device);
|
||||||
|
|
||||||
|
var descriptor = std.mem.zeroes(c.WGPUSwapChainDescriptor);
|
||||||
|
descriptor.implementation = c.machUtilsBackendBinding_getSwapChainImplementation(setup.binding);
|
||||||
|
const swap_chain = c.wgpuDeviceCreateSwapChain(setup.device, null, &descriptor);
|
||||||
|
|
||||||
|
const swap_chain_format = c.machUtilsBackendBinding_getPreferredSwapChainTextureFormat(setup.binding);
|
||||||
|
c.wgpuSwapChainConfigure(swap_chain, swap_chain_format, c.WGPUTextureUsage_RenderAttachment, 640, 480);
|
||||||
|
|
||||||
|
const vs =
|
||||||
|
\\ [[stage(vertex)]] fn main(
|
||||||
|
\\ [[builtin(vertex_index)]] VertexIndex : u32
|
||||||
|
\\ ) -> [[builtin(position)]] vec4<f32> {
|
||||||
|
\\ var pos = array<vec2<f32>, 3>(
|
||||||
|
\\ vec2<f32>( 0.0, 0.5),
|
||||||
|
\\ vec2<f32>(-0.5, -0.5),
|
||||||
|
\\ vec2<f32>( 0.5, -0.5)
|
||||||
|
\\ );
|
||||||
|
\\ return vec4<f32>(pos[VertexIndex], 0.0, 1.0);
|
||||||
|
\\ }
|
||||||
|
;
|
||||||
|
var vs_wgsl_descriptor = try allocator.create(c.WGPUShaderModuleWGSLDescriptor);
|
||||||
|
vs_wgsl_descriptor.chain.next = null;
|
||||||
|
vs_wgsl_descriptor.chain.sType = c.WGPUSType_ShaderModuleWGSLDescriptor;
|
||||||
|
vs_wgsl_descriptor.source = vs;
|
||||||
|
const vs_shader_descriptor = c.WGPUShaderModuleDescriptor{
|
||||||
|
.nextInChain = @ptrCast(*const c.WGPUChainedStruct, vs_wgsl_descriptor),
|
||||||
|
.label = "my vertex shader",
|
||||||
|
};
|
||||||
|
const vs_module = c.wgpuDeviceCreateShaderModule(setup.device, &vs_shader_descriptor);
|
||||||
|
|
||||||
|
const fs =
|
||||||
|
\\ [[stage(fragment)]] fn main() -> [[location(0)]] vec4<f32> {
|
||||||
|
\\ return vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
||||||
|
\\ }
|
||||||
|
;
|
||||||
|
var fs_wgsl_descriptor = try allocator.create(c.WGPUShaderModuleWGSLDescriptor);
|
||||||
|
fs_wgsl_descriptor.chain.next = null;
|
||||||
|
fs_wgsl_descriptor.chain.sType = c.WGPUSType_ShaderModuleWGSLDescriptor;
|
||||||
|
fs_wgsl_descriptor.source = fs;
|
||||||
|
const fs_shader_descriptor = c.WGPUShaderModuleDescriptor{
|
||||||
|
.nextInChain = @ptrCast(*const c.WGPUChainedStruct, fs_wgsl_descriptor),
|
||||||
|
.label = "my fragment shader",
|
||||||
|
};
|
||||||
|
const fs_module = c.wgpuDeviceCreateShaderModule(setup.device, &fs_shader_descriptor);
|
||||||
|
|
||||||
|
// Fragment state
|
||||||
|
var blend = std.mem.zeroes(c.WGPUBlendState);
|
||||||
|
blend.color.operation = c.WGPUBlendOperation_Add;
|
||||||
|
blend.color.srcFactor = c.WGPUBlendFactor_One;
|
||||||
|
blend.color.dstFactor = c.WGPUBlendFactor_One;
|
||||||
|
blend.alpha.operation = c.WGPUBlendOperation_Add;
|
||||||
|
blend.alpha.srcFactor = c.WGPUBlendFactor_One;
|
||||||
|
blend.alpha.dstFactor = c.WGPUBlendFactor_One;
|
||||||
|
|
||||||
|
var color_target = std.mem.zeroes(c.WGPUColorTargetState);
|
||||||
|
color_target.format = swap_chain_format;
|
||||||
|
color_target.blend = &blend;
|
||||||
|
color_target.writeMask = c.WGPUColorWriteMask_All;
|
||||||
|
|
||||||
|
var fragment = std.mem.zeroes(c.WGPUFragmentState);
|
||||||
|
fragment.module = fs_module;
|
||||||
|
fragment.entryPoint = "main";
|
||||||
|
fragment.targetCount = 1;
|
||||||
|
fragment.targets = &color_target;
|
||||||
|
|
||||||
|
var pipeline_descriptor = std.mem.zeroes(c.WGPURenderPipelineDescriptor);
|
||||||
|
pipeline_descriptor.fragment = &fragment;
|
||||||
|
|
||||||
|
// Other state
|
||||||
|
pipeline_descriptor.layout = null;
|
||||||
|
pipeline_descriptor.depthStencil = null;
|
||||||
|
|
||||||
|
pipeline_descriptor.vertex.module = vs_module;
|
||||||
|
pipeline_descriptor.vertex.entryPoint = "main";
|
||||||
|
pipeline_descriptor.vertex.bufferCount = 0;
|
||||||
|
pipeline_descriptor.vertex.buffers = null;
|
||||||
|
|
||||||
|
pipeline_descriptor.multisample.count = 1;
|
||||||
|
pipeline_descriptor.multisample.mask = 0xFFFFFFFF;
|
||||||
|
pipeline_descriptor.multisample.alphaToCoverageEnabled = false;
|
||||||
|
|
||||||
|
pipeline_descriptor.primitive.frontFace = c.WGPUFrontFace_CCW;
|
||||||
|
pipeline_descriptor.primitive.cullMode = c.WGPUCullMode_None;
|
||||||
|
pipeline_descriptor.primitive.topology = c.WGPUPrimitiveTopology_TriangleList;
|
||||||
|
pipeline_descriptor.primitive.stripIndexFormat = c.WGPUIndexFormat_Undefined;
|
||||||
|
|
||||||
|
const pipeline = c.wgpuDeviceCreateRenderPipeline(setup.device, &pipeline_descriptor);
|
||||||
|
|
||||||
|
c.wgpuShaderModuleRelease(vs_module);
|
||||||
|
c.wgpuShaderModuleRelease(fs_module);
|
||||||
|
|
||||||
|
while (!setup.window.shouldClose()) {
|
||||||
|
// _ = pipeline;
|
||||||
|
// _ = queue;
|
||||||
|
// try glfw.pollEvents();
|
||||||
|
try frame(.{
|
||||||
|
.device = setup.device,
|
||||||
|
.swap_chain = swap_chain,
|
||||||
|
.pipeline = pipeline,
|
||||||
|
.queue = queue,
|
||||||
|
});
|
||||||
|
std.time.sleep(16000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const FrameParams = struct {
|
||||||
|
device: c.WGPUDevice,
|
||||||
|
swap_chain: c.WGPUSwapChain,
|
||||||
|
pipeline: c.WGPURenderPipeline,
|
||||||
|
queue: c.WGPUQueue,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn frame(params: FrameParams) !void {
|
||||||
|
const back_buffer_view = c.wgpuSwapChainGetCurrentTextureView(params.swap_chain);
|
||||||
|
var render_pass_info = std.mem.zeroes(c.WGPURenderPassDescriptor);
|
||||||
|
var color_attachment = std.mem.zeroes(c.WGPURenderPassColorAttachment);
|
||||||
|
color_attachment.view = back_buffer_view;
|
||||||
|
color_attachment.resolveTarget = null;
|
||||||
|
color_attachment.clearColor = c.WGPUColor{ .r = 0.0, .g = 0.0, .b = 0.0, .a = 0.0 };
|
||||||
|
color_attachment.loadOp = c.WGPULoadOp_Clear;
|
||||||
|
color_attachment.storeOp = c.WGPUStoreOp_Store;
|
||||||
|
render_pass_info.colorAttachmentCount = 1;
|
||||||
|
render_pass_info.colorAttachments = &color_attachment;
|
||||||
|
render_pass_info.depthStencilAttachment = null;
|
||||||
|
|
||||||
|
const encoder = c.wgpuDeviceCreateCommandEncoder(params.device, null);
|
||||||
|
const pass = c.wgpuCommandEncoderBeginRenderPass(encoder, &render_pass_info);
|
||||||
|
c.wgpuRenderPassEncoderSetPipeline(pass, params.pipeline);
|
||||||
|
c.wgpuRenderPassEncoderDraw(pass, 3, 1, 0, 0);
|
||||||
|
c.wgpuRenderPassEncoderEndPass(pass);
|
||||||
|
c.wgpuRenderPassEncoderRelease(pass);
|
||||||
|
|
||||||
|
const commands = c.wgpuCommandEncoderFinish(encoder, null);
|
||||||
|
c.wgpuCommandEncoderRelease(encoder);
|
||||||
|
|
||||||
|
c.wgpuQueueSubmit(params.queue, 1, &commands);
|
||||||
|
c.wgpuCommandBufferRelease(commands);
|
||||||
|
c.wgpuSwapChainPresent(params.swap_chain);
|
||||||
|
c.wgpuTextureViewRelease(back_buffer_view);
|
||||||
|
|
||||||
|
// if (cmdBufType == CmdBufType::Terrible) {
|
||||||
|
// bool c2sSuccess = c2sBuf->Flush();
|
||||||
|
// bool s2cSuccess = s2cBuf->Flush();
|
||||||
|
|
||||||
|
// ASSERT(c2sSuccess && s2cSuccess);
|
||||||
|
// }
|
||||||
|
try glfw.pollEvents();
|
||||||
|
}
|
||||||
270
webgpu/src/dawn/sample_utils.zig
Normal file
270
webgpu/src/dawn/sample_utils.zig
Normal file
|
|
@ -0,0 +1,270 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
const glfw = @import("glfw");
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
|
||||||
|
// #include "SampleUtils.h"
|
||||||
|
|
||||||
|
// #include "common/Assert.h"
|
||||||
|
// #include "common/Log.h"
|
||||||
|
// #include "common/Platform.h"
|
||||||
|
// #include "common/SystemUtils.h"
|
||||||
|
// #include "utils/BackendBinding.h"
|
||||||
|
// #include "utils/GLFWUtils.h"
|
||||||
|
// #include "utils/TerribleCommandBuffer.h"
|
||||||
|
|
||||||
|
// #include <dawn/dawn_proc.h>
|
||||||
|
// #include <dawn/dawn_wsi.h>
|
||||||
|
// #include <dawn_native/DawnNative.h>
|
||||||
|
// #include <dawn_wire/WireClient.h>
|
||||||
|
// #include <dawn_wire/WireServer.h>
|
||||||
|
// #include "GLFW/glfw3.h"
|
||||||
|
|
||||||
|
// #include <algorithm>
|
||||||
|
// #include <cstring>
|
||||||
|
|
||||||
|
fn printDeviceError(error_type: c.WGPUErrorType, message: [*c]const u8, ptr: ?*c_void) callconv(.C) void {
|
||||||
|
_ = ptr;
|
||||||
|
switch (error_type) {
|
||||||
|
c.WGPUErrorType_Validation => std.debug.print("dawn: validation error: {s}\n", .{message}),
|
||||||
|
c.WGPUErrorType_OutOfMemory => std.debug.print("dawn: out of memory: {s}\n", .{message}),
|
||||||
|
c.WGPUErrorType_Unknown => std.debug.print("dawn: unknown error: {s}\n", .{message}),
|
||||||
|
c.WGPUErrorType_DeviceLost => std.debug.print("dawn: device lost: {s}\n", .{message}),
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// // Default to D3D12, Metal, Vulkan, OpenGL in that order as D3D12 and Metal are the preferred on
|
||||||
|
// // their respective platforms, and Vulkan is preferred to OpenGL
|
||||||
|
// #if defined(DAWN_ENABLE_BACKEND_D3D12)
|
||||||
|
// static wgpu::BackendType backendType = wgpu::BackendType::D3D12;
|
||||||
|
// #elif defined(DAWN_ENABLE_BACKEND_METAL)
|
||||||
|
// static wgpu::BackendType backendType = wgpu::BackendType::Metal;
|
||||||
|
// #elif defined(DAWN_ENABLE_BACKEND_VULKAN)
|
||||||
|
// static wgpu::BackendType backendType = wgpu::BackendType::Vulkan;
|
||||||
|
// #elif defined(DAWN_ENABLE_BACKEND_OPENGLES)
|
||||||
|
// static wgpu::BackendType backendType = wgpu::BackendType::OpenGLES;
|
||||||
|
// #elif defined(DAWN_ENABLE_BACKEND_DESKTOP_GL)
|
||||||
|
// static wgpu::BackendType backendType = wgpu::BackendType::OpenGL;
|
||||||
|
// #else
|
||||||
|
// # error
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
|
||||||
|
const CmdBufType = enum {
|
||||||
|
none,
|
||||||
|
terrible
|
||||||
|
};
|
||||||
|
|
||||||
|
// static std::unique_ptr<dawn_native::Instance> instance;
|
||||||
|
// static utils::BackendBinding* binding = nullptr;
|
||||||
|
|
||||||
|
// static GLFWwindow* window = nullptr;
|
||||||
|
|
||||||
|
// static dawn_wire::WireServer* wireServer = nullptr;
|
||||||
|
// static dawn_wire::WireClient* wireClient = nullptr;
|
||||||
|
// static utils::TerribleCommandBuffer* c2sBuf = nullptr;
|
||||||
|
// static utils::TerribleCommandBuffer* s2cBuf = nullptr;
|
||||||
|
|
||||||
|
const Setup = struct {
|
||||||
|
device: c.WGPUDevice,
|
||||||
|
binding: c.MachUtilsBackendBinding,
|
||||||
|
window: glfw.Window,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn setup() !Setup {
|
||||||
|
const backend_type = c.WGPUBackendType_Metal;
|
||||||
|
const cmd_buf_type = CmdBufType.none;
|
||||||
|
|
||||||
|
try glfw.init();
|
||||||
|
|
||||||
|
// Create the test window and discover adapters using it (esp. for OpenGL)
|
||||||
|
try setupGLFWWindowHintsForBackend(backend_type);
|
||||||
|
glfw.Window.hint(.cocoa_retina_framebuffer, 0) catch {}; // false
|
||||||
|
const window = try glfw.Window.create(640, 480, "Dawn window", null, null);
|
||||||
|
|
||||||
|
const instance = c.machDawnNativeInstance_init();
|
||||||
|
try discoverAdapter(instance, window, backend_type);
|
||||||
|
|
||||||
|
const adapters = c.machDawnNativeInstance_getAdapters(instance);
|
||||||
|
var backend_adapter: ?c.MachDawnNativeAdapter = null;
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < c.machDawnNativeAdapters_length(adapters)) : (i += 1) {
|
||||||
|
const adapter = c.machDawnNativeAdapters_index(adapters, i);
|
||||||
|
const properties = c.machDawnNativeAdapter_getProperties(adapter);
|
||||||
|
if (c.machDawnNativeAdapterProperties_getBackendType(properties) == backend_type) {
|
||||||
|
backend_adapter = adapter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(backend_adapter != null);
|
||||||
|
|
||||||
|
const backend_device = c.machDawnNativeAdapter_createDevice(backend_adapter.?, null);
|
||||||
|
const backend_procs = c.machDawnNativeGetProcs();
|
||||||
|
|
||||||
|
const binding = c.machUtilsCreateBinding(backend_type, @ptrCast(*c.GLFWwindow, window.handle), backend_device);
|
||||||
|
if (binding == null) {
|
||||||
|
@panic("failed to create binding");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choose whether to use the backend procs and devices directly, or set up the wire.
|
||||||
|
var procs: ?*const c.DawnProcTable = null;
|
||||||
|
var c_device: ?c.WGPUDevice = null;
|
||||||
|
switch (cmd_buf_type) {
|
||||||
|
CmdBufType.none => {
|
||||||
|
procs = backend_procs;
|
||||||
|
c_device = backend_device;
|
||||||
|
},
|
||||||
|
CmdBufType.terrible => {
|
||||||
|
// TODO(slimsag):
|
||||||
|
@panic("not implemented");
|
||||||
|
// c2sBuf = new utils::TerribleCommandBuffer();
|
||||||
|
// s2cBuf = new utils::TerribleCommandBuffer();
|
||||||
|
|
||||||
|
// dawn_wire::WireServerDescriptor serverDesc = {};
|
||||||
|
// serverDesc.procs = &backendProcs;
|
||||||
|
// serverDesc.serializer = s2cBuf;
|
||||||
|
|
||||||
|
// wireServer = new dawn_wire::WireServer(serverDesc);
|
||||||
|
// c2sBuf->SetHandler(wireServer);
|
||||||
|
|
||||||
|
// dawn_wire::WireClientDescriptor clientDesc = {};
|
||||||
|
// clientDesc.serializer = c2sBuf;
|
||||||
|
|
||||||
|
// wireClient = new dawn_wire::WireClient(clientDesc);
|
||||||
|
// procs = dawn_wire::client::GetProcs();
|
||||||
|
// s2cBuf->SetHandler(wireClient);
|
||||||
|
|
||||||
|
// auto deviceReservation = wireClient->ReserveDevice();
|
||||||
|
// wireServer->InjectDevice(backendDevice, deviceReservation.id,
|
||||||
|
// deviceReservation.generation);
|
||||||
|
|
||||||
|
// cDevice = deviceReservation.device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.dawnProcSetProcs(procs.?);
|
||||||
|
procs.?.deviceSetUncapturedErrorCallback.?(c_device.?, printDeviceError, null);
|
||||||
|
return Setup{
|
||||||
|
.device = c_device.?,
|
||||||
|
.binding = binding,
|
||||||
|
.window = window,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setupGLFWWindowHintsForBackend(backend: c.WGPUBackendType) !void {
|
||||||
|
switch (backend) {
|
||||||
|
c.WGPUBackendType_OpenGL => {
|
||||||
|
// Ask for OpenGL 4.4 which is what the GL backend requires for compute shaders and
|
||||||
|
// texture views.
|
||||||
|
try glfw.Window.hint(.context_version_major, 4);
|
||||||
|
try glfw.Window.hint(.context_version_minor, 4);
|
||||||
|
try glfw.Window.hint(.opengl_forward_compat, 1); // true
|
||||||
|
try glfw.Window.hint(.opengl_profile, glfw.opengl_core_profile);
|
||||||
|
},
|
||||||
|
c.WGPUBackendType_OpenGLES => {
|
||||||
|
try glfw.Window.hint(.context_version_major, 3);
|
||||||
|
try glfw.Window.hint(.context_version_minor, 1);
|
||||||
|
try glfw.Window.hint(.client_api, glfw.opengl_es_api);
|
||||||
|
try glfw.Window.hint(.context_creation_api, glfw.egl_context_api);
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
// Without this GLFW will initialize a GL context on the window, which prevents using
|
||||||
|
// the window with other APIs (by crashing in weird ways).
|
||||||
|
try glfw.Window.hint(.client_api, glfw.no_api);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn discoverAdapter(instance: c.MachDawnNativeInstance, window: glfw.Window, typ: c.WGPUBackendType) !void {
|
||||||
|
if (typ == c.WGPUBackendType_OpenGL or typ == c.WGPUBackendType_OpenGLES) {
|
||||||
|
try glfw.makeContextCurrent(window);
|
||||||
|
// auto getProc = reinterpret_cast<void* (*)(const char*)>(glfwGetProcAddress);
|
||||||
|
// if (type == wgpu::BackendType::OpenGL) {
|
||||||
|
// dawn_native::opengl::AdapterDiscoveryOptions adapterOptions;
|
||||||
|
// adapterOptions.getProc = getProc;
|
||||||
|
// instance->DiscoverAdapters(&adapterOptions);
|
||||||
|
// } else {
|
||||||
|
// dawn_native::opengl::AdapterDiscoveryOptionsES adapterOptions;
|
||||||
|
// adapterOptions.getProc = getProc;
|
||||||
|
// instance->DiscoverAdapters(&adapterOptions);
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
c.machDawnNativeInstance_discoverDefaultAdapters(instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wgpu::TextureFormat GetPreferredSwapChainTextureFormat() {
|
||||||
|
// DoFlush();
|
||||||
|
// return static_cast<wgpu::TextureFormat>(binding->GetPreferredSwapChainTextureFormat());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// wgpu::TextureView CreateDefaultDepthStencilView(const wgpu::Device& device) {
|
||||||
|
// wgpu::TextureDescriptor descriptor;
|
||||||
|
// descriptor.dimension = wgpu::TextureDimension::e2D;
|
||||||
|
// descriptor.size.width = 640;
|
||||||
|
// descriptor.size.height = 480;
|
||||||
|
// descriptor.size.depthOrArrayLayers = 1;
|
||||||
|
// descriptor.sampleCount = 1;
|
||||||
|
// descriptor.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||||
|
// descriptor.mipLevelCount = 1;
|
||||||
|
// descriptor.usage = wgpu::TextureUsage::RenderAttachment;
|
||||||
|
// auto depthStencilTexture = device.CreateTexture(&descriptor);
|
||||||
|
// return depthStencilTexture.CreateView();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool InitSample(int argc, const char** argv) {
|
||||||
|
// for (int i = 1; i < argc; i++) {
|
||||||
|
// if (std::string("-b") == argv[i] || std::string("--backend") == argv[i]) {
|
||||||
|
// i++;
|
||||||
|
// if (i < argc && std::string("d3d12") == argv[i]) {
|
||||||
|
// backendType = wgpu::BackendType::D3D12;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (i < argc && std::string("metal") == argv[i]) {
|
||||||
|
// backendType = wgpu::BackendType::Metal;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (i < argc && std::string("null") == argv[i]) {
|
||||||
|
// backendType = wgpu::BackendType::Null;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (i < argc && std::string("opengl") == argv[i]) {
|
||||||
|
// backendType = wgpu::BackendType::OpenGL;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (i < argc && std::string("opengles") == argv[i]) {
|
||||||
|
// backendType = wgpu::BackendType::OpenGLES;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (i < argc && std::string("vulkan") == argv[i]) {
|
||||||
|
// backendType = wgpu::BackendType::Vulkan;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// fprintf(stderr,
|
||||||
|
// "--backend expects a backend name (opengl, opengles, metal, d3d12, null, "
|
||||||
|
// "vulkan)\n");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// if (std::string("-c") == argv[i] || std::string("--command-buffer") == argv[i]) {
|
||||||
|
// i++;
|
||||||
|
// if (i < argc && std::string("none") == argv[i]) {
|
||||||
|
// cmdBufType = CmdBufType::None;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (i < argc && std::string("terrible") == argv[i]) {
|
||||||
|
// cmdBufType = CmdBufType::Terrible;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// fprintf(stderr, "--command-buffer expects a command buffer name (none, terrible)\n");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// if (std::string("-h") == argv[i] || std::string("--help") == argv[i]) {
|
||||||
|
// printf("Usage: %s [-b BACKEND] [-c COMMAND_BUFFER]\n", argv[0]);
|
||||||
|
// printf(" BACKEND is one of: d3d12, metal, null, opengl, opengles, vulkan\n");
|
||||||
|
// printf(" COMMAND_BUFFER is one of: none, terrible\n");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
Loading…
Add table
Add a link
Reference in a new issue