Compare commits
1 Commits
ImmediateG
...
mhoff/text
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
667da2aabe |
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user