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) };
|
const auto srcTarget{ handleCast<WebGPURenderTarget>(sourceRenderTargetHandle) };
|
||||||
assert_invariant(srcTarget);
|
assert_invariant(srcTarget);
|
||||||
|
|
||||||
|
uint32_t srcMipLevel = 0;
|
||||||
wgpu::Texture srcTexture{ nullptr };
|
wgpu::Texture srcTexture{ nullptr };
|
||||||
if (srcTarget->isDefaultRenderTarget()) {
|
if (srcTarget->isDefaultRenderTarget()) {
|
||||||
assert_invariant(mSwapChain);
|
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.
|
// TODO we are currently assuming the first attachment is the desired texture.
|
||||||
if (colorAttachmentInfos[0].handle) {
|
if (colorAttachmentInfos[0].handle) {
|
||||||
auto texture = handleCast<WebGPUTexture>(colorAttachmentInfos[0].handle);
|
auto texture = handleCast<WebGPUTexture>(colorAttachmentInfos[0].handle);
|
||||||
|
srcMipLevel = colorAttachmentInfos[0].level;
|
||||||
if (texture) {
|
if (texture) {
|
||||||
srcTexture = texture->getTexture();
|
srcTexture = texture->getTexture();
|
||||||
}
|
}
|
||||||
@@ -1494,15 +1496,20 @@ void WebGPUDriver::readPixels(Handle<HwRenderTarget> sourceRenderTargetHandle, c
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const uint32_t srcWidth {srcTexture.GetWidth()};
|
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
|
// Clamp read region to texture bounds
|
||||||
if (UTILS_UNLIKELY(x >= srcWidth || y >= srcHeight)) {
|
if (UTILS_UNLIKELY(x >= mipLeveledSrcWidth || y >= mipLeveledSrcHeight)) {
|
||||||
scheduleDestroy(std::move(pixelBufferDescriptor));
|
scheduleDestroy(std::move(pixelBufferDescriptor));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto actualWidth{ std::min(width, srcWidth - x) };
|
auto actualWidth{ std::min(width, mipLeveledSrcWidth - x) };
|
||||||
auto actualHeight{ std::min(height, srcHeight - y)};
|
auto actualHeight{ std::min(height, mipLeveledSrcHeight - y)};
|
||||||
if (UTILS_UNLIKELY(actualWidth == 0 || actualHeight == 0)) {
|
if (UTILS_UNLIKELY(actualWidth == 0 || actualHeight == 0)) {
|
||||||
scheduleDestroy(std::move(pixelBufferDescriptor));
|
scheduleDestroy(std::move(pixelBufferDescriptor));
|
||||||
return;
|
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),
|
// If the source format is different from the destination (e.g. BGRA vs RGBA),
|
||||||
// we need to perform a conversion using an intermediate blit.
|
// we need to perform a conversion using an intermediate blit.
|
||||||
if (conversionNecessary(srcFormat, dstFormat, pixelBufferDescriptor.type)) {
|
if (conversionNecessary(srcFormat, dstFormat, pixelBufferDescriptor.type)) {
|
||||||
|
// TODO: check if the blit process here is correct when mipmap level > 0
|
||||||
const wgpu::TextureDescriptor stagingDescriptor{
|
const wgpu::TextureDescriptor stagingDescriptor{
|
||||||
.label = "readpixels_staging_texture",
|
.label = "readpixels_staging_texture",
|
||||||
.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment,
|
.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment,
|
||||||
@@ -1536,7 +1544,7 @@ void WebGPUDriver::readPixels(Handle<HwRenderTarget> sourceRenderTargetHandle, c
|
|||||||
.depthOrArrayLayers = 1,
|
.depthOrArrayLayers = 1,
|
||||||
},
|
},
|
||||||
.format = dstFormat,
|
.format = dstFormat,
|
||||||
.mipLevelCount = 1,
|
.mipLevelCount = srcMipLevelCount,
|
||||||
.sampleCount = srcTexture.GetSampleCount(),
|
.sampleCount = srcTexture.GetSampleCount(),
|
||||||
};
|
};
|
||||||
stagingTexture = mDevice.CreateTexture(&stagingDescriptor);
|
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
|
// 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.
|
// 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{ mipLeveledSrcHeight - readY - actualHeight };
|
||||||
const uint32_t flippedY{ textureHeight - readY - actualHeight };
|
|
||||||
|
|
||||||
const wgpu::TexelCopyTextureInfo source{
|
const wgpu::TexelCopyTextureInfo source{
|
||||||
.texture = textureToReadFrom, // Read from the original or intermediate texture
|
.texture = textureToReadFrom, // Read from the original or intermediate texture
|
||||||
.mipLevel = 0,
|
.mipLevel = srcMipLevel,
|
||||||
.origin = {.x = readX, .y = flippedY, .z = 0,},
|
.origin = {.x = readX, .y = flippedY, .z = 0,},
|
||||||
};
|
};
|
||||||
const wgpu::TexelCopyBufferInfo destination{
|
const wgpu::TexelCopyBufferInfo destination{
|
||||||
|
|||||||
@@ -83,8 +83,10 @@ TEST_F(BackendTest, ScissorViewportRegion) {
|
|||||||
Handle<HwTexture> srcTexture = addCleanup(api.createTexture(SamplerType::SAMPLER_2D,
|
Handle<HwTexture> srcTexture = addCleanup(api.createTexture(SamplerType::SAMPLER_2D,
|
||||||
kNumLevels, kSrcTexFormat, 1, kSrcTexWidth, kSrcTexHeight, 1,
|
kNumLevels, kSrcTexFormat, 1, kSrcTexWidth, kSrcTexHeight, 1,
|
||||||
TextureUsage::SAMPLEABLE | TextureUsage::COLOR_ATTACHMENT TEXTURE_USAGE_READ_PIXELS));
|
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.
|
// Render into the bottom-left quarter of the texture.
|
||||||
Viewport srcRect = {
|
Viewport srcRect = {
|
||||||
|
|||||||
Reference in New Issue
Block a user