From 8ed6a858fe232e94e0bb94c8aa484b6213841858 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 1 Nov 2024 19:23:56 -0700 Subject: [PATCH] A better fix for the PeekZ error messages in WebGPU Just use unfiltered floats. Also, fix PeekZ being Y flipped. --- src/ZeldaWindWaker/d_dlst_peekZ.ts | 12 +++++++----- src/ZeldaWindWaker/d_kankyo.ts | 3 +++ src/gfx/platform/GfxPlatformImpl.ts | 10 ++++++++++ src/gfx/platform/GfxPlatformUtil.ts | 1 - src/gfx/platform/GfxPlatformWebGL2.ts | 4 ++-- src/gfx/platform/GfxPlatformWebGPU.ts | 17 +++-------------- 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/ZeldaWindWaker/d_dlst_peekZ.ts b/src/ZeldaWindWaker/d_dlst_peekZ.ts index 43460a610..51383cc9c 100644 --- a/src/ZeldaWindWaker/d_dlst_peekZ.ts +++ b/src/ZeldaWindWaker/d_dlst_peekZ.ts @@ -1,5 +1,5 @@ -import { GfxDevice, GfxFormat, GfxSamplerBinding, GfxTexFilterMode, GfxMipFilterMode, GfxWrapMode, GfxTextureDimension, GfxSamplerFormatKind, GfxClipSpaceNearZ } from "../gfx/platform/GfxPlatform.js"; +import { GfxDevice, GfxFormat, GfxSamplerBinding, GfxTexFilterMode, GfxMipFilterMode, GfxWrapMode, GfxTextureDimension, GfxSamplerFormatKind, GfxClipSpaceNearZ, GfxViewportOrigin } from "../gfx/platform/GfxPlatform.js"; import { GfxReadback, GfxProgram, GfxSampler, GfxTexture } from "../gfx/platform/GfxPlatformImpl.js"; import { preprocessProgram_GLSL } from "../gfx/shaderc/GfxShaderCompiler.js"; import { fullscreenMegaState } from "../gfx/helpers/GfxMegaStateDescriptorHelpers.js"; @@ -9,7 +9,6 @@ import { GfxRenderInstManager } from "../gfx/render/GfxRenderInstManager.js"; import { GfxShaderLibrary } from "../gfx/helpers/GfxShaderLibrary.js"; import { GfxRenderCache } from "../gfx/render/GfxRenderCache.js"; -// TODO(jstpierre): Port the PeekZ system to occlusion queries? export class PeekZResult { public triviallyCulled: boolean = false; public value: number | null = null; @@ -150,10 +149,13 @@ void main() { private submitFramePost(device: GfxDevice, frame: PeekZFrame, depthColorTexture: GfxTexture, width: number, height: number): void { // Now go through and start submitting readbacks on our texture. + const yScale = (device.queryVendorInfo().viewportOrigin === GfxViewportOrigin.UpperLeft) ? -1 : 1; + for (let i = 0; i < frame.results.length; i++) { - // User specifies coordinates in -1 to 1 normalized space. Convert to attachment space. + // User specifies coordinates in -1 to 1 normalized space (with -1, -1 being the bottom left). + // Convert to attachment space. const attachmentX = (((frame.entryX[i] * 0.5) + 0.5) * width) | 0; - const attachmentY = (((frame.entryY[i] * 0.5) + 0.5) * height) | 0; + const attachmentY = (((frame.entryY[i] * yScale * 0.5) + 0.5) * height) | 0; device.readPixelFromTexture(frame.readback, i, depthColorTexture, attachmentX, attachmentY); } @@ -189,7 +191,7 @@ void main() { renderInst.setBindingLayouts([{ numUniformBuffers: 0, numSamplers: 1, - samplerEntries: [{ dimension: GfxTextureDimension.n2D, formatKind: GfxSamplerFormatKind.Depth, }], + samplerEntries: [{ dimension: GfxTextureDimension.n2D, formatKind: GfxSamplerFormatKind.UnfilterableFloat, }], }]); renderInst.setDrawCount(3); diff --git a/src/ZeldaWindWaker/d_kankyo.ts b/src/ZeldaWindWaker/d_kankyo.ts index 9ab640388..1d71467df 100644 --- a/src/ZeldaWindWaker/d_kankyo.ts +++ b/src/ZeldaWindWaker/d_kankyo.ts @@ -1159,6 +1159,9 @@ function envcolor_init(globals: dGlobals): void { envLight.timeAdv = 0.02; + envLight.curTime = 180; + envLight.timeAdv = 0; + colorFromRGBA(envLight.lightStatus[0].Color, 1.0, 0.0, 0.0, 0.0); colorFromRGBA(envLight.lightStatus[1].Color, 0.0, 0.0, 0.0, 0.0); diff --git a/src/gfx/platform/GfxPlatformImpl.ts b/src/gfx/platform/GfxPlatformImpl.ts index da3984975..642b0025d 100644 --- a/src/gfx/platform/GfxPlatformImpl.ts +++ b/src/gfx/platform/GfxPlatformImpl.ts @@ -28,3 +28,13 @@ export const defaultBindingLayoutSamplerDescriptor: GfxBindingLayoutSamplerDescr formatKind: GfxSamplerFormatKind.Float, dimension: GfxTextureDimension.n2D, }; + +export function isFormatSamplerKindCompatible(samplerKind: GfxSamplerFormatKind, textureKind: GfxSamplerFormatKind): boolean { + if (textureKind === samplerKind) + return true; + // Depth textures can either be bound as depth, or as unfilterable float textures. + else if (textureKind === GfxSamplerFormatKind.Depth && samplerKind === GfxSamplerFormatKind.UnfilterableFloat) + return true; + + return false; +} diff --git a/src/gfx/platform/GfxPlatformUtil.ts b/src/gfx/platform/GfxPlatformUtil.ts index 0c4f99151..8c3cdb734 100644 --- a/src/gfx/platform/GfxPlatformUtil.ts +++ b/src/gfx/platform/GfxPlatformUtil.ts @@ -71,4 +71,3 @@ export function gfxColorNewCopy(src: Readonly): GfxColor { const { r, g, b, a } = src; return { r, g, b, a }; } - diff --git a/src/gfx/platform/GfxPlatformWebGL2.ts b/src/gfx/platform/GfxPlatformWebGL2.ts index fe49a26ce..8b294f4f2 100644 --- a/src/gfx/platform/GfxPlatformWebGL2.ts +++ b/src/gfx/platform/GfxPlatformWebGL2.ts @@ -1,7 +1,7 @@ import { GfxAttachmentState, GfxBindingLayoutDescriptor, GfxBindingsDescriptor, GfxBlendFactor, GfxBlendMode, GfxBufferBinding, GfxBufferFrequencyHint, GfxBufferUsage, GfxChannelBlendState, GfxChannelWriteMask, GfxClipSpaceNearZ, GfxCompareMode, GfxComputePass, GfxComputePipelineDescriptor, GfxComputeProgramDescriptor, GfxCullMode, GfxStatisticsGroup, GfxDevice, GfxDeviceLimits, GfxIndexBufferDescriptor, GfxInputLayoutBufferDescriptor, GfxInputLayoutDescriptor, GfxMegaStateDescriptor, GfxMipFilterMode, GfxPass, GfxPlatformFramebuffer, GfxPrimitiveTopology, GfxRenderProgramDescriptor, GfxQueryPoolType, GfxRenderPass, GfxRenderPassDescriptor, GfxRenderPipelineDescriptor, GfxRenderTargetDescriptor, GfxSamplerBinding, GfxSamplerDescriptor, GfxSamplerFormatKind, GfxSwapChain, GfxTexFilterMode, GfxTextureDescriptor, GfxTextureDimension, GfxTextureUsage, GfxVendorInfo, GfxVertexAttributeDescriptor, GfxVertexBufferDescriptor, GfxVertexBufferFrequency, GfxViewportOrigin, GfxWrapMode, GfxRenderAttachmentView, GfxRenderPassAttachmentColor, GfxRenderPassAttachment, GfxRenderPassAttachmentDepthStencil } from './GfxPlatform.js'; import { FormatCompFlags, FormatFlags, FormatTypeFlags, GfxFormat, getFormatByteSize, getFormatCompByteSize, getFormatCompFlags, getFormatFlags, getFormatSamplerKind, getFormatTypeFlags } from "./GfxPlatformFormat.js"; -import { GfxBindings, GfxBuffer, GfxComputePipeline, GfxInputLayout, GfxProgram, GfxQueryPool, GfxReadback, GfxRenderPipeline, GfxRenderTarget, GfxResource, GfxSampler, GfxTexture, GfxTextureImpl, _T, defaultBindingLayoutSamplerDescriptor } from "./GfxPlatformImpl.js"; +import { GfxBindings, GfxBuffer, GfxComputePipeline, GfxInputLayout, GfxProgram, GfxQueryPool, GfxReadback, GfxRenderPipeline, GfxRenderTarget, GfxResource, GfxSampler, GfxTexture, GfxTextureImpl, _T, defaultBindingLayoutSamplerDescriptor, isFormatSamplerKindCompatible } from "./GfxPlatformImpl.js"; import { copyAttachmentState, copyMegaState, defaultMegaState } from '../helpers/GfxMegaStateDescriptorHelpers.js'; import { assert, assertExists, leftPad, nArray, nullify } from './GfxPlatformUtil.js'; @@ -1992,7 +1992,7 @@ class GfxImplP_GL implements GfxSwapChain, GfxDevice { // Validate sampler entry. assert(samplerEntry.gl_target === gl_target); - assert(samplerEntry.formatKind === formatKind); + assert(isFormatSamplerKindCompatible(samplerEntry.formatKind, formatKind)); } else { gl.bindTexture(samplerEntry.gl_target, this._getFallbackTexture(samplerEntry)); } diff --git a/src/gfx/platform/GfxPlatformWebGPU.ts b/src/gfx/platform/GfxPlatformWebGPU.ts index cdc252def..2aec3f094 100644 --- a/src/gfx/platform/GfxPlatformWebGPU.ts +++ b/src/gfx/platform/GfxPlatformWebGPU.ts @@ -4,7 +4,7 @@ import { HashMap, nullHashFunc } from "../../HashMap.js"; import { rust } from "../../rustlib.js"; import { GfxAttachmentState, GfxBindingLayoutDescriptor, GfxBindingLayoutSamplerDescriptor, GfxBindings, GfxBindingsDescriptor, GfxBlendFactor, GfxBlendMode, GfxBuffer, GfxBufferFrequencyHint, GfxBufferUsage, GfxChannelBlendState, GfxClipSpaceNearZ, GfxCompareMode, GfxComputePass, GfxComputePipelineDescriptor, GfxComputeProgramDescriptor, GfxCullMode, GfxStatisticsGroup, GfxDevice, GfxDeviceLimits, GfxFormat, GfxFrontFaceMode, GfxIndexBufferDescriptor, GfxInputLayout, GfxInputLayoutDescriptor, GfxMegaStateDescriptor, GfxMipFilterMode, GfxPass, GfxPrimitiveTopology, GfxProgram, GfxQueryPoolType, GfxRenderPass, GfxRenderPassDescriptor, GfxRenderPipeline, GfxRenderPipelineDescriptor, GfxRenderTarget, GfxRenderTargetDescriptor, GfxSampler, GfxSamplerDescriptor, GfxSamplerFormatKind, GfxShadingLanguage, GfxSwapChain, GfxTexFilterMode, GfxTexture, GfxTextureDescriptor, GfxTextureDimension, GfxTextureUsage, GfxVendorInfo, GfxVertexBufferDescriptor, GfxVertexBufferFrequency, GfxViewportOrigin, GfxWrapMode, GfxRenderAttachmentView, GfxRenderProgramDescriptor } from "./GfxPlatform.js"; import { FormatFlags, FormatTypeFlags, getFormatByteSize, getFormatFlags, getFormatSamplerKind, getFormatTypeFlags } from "./GfxPlatformFormat.js"; -import { GfxComputePipeline, GfxQueryPool, GfxReadback, GfxResource, GfxTextureImpl, _T, defaultBindingLayoutSamplerDescriptor } from "./GfxPlatformImpl.js"; +import { GfxComputePipeline, GfxQueryPool, GfxReadback, GfxResource, GfxTextureImpl, _T, defaultBindingLayoutSamplerDescriptor, isFormatSamplerKindCompatible } from "./GfxPlatformImpl.js"; import { align, assert, assertExists } from "./GfxPlatformUtil.js"; import { gfxBindingLayoutDescriptorEqual } from './GfxPlatformObjUtil.js'; import { IS_DEVELOPMENT } from "../../BuildVersion.js"; @@ -1102,18 +1102,6 @@ class GfxImplP_WebGPU implements GfxSwapChain, GfxDevice { throw "whoops"; } - // Workaround for https://github.com/gfx-rs/naga/issues/1355 - for (const depthTextureName of ['u_TextureFramebufferDepth']) { - if (!code.includes(depthTextureName)) continue; - code = code.replace(`var T_${depthTextureName}: texture_2d;`, `var T_${depthTextureName}: texture_depth_2d;`); - code = code.replace(new RegExp(`textureSample\\\(T_${depthTextureName}(.*)\\\);$`, 'gm'), (sub, cap) => { - return `vec4(textureSample(T_${depthTextureName}${cap}), 0.0, 0.0, 0.0);` - }); - code = code.replace(new RegExp(`textureLoad\\\(T_${depthTextureName}(.*)\\\);$`, 'gm'), (sub, cap) => { - return `vec4(textureLoad(T_${depthTextureName}${cap}), 0.0, 0.0, 0.0);` - }); - } - const shaderModule = this.device.createShaderModule({ code }); const stage = { module: shaderModule, entryPoint: 'main' }; if (IS_DEVELOPMENT) { @@ -1206,7 +1194,8 @@ class GfxImplP_WebGPU implements GfxSwapChain, GfxDevice { const gfxBinding = bindingsDescriptor.samplerBindings[i]; const gfxTexture = (gfxBinding.gfxTexture !== null ? gfxBinding.gfxTexture : this._getFallbackTexture(samplerEntry)) as GfxTextureP_WebGPU; assert(samplerEntry.dimension === gfxTexture.dimension); - assert(samplerEntry.formatKind === getFormatSamplerKind(gfxTexture.pixelFormat)); + const formatKind = getFormatSamplerKind(gfxTexture.pixelFormat); + assert(isFormatSamplerKindCompatible(samplerEntry.formatKind, formatKind)); const gpuTextureView = (gfxTexture as GfxTextureP_WebGPU).gpuTextureView; gpuBindGroupEntries.push({ binding: numBindings++, resource: gpuTextureView });