Compare commits

...

1 Commits

Author SHA1 Message Date
Matt Hoffman
667da2aabe Create a helper for setting texture uniforms in backend tests.
BUGS=[407799122]
2025-04-14 16:06:03 -05:00
6 changed files with 83 additions and 53 deletions

View File

@@ -23,6 +23,14 @@ namespace test {
using namespace filament::backend;
filament::backend::descriptor_binding_t TextureBindingConfig::getBinding() const {
return binding.value_or(0);
}
filament::backend::SamplerParams TextureBindingConfig::getParams() const {
return samplerParams.value_or(SamplerParams{});
}
Shader::Shader(DriverApi& api, Cleanup& cleanup, ShaderConfig config) : mCleanup(cleanup) {
utils::FixedCapacityVector<DescriptorSetLayoutBinding> kLayouts(config.uniforms.size());
for (unsigned char i = 0; i < config.uniforms.size(); ++i) {
@@ -57,6 +65,19 @@ Shader::Shader(DriverApi& api, Cleanup& cleanup, ShaderConfig config) : mCleanup
mDescriptorSetLayout = cleanup.add(
api.createDescriptorSetLayout(DescriptorSetLayout{ kLayouts }));
mDefaultDescriptorSet = createDescriptorSet(api);
}
void Shader::updateTextureUniform(filament::backend::DriverApi& api,
TextureBindingConfig config) const {
DescriptorSetHandle descriptorSet = config.descriptorSet.value_or(mDefaultDescriptorSet);
api.updateDescriptorSetTexture(descriptorSet, config.getBinding(), config.textureHandle,
config.getParams());
if (config.alsoBindToSet.has_value()) {
api.bindDescriptorSet(descriptorSet, *config.alsoBindToSet, {});
}
}
filament::backend::DescriptorSetHandle Shader::createDescriptorSet(DriverApi& api) const {

View File

@@ -61,6 +61,18 @@ struct UniformBindingConfig {
ResolvedUniformBindingConfig resolve();
};
struct TextureBindingConfig {
filament::backend::TextureHandle textureHandle;
std::optional<filament::backend::DescriptorSetHandle> descriptorSet;
std::optional<filament::backend::descriptor_binding_t> binding;
std::optional<filament::backend::SamplerParams> samplerParams;
// If present then the call to update the texture will also bind the descriptor set.
std::optional<filament::backend::descriptor_set_t> alsoBindToSet;
filament::backend::descriptor_binding_t getBinding() const;
filament::backend::SamplerParams getParams() const;
};
class Shader {
public:
// All graphics resources have their lifetime controlled by the Cleanup and not this object.
@@ -86,17 +98,20 @@ public:
void bindUniform(filament::backend::DriverApi& api,
filament::backend::Handle<filament::backend::HwBufferObject> hwBuffer,
UniformBindingConfig config) const;
filament::backend::ProgramHandle getProgram() const;
filament::backend::DescriptorSetLayoutHandle getDescriptorSetLayout() const;
void updateTextureUniform(filament::backend::DriverApi& api, TextureBindingConfig config) const;
filament::backend::DescriptorSetHandle createDescriptorSet(
filament::backend::DriverApi& api) const;
filament::backend::ProgramHandle getProgram() const;
filament::backend::DescriptorSetLayoutHandle getDescriptorSetLayout() const;
protected:
Cleanup& mCleanup;
filament::backend::ProgramHandle mProgram;
filament::backend::DescriptorSetLayoutHandle mDescriptorSetLayout;
// Used whenever the caller doesn't provide a descriptor set.
filament::backend::DescriptorSetHandle mDefaultDescriptorSet;
};
template<typename UniformType>
@@ -133,12 +148,8 @@ void Shader::bindUniform(filament::backend::DriverApi& api,
UniformBindingConfig config) const {
auto resolvedConfig = config.resolve<UniformType>();
filament::backend::DescriptorSetHandle descriptorSet;
if (resolvedConfig.descriptorSet.has_value()) {
descriptorSet = *resolvedConfig.descriptorSet;
} else {
descriptorSet = createDescriptorSet(api);
}
filament::backend::DescriptorSetHandle descriptorSet =
resolvedConfig.descriptorSet.value_or(mDefaultDescriptorSet);
api.updateDescriptorSetBuffer(descriptorSet, resolvedConfig.binding, hwBuffer, 0,
resolvedConfig.bufferSize);

View File

@@ -198,12 +198,14 @@ TEST_F(BackendTest, FeedbackLoops) {
params.viewport.width = kTexWidth >> targetLevel;
params.viewport.height = kTexHeight >> targetLevel;
// Each pass needs its own descriptor set.
auto descriptorSet = shader.createDescriptorSet(api);
auto textureView = passCleanup.add(api.createTextureView(texture, sourceLevel, 1));
api.updateDescriptorSetTexture(descriptorSet, 0, textureView, {
.filterMag = SamplerMagFilter::LINEAR,
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST
});
shader.updateTextureUniform(api,
TextureBindingConfig{ .textureHandle = textureView,
.descriptorSet = descriptorSet,
.samplerParams = SamplerParams{ .filterMag = SamplerMagFilter::LINEAR,
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST } });
UniformBindingConfig uniformBinding{
.binding = 1,

View File

@@ -329,12 +329,14 @@ TEST_F(LoadImageTest, UpdateImage2D) {
checkerboardPixelBuffer(t.pixelFormat, t.pixelType, 512, t.bufferPadding));
}
// Each loop needs its own descriptor set.
DescriptorSetHandle descriptorSet = shader.createDescriptorSet(api);
api.updateDescriptorSetTexture(descriptorSet, 0, texture, {
.filterMag = SamplerMagFilter::NEAREST,
.filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST });
api.bindDescriptorSet(descriptorSet, 1, {});
shader.updateTextureUniform(api,
TextureBindingConfig{ .textureHandle = texture,
.descriptorSet = descriptorSet,
.samplerParams = SamplerParams{ .filterMag = SamplerMagFilter::NEAREST,
.filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST },
.alsoBindToSet = 1 });
renderTriangle({{ DescriptorSetLayoutHandle{}, shader.getDescriptorSetLayout() }},
defaultRenderTarget, swapChain, shader.getProgram());
@@ -405,13 +407,11 @@ TEST_F(LoadImageTest, UpdateImageSRGB) {
api.beginFrame(0, 0, 0);
// Update samplers.
DescriptorSetHandle descriptorSet = shader.createDescriptorSet(api);
api.updateDescriptorSetTexture(descriptorSet, 0, texture, {
.filterMag = SamplerMagFilter::LINEAR,
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST
});
api.bindDescriptorSet(descriptorSet, 1, {});
shader.updateTextureUniform(api,
TextureBindingConfig{ .textureHandle = texture,
.samplerParams = SamplerParams{ .filterMag = SamplerMagFilter::LINEAR,
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST },
.alsoBindToSet = 1 });
renderTriangle({{ DescriptorSetLayoutHandle{}, shader.getDescriptorSetLayout() }},
defaultRenderTarget, swapChain, shader.getProgram());
@@ -467,13 +467,11 @@ TEST_F(LoadImageTest, UpdateImageMipLevel) {
api.beginFrame(0, 0, 0);
// Update samplers.
DescriptorSetHandle descriptorSet = shader.createDescriptorSet(api);
api.updateDescriptorSetTexture(descriptorSet, 0, texture, {
.filterMag = SamplerMagFilter::LINEAR,
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST
});
api.bindDescriptorSet(descriptorSet, 1, {});
shader.updateTextureUniform(api,
TextureBindingConfig{ .textureHandle = texture,
.samplerParams = SamplerParams{ .filterMag = SamplerMagFilter::LINEAR,
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST },
.alsoBindToSet = 1 });
renderTriangle({{ DescriptorSetLayoutHandle{}, shader.getDescriptorSetLayout() }},
defaultRenderTarget, swapChain, shader.getProgram());
@@ -541,13 +539,11 @@ TEST_F(LoadImageTest, UpdateImage3D) {
api.beginFrame(0, 0, 0);
// Update samplers.
DescriptorSetHandle descriptorSet = shader.createDescriptorSet(api);
api.updateDescriptorSetTexture(descriptorSet, 0, texture, {
.filterMag = SamplerMagFilter::LINEAR,
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST
});
api.bindDescriptorSet(descriptorSet, 1, {});
shader.updateTextureUniform(api,
TextureBindingConfig{ .textureHandle = texture,
.samplerParams = SamplerParams{ .filterMag = SamplerMagFilter::LINEAR,
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST },
.alsoBindToSet = 1 });
renderTriangle({{ DescriptorSetLayoutHandle{}, shader.getDescriptorSetLayout() }},
defaultRenderTarget, swapChain, shader.getProgram());

View File

@@ -171,11 +171,12 @@ TEST_F(BackendTest, TextureViewLod) {
state.rasterState.culling = CullingMode::NONE;
DescriptorSetHandle descriptorSet13 = texturedShader.createDescriptorSet(api);
api.updateDescriptorSetTexture(descriptorSet13, 0, texture13, {
.filterMag = SamplerMagFilter::NEAREST,
.filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST });
api.bindDescriptorSet(descriptorSet13, 0, {});
texturedShader.updateTextureUniform(api,
TextureBindingConfig{ .textureHandle = texture13,
.descriptorSet = descriptorSet13,
.samplerParams = SamplerParams{ .filterMag = SamplerMagFilter::NEAREST,
.filterMin = SamplerMinFilter::NEAREST },
.alsoBindToSet = 0 });
// Render a triangle to the screen, sampling from mip level 1.
// Because the min level is 1, the result color should be the white triangle drawn in the
@@ -189,11 +190,12 @@ TEST_F(BackendTest, TextureViewLod) {
auto texture22 = cleanup.add(api.createTextureView(texture, 2, 2));
DescriptorSetHandle descriptorSet22 = texturedShader.createDescriptorSet(api);
api.updateDescriptorSetTexture(descriptorSet22, 0, texture22, {
.filterMag = SamplerMagFilter::NEAREST,
.filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST });
api.bindDescriptorSet(descriptorSet22, 0, {});
texturedShader.updateTextureUniform(api,
TextureBindingConfig{ .textureHandle = texture22,
.descriptorSet = descriptorSet22,
.samplerParams = SamplerParams{ .filterMag = SamplerMagFilter::NEAREST,
.filterMin = SamplerMinFilter::NEAREST },
.alsoBindToSet = 0 });
// Render a second, smaller, triangle, again sampling from mip level 1.
// This triangle should be yellow striped.

View File

@@ -84,14 +84,12 @@ TEST_F(BackendTest, RenderExternalImageWithoutSet) {
state.rasterState.depthFunc = RasterState::DepthFunc::A;
state.rasterState.culling = CullingMode::NONE;
DescriptorSetHandle descriptorSet = shader.createDescriptorSet(api);
api.startCapture(0);
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
api.updateDescriptorSetTexture(descriptorSet, 0, texture, {});
api.bindDescriptorSet(descriptorSet, 1, {});
shader.updateTextureUniform(api,
TextureBindingConfig{ .textureHandle = texture, .alsoBindToSet = 1 });
// Render a triangle.
api.beginRenderPass(defaultRenderTarget, params);