mirror of
https://github.com/encounter/aurora.git
synced 2026-07-09 18:19:33 -07:00
Support for wgpu::FeatureLevel::Compatibility
This commit is contained in:
@@ -71,6 +71,7 @@ struct PendingMap {
|
||||
uint64_t byteSize = 0;
|
||||
};
|
||||
|
||||
bool g_enabled = false;
|
||||
std::array<Slot, SlotCount> g_slots;
|
||||
size_t g_nextSlot = 0;
|
||||
wgpu::BindGroupLayout g_bindGroupLayout;
|
||||
@@ -305,8 +306,12 @@ void complete_slot(size_t slotIdx, wgpu::MapAsyncStatus status, wgpu::StringView
|
||||
} // namespace
|
||||
|
||||
void initialize() {
|
||||
if (!webgpu::g_hasCoreCompatibility) {
|
||||
return;
|
||||
}
|
||||
g_bindGroupLayout = create_bind_group_layout("Depth Peek Bind Group Layout");
|
||||
g_pipeline = create_pipeline(g_bindGroupLayout, "Depth Peek Pipeline");
|
||||
g_enabled = true;
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
@@ -319,6 +324,9 @@ void shutdown() {
|
||||
}
|
||||
|
||||
void request_snapshot() noexcept {
|
||||
if (!g_enabled) {
|
||||
return;
|
||||
}
|
||||
std::lock_guard lock{g_mutex};
|
||||
g_snapshotRequested = true;
|
||||
}
|
||||
@@ -334,6 +342,10 @@ bool read_latest(uint16_t x, uint16_t y, uint32_t& z) noexcept {
|
||||
|
||||
void encode_frame_snapshot(const wgpu::CommandEncoder& cmd, const wgpu::TextureView& depthView,
|
||||
wgpu::Extent3D sourceSize, uint32_t msaaSamples) noexcept {
|
||||
if (!g_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZoneScoped;
|
||||
const auto now = Clock::now();
|
||||
{
|
||||
@@ -413,6 +425,10 @@ void encode_frame_snapshot(const wgpu::CommandEncoder& cmd, const wgpu::TextureV
|
||||
}
|
||||
|
||||
void after_submit() noexcept {
|
||||
if (!g_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<PendingMap> pendingMaps;
|
||||
{
|
||||
std::lock_guard lock{g_mutex};
|
||||
|
||||
@@ -400,10 +400,13 @@ void initialize() {
|
||||
Log.fatal("Output format mismatch for {}", conv.fmt);
|
||||
}
|
||||
}
|
||||
for (const auto& conv : DepthConvPipelines) {
|
||||
g_pipelines[conv.fmt] = create_pipeline(conv, DepthShaderPreamble, g_depthBindGroupLayout);
|
||||
if (conv.outputFormat != to_wgpu(conv.fmt)) {
|
||||
Log.fatal("Output format mismatch for {}", conv.fmt);
|
||||
// Skip depth copies in compatibility mode
|
||||
if (webgpu::g_hasCoreCompatibility) {
|
||||
for (const auto& conv : DepthConvPipelines) {
|
||||
g_pipelines[conv.fmt] = create_pipeline(conv, DepthShaderPreamble, g_depthBindGroupLayout);
|
||||
if (conv.outputFormat != to_wgpu(conv.fmt)) {
|
||||
Log.fatal("Output format mismatch for {}", conv.fmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,8 +435,15 @@ void shutdown() {
|
||||
}
|
||||
|
||||
static void execute(const wgpu::CommandEncoder& cmd, const ConvRequest& req, const wgpu::RenderPipeline& pipeline) {
|
||||
if (!pipeline) {
|
||||
return;
|
||||
}
|
||||
wgpu::BindGroup bindGroup;
|
||||
if (gx::is_depth_format(req.fmt)) {
|
||||
// Skip depth copies in compatibility mode
|
||||
if (!webgpu::g_hasCoreCompatibility) {
|
||||
return;
|
||||
}
|
||||
const std::array bindGroupEntries{
|
||||
wgpu::BindGroupEntry{
|
||||
.binding = 0,
|
||||
|
||||
+4
-1
@@ -635,13 +635,16 @@ wgpu::RenderPipeline build_pipeline(const PipelineConfig& config, ArrayRef<wgpu:
|
||||
ZoneScoped;
|
||||
const float depthBias = (UseReversedZ ? -1.0f : 1.0f) * std::bit_cast<float>(config.polygonOffsetBits);
|
||||
const float depthBiasSlopeScale = (UseReversedZ ? -1.0f : 1.0f) * std::bit_cast<float>(config.polygonOffsetScaleBits);
|
||||
const float depthBiasClamp = webgpu::g_hasCoreCompatibility
|
||||
? std::bit_cast<float>(config.polygonOffsetClampBits)
|
||||
: 0.0f;
|
||||
const wgpu::DepthStencilState depthStencil{
|
||||
.format = g_graphicsConfig.depthFormat,
|
||||
.depthWriteEnabled = config.depthCompare && config.depthUpdate,
|
||||
.depthCompare = config.depthCompare ? to_compare_function(config.depthFunc) : wgpu::CompareFunction::Always,
|
||||
.depthBias = round_away_from_zero<int32_t>(depthBias),
|
||||
.depthBiasSlopeScale = depthBiasSlopeScale,
|
||||
.depthBiasClamp = std::bit_cast<float>(config.polygonOffsetClampBits),
|
||||
.depthBiasClamp = depthBiasClamp,
|
||||
};
|
||||
const auto blendState =
|
||||
to_blend_state(config.blendMode, config.blendFacSrc, config.blendFacDst, config.blendOp, config.dstAlpha);
|
||||
|
||||
+69
-35
@@ -4,6 +4,7 @@
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -59,6 +60,7 @@ static wgpu::Adapter g_adapter;
|
||||
wgpu::Instance g_instance;
|
||||
wgpu::AdapterInfo g_adapterInfo;
|
||||
static wgpu::SurfaceCapabilities g_surfaceCapabilities;
|
||||
bool g_hasCoreCompatibility = false;
|
||||
bool g_bcTexturesSupported = false;
|
||||
bool g_astcTexturesSupported = false;
|
||||
bool g_textureComponentSwizzleSupported = false;
|
||||
@@ -66,6 +68,25 @@ static std::atomic_bool g_initialized = false;
|
||||
|
||||
namespace {
|
||||
|
||||
AuroraLogLevel wgpu_log_level(wgpu::LoggingType type) {
|
||||
switch (type) {
|
||||
case wgpu::LoggingType::Verbose:
|
||||
return LOG_DEBUG;
|
||||
case wgpu::LoggingType::Info:
|
||||
return LOG_INFO;
|
||||
case wgpu::LoggingType::Warning:
|
||||
return LOG_WARNING;
|
||||
case wgpu::LoggingType::Error:
|
||||
return LOG_ERROR;
|
||||
default:
|
||||
return LOG_FATAL;
|
||||
}
|
||||
}
|
||||
|
||||
void wgpu_log(wgpu::LoggingType type, wgpu::StringView message) {
|
||||
Log.report(wgpu_log_level(type), "WebGPU message: {}", message);
|
||||
}
|
||||
|
||||
struct ResampleUniformBlock {
|
||||
uint32_t samplerMode = 0;
|
||||
float frameWidth = 0.f;
|
||||
@@ -742,6 +763,7 @@ bool initialize(AuroraBackend auroraBackend, bool allowCpu) {
|
||||
#ifdef WEBGPU_DAWN
|
||||
dawn::native::DawnInstanceDescriptor dawnInstanceDescriptor;
|
||||
dawnInstanceDescriptor.backendValidationLevel = dawn::native::BackendValidationLevel::Disabled;
|
||||
dawnInstanceDescriptor.SetLoggingCallback(wgpu_log);
|
||||
#ifdef TRACY_ENABLE
|
||||
dawnInstanceDescriptor.platform = tracy_dawn_platform();
|
||||
#endif
|
||||
@@ -765,26 +787,47 @@ bool initialize(AuroraBackend auroraBackend, bool allowCpu) {
|
||||
}
|
||||
{
|
||||
const wgpu::RequestAdapterOptions options{
|
||||
.featureLevel = wgpu::FeatureLevel::Compatibility,
|
||||
.powerPreference = wgpu::PowerPreference::HighPerformance,
|
||||
.backendType = backend,
|
||||
.compatibleSurface = g_surface,
|
||||
};
|
||||
Log.info("Requesting adapter\n Feature level: {}\n Power preference: {}\n Backend: {}\n Compatible surface: {}",
|
||||
magic_enum::enum_name(options.featureLevel), magic_enum::enum_name(options.powerPreference),
|
||||
magic_enum::enum_name(options.backendType), static_cast<bool>(options.compatibleSurface));
|
||||
bool requestAdapterCallbackCompleted = false;
|
||||
wgpu::RequestAdapterStatus requestAdapterStatus = wgpu::RequestAdapterStatus::CallbackCancelled;
|
||||
std::string requestAdapterMessage;
|
||||
const auto future = g_instance.RequestAdapter(
|
||||
&options, wgpu::CallbackMode::WaitAnyOnly,
|
||||
[](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, wgpu::StringView message) {
|
||||
[&](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, wgpu::StringView message) {
|
||||
requestAdapterCallbackCompleted = true;
|
||||
requestAdapterStatus = status;
|
||||
requestAdapterMessage = std::string{std::string_view{message}};
|
||||
if (status == wgpu::RequestAdapterStatus::Success) {
|
||||
g_adapter = std::move(adapter);
|
||||
} else {
|
||||
Log.warn("Adapter request failed: {}", message);
|
||||
Log.warn("Adapter request failed: {}: {}", magic_enum::enum_name(status), message);
|
||||
}
|
||||
});
|
||||
const auto status = g_instance.WaitAny(future, 5000000000);
|
||||
if (status != wgpu::WaitStatus::Success) {
|
||||
Log.error("Failed to create adapter: {}", magic_enum::enum_name(status));
|
||||
if (requestAdapterCallbackCompleted) {
|
||||
Log.error("Failed to create adapter: wait status {}, request status {}, message: {}",
|
||||
magic_enum::enum_name(status), magic_enum::enum_name(requestAdapterStatus), requestAdapterMessage);
|
||||
} else {
|
||||
Log.error("Failed to create adapter: wait status {}, request callback did not complete",
|
||||
magic_enum::enum_name(status));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!g_adapter) {
|
||||
Log.error("Failed to create adapter");
|
||||
if (requestAdapterCallbackCompleted) {
|
||||
Log.error("Failed to create adapter: request status {}, message: {}",
|
||||
magic_enum::enum_name(requestAdapterStatus), requestAdapterMessage);
|
||||
} else {
|
||||
Log.error("Failed to create adapter: request callback did not complete");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -811,7 +854,12 @@ bool initialize(AuroraBackend auroraBackend, bool allowCpu) {
|
||||
{
|
||||
wgpu::Limits supportedLimits{};
|
||||
g_adapter.GetLimits(&supportedLimits);
|
||||
wgpu::CompatibilityModeLimits compatibilityModeLimits{wgpu::CompatibilityModeLimits::Init{
|
||||
.maxStorageBuffersInVertexStage = 2,
|
||||
.maxStorageBuffersInFragmentStage = 2,
|
||||
}};
|
||||
const wgpu::Limits requiredLimits{
|
||||
.nextInChain = &compatibilityModeLimits,
|
||||
// Use "best" supported limits
|
||||
.maxTextureDimension1D = supportedLimits.maxTextureDimension1D == 0 ? WGPU_LIMIT_U32_UNDEFINED
|
||||
: supportedLimits.maxTextureDimension1D,
|
||||
@@ -821,12 +869,7 @@ bool initialize(AuroraBackend auroraBackend, bool allowCpu) {
|
||||
: supportedLimits.maxTextureDimension3D,
|
||||
.maxTextureArrayLayers = supportedLimits.maxTextureArrayLayers == 0 ? WGPU_LIMIT_U32_UNDEFINED
|
||||
: supportedLimits.maxTextureArrayLayers,
|
||||
.maxDynamicStorageBuffersPerPipelineLayout = supportedLimits.maxDynamicStorageBuffersPerPipelineLayout == 0
|
||||
? WGPU_LIMIT_U32_UNDEFINED
|
||||
: supportedLimits.maxDynamicStorageBuffersPerPipelineLayout,
|
||||
.maxStorageBuffersPerShaderStage = supportedLimits.maxStorageBuffersPerShaderStage == 0
|
||||
? WGPU_LIMIT_U32_UNDEFINED
|
||||
: supportedLimits.maxStorageBuffersPerShaderStage,
|
||||
.maxStorageBuffersPerShaderStage = 2,
|
||||
.minUniformBufferOffsetAlignment =
|
||||
supportedLimits.minUniformBufferOffsetAlignment < 64 ? 64 : supportedLimits.minUniformBufferOffsetAlignment,
|
||||
.minStorageBufferOffsetAlignment =
|
||||
@@ -838,15 +881,15 @@ bool initialize(AuroraBackend auroraBackend, bool allowCpu) {
|
||||
"\n maxTextureDimension2D: {}"
|
||||
"\n maxTextureDimension3D: {}"
|
||||
"\n maxTextureArrayLayers: {}"
|
||||
"\n maxDynamicStorageBuffersPerPipelineLayout: {}"
|
||||
"\n maxStorageBuffersPerShaderStage: {}"
|
||||
"\n minUniformBufferOffsetAlignment: {}"
|
||||
"\n minStorageBufferOffsetAlignment: {}",
|
||||
requiredLimits.maxTextureDimension1D, requiredLimits.maxTextureDimension2D,
|
||||
requiredLimits.maxTextureDimension3D, requiredLimits.maxTextureArrayLayers,
|
||||
requiredLimits.maxDynamicStorageBuffersPerPipelineLayout, requiredLimits.maxStorageBuffersPerShaderStage,
|
||||
requiredLimits.minUniformBufferOffsetAlignment, requiredLimits.minStorageBufferOffsetAlignment);
|
||||
requiredLimits.maxStorageBuffersPerShaderStage, requiredLimits.minUniformBufferOffsetAlignment,
|
||||
requiredLimits.minStorageBufferOffsetAlignment);
|
||||
std::vector<wgpu::FeatureName> requiredFeatures;
|
||||
g_hasCoreCompatibility = false;
|
||||
g_bcTexturesSupported = false;
|
||||
g_astcTexturesSupported = false;
|
||||
g_textureComponentSwizzleSupported = false;
|
||||
@@ -854,9 +897,12 @@ bool initialize(AuroraBackend auroraBackend, bool allowCpu) {
|
||||
g_adapter.GetFeatures(&supportedFeatures);
|
||||
for (size_t i = 0; i < supportedFeatures.featureCount; ++i) {
|
||||
const auto feature = supportedFeatures.features[i];
|
||||
if (feature == wgpu::FeatureName::TextureCompressionBC || feature == wgpu::FeatureName::TextureCompressionASTC ||
|
||||
if (feature == wgpu::FeatureName::CoreFeaturesAndLimits || feature == wgpu::FeatureName::TextureCompressionBC ||
|
||||
feature == wgpu::FeatureName::TextureCompressionASTC ||
|
||||
feature == wgpu::FeatureName::TextureComponentSwizzle) {
|
||||
if (feature == wgpu::FeatureName::TextureCompressionBC) {
|
||||
if (feature == wgpu::FeatureName::CoreFeaturesAndLimits) {
|
||||
g_hasCoreCompatibility = true;
|
||||
} else if (feature == wgpu::FeatureName::TextureCompressionBC) {
|
||||
g_bcTexturesSupported = true;
|
||||
} else if (feature == wgpu::FeatureName::TextureCompressionASTC) {
|
||||
g_astcTexturesSupported = true;
|
||||
@@ -871,6 +917,12 @@ bool initialize(AuroraBackend auroraBackend, bool allowCpu) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
std::string featureList;
|
||||
for (auto featureName : requiredFeatures) {
|
||||
featureList += "\n ";
|
||||
featureList += magic_enum::enum_name(featureName);
|
||||
}
|
||||
Log.info("Enabling features: {}", featureList);
|
||||
#ifdef WEBGPU_DAWN
|
||||
wgpu::DawnCacheDeviceDescriptor cacheDescriptor({
|
||||
.isolationKey = nullptr,
|
||||
@@ -896,6 +948,7 @@ bool initialize(AuroraBackend auroraBackend, bool allowCpu) {
|
||||
"allow_unsafe_apis",
|
||||
"disable_symbol_renaming",
|
||||
"enable_immediate_error_handling",
|
||||
"gl_allow_context_on_multi_threads",
|
||||
};
|
||||
constexpr std::array disableToggles{
|
||||
"timestamp_quantization",
|
||||
@@ -950,26 +1003,7 @@ bool initialize(AuroraBackend auroraBackend, bool allowCpu) {
|
||||
if (!g_device) {
|
||||
return false;
|
||||
}
|
||||
g_device.SetLoggingCallback([](wgpu::LoggingType type, wgpu::StringView message) {
|
||||
AuroraLogLevel level = LOG_FATAL;
|
||||
switch (type) {
|
||||
case wgpu::LoggingType::Verbose:
|
||||
level = LOG_DEBUG;
|
||||
break;
|
||||
case wgpu::LoggingType::Info:
|
||||
level = LOG_INFO;
|
||||
break;
|
||||
case wgpu::LoggingType::Warning:
|
||||
level = LOG_WARNING;
|
||||
break;
|
||||
case wgpu::LoggingType::Error:
|
||||
level = LOG_ERROR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Log.report(level, "WebGPU message: {}", message);
|
||||
});
|
||||
g_device.SetLoggingCallback(wgpu_log);
|
||||
}
|
||||
g_queue = g_device.GetQueue();
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ extern wgpu::RenderPipeline g_CopyPremultipliedAlphaPipeline;
|
||||
extern wgpu::BindGroup g_CopyBindGroup;
|
||||
extern wgpu::Instance g_instance;
|
||||
extern wgpu::AdapterInfo g_adapterInfo;
|
||||
extern bool g_hasCoreCompatibility;
|
||||
extern bool g_bcTexturesSupported;
|
||||
extern bool g_astcTexturesSupported;
|
||||
extern bool g_textureComponentSwizzleSupported;
|
||||
|
||||
Reference in New Issue
Block a user