Compare commits

...

1 Commits

Author SHA1 Message Date
Powei Feng
4261577724 Add unfilterable 2025-06-16 10:25:13 -07:00
23 changed files with 123 additions and 56 deletions

View File

@@ -474,7 +474,12 @@ constexpr std::string_view to_string(DescriptorType type) noexcept {
enum class DescriptorFlags : uint8_t {
NONE = 0x00,
DYNAMIC_OFFSET = 0x01
// Indicate a UNIFORM_BUFFER will have dynamic offsets.
DYNAMIC_OFFSET = 0x01,
// To indicate a texture/sampler type should be unfiltered.
UNFILTERABLE = 0x02,
};
using descriptor_set_t = uint8_t;

View File

@@ -15,6 +15,7 @@
*/
#include "WebGPUDescriptorSetLayout.h"
#include "WebGPUConstants.h"
#include <backend/DriverEnums.h>
@@ -117,10 +118,10 @@ WebGPUDescriptorSetLayout::WebGPUDescriptorSetLayout(DescriptorSetLayout const&
samplerEntryInfo.binding = samplerEntry.binding;
samplerEntry.visibility = wEntry.visibility;
wEntry.texture.multisampled = isMultiSampledTypeDescriptor(fEntry.type);
// TODO: Set once we have the filtering values
if (isDepthDescriptor(fEntry.type)) {
samplerEntry.sampler.type = wgpu::SamplerBindingType::Comparison;
} else if (isIntDescriptor(fEntry.type)) {
} else if (isIntDescriptor(fEntry.type) ||
any(fEntry.flags & DescriptorFlags::UNFILTERABLE)) {
samplerEntry.sampler.type = wgpu::SamplerBindingType::NonFiltering;
} else {
samplerEntry.sampler.type = wgpu::SamplerBindingType::Filtering;
@@ -151,8 +152,11 @@ WebGPUDescriptorSetLayout::WebGPUDescriptorSetLayout(DescriptorSetLayout const&
if (isDepthDescriptor(fEntry.type)) {
wEntry.texture.sampleType = wgpu::TextureSampleType::Depth;
} else if (isFloatDescriptor(fEntry.type)) {
// TODO: Set once we have the filtering values
wEntry.texture.sampleType = wgpu::TextureSampleType::Float;
if (any(fEntry.flags & DescriptorFlags::UNFILTERABLE)) {
wEntry.texture.sampleType = wgpu::TextureSampleType::UnfilterableFloat;
} else {
wEntry.texture.sampleType = wgpu::TextureSampleType::Float;
}
} else if (isIntDescriptor(fEntry.type)) {
wEntry.texture.sampleType = wgpu::TextureSampleType::Sint;
} else if (isUnsignedIntDescriptor(fEntry.type)) {

View File

@@ -32,6 +32,7 @@
#include "CommandStreamDispatcher.h"
#include "DriverBase.h"
#include "private/backend/Dispatcher.h"
#include "webgpu/WebGPUConstants.h"
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <backend/TargetBufferInfo.h>
@@ -1166,6 +1167,7 @@ void WebGPUDriver::updateDescriptorSetBuffer(Handle<HwDescriptorSet> descriptorS
void WebGPUDriver::updateDescriptorSetTexture(Handle<HwDescriptorSet> descriptorSetHandle,
const backend::descriptor_binding_t binding, Handle<HwTexture> textureHandle,
const SamplerParams params) {
auto bindGroup = handleCast<WebGPUDescriptorSet>(descriptorSetHandle);
auto texture = handleCast<WebGPUTexture>(textureHandle);

View File

@@ -91,16 +91,20 @@ void WebGPURenderTarget::setUpRenderPassAttachments(wgpu::RenderPassDescriptor&
.clearValue = { params.clearColor.r, params.clearColor.g, params.clearColor.b,
params.clearColor.a } });
bool const depthReadonly =
(params.readOnlyDepthStencil & RenderPassParams::READONLY_DEPTH) > 0;
if (defaultDepthStencilTextureView) {
mDepthStencilAttachmentDescriptor = {
.view = defaultDepthStencilTextureView,
.depthLoadOp =
WebGPURenderTarget::getLoadOperation(params, TargetBufferFlags::DEPTH),
.depthStoreOp =
WebGPURenderTarget::getStoreOperation(params, TargetBufferFlags::DEPTH),
.depthLoadOp = depthReadonly ? wgpu::LoadOp::Undefined
: WebGPURenderTarget::getLoadOperation(params,
TargetBufferFlags::DEPTH),
.depthStoreOp = depthReadonly ? wgpu::StoreOp::Undefined
: WebGPURenderTarget::getStoreOperation(params,
TargetBufferFlags::DEPTH),
.depthClearValue = static_cast<float>(params.clearDepth),
.depthReadOnly =
(params.readOnlyDepthStencil & RenderPassParams::READONLY_DEPTH) > 0,
.depthReadOnly = depthReadonly,
.stencilLoadOp = wgpu::LoadOp::Undefined,
.stencilStoreOp = wgpu::StoreOp::Undefined,
.stencilClearValue = params.clearStencil,
@@ -156,14 +160,19 @@ void WebGPURenderTarget::setUpRenderPassAttachments(wgpu::RenderPassDescriptor&
customDepthTextureView ? customDepthTextureView : customStencilTextureView;
if (hasDepth) {
bool const depthReadonly =
(params.readOnlyDepthStencil & RenderPassParams::READONLY_DEPTH) > 0;
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.depthReadOnly =
(params.readOnlyDepthStencil & RenderPassParams::READONLY_DEPTH) > 0;
mDepthStencilAttachmentDescriptor.depthReadOnly = depthReadonly;
} else {
mDepthStencilAttachmentDescriptor.depthLoadOp = wgpu::LoadOp::Undefined;
mDepthStencilAttachmentDescriptor.depthStoreOp = wgpu::StoreOp::Undefined;

View File

@@ -481,6 +481,7 @@ bool ChunkSamplerInterfaceBlock::unflatten(Unflattener& unflattener,
uint8_t fieldType = 0;
uint8_t fieldFormat = 0;
uint8_t fieldPrecision = 0;
bool fieldUnfilterable = false;
bool fieldMultisample = false;
if (!unflattener.read(&fieldName)) {
@@ -503,6 +504,10 @@ bool ChunkSamplerInterfaceBlock::unflatten(Unflattener& unflattener,
return false;
}
if (!unflattener.read(&fieldUnfilterable)) {
return false;
}
if (!unflattener.read(&fieldMultisample)) {
return false;
}
@@ -512,6 +517,7 @@ bool ChunkSamplerInterfaceBlock::unflatten(Unflattener& unflattener,
SamplerInterfaceBlock::Type(fieldType),
SamplerInterfaceBlock::Format(fieldFormat),
SamplerInterfaceBlock::Precision(fieldPrecision),
fieldUnfilterable,
fieldMultisample);
}

View File

@@ -8,7 +8,8 @@ material {
{
type : sampler2d,
name : depth,
precision: high
precision: high,
unfilterable: true
},
{
type : float,

View File

@@ -4,7 +4,8 @@ material {
{
type : sampler2d,
name : depth,
precision: medium
precision: medium,
unfilterable: true
},
{
type : float4,

View File

@@ -9,7 +9,8 @@ material {
{
type : sampler2d,
name : depth,
precision: high
precision: high,
unfilterable: true
},
{
type : float4,
@@ -77,4 +78,3 @@ fragment {
postProcess.color = color;
}
}

View File

@@ -9,7 +9,8 @@ material {
{
type : sampler2d,
name : depth,
precision: medium
precision: medium,
unfilterable: true
},
{
type : float2,

View File

@@ -9,7 +9,8 @@ material {
{
type : sampler2d,
name : depth,
precision: medium
precision: medium,
unfilterable: true
},
{
type : float2,

View File

@@ -5,7 +5,8 @@ material {
type : sampler2d,
name : depth,
precision: high,
multisample : true
multisample : true,
unfilterable: true
}
],
outputs : [

View File

@@ -4,7 +4,8 @@ material {
{
type : sampler2d,
name : depth,
precision: high
precision: high,
unfilterable: true
},
{
type : mat4,

View File

@@ -4,7 +4,8 @@ material {
{
type : sampler2d,
name : depth,
precision: high
precision: high,
unfilterable: true
},
{
type : mat4,

View File

@@ -4,7 +4,8 @@ material {
{
type : sampler2d,
name : depth,
precision: high
precision: high,
unfilterable: true
}
],
variables : [

View File

@@ -4,7 +4,8 @@ material {
{
type : sampler2d,
name : depth,
precision: high
precision: high,
unfilterable: true
},
{
type : mat4,

View File

@@ -4,7 +4,8 @@ material {
{
type : sampler2d,
name : depth,
precision: high
precision: high,
unfilterable: true
},
{
type : mat4,

View File

@@ -61,6 +61,7 @@ public:
Type type; // type of this sampler
Format format; // format of this sampler
Precision precision; // precision of this sampler
bool unfilterable; // whether the sampling should be unfiltered.
bool multisample; // multisample capable
ShaderStageFlags stages; // stages the sampler can be accessed from
};
@@ -83,6 +84,7 @@ public:
Type type; // type of this sampler
Format format; // format of this sampler
Precision precision; // precision of this sampler
bool unfilterable = false; // whether the sampling should be unfiltered.
bool multisample = false; // multisample capable
ShaderStageFlags stages =
ShaderStageFlags::ALL_SHADER_STAGE_FLAGS; // shader stages using this sampler
@@ -95,7 +97,8 @@ public:
// Add a sampler
Builder& add(std::string_view samplerName, Binding binding, Type type, Format format,
Precision precision = Precision::MEDIUM, bool multisample = false,
Precision precision = Precision::MEDIUM, bool unfilterable = false,
bool multisample = false,
ShaderStageFlags stages = ShaderStageFlags::ALL_SHADER_STAGE_FLAGS) noexcept;
// Add multiple samplers

View File

@@ -50,12 +50,12 @@ SamplerInterfaceBlock::Builder::stageFlags(backend::ShaderStageFlags stageFlags)
}
SamplerInterfaceBlock::Builder& SamplerInterfaceBlock::Builder::add(std::string_view samplerName,
Binding binding, Type type, Format format, Precision precision, bool multisample,
ShaderStageFlags stages) noexcept {
Binding binding, Type type, Format format, Precision precision, bool unfilterable,
bool multisample, ShaderStageFlags stages) noexcept {
mEntries.push_back({
{ samplerName.data(), samplerName.size() }, // name
{ }, // uniform name
binding, type, format, precision, multisample, stages });
{ samplerName.data(), samplerName.size() }, // name
{}, // uniform name
binding, type, format, precision, unfilterable, multisample, stages });
return *this;
}
@@ -65,8 +65,9 @@ SamplerInterfaceBlock SamplerInterfaceBlock::Builder::build() {
SamplerInterfaceBlock::Builder& SamplerInterfaceBlock::Builder::add(
std::initializer_list<ListEntry> list) noexcept {
for (auto& e : list) {
add(e.name, e.binding, e.type, e.format, e.precision, e.multisample, e.stages);
for (auto& e: list) {
add(e.name, e.binding, e.type, e.format, e.precision, e.unfilterable, e.multisample,
e.stages);
}
return *this;
}

View File

@@ -323,8 +323,8 @@ public:
*/
MaterialBuilder& parameter(const char* name, SamplerType samplerType,
SamplerFormat format = SamplerFormat::FLOAT,
ParameterPrecision precision = ParameterPrecision::DEFAULT, bool multisample = false,
const char* transformName = "",
ParameterPrecision precision = ParameterPrecision::DEFAULT, bool unfilterable = false,
bool multisample = false, const char* transformName = "",
ShaderStageFlags stages = ShaderStageFlags::ALL_SHADER_STAGE_FLAGS);
MaterialBuilder& buffer(filament::BufferInterfaceBlock bib);
@@ -658,9 +658,17 @@ public:
// Sampler
Parameter(const char* paramName, SamplerType t, SamplerFormat f, ParameterPrecision p,
bool ms, const char* tn, ShaderStageFlags s)
: name(paramName), size(1), precision(p), samplerType(t), format(f),
parameterType(SAMPLER), multisample(ms), transformName(tn), stages(s) { }
bool unfilterable, bool ms, const char* tn, ShaderStageFlags s)
: name(paramName),
size(1),
precision(p),
samplerType(t),
format(f),
parameterType(SAMPLER),
unfilterable(unfilterable),
multisample(ms),
transformName(tn),
stages(s) {}
// Uniform
Parameter(const char* paramName, UniformType t, size_t typeSize, ParameterPrecision p)
@@ -676,8 +684,9 @@ public:
ParameterPrecision precision;
SamplerType samplerType;
SubpassType subpassType;
SamplerFormat format;
bool multisample;
SamplerFormat format = SamplerFormat::INT; // 0 of the enum
bool unfilterable = false;
bool multisample = false;
utils::CString transformName;
ShaderStageFlags stages;
enum {

View File

@@ -300,19 +300,19 @@ MaterialBuilder& MaterialBuilder::parameter(const char* name, UniformType const
return parameter(name, 1, type, precision);
}
MaterialBuilder& MaterialBuilder::parameter(const char* name, SamplerType samplerType,
SamplerFormat format, ParameterPrecision precision, bool multisample,
SamplerFormat format, ParameterPrecision precision, bool unfilterable, bool multisample,
const char* transformName, ShaderStageFlags stages) {
FILAMENT_CHECK_PRECONDITION(!multisample ||
(format != SamplerFormat::SHADOW &&
(samplerType == SamplerType::SAMPLER_2D ||
samplerType == SamplerType::SAMPLER_2D_ARRAY)))
FILAMENT_CHECK_PRECONDITION(
!multisample || (format != SamplerFormat::SHADOW &&
(samplerType == SamplerType::SAMPLER_2D ||
samplerType == SamplerType::SAMPLER_2D_ARRAY)))
<< "multisample samplers only possible with SAMPLER_2D or SAMPLER_2D_ARRAY,"
" as long as type is not SHADOW";
FILAMENT_CHECK_POSTCONDITION(mParameterCount < MAX_PARAMETERS_COUNT) << "Too many parameters";
mParameters[mParameterCount++] = { name, samplerType, format, precision, multisample, transformName, stages };
mParameters[mParameterCount++] = { name, samplerType, format, precision, unfilterable,
multisample, transformName, stages };
return *this;
}
@@ -639,10 +639,12 @@ void MaterialBuilder::prepareToBuild(MaterialInfo& info) noexcept {
assert_invariant(!param.isSubpass());
if (param.isSampler()) {
sbb.add({ param.name.data(), param.name.size() }, binding, param.samplerType,
param.format, param.precision, param.multisample, param.stages);
param.format, param.precision, param.unfilterable, param.multisample,
param.stages);
if (!param.transformName.empty()) {
ibb.add({{{ param.transformName.data(), param.transformName.size() }, uint8_t(binding),
0, UniformType::MAT3, Precision::DEFAULT, FeatureLevel::FEATURE_LEVEL_0 }});
ibb.add({ { { param.transformName.data(), param.transformName.size() },
uint8_t(binding), 0, UniformType::MAT3, Precision::DEFAULT,
FeatureLevel::FEATURE_LEVEL_0 } });
}
binding++;
} else if (param.isUniform()) {

View File

@@ -77,6 +77,7 @@ void MaterialSamplerInterfaceBlockChunk::flatten(Flattener& f) {
f.writeUint8(static_cast<uint8_t>(sInfo.type));
f.writeUint8(static_cast<uint8_t>(sInfo.format));
f.writeUint8(static_cast<uint8_t>(sInfo.precision));
f.writeBool(sInfo.unfilterable);
f.writeBool(sInfo.multisample);
}
}
@@ -230,7 +231,11 @@ void MaterialDescriptorSetLayoutChunk::flatten(Flattener& f) {
f.writeUint8(uint8_t(descriptor_sets::getDescriptorType(entry.type, entry.format)));
f.writeUint8(uint8_t(entry.stages));
f.writeUint8(entry.binding);
f.writeUint8(uint8_t(DescriptorFlags::NONE));
if (entry.unfilterable) {
f.writeUint8(uint8_t(DescriptorFlags::UNFILTERABLE));
} else {
f.writeUint8(uint8_t(DescriptorFlags::NONE));
}
f.writeUint16(0);
}
}

View File

@@ -383,8 +383,10 @@ ViewerGui::ViewerGui(filament::Engine* engine, filament::Scene* scene, filament:
mSettings.view.vsmShadowOptions.anisotropy = 0;
mSettings.view.dithering = Dithering::TEMPORAL;
mSettings.view.antiAliasing = AntiAliasing::FXAA;
mSettings.view.msaa = { .enabled = true, .sampleCount = 4 };
mSettings.view.ssao.enabled = true;
// mSettings.view.msaa = { .enabled = true, .sampleCount = 4 };
mSettings.view.msaa = { .enabled = false, .sampleCount = 4 };
// mSettings.view.ssao.enabled = true;
mSettings.view.ssao.enabled = false;
mSettings.view.bloom.enabled = true;
DebugRegistry& debug = mEngine->getDebugRegistry();

View File

@@ -185,6 +185,13 @@ static bool processParameter(MaterialBuilder& builder, const JsonishObject& json
}
}
const JsonishValue* unfilterableValue = jsonObject.getValue("unfilterable");
if (unfilterableValue) {
if (unfilterableValue->getType() != JsonishValue::BOOL) {
std::cerr << "parameters: unfilterable must be a BOOL." << std::endl;
return false;
}
}
const JsonishValue* multiSampleValue = jsonObject.getValue("multisample");
if (multiSampleValue) {
if (multiSampleValue->getType() != JsonishValue::BOOL) {
@@ -260,6 +267,7 @@ static bool processParameter(MaterialBuilder& builder, const JsonishObject& json
auto precision = precisionValue ? Enums::toEnum<ParameterPrecision>(
precisionValue->toJsonString()->getString()) : ParameterPrecision::DEFAULT;
auto unfilterable = unfilterableValue ? unfilterableValue->toJsonBool()->getBool() : false;
auto multisample = multiSampleValue ? multiSampleValue->toJsonBool()->getBool() : false;
if (stages == ShaderStageFlags::NONE) {
@@ -276,10 +284,11 @@ static bool processParameter(MaterialBuilder& builder, const JsonishObject& json
return false;
}
auto transformName = transformNameValue->toJsonString()->getString();
builder.parameter(nameString.c_str(), type, format, precision, multisample,
transformName.c_str(), stages);
builder.parameter(nameString.c_str(), type, format, precision, unfilterable,
multisample, transformName.c_str(), stages);
} else {
builder.parameter(nameString.c_str(), type, format, precision, multisample, "", stages);
builder.parameter(nameString.c_str(), type, format, precision, unfilterable,
multisample, "", stages);
}
} else {