Skip to content

Commit 68e8079

Browse files
committed
webgpu: support depth in blit + copy when we can.
1 parent b4c9b9f commit 68e8079

9 files changed

+771
-515
lines changed

filament/backend/src/webgpu/WebGPUBlitter.cpp

Lines changed: 264 additions & 117 deletions
Large diffs are not rendered by default.

filament/backend/src/webgpu/WebGPUBlitter.h

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class WebGPUBlitter final {
3131
struct BlitArgs final {
3232
struct Attachment final {
3333
wgpu::Texture const& texture;
34+
wgpu::TextureAspect aspect{ wgpu::TextureAspect::Undefined };
3435
wgpu::Origin2D origin{};
3536
wgpu::Extent2D extent{};
3637
uint32_t mipLevel{ 0 };
@@ -47,45 +48,52 @@ class WebGPUBlitter final {
4748
void blit(wgpu::Queue const&, wgpu::CommandEncoder const&, BlitArgs const&);
4849

4950
private:
51+
/**
52+
* ONLY should be called if canDoDirectCopy(...) is true (see it in WebGPUBlitter.cpp)
53+
*/
54+
void copy(wgpu::CommandEncoder const&, BlitArgs const&);
55+
5056
void createSampler(SamplerMagFilter);
5157

5258
[[nodiscard]] wgpu::RenderPipeline const& getOrCreateRenderPipeline(SamplerMagFilter,
5359
wgpu::TextureViewDimension sourceDimension, uint32_t sourceSampleCount,
54-
wgpu::TextureFormat destinationTextureFormat);
60+
bool depthSource, wgpu::TextureFormat destinationTextureFormat);
5561

5662
[[nodiscard]] wgpu::RenderPipeline createRenderPipeline(SamplerMagFilter,
5763
wgpu::TextureViewDimension sourceDimension, uint32_t sourceSampleCount,
58-
wgpu::TextureFormat destinationTextureFormat);
64+
bool depthSource, wgpu::TextureFormat destinationTextureFormat);
5965

6066
[[nodiscard]] static size_t hashRenderPipelineKey(SamplerMagFilter,
61-
wgpu::TextureViewDimension sourceDimension, uint32_t sourceSampleCount);
67+
wgpu::TextureViewDimension sourceDimension, uint32_t sourceSampleCount,
68+
bool depthSource, wgpu::TextureFormat destinationTextureFormat);
6269

6370
[[nodiscard]] wgpu::PipelineLayout const& getOrCreatePipelineLayout(SamplerMagFilter,
64-
wgpu::TextureViewDimension, bool multisampledSource);
71+
wgpu::TextureViewDimension, bool multisampledSource, bool depthSource);
6572

6673
[[nodiscard]] wgpu::PipelineLayout createPipelineLayout(SamplerMagFilter,
67-
wgpu::TextureViewDimension sourceDimension, bool multisampledSource);
74+
wgpu::TextureViewDimension sourceDimension, bool multisampledSource, bool depthSource);
6875

6976
[[nodiscard]] static size_t hashPipelineLayoutKey(SamplerMagFilter,
70-
wgpu::TextureViewDimension sourceDimension, bool multisampledSource);
77+
wgpu::TextureViewDimension sourceDimension, bool multisampledSource, bool depthSource);
7178

7279
[[nodiscard]] wgpu::BindGroupLayout const& getOrCreateTextureBindGroupLayout(SamplerMagFilter,
73-
wgpu::TextureViewDimension sourceDimension, bool multisampledSource);
80+
wgpu::TextureViewDimension sourceDimension, bool multisampledSource, bool depthSource);
7481

7582
[[nodiscard]] wgpu::BindGroupLayout createTextureBindGroupLayout(SamplerMagFilter,
76-
wgpu::TextureViewDimension sourceDimension, bool multisampledSource);
83+
wgpu::TextureViewDimension sourceDimension, bool multisampledSource, bool depthSource);
7784

7885
[[nodiscard]] static size_t hashTextureBindGroupLayoutKey(SamplerMagFilter,
79-
wgpu::TextureViewDimension sourceDimension, bool multisampledSource);
86+
wgpu::TextureViewDimension sourceDimension, bool multisampledSource, bool depthSource);
8087

8188
[[nodiscard]] wgpu::ShaderModule const& getOrCreateShaderModule(
82-
wgpu::TextureViewDimension sourceDimension, bool multisampledSource);
89+
wgpu::TextureViewDimension sourceDimension, bool multisampledSource, bool depthSource,
90+
bool depthDestination);
8391

8492
[[nodiscard]] wgpu::ShaderModule createShaderModule(wgpu::TextureViewDimension sourceDimension,
85-
bool multisampledSource);
93+
bool multisampledSource, bool depthSource, bool depthDestination);
8694

8795
[[nodiscard]] static size_t hashShaderModuleKey(wgpu::TextureViewDimension sourceDimension,
88-
bool multisampledSource);
96+
bool multisampledSource, bool depthSource, bool depthDestination);
8997

9098
wgpu::Device mDevice;
9199
wgpu::Sampler mNearestSampler{ nullptr };

filament/backend/src/webgpu/WebGPUDriver.cpp

Lines changed: 70 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -572,26 +572,26 @@ FenceStatus WebGPUDriver::getFenceStatus(Handle<HwFence> fenceHandle) {
572572
// We create all textures using VK_IMAGE_TILING_OPTIMAL, so our definition of "supported" is that
573573
// the GPU supports the given texture format with non-zero optimal tiling features.
574574
bool WebGPUDriver::isTextureFormatSupported(const TextureFormat format) {
575-
return WebGPUTexture::fToWGPUTextureFormat(format) != wgpu::TextureFormat::Undefined;
575+
return toWGPUTextureFormat(format) != wgpu::TextureFormat::Undefined;
576576
}
577577

578578
bool WebGPUDriver::isTextureSwizzleSupported() {
579579
return false;
580580
}
581581

582582
bool WebGPUDriver::isTextureFormatMipmappable(const TextureFormat format) {
583+
const wgpu::TextureFormat webGpuFormat{ toWGPUTextureFormat(format) };
583584
// passing 2D and sampleCount 1 to only check the format
584585
const WebGPURenderPassMipmapGenerator::FormatCompatibility renderPassCompatibility{
585-
WebGPURenderPassMipmapGenerator::getCompatibilityFor(
586-
WebGPUTexture::fToWGPUTextureFormat(format), wgpu::TextureDimension::e2D, 1)
586+
WebGPURenderPassMipmapGenerator::getCompatibilityFor(webGpuFormat,
587+
wgpu::TextureDimension::e2D, 1)
587588
};
588589

589590
if (renderPassCompatibility.compatible) {
590591
return true;
591592
}
592593

593-
return WebGPUTexture::supportsMultipleMipLevelsViaStorageBinding(
594-
WebGPUTexture::fToWGPUTextureFormat(format));
594+
return WebGPUTexture::supportsMultipleMipLevelsViaStorageBinding(webGpuFormat);
595595
}
596596

597597
bool WebGPUDriver::isRenderTargetFormatSupported(const TextureFormat format) {
@@ -768,34 +768,33 @@ void WebGPUDriver::update3DImage(Handle<HwTexture> textureHandle, const uint32_t
768768
scheduleDestroy(std::move(pixelBufferDescriptor));
769769
return;
770770
}
771-
772771
const wgpu::TextureFormat inputPixelFormat{ toWebGPUFormat(inputData->format,
773772
inputData->type) };
774-
const wgpu::TextureFormat outputLinearFormat{ toWebGPULinearFormat(
773+
const wgpu::TextureFormat outputLinearFormat{ toLinearFormat(
775774
texture->getTexture().GetFormat()) };
776775
const bool conversionNecessary{
777776
inputPixelFormat != outputLinearFormat && inputData->type != PixelDataType::COMPRESSED
778777
}; // compressed formats should never need conversion
779778
const bool doBlit{ conversionNecessary };
780-
#if FWGPU_ENABLED(FWGPU_DEBUG_VALIDATION)
781-
if (texture->width > 1000 && texture->height > 500) {
782-
FWGPU_LOGD << "Update3DImage(..., level=" << level << ", xoffset=" << xoffset
783-
<< ", yoffset=" << yoffset << ", zoffset=" << zoffset << ", width=" << width
784-
<< ", height=" << height << ", depth=" << depth << ", ...):";
785-
FWGPU_LOGD << " PixelBufferDescriptor format (input): " << toString(inputData->format);
786-
FWGPU_LOGD << " PixelBufferDescriptor type (input): " << toString(inputData->type);
787-
FWGPU_LOGD << " Pixel WebGPUFormat (input): "
788-
<< webGPUTextureFormatToString(inputPixelFormat);
789-
FWGPU_LOGD << " Texture View format (output): "
790-
<< webGPUTextureFormatToString(texture->getViewFormat());
791-
FWGPU_LOGD << " Texture format (output): "
792-
<< webGPUTextureFormatToString(texture->getTexture().GetFormat());
793-
FWGPU_LOGD << " Linear Texture format (output): "
794-
<< webGPUTextureFormatToString(outputLinearFormat);
795-
FWGPU_LOGD << " Conversion Necessary: " << conversionNecessary;
796-
FWGPU_LOGD << " Do Blit: " << doBlit;
797-
}
798-
#endif
779+
//#if FWGPU_ENABLED(FWGPU_DEBUG_VALIDATION)
780+
// if (texture->width > 1000 && texture->height > 500) {
781+
// FWGPU_LOGD << "Update3DImage(..., level=" << level << ", xoffset=" << xoffset
782+
// << ", yoffset=" << yoffset << ", zoffset=" << zoffset << ", width=" << width
783+
// << ", height=" << height << ", depth=" << depth << ", ...):";
784+
// FWGPU_LOGD << " PixelBufferDescriptor format (input): " << toString(inputData->format);
785+
// FWGPU_LOGD << " PixelBufferDescriptor type (input): " << toString(inputData->type);
786+
// FWGPU_LOGD << " Pixel WebGPUFormat (input): "
787+
// << webGPUTextureFormatToString(inputPixelFormat);
788+
// FWGPU_LOGD << " Texture View format (output): "
789+
// << webGPUTextureFormatToString(texture->getViewFormat());
790+
// FWGPU_LOGD << " Texture format (output): "
791+
// << webGPUTextureFormatToString(texture->getTexture().GetFormat());
792+
// FWGPU_LOGD << " Linear Texture format (output): "
793+
// << webGPUTextureFormatToString(outputLinearFormat);
794+
// FWGPU_LOGD << " Conversion Necessary: " << conversionNecessary;
795+
// FWGPU_LOGD << " Do Blit: " << doBlit;
796+
// }
797+
//#endif
799798
FILAMENT_CHECK_PRECONDITION(inputData->type == PixelDataType::COMPRESSED ||
800799
inputPixelFormat != wgpu::TextureFormat::Undefined)
801800
<< "Failed to determine uncompressed input pixel format for WebGPU. Pixel format "
@@ -1290,8 +1289,7 @@ void WebGPUDriver::readPixels(Handle<HwRenderTarget> sourceRenderTargetHandle, c
12901289

12911290
const size_t dstBytesPerPixel = PixelBufferDescriptor::computePixelSize(
12921291
pixelBufferDescriptor.format, pixelBufferDescriptor.type);
1293-
const size_t srcBytesPerPixel =
1294-
WebGPUTexture::getWGPUTextureFormatPixelSize(srcTexture.GetFormat());
1292+
const size_t srcBytesPerPixel = getWGPUTextureFormatPixelSize(srcTexture.GetFormat());
12951293

12961294
FILAMENT_CHECK_PRECONDITION(dstBytesPerPixel == srcBytesPerPixel && dstBytesPerPixel > 0)
12971295
<< "Source texture pixel size (" << srcBytesPerPixel
@@ -1384,7 +1382,9 @@ void WebGPUDriver::readBufferSubData(Handle<HwBufferObject> bufferObjectHandle,
13841382
void WebGPUDriver::blitDEPRECATED(TargetBufferFlags buffers,
13851383
Handle<HwRenderTarget> destinationRenderTargetHandle, const Viewport destinationViewport,
13861384
Handle<HwRenderTarget> sourceRenderTargetHandle, const Viewport sourceViewport,
1387-
const SamplerMagFilter filter) {}
1385+
const SamplerMagFilter filter) {
1386+
PANIC_PRECONDITION("WebGPUDriver::blitDEPRECATED not supported");
1387+
}
13881388

13891389
void WebGPUDriver::resolve(Handle<HwTexture> destinationTextureHandle, const uint8_t sourceLevel,
13901390
const uint8_t sourceLayer, Handle<HwTexture> sourceTextureHandle,
@@ -1424,43 +1424,47 @@ void WebGPUDriver::blit(Handle<HwTexture> destinationTextureHandle, const uint8_
14241424
const uint8_t destinationLayer, const math::uint2 sourceOrigin, const math::uint2 size) {
14251425
// TODO uncomment when texture format is taken into account with sampler settings in the
14261426
// blitter
1427-
// bool reusedCommandEncoder{ true };
1428-
// if (!mCommandEncoder) {
1429-
// reusedCommandEncoder = false;
1430-
// const wgpu::CommandEncoderDescriptor commandEncoderDescriptor{
1431-
// .label = "blit_command",
1432-
// };
1433-
// mCommandEncoder = mDevice.CreateCommandEncoder(&commandEncoderDescriptor);
1434-
// FILAMENT_CHECK_POSTCONDITION(mCommandEncoder)
1435-
// << "Failed to create command encoder for blit?";
1436-
// }
1437-
// const WebGPUBlitter::BlitArgs blitArgs{
1438-
// .source = {
1439-
// .texture = handleCast<WebGPUTexture>(sourceTextureHandle)->getTexture(),
1440-
// .origin = {.x = sourceOrigin.x, .y=sourceOrigin.y},
1441-
// .extent = {.width=size.x, .height =size.y},
1442-
// .mipLevel = sourceLevel,
1443-
// .layerOrDepth = sourceLayer,
1444-
// },
1445-
// .destination = {
1446-
// .texture = handleCast<WebGPUTexture>(destinationTextureHandle)->getTexture(),
1447-
// .origin = {.x = destinationOrigin.x, .y=destinationOrigin.y},
1448-
// .extent = {.width=size.x, .height =size.y},
1449-
// .mipLevel = destinationLevel,
1450-
// .layerOrDepth = destinationLayer,
1451-
// },
1452-
// .filter = SamplerMagFilter::NEAREST,
1453-
// };
1454-
// mBlitter.blit(mQueue, mCommandEncoder, blitArgs);
1455-
// if (!reusedCommandEncoder) {
1456-
// const wgpu::CommandBufferDescriptor commandBufferDescriptor{
1457-
// .label = "blit_command_buffer",
1458-
// };
1459-
// const wgpu::CommandBuffer blitCommand{ mCommandEncoder.Finish(&commandBufferDescriptor) };
1460-
// FILAMENT_CHECK_POSTCONDITION(blitCommand) << "Failed to create command buffer for blit?";
1461-
// mQueue.Submit(1, &blitCommand);
1462-
// mCommandEncoder = nullptr;
1463-
// }
1427+
bool reusedCommandEncoder{ true };
1428+
if (!mCommandEncoder) {
1429+
reusedCommandEncoder = false;
1430+
const wgpu::CommandEncoderDescriptor commandEncoderDescriptor{
1431+
.label = "blit_command",
1432+
};
1433+
mCommandEncoder = mDevice.CreateCommandEncoder(&commandEncoderDescriptor);
1434+
FILAMENT_CHECK_POSTCONDITION(mCommandEncoder)
1435+
<< "Failed to create command encoder for blit?";
1436+
}
1437+
const auto sourceTexture{ handleCast<WebGPUTexture>(sourceTextureHandle) };
1438+
const auto destinationTexture{ handleCast<WebGPUTexture>(destinationTextureHandle) };
1439+
const WebGPUBlitter::BlitArgs blitArgs{
1440+
.source = {
1441+
.texture = sourceTexture->getTexture(),
1442+
.aspect = sourceTexture->getAspect(),
1443+
.origin = {.x = sourceOrigin.x, .y=sourceOrigin.y},
1444+
.extent = {.width=size.x, .height =size.y},
1445+
.mipLevel = sourceLevel,
1446+
.layerOrDepth = sourceLayer,
1447+
},
1448+
.destination = {
1449+
.texture = destinationTexture->getTexture(),
1450+
.aspect = destinationTexture->getAspect(),
1451+
.origin = {.x = destinationOrigin.x, .y=destinationOrigin.y},
1452+
.extent = {.width=size.x, .height =size.y},
1453+
.mipLevel = destinationLevel,
1454+
.layerOrDepth = destinationLayer,
1455+
},
1456+
.filter = SamplerMagFilter::NEAREST,
1457+
};
1458+
mBlitter.blit(mQueue, mCommandEncoder, blitArgs);
1459+
if (!reusedCommandEncoder) {
1460+
const wgpu::CommandBufferDescriptor commandBufferDescriptor{
1461+
.label = "blit_command_buffer",
1462+
};
1463+
const wgpu::CommandBuffer blitCommand{ mCommandEncoder.Finish(&commandBufferDescriptor) };
1464+
FILAMENT_CHECK_POSTCONDITION(blitCommand) << "Failed to create command buffer for blit?";
1465+
mQueue.Submit(1, &blitCommand);
1466+
mCommandEncoder = nullptr;
1467+
}
14641468
}
14651469

14661470
void WebGPUDriver::bindPipeline(PipelineState const& pipelineState) {

filament/backend/src/webgpu/WebGPUMsaaTextureResolver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
#include "WebGPUMsaaTextureResolver.h"
1818

19-
#include "WebGPUTexture.h"
19+
#include "WebGPUTextureHelpers.h"
2020

2121
#include <utils/Panic.h>
2222

filament/backend/src/webgpu/WebGPUPipelineCache.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "WebGPUPipelineCache.h"
1818

1919
#include "WebGPUConstants.h"
20-
#include "WebGPUTexture.h"
20+
#include "WebGPUTextureHelpers.h"
2121
#include "WebGPUVertexBufferInfo.h"
2222

2323
#include <backend/DriverEnums.h>

0 commit comments

Comments
 (0)