simplified attachment logic

This commit is contained in:
Jeremy Nelson
2025-06-23 14:30:04 -07:00
committed by Jeremy Nelson
parent 6d1c337363
commit 8304cd9c32
6 changed files with 94 additions and 92 deletions
+14 -11
View File
@@ -452,7 +452,7 @@ void WebGPUDriver::createDefaultRenderTargetR(Handle<HwRenderTarget> renderTarge
}
void WebGPUDriver::createRenderTargetR(Handle<HwRenderTarget> renderTargetHandle,
const TargetBufferFlags targets, const uint32_t width, const uint32_t height,
const TargetBufferFlags targetFlags, const uint32_t width, const uint32_t height,
const uint8_t samples, const uint8_t layerCount, const MRT color,
const TargetBufferInfo depth, const TargetBufferInfo stencil) {
constructHandle<WebGPURenderTarget>(renderTargetHandle, width, height, samples, layerCount,
@@ -834,7 +834,7 @@ void WebGPUDriver::beginRenderPass(Handle<HwRenderTarget> renderTargetHandle,
defaultDepthStencilView = mSwapChain->getDepthTextureView();
defaultDepthStencilFormat = mSwapChain->getDepthFormat();
if (any(renderTarget->getTargets() & TargetBufferFlags::STENCIL) &&
if (any(renderTarget->getTargetFlags() & TargetBufferFlags::STENCIL) &&
!(defaultDepthStencilFormat == wgpu::TextureFormat::Depth24PlusStencil8 ||
defaultDepthStencilFormat == wgpu::TextureFormat::Depth32FloatStencil8 ||
defaultDepthStencilFormat == wgpu::TextureFormat::Stencil8)) {
@@ -842,7 +842,7 @@ void WebGPUDriver::beginRenderPass(Handle<HwRenderTarget> renderTargetHandle,
<< (uint32_t)defaultDepthStencilFormat << " does not have a stencil aspect.";
}
if (any(renderTarget->getTargets() & TargetBufferFlags::DEPTH) &&
if (any(renderTarget->getTargetFlags() & TargetBufferFlags::DEPTH) &&
!(defaultDepthStencilFormat == wgpu::TextureFormat::Depth16Unorm ||
defaultDepthStencilFormat == wgpu::TextureFormat::Depth32Float ||
defaultDepthStencilFormat == wgpu::TextureFormat::Depth24Plus ||
@@ -893,7 +893,7 @@ void WebGPUDriver::beginRenderPass(Handle<HwRenderTarget> renderTargetHandle,
customDepthStencilView = dsTexture->getOrMakeTextureView(dsMipLevel, dsArrayLayer);
customDepthStencilFormat = dsTexture->getViewFormat();
if (any(renderTarget->getTargets() & TargetBufferFlags::STENCIL) &&
if (any(renderTarget->getTargetFlags() & TargetBufferFlags::STENCIL) &&
!(customDepthStencilFormat == wgpu::TextureFormat::Depth24PlusStencil8 ||
customDepthStencilFormat ==
wgpu::TextureFormat::Depth32FloatStencil8 ||
@@ -905,7 +905,7 @@ void WebGPUDriver::beginRenderPass(Handle<HwRenderTarget> renderTargetHandle,
<< (uint32_t) customDepthStencilFormat
<< " does not have a stencil aspect.";
}
if (any(renderTarget->getTargets() & TargetBufferFlags::DEPTH) &&
if (any(renderTarget->getTargetFlags() & TargetBufferFlags::DEPTH) &&
!(customDepthStencilFormat == wgpu::TextureFormat::Depth16Unorm ||
customDepthStencilFormat == wgpu::TextureFormat::Depth32Float ||
customDepthStencilFormat ==
@@ -972,18 +972,21 @@ void WebGPUDriver::makeCurrent(Handle<HwSwapChain> drawSch, Handle<HwSwapChain>
assert_invariant(mDefaultRenderTarget);
wgpu::TextureFormat depthFormat = mSwapChain->getDepthFormat();
mDefaultRenderTarget->mTargetFlags = filament::backend::TargetBufferFlags::NONE;
TargetBufferFlags newTargetFlags = filament::backend::TargetBufferFlags::NONE;
mDefaultRenderTarget->mTargetFlags |= filament::backend::TargetBufferFlags::COLOR;
newTargetFlags = filament::backend::TargetBufferFlags::NONE;
newTargetFlags |= filament::backend::TargetBufferFlags::COLOR;
if (depthFormat != wgpu::TextureFormat::Undefined) {
mDefaultRenderTarget->mTargetFlags |= filament::backend::TargetBufferFlags::DEPTH;
newTargetFlags |= filament::backend::TargetBufferFlags::DEPTH;
if (depthFormat == wgpu::TextureFormat::Depth24PlusStencil8 ||
depthFormat == wgpu::TextureFormat::Depth32FloatStencil8) {
mDefaultRenderTarget->mTargetFlags |= filament::backend::TargetBufferFlags::STENCIL;
newTargetFlags |= filament::backend::TargetBufferFlags::STENCIL;
}
}
mDefaultRenderTarget->setTargetFlags(newTargetFlags);
wgpu::CommandEncoderDescriptor commandEncoderDescriptor = { .label = "command_encoder" };
mCommandEncoder = mDevice.CreateCommandEncoder(&commandEncoderDescriptor);
assert_invariant(mCommandEncoder);
@@ -1127,7 +1130,7 @@ void WebGPUDriver::bindPipeline(PipelineState const& pipelineState) {
pipelineColorFormats.push_back(mSwapChain->getColorFormat());
pipelineDepthStencilFormat = mSwapChain->getDepthFormat();
pipelineSamples = mCurrentRenderTarget->getSamples();
requestedStencil = any(mCurrentRenderTarget->getTargets() & TargetBufferFlags::STENCIL);
requestedStencil = any(mCurrentRenderTarget->getTargetFlags() & TargetBufferFlags::STENCIL);
} else {
const auto& mrtColorAttachments = mCurrentRenderTarget->getColorAttachmentInfos();
for (size_t i = 0; i < MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT; ++i) {
@@ -1155,7 +1158,7 @@ void WebGPUDriver::bindPipeline(PipelineState const& pipelineState) {
}
}
pipelineSamples = mCurrentRenderTarget->getSamples();
requestedStencil = any(mCurrentRenderTarget->getTargets() & TargetBufferFlags::STENCIL);
requestedStencil = any(mCurrentRenderTarget->getTargetFlags() & TargetBufferFlags::STENCIL);
}
// TODO: We expected this to be a sane check, however it complains when running shadowtest.
@@ -169,7 +169,7 @@ wgpu::RenderPipeline createWebGPURenderPipeline(wgpu::Device const& device,
wgpu::PipelineLayout const& layout, RasterState const& rasterState,
StencilState const& stencilState, PolygonOffset const& polygonOffset,
const PrimitiveType primitiveType, std::vector<wgpu::TextureFormat> const& colorFormats,
const wgpu::TextureFormat depthStencilFormat, const uint8_t samplesCount, bool filamentRequestedStencil) {
const wgpu::TextureFormat depthStencilFormat, const uint8_t samplesCount, bool requestedStencil) {
assert_invariant(program.vertexShaderModule);
wgpu::DepthStencilState depthStencilState{};
@@ -188,7 +188,7 @@ wgpu::RenderPipeline createWebGPURenderPipeline(wgpu::Device const& device,
depthStencilState.depthBiasClamp = 0.0f;
}
if (hasStencilAspect(depthStencilFormat) && filamentRequestedStencil) {
if (hasStencilAspect(depthStencilFormat) && requestedStencil) {
depthStencilState.stencilFront = {
.compare = toWebGPU(stencilState.front.stencilFunc),
.failOp = toWebGPU(stencilState.front.stencilOpStencilFail),
@@ -41,7 +41,7 @@ class WebGPUProgram;
WebGPUProgram const&, WebGPUVertexBufferInfo const&, wgpu::PipelineLayout const&,
RasterState const&, StencilState const&, PolygonOffset const&, PrimitiveType primitiveType,
std::vector<wgpu::TextureFormat> const& colorFormats, wgpu::TextureFormat depthFormat,
uint8_t samplesCount, bool filamentRequestedStencil);
uint8_t samplesCount, bool requestedStencil);
}// namespace filament::backend
@@ -32,10 +32,10 @@ namespace filament::backend {
WebGPURenderTarget::WebGPURenderTarget(const uint32_t width, const uint32_t height,
const uint8_t samples, const uint8_t layerCount, MRT const& colorAttachmentsMRT,
Attachment const& depthAttachmentInfo, Attachment const& stencilAttachmentInfo, TargetBufferFlags targetFlags)
Attachment const& depthAttachmentInfo, Attachment const& stencilAttachmentInfo, TargetBufferFlags const& targetFlags)
: HwRenderTarget{ width, height },
mTargetFlags(targetFlags),
mDefaultRenderTarget{ false },
mTargetFlags{ targetFlags },
mSamples{ samples },
mLayerCount{ layerCount },
mColorAttachments{ colorAttachmentsMRT },
@@ -48,8 +48,8 @@ WebGPURenderTarget::WebGPURenderTarget(const uint32_t width, const uint32_t heig
// Default constructor for the default render target
WebGPURenderTarget::WebGPURenderTarget()
: HwRenderTarget{ 0, 0 },
mTargetFlags(TargetBufferFlags::NONE),
mDefaultRenderTarget{ true },
mTargetFlags{ TargetBufferFlags::NONE },
mSamples{ 1 },
mLayerCount{ 1 }
{}
@@ -83,27 +83,26 @@ void WebGPURenderTarget::setUpRenderPassAttachments(wgpu::RenderPassDescriptor&
const wgpu::TextureFormat customDepthFormat,
const wgpu::TextureFormat customStencilFormat) {
mColorAttachmentDescriptors.clear();
mHasDepthStencilAttachment = false;
bool hasDepth = any(mTargetFlags & TargetBufferFlags::DEPTH);
bool hasStencil = any(mTargetFlags & TargetBufferFlags::STENCIL);
const bool hasDepth = any(mTargetFlags & TargetBufferFlags::DEPTH);
const bool hasStencil = any(mTargetFlags & TargetBufferFlags::STENCIL);
mHasDepthStencilAttachment = hasDepth || hasStencil;
bool const depthReadOnly =
(params.readOnlyDepthStencil & RenderPassParams::READONLY_DEPTH) > 0;
// Color attachments
if (mDefaultRenderTarget) {
assert_invariant(defaultColorTextureView);
mColorAttachmentDescriptors.push_back({ .view = defaultColorTextureView,
mColorAttachmentDescriptors.push_back({
.view = defaultColorTextureView,
.resolveTarget = nullptr,
.loadOp = WebGPURenderTarget::getLoadOperation(params, TargetBufferFlags::COLOR0),
.storeOp = WebGPURenderTarget::getStoreOperation(params, TargetBufferFlags::COLOR0),
.clearValue = { params.clearColor.r, params.clearColor.g, params.clearColor.b,
params.clearColor.a } });
outDescriptor.colorAttachmentCount = mColorAttachmentDescriptors.size();
outDescriptor.colorAttachments = mColorAttachmentDescriptors.data();
params.clearColor.a }
});
} else {
outDescriptor.colorAttachmentCount = customColorTextureViewCount;
for (uint32_t i = 0; i < customColorTextureViewCount; ++i) {
if (customColorTextureViews[i]) {
mColorAttachmentDescriptors.push_back({ .view = customColorTextureViews[i],
@@ -118,61 +117,60 @@ void WebGPURenderTarget::setUpRenderPassAttachments(wgpu::RenderPassDescriptor&
.a = params.clearColor.a } });
}
}
outDescriptor.colorAttachmentCount = mColorAttachmentDescriptors.size(); // Set actual count
outDescriptor.colorAttachments = mColorAttachmentDescriptors.data();
}
outDescriptor.colorAttachmentCount = mColorAttachmentDescriptors.size();
outDescriptor.colorAttachments = mColorAttachmentDescriptors.data();
if(mHasDepthStencilAttachment){
wgpu::TextureView depthStencilViewToUse;
if (mDefaultRenderTarget) {
depthStencilViewToUse = defaultDepthStencilTextureView;
assert_invariant(depthStencilViewToUse);
} else {
if (customDepthTextureView || customStencilTextureView) {
// WebGPU requires combined depth/stencil textures. Ensure consistency for custom RTs.
FILAMENT_CHECK_POSTCONDITION(
customDepthTextureView.Get() == customStencilTextureView.Get() ||
!customDepthTextureView || !customStencilTextureView)
<< "WebGPU backend requires depth and stencil to be in a single texture. "
<< "If both are specified, they must refer to the same resource "
"(wgpu::TextureView).";
depthStencilViewToUse = customDepthTextureView ? customDepthTextureView : customStencilTextureView;
}
}
}
// Depth/Stencil attachment
if (mDefaultRenderTarget) {
if (hasDepth || hasStencil) {
assert_invariant(defaultDepthStencilTextureView);
mDepthStencilAttachmentDescriptor.view = defaultDepthStencilTextureView;
// Depth/Stencil Attachments
if (mHasDepthStencilAttachment) {
wgpu::TextureView depthStencilViewToUse;
if (mDefaultRenderTarget) {
depthStencilViewToUse = defaultDepthStencilTextureView;
if (hasDepth) {
mDepthStencilAttachmentDescriptor.depthLoadOp = depthReadOnly ? wgpu::LoadOp::Undefined :
getLoadOperation(params, TargetBufferFlags::DEPTH);
mDepthStencilAttachmentDescriptor.depthStoreOp = depthReadOnly ? wgpu::StoreOp::Undefined :
getStoreOperation(params, TargetBufferFlags::DEPTH);
mDepthStencilAttachmentDescriptor.depthClearValue = static_cast<float>(params.clearDepth);
mDepthStencilAttachmentDescriptor.depthReadOnly =
(params.readOnlyDepthStencil & RenderPassParams::READONLY_DEPTH) > 0;
} else {
mDepthStencilAttachmentDescriptor.depthLoadOp = wgpu::LoadOp::Undefined;
mDepthStencilAttachmentDescriptor.depthStoreOp = wgpu::StoreOp::Undefined;
mDepthStencilAttachmentDescriptor.depthReadOnly = true;
}
assert_invariant(depthStencilViewToUse);
} else {
if (customDepthTextureView || customStencilTextureView) {
if (hasStencil) {
mDepthStencilAttachmentDescriptor.stencilLoadOp =
getLoadOperation(params, TargetBufferFlags::STENCIL);
mDepthStencilAttachmentDescriptor.stencilStoreOp =
getStoreOperation(params, TargetBufferFlags::STENCIL);
mDepthStencilAttachmentDescriptor.stencilClearValue = params.clearStencil;
mDepthStencilAttachmentDescriptor.stencilReadOnly =
(params.readOnlyDepthStencil & RenderPassParams::READONLY_STENCIL) > 0;
} else {
mDepthStencilAttachmentDescriptor.stencilLoadOp = wgpu::LoadOp::Undefined;
mDepthStencilAttachmentDescriptor.stencilStoreOp = wgpu::StoreOp::Undefined;
mDepthStencilAttachmentDescriptor.stencilReadOnly = true;
FILAMENT_CHECK_POSTCONDITION(
customDepthTextureView.Get() == customStencilTextureView.Get() ||
!customDepthTextureView || !customStencilTextureView)
<< "WebGPU backend requires depth and stencil to be in a single texture. "
<< "If both are specified, they must refer to the same resource "
"(wgpu::TextureView).";
depthStencilViewToUse = customDepthTextureView ? customDepthTextureView : customStencilTextureView;
}
mHasDepthStencilAttachment = true;
}
} else {
if (customDepthTextureView || customStencilTextureView) {
assert_invariant((hasDepth || hasStencil) &&
"Depth or Texture view without a valid texture format");
if (depthStencilViewToUse) {
mDepthStencilAttachmentDescriptor = {};
mDepthStencilAttachmentDescriptor.view =
customDepthTextureView ? customDepthTextureView : customStencilTextureView;
mDepthStencilAttachmentDescriptor.view = depthStencilViewToUse;
if (hasDepth) {
mDepthStencilAttachmentDescriptor.depthLoadOp = depthReadOnly ? wgpu::LoadOp::Undefined :
WebGPURenderTarget::getLoadOperation(params, TargetBufferFlags::DEPTH);
mDepthStencilAttachmentDescriptor.depthStoreOp =
depthReadOnly ? wgpu::StoreOp::Undefined :
WebGPURenderTarget::getStoreOperation(params, TargetBufferFlags::DEPTH);
mDepthStencilAttachmentDescriptor.depthClearValue =
static_cast<float>(params.clearDepth);
mDepthStencilAttachmentDescriptor.depthLoadOp = depthReadOnly ? wgpu::LoadOp::Undefined :getLoadOperation(params, TargetBufferFlags::DEPTH);
mDepthStencilAttachmentDescriptor.depthStoreOp = depthReadOnly ? wgpu::StoreOp::Undefined :getStoreOperation(params, TargetBufferFlags::DEPTH);
mDepthStencilAttachmentDescriptor.depthClearValue = params.clearDepth;
mDepthStencilAttachmentDescriptor.depthReadOnly = depthReadOnly;
} else {
mDepthStencilAttachmentDescriptor.depthLoadOp = wgpu::LoadOp::Undefined;
@@ -181,23 +179,27 @@ void WebGPURenderTarget::setUpRenderPassAttachments(wgpu::RenderPassDescriptor&
}
if (hasStencil) {
mDepthStencilAttachmentDescriptor.stencilLoadOp =
getLoadOperation(params, TargetBufferFlags::STENCIL);
mDepthStencilAttachmentDescriptor.stencilStoreOp =
getStoreOperation(params, TargetBufferFlags::STENCIL);
mDepthStencilAttachmentDescriptor.stencilLoadOp = getLoadOperation(params, TargetBufferFlags::STENCIL);
mDepthStencilAttachmentDescriptor.stencilStoreOp = getStoreOperation(params, TargetBufferFlags::STENCIL);
mDepthStencilAttachmentDescriptor.stencilClearValue = params.clearStencil;
mDepthStencilAttachmentDescriptor.stencilReadOnly =
(params.readOnlyDepthStencil & RenderPassParams::READONLY_STENCIL) > 0;
mDepthStencilAttachmentDescriptor.stencilReadOnly = (params.readOnlyDepthStencil & RenderPassParams::READONLY_STENCIL) > 0;
} else {
mDepthStencilAttachmentDescriptor.stencilLoadOp = wgpu::LoadOp::Undefined;
mDepthStencilAttachmentDescriptor.stencilStoreOp = wgpu::StoreOp::Undefined;
mDepthStencilAttachmentDescriptor.stencilReadOnly = true;
}
mHasDepthStencilAttachment = true;
outDescriptor.depthStencilAttachment = &mDepthStencilAttachmentDescriptor;
} else {
outDescriptor.depthStencilAttachment = nullptr;
mDepthStencilAttachmentDescriptor = {};
}
} else {
outDescriptor.depthStencilAttachment = nullptr;
mDepthStencilAttachmentDescriptor = {};
}
outDescriptor.depthStencilAttachment =
mHasDepthStencilAttachment ? &mDepthStencilAttachmentDescriptor : nullptr;
// descriptor.sampleCount was removed from the core spec. If your webgpu.h still has it,
// and your Dawn version expects it, you might need to set it here based on this->samples.
@@ -34,13 +34,13 @@ public:
WebGPURenderTarget(uint32_t width, uint32_t height, uint8_t samples, uint8_t layerCount,
MRT const& colorAttachments, Attachment const& depthAttachment,
Attachment const& stencilAttachment, TargetBufferFlags targetFlags);
Attachment const& stencilAttachment, TargetBufferFlags const& targetFlags);
// Default constructor for the default render target
WebGPURenderTarget();
// Updated signature: takes resolved views for custom RTs, and default views for default RT
void setUpRenderPassAttachments(wgpu::RenderPassDescriptor& outDescriptor,
void setUpRenderPassAttachments(
wgpu::RenderPassDescriptor& outDescriptor,
RenderPassParams const& params,
// For default render target:
wgpu::TextureView const& defaultColorTextureView,
@@ -48,7 +48,8 @@ public:
wgpu::TextureFormat const& defaultDepthStencilFormat,
// For custom render targets:
wgpu::TextureView const* customColorTextureViews, // Array of views
uint32_t customColorTextureViewCount, wgpu::TextureView const& customDepthTextureView,
uint32_t customColorTextureViewCount,
wgpu::TextureView const& customDepthTextureView,
wgpu::TextureView const& customStencilTextureView,
wgpu::TextureFormat customDepthFormat, wgpu::TextureFormat customStencilFormat);
@@ -56,23 +57,21 @@ public:
[[nodiscard]] uint8_t getSamples() const { return mSamples; }
[[nodiscard]] uint8_t getLayerCount() const { return mLayerCount; }
// Accessors for the driver to get stored attachment info
[[nodiscard]] MRT const& getColorAttachmentInfos() const { return mColorAttachments; }
[[nodiscard]] Attachment const& getDepthAttachmentInfo() const { return mDepthAttachment; }
[[nodiscard]] Attachment const& getStencilAttachmentInfo() const { return mStencilAttachment; }
// Static helpers for load/store operations
[[nodiscard]] static wgpu::LoadOp getLoadOperation(RenderPassParams const& params,
TargetBufferFlags buffer);
[[nodiscard]] static wgpu::StoreOp getStoreOperation(RenderPassParams const& params,
TargetBufferFlags buffer);
[[nodiscard]] TargetBufferFlags getTargets() const { return mTargetFlags; }
TargetBufferFlags mTargetFlags = TargetBufferFlags::NONE;
[[nodiscard]] TargetBufferFlags getTargetFlags() const { return mTargetFlags; }
void setTargetFlags( TargetBufferFlags value) { mTargetFlags = value; }
private:
bool mDefaultRenderTarget = false;
TargetBufferFlags mTargetFlags = TargetBufferFlags::NONE;
uint8_t mSamples = 1;
uint8_t mLayerCount = 1;
@@ -36,8 +36,6 @@ public:
[[nodiscard]] wgpu::TextureFormat getDepthFormat() const { return mDepthFormat; }
[[nodiscard]] bool getNeedStencil() const { return mNeedStencil; }
[[nodiscard]] wgpu::TextureView getCurrentSurfaceTextureView(wgpu::Extent2D const&);
[[nodiscard]] wgpu::TextureView getDepthTextureView() const { return mDepthTextureView; }