Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ad90d139d | ||
|
|
cf694a3334 | ||
|
|
863379b5b4 |
@@ -1472,6 +1472,7 @@ void WebGPUDriver::readPixels(Handle<HwRenderTarget> sourceRenderTargetHandle, c
|
||||
const auto srcTarget{ handleCast<WebGPURenderTarget>(sourceRenderTargetHandle) };
|
||||
assert_invariant(srcTarget);
|
||||
|
||||
uint32_t srcMipLevel = 0;
|
||||
wgpu::Texture srcTexture{ nullptr };
|
||||
if (srcTarget->isDefaultRenderTarget()) {
|
||||
assert_invariant(mSwapChain);
|
||||
@@ -1482,6 +1483,7 @@ void WebGPUDriver::readPixels(Handle<HwRenderTarget> sourceRenderTargetHandle, c
|
||||
// TODO we are currently assuming the first attachment is the desired texture.
|
||||
if (colorAttachmentInfos[0].handle) {
|
||||
auto texture = handleCast<WebGPUTexture>(colorAttachmentInfos[0].handle);
|
||||
srcMipLevel = colorAttachmentInfos[0].level;
|
||||
if (texture) {
|
||||
srcTexture = texture->getTexture();
|
||||
}
|
||||
@@ -1494,15 +1496,20 @@ void WebGPUDriver::readPixels(Handle<HwRenderTarget> sourceRenderTargetHandle, c
|
||||
return;
|
||||
}
|
||||
const uint32_t srcWidth {srcTexture.GetWidth()};
|
||||
const uint32_t srcHeight{srcTexture.GetHeight()};
|
||||
const uint32_t srcHeight {srcTexture.GetHeight()};
|
||||
const uint32_t srcMipLevelCount {srcTexture.GetMipLevelCount()};
|
||||
|
||||
constexpr uint32_t minValidTextureSize = 1;
|
||||
const uint32_t mipLeveledSrcWidth = std::max(minValidTextureSize, srcWidth >> srcMipLevel);
|
||||
const uint32_t mipLeveledSrcHeight = std::max(minValidTextureSize, srcHeight >> srcMipLevel);
|
||||
|
||||
// Clamp read region to texture bounds
|
||||
if (UTILS_UNLIKELY(x >= srcWidth || y >= srcHeight)) {
|
||||
if (UTILS_UNLIKELY(x >= mipLeveledSrcWidth || y >= mipLeveledSrcHeight)) {
|
||||
scheduleDestroy(std::move(pixelBufferDescriptor));
|
||||
return;
|
||||
}
|
||||
auto actualWidth{ std::min(width, srcWidth - x) };
|
||||
auto actualHeight{ std::min(height, srcHeight - y)};
|
||||
auto actualWidth{ std::min(width, mipLeveledSrcWidth - x) };
|
||||
auto actualHeight{ std::min(height, mipLeveledSrcHeight - y)};
|
||||
if (UTILS_UNLIKELY(actualWidth == 0 || actualHeight == 0)) {
|
||||
scheduleDestroy(std::move(pixelBufferDescriptor));
|
||||
return;
|
||||
@@ -1526,6 +1533,7 @@ void WebGPUDriver::readPixels(Handle<HwRenderTarget> sourceRenderTargetHandle, c
|
||||
// If the source format is different from the destination (e.g. BGRA vs RGBA),
|
||||
// we need to perform a conversion using an intermediate blit.
|
||||
if (conversionNecessary(srcFormat, dstFormat, pixelBufferDescriptor.type)) {
|
||||
// TODO: check if the blit process here is correct when mipmap level > 0
|
||||
const wgpu::TextureDescriptor stagingDescriptor{
|
||||
.label = "readpixels_staging_texture",
|
||||
.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment,
|
||||
@@ -1536,7 +1544,7 @@ void WebGPUDriver::readPixels(Handle<HwRenderTarget> sourceRenderTargetHandle, c
|
||||
.depthOrArrayLayers = 1,
|
||||
},
|
||||
.format = dstFormat,
|
||||
.mipLevelCount = 1,
|
||||
.mipLevelCount = srcMipLevelCount,
|
||||
.sampleCount = srcTexture.GetSampleCount(),
|
||||
};
|
||||
stagingTexture = mDevice.CreateTexture(&stagingDescriptor);
|
||||
@@ -1586,12 +1594,11 @@ void WebGPUDriver::readPixels(Handle<HwRenderTarget> sourceRenderTargetHandle, c
|
||||
|
||||
// WebGPU's texture coordinates for copies are top-left, but Filament's y-coordinate is
|
||||
// bottom-left. We must flip the y-coordinate relative to the texture we are reading from.
|
||||
const uint32_t textureHeight{ textureToReadFrom.GetHeight() };
|
||||
const uint32_t flippedY{ textureHeight - readY - actualHeight };
|
||||
const uint32_t flippedY{ mipLeveledSrcHeight - readY - actualHeight };
|
||||
|
||||
const wgpu::TexelCopyTextureInfo source{
|
||||
.texture = textureToReadFrom, // Read from the original or intermediate texture
|
||||
.mipLevel = 0,
|
||||
.mipLevel = srcMipLevel,
|
||||
.origin = {.x = readX, .y = flippedY, .z = 0,},
|
||||
};
|
||||
const wgpu::TexelCopyBufferInfo destination{
|
||||
|
||||
@@ -83,8 +83,10 @@ TEST_F(BackendTest, ScissorViewportRegion) {
|
||||
Handle<HwTexture> srcTexture = addCleanup(api.createTexture(SamplerType::SAMPLER_2D,
|
||||
kNumLevels, kSrcTexFormat, 1, kSrcTexWidth, kSrcTexHeight, 1,
|
||||
TextureUsage::SAMPLEABLE | TextureUsage::COLOR_ATTACHMENT TEXTURE_USAGE_READ_PIXELS));
|
||||
Handle<HwTexture> depthTexture = addCleanup(api.createTexture(SamplerType::SAMPLER_2D, 1,
|
||||
TextureFormat::DEPTH16, 1, 512, 512, 1, TextureUsage::DEPTH_ATTACHMENT));
|
||||
|
||||
Handle<HwTexture> depthTexture =
|
||||
addCleanup(api.createTexture(SamplerType::SAMPLER_2D, 1, TextureFormat::DEPTH16, 1,
|
||||
512, 512, 1, TextureUsage::DEPTH_ATTACHMENT | TextureUsage::SAMPLEABLE));
|
||||
|
||||
// Render into the bottom-left quarter of the texture.
|
||||
Viewport srcRect = {
|
||||
|
||||
Reference in New Issue
Block a user