aboutsummaryrefslogtreecommitdiff
path: root/src/libANGLE/renderer/wgpu/wgpu_helpers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libANGLE/renderer/wgpu/wgpu_helpers.cpp')
-rw-r--r--src/libANGLE/renderer/wgpu/wgpu_helpers.cpp106
1 files changed, 89 insertions, 17 deletions
diff --git a/src/libANGLE/renderer/wgpu/wgpu_helpers.cpp b/src/libANGLE/renderer/wgpu/wgpu_helpers.cpp
index d679ecb664..422f86023a 100644
--- a/src/libANGLE/renderer/wgpu/wgpu_helpers.cpp
+++ b/src/libANGLE/renderer/wgpu/wgpu_helpers.cpp
@@ -9,6 +9,7 @@
#include "libANGLE/renderer/wgpu/ContextWgpu.h"
#include "libANGLE/renderer/wgpu/DisplayWgpu.h"
+#include "libANGLE/renderer/wgpu/FramebufferWgpu.h"
#include "wgpu_helpers.h"
namespace rx
@@ -35,32 +36,63 @@ angle::Result ImageHelper::initImage(wgpu::Device &device,
return angle::Result::Continue;
}
-void ImageHelper::flushStagedUpdates(ContextWgpu *contextWgpu)
+angle::Result ImageHelper::flushStagedUpdates(ContextWgpu *contextWgpu,
+ ClearValuesArray *deferredClears,
+ uint32_t deferredClearIndex)
{
- if (mBufferQueue.empty())
+ if (mSubresourceQueue.empty())
{
- return;
+ return angle::Result::Continue;
}
wgpu::Device device = contextWgpu->getDevice();
wgpu::Queue queue = contextWgpu->getQueue();
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
wgpu::ImageCopyTexture dst;
dst.texture = mTexture;
- for (const QueuedDataUpload &src : mBufferQueue)
+ std::vector<wgpu::RenderPassColorAttachment> colorAttachments;
+ for (const SubresourceUpdate &srcUpdate : mSubresourceQueue)
{
- if (src.targetLevel < mFirstAllocatedLevel ||
- src.targetLevel >= (mFirstAllocatedLevel + mTextureDescriptor.mipLevelCount))
+ if (!isTextureLevelInAllocatedImage(srcUpdate.targetLevel))
{
continue;
}
- LevelIndex targetLevelWgpu = toWgpuLevel(src.targetLevel);
- dst.mipLevel = targetLevelWgpu.get();
- encoder.CopyBufferToTexture(&src.buffer, &dst, &mTextureDescriptor.size);
+ switch (srcUpdate.updateSource)
+ {
+ case UpdateSource::Texture:
+ dst.mipLevel = toWgpuLevel(srcUpdate.targetLevel).get();
+ encoder.CopyBufferToTexture(&srcUpdate.textureData, &dst, &mTextureDescriptor.size);
+ break;
+ case UpdateSource::Clear:
+ if (deferredClears)
+ {
+ deferredClears->store(deferredClearIndex, srcUpdate.clearData);
+ }
+ else
+ {
+
+ wgpu::TextureView textureView;
+ ANGLE_TRY(createTextureView(srcUpdate.targetLevel, 0, textureView));
+
+ colorAttachments.push_back(
+ CreateNewClearColorAttachment(srcUpdate.clearData.clearColor,
+ srcUpdate.clearData.depthSlice, textureView));
+ }
+ break;
+ }
+ }
+
+ if (!colorAttachments.empty())
+ {
+ FramebufferWgpu *frameBuffer =
+ GetImplAs<FramebufferWgpu>(contextWgpu->getState().getDrawFramebuffer());
+ frameBuffer->addNewColorAttachments(colorAttachments);
}
wgpu::CommandBuffer commandBuffer = encoder.Finish();
queue.Submit(1, &commandBuffer);
encoder = nullptr;
- mBufferQueue.clear();
+ mSubresourceQueue.clear();
+
+ return angle::Result::Continue;
}
wgpu::TextureDescriptor ImageHelper::createTextureDescriptor(wgpu::TextureUsage usage,
@@ -113,20 +145,26 @@ angle::Result ImageHelper::stageTextureUpload(ContextWgpu *contextWgpu,
textureDataLayout.bytesPerRow = outputRowPitch;
textureDataLayout.rowsPerImage = outputDepthPitch;
wgpu::ImageCopyBuffer imageCopyBuffer;
- imageCopyBuffer.layout = textureDataLayout;
- imageCopyBuffer.buffer = bufferHelper.getBuffer();
- QueuedDataUpload dataUpload = {imageCopyBuffer, levelGL};
- mBufferQueue.push_back(dataUpload);
+ imageCopyBuffer.layout = textureDataLayout;
+ imageCopyBuffer.buffer = bufferHelper.getBuffer();
+ SubresourceUpdate subresourceUpdate(UpdateSource::Texture, levelGL, imageCopyBuffer);
+ mSubresourceQueue.push_back(subresourceUpdate);
return angle::Result::Continue;
}
+void ImageHelper::stageClear(gl::LevelIndex targetLevel, ClearValues clearValues)
+{
+ SubresourceUpdate subresourceUpdate(UpdateSource::Clear, targetLevel, clearValues);
+ mSubresourceQueue.push_back(subresourceUpdate);
+}
+
void ImageHelper::removeStagedUpdates(gl::LevelIndex levelToRemove)
{
- for (auto it = mBufferQueue.begin(); it != mBufferQueue.end(); it++)
+ for (auto it = mSubresourceQueue.begin(); it != mSubresourceQueue.end(); it++)
{
- if (it->targetLevel == levelToRemove)
+ if (it->updateSource == UpdateSource::Texture && it->targetLevel == levelToRemove)
{
- mBufferQueue.erase(it);
+ mSubresourceQueue.erase(it);
}
}
}
@@ -212,6 +250,40 @@ angle::Result ImageHelper::readPixels(rx::ContextWgpu *contextWgpu,
return angle::Result::Continue;
}
+angle::Result ImageHelper::createTextureView(gl::LevelIndex targetLevel,
+ uint32_t layerIndex,
+ wgpu::TextureView &textureViewOut)
+{
+ if (!isTextureLevelInAllocatedImage(targetLevel))
+ {
+ return angle::Result::Stop;
+ }
+ wgpu::TextureViewDescriptor textureViewDesc;
+ textureViewDesc.aspect = wgpu::TextureAspect::All;
+ textureViewDesc.baseArrayLayer = layerIndex;
+ textureViewDesc.arrayLayerCount = 1;
+ textureViewDesc.baseMipLevel = toWgpuLevel(targetLevel).get();
+ textureViewDesc.mipLevelCount = 1;
+ switch (mTextureDescriptor.dimension)
+ {
+ case wgpu::TextureDimension::Undefined:
+ textureViewDesc.dimension = wgpu::TextureViewDimension::Undefined;
+ break;
+ case wgpu::TextureDimension::e1D:
+ textureViewDesc.dimension = wgpu::TextureViewDimension::e1D;
+ break;
+ case wgpu::TextureDimension::e2D:
+ textureViewDesc.dimension = wgpu::TextureViewDimension::e2D;
+ break;
+ case wgpu::TextureDimension::e3D:
+ textureViewDesc.dimension = wgpu::TextureViewDimension::e3D;
+ break;
+ }
+ textureViewDesc.format = mTextureDescriptor.format;
+ textureViewOut = mTexture.CreateView(&textureViewDesc);
+ return angle::Result::Continue;
+}
+
gl::LevelIndex ImageHelper::getLastAllocatedLevel()
{
return mFirstAllocatedLevel + mTextureDescriptor.mipLevelCount - 1;