Compare commits
1 Commits
ma/1.70.0
...
bjd/backen
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ed10d77de |
@@ -36,14 +36,16 @@
|
||||
namespace test {
|
||||
|
||||
ScreenshotParams::ScreenshotParams(int width, int height, std::string fileName,
|
||||
uint32_t expectedHash, bool isSrgb, int numAllowedDeviations, int pixelMatchThreshold)
|
||||
uint32_t expectedHash, bool isSrgb, int numAllowedDeviations, int pixelMatchThreshold,
|
||||
std::optional<float> forceAlphaValue)
|
||||
: mWidth(width),
|
||||
mHeight(height),
|
||||
mIsSrgb(isSrgb),
|
||||
mExpectedPixelHash(expectedHash),
|
||||
mFileName(std::move(fileName)),
|
||||
mAllowedPixelDeviations(numAllowedDeviations),
|
||||
mPixelMatchThreshold(pixelMatchThreshold) {}
|
||||
mPixelMatchThreshold(pixelMatchThreshold),
|
||||
mForceAlphaValue(forceAlphaValue) {}
|
||||
|
||||
int ScreenshotParams::width() const {
|
||||
return mWidth;
|
||||
@@ -61,6 +63,10 @@ uint32_t ScreenshotParams::expectedHash() const {
|
||||
return mExpectedPixelHash;
|
||||
}
|
||||
|
||||
std::optional<float> ScreenshotParams::forceAlphaValue() const {
|
||||
return mForceAlphaValue;
|
||||
}
|
||||
|
||||
std::filesystem::path ScreenshotParams::actualDirectoryPath() {
|
||||
return BackendTest::binaryDirectory().append("images/actual_images");
|
||||
}
|
||||
@@ -177,9 +183,29 @@ RenderTargetDump::RenderTargetDump(filament::backend::DriverApi& api,
|
||||
const size_t size = mInternal->params.width() * mInternal->params.height() * 4;
|
||||
mInternal->bytes.resize(size);
|
||||
|
||||
using filament::backend::PixelDataFormat;
|
||||
using filament::backend::PixelDataType;
|
||||
constexpr PixelDataFormat readPixelFormat = PixelDataFormat::RGBA;
|
||||
constexpr PixelDataType readPixelType = PixelDataType::UBYTE;
|
||||
|
||||
auto cb = [](void* buffer, size_t size, void* user) {
|
||||
auto* internal = static_cast<RenderTargetDump::Internal*>(user);
|
||||
internal->bytesFilled = true;
|
||||
|
||||
// If requested, we overwrite the alpha value.
|
||||
// If the read pixel format or type changes, this logic must be updated.
|
||||
static_assert(readPixelFormat == PixelDataFormat::RGBA);
|
||||
static_assert(readPixelType == PixelDataType::UBYTE);
|
||||
if (auto alphaValue = internal->params.forceAlphaValue(); alphaValue) {
|
||||
const int pixelCount = internal->params.width() * internal->params.height();
|
||||
const int channels = 4;
|
||||
constexpr int kAlphaChannel = 3;
|
||||
uint8_t* pixelBuffer = static_cast<uint8_t*>(buffer);
|
||||
for (int p = 0; p < pixelCount; p++) {
|
||||
pixelBuffer[p * channels + kAlphaChannel] = *alphaValue * 255.0f;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FILAMENT_IOS
|
||||
image::LinearImage image;
|
||||
if (internal->params.isSrgb()) {
|
||||
@@ -203,9 +229,8 @@ RenderTargetDump::RenderTargetDump(filament::backend::DriverApi& api,
|
||||
filePath);
|
||||
#endif
|
||||
};
|
||||
filament::backend::PixelBufferDescriptor pb(mInternal->bytes.data(), size,
|
||||
filament::backend::PixelDataFormat::RGBA, filament::backend::PixelDataType::UBYTE, cb,
|
||||
(void*)mInternal.get());
|
||||
filament::backend::PixelBufferDescriptor pb(mInternal->bytes.data(), size, readPixelFormat,
|
||||
readPixelType, cb, (void*) mInternal.get());
|
||||
api.readPixels(renderTarget, 0, 0, mInternal->params.width(), mInternal->params.height(),
|
||||
std::move(pb));
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
@@ -45,12 +46,72 @@ class ScreenshotParams {
|
||||
public:
|
||||
// TODO(b/422804941): Add a set of environments where this test should use a different golden.
|
||||
ScreenshotParams(int width, int height, std::string fileName, uint32_t expectedPixelHash,
|
||||
bool isSrgb = false, int numAllowedDeviations = 0, int pixelMatchThreshold = 0);
|
||||
bool isSrgb = false, int numAllowedDeviations = 0, int pixelMatchThreshold = 0,
|
||||
std::optional<float> forceAlphaValue = std::nullopt);
|
||||
|
||||
class Builder {
|
||||
public:
|
||||
Builder& width(int width) {
|
||||
mWidth = width;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& height(int height) {
|
||||
mHeight = height;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& fileName(std::string fileName) {
|
||||
mFileName = fileName;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& expectedPixelHash(uint32_t pixelHash) {
|
||||
mExpectedPixelHash = pixelHash;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& isSrgb(bool isSrgb) {
|
||||
mIsSrgb = isSrgb;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& numAllowedDeviations(int numAllowedDeviations) {
|
||||
mNumAllowedDeviations = numAllowedDeviations;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& pixelMatchTheshold(int pixelMatchTheshold) {
|
||||
mPixelMatchThreshold = pixelMatchTheshold;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& forceAlphaValue(float alphaValue) {
|
||||
mForceAlphaValue = alphaValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ScreenshotParams build() {
|
||||
return ScreenshotParams(mWidth, mHeight, mFileName, mExpectedPixelHash, mIsSrgb,
|
||||
mNumAllowedDeviations, mPixelMatchThreshold, mForceAlphaValue);
|
||||
}
|
||||
|
||||
private:
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
std::string mFileName;
|
||||
uint32_t mExpectedPixelHash;
|
||||
bool mIsSrgb;
|
||||
int mNumAllowedDeviations;
|
||||
int mPixelMatchThreshold;
|
||||
std::optional<float> mForceAlphaValue;
|
||||
};
|
||||
|
||||
int width() const;
|
||||
int height() const;
|
||||
bool isSrgb() const;
|
||||
uint32_t expectedHash() const;
|
||||
std::optional<float> forceAlphaValue() const;
|
||||
|
||||
static std::filesystem::path actualDirectoryPath();
|
||||
std::string actualFileName() const;
|
||||
@@ -70,6 +131,7 @@ private:
|
||||
std::string mFileName;
|
||||
int mAllowedPixelDeviations;
|
||||
int mPixelMatchThreshold;
|
||||
std::optional<float> mForceAlphaValue;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -158,9 +158,19 @@ layout(binding = 0, set = 0) uniform Params {
|
||||
} params;
|
||||
)";
|
||||
}
|
||||
case ShaderUniformType::Sampler: {
|
||||
case ShaderUniformType::Sampler2D: {
|
||||
return R"(
|
||||
layout(location = 0, set = 0) uniform sampler2D test_tex;
|
||||
)";
|
||||
}
|
||||
case ShaderUniformType::ISampler2D: {
|
||||
return R"(
|
||||
layout(location = 0, set = 0) uniform isampler2D test_tex;
|
||||
)";
|
||||
}
|
||||
case ShaderUniformType::USampler2D: {
|
||||
return R"(
|
||||
layout(location = 0, set = 0) uniform usampler2D test_tex;
|
||||
)";
|
||||
}
|
||||
default:
|
||||
@@ -179,7 +189,7 @@ std::vector<UniformConfig> GetUniformConfig(ShaderUniformType type) {
|
||||
case ShaderUniformType::SimpleWithPadding: {
|
||||
return {{ "Params" }};
|
||||
}
|
||||
case ShaderUniformType::Sampler: {
|
||||
case ShaderUniformType::Sampler2D: {
|
||||
filament::SamplerInterfaceBlock::SamplerInfo samplerInfo{
|
||||
"backend_test", "test_tex", 0,
|
||||
SamplerType::SAMPLER_2D, SamplerFormat::FLOAT, Precision::HIGH, false };
|
||||
@@ -187,6 +197,22 @@ std::vector<UniformConfig> GetUniformConfig(ShaderUniformType type) {
|
||||
"test_tex", DescriptorType::SAMPLER_2D_FLOAT, samplerInfo
|
||||
}};
|
||||
}
|
||||
case ShaderUniformType::ISampler2D: {
|
||||
filament::SamplerInterfaceBlock::SamplerInfo samplerInfo{
|
||||
"backend_test", "test_tex", 0,
|
||||
SamplerType::SAMPLER_2D, SamplerFormat::INT, Precision::HIGH, false };
|
||||
return {{
|
||||
"test_tex", DescriptorType::SAMPLER_2D_INT, samplerInfo
|
||||
}};
|
||||
}
|
||||
case ShaderUniformType::USampler2D: {
|
||||
filament::SamplerInterfaceBlock::SamplerInfo samplerInfo{
|
||||
"backend_test", "test_tex", 0,
|
||||
SamplerType::SAMPLER_2D, SamplerFormat::UINT, Precision::HIGH, false };
|
||||
return {{
|
||||
"test_tex", DescriptorType::SAMPLER_2D_INT, samplerInfo
|
||||
}};
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
@@ -252,4 +278,4 @@ std::string SharedShaders::getFragmentShaderText(FragmentShaderType fragment,
|
||||
return fragmentText->withUniform(*uniformText);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace test
|
||||
|
||||
@@ -23,7 +23,9 @@ enum class ShaderUniformType : uint8_t {
|
||||
None,
|
||||
Simple,
|
||||
SimpleWithPadding,
|
||||
Sampler,
|
||||
Sampler2D,
|
||||
ISampler2D,
|
||||
USampler2D,
|
||||
};
|
||||
|
||||
struct SimpleMaterialParams {
|
||||
|
||||
@@ -287,9 +287,9 @@ TEST_F(LoadImageTest, UpdateImage2D) {
|
||||
// Test integer format uploads.
|
||||
// TODO: These cases fail on OpenGL and Vulkan.
|
||||
// TODO: These cases now also fail on Metal, but at some point previously worked.
|
||||
testCases.emplace_back("RGB_INTEGER UBYTE to RGB8UI", PixelDataFormat::RGB_INTEGER, PixelDataType::UBYTE, TextureFormat::RGB8UI);
|
||||
testCases.emplace_back("RGB_INTEGER USHORT to RGB16UI", PixelDataFormat::RGB_INTEGER, PixelDataType::USHORT, TextureFormat::RGB16UI);
|
||||
testCases.emplace_back("RGB_INTEGER INT to RGB32I", PixelDataFormat::RGB_INTEGER, PixelDataType::INT, TextureFormat::RGB32I);
|
||||
testCases.emplace_back("RGB_INTEGER UBYTE to RGB8UI", PixelDataFormat::RGB_INTEGER, PixelDataType::UBYTE, TextureFormat::RGB8UI);
|
||||
testCases.emplace_back("RGB_INTEGER USHORT to RGB16UI", PixelDataFormat::RGB_INTEGER, PixelDataType::USHORT, TextureFormat::RGB16UI);
|
||||
testCases.emplace_back("RGB_INTEGER INT to RGB32I", PixelDataFormat::RGB_INTEGER, PixelDataType::INT, TextureFormat::RGB32I);
|
||||
|
||||
// Test uploads with buffer padding.
|
||||
// TODO: Vulkan crashes with "Assertion failed: (offset + size <= allocationSize)"
|
||||
@@ -319,14 +319,23 @@ TEST_F(LoadImageTest, UpdateImage2D) {
|
||||
auto defaultRenderTarget = cleanup.add(api.createDefaultRenderTarget(0));
|
||||
|
||||
// Create a program.
|
||||
filament::SamplerInterfaceBlock::SamplerInfo samplerInfo { "test", "tex", 0,
|
||||
SamplerType::SAMPLER_2D, getSamplerFormat(t.textureFormat), Precision::HIGH, false };
|
||||
|
||||
std::string const fragment = getFormattedFragment(fragmentTemplate, t.textureFormat);
|
||||
Shader shader(api, cleanup, ShaderConfig{
|
||||
.vertexShader = mVertexShader,
|
||||
.fragmentShader= fragment,
|
||||
.uniforms = {{"test_tex", DescriptorType::SAMPLER_2D_FLOAT, samplerInfo}}
|
||||
ShaderUniformType uniformType;
|
||||
switch (getSamplerFormat(t.textureFormat)) {
|
||||
case SamplerFormat::FLOAT:
|
||||
case SamplerFormat::SHADOW: // not used for tests, but must cover all cases
|
||||
uniformType = ShaderUniformType::Sampler2D;
|
||||
break;
|
||||
case SamplerFormat::INT:
|
||||
uniformType = ShaderUniformType::ISampler2D;
|
||||
break;
|
||||
case SamplerFormat::UINT:
|
||||
uniformType = ShaderUniformType::USampler2D;
|
||||
break;
|
||||
}
|
||||
Shader shader = SharedShaders::makeShader(api, cleanup, {
|
||||
.mVertexType = VertexShaderType::Textured,
|
||||
.mFragmentType = FragmentShaderType::Textured,
|
||||
.mUniformType = uniformType,
|
||||
});
|
||||
|
||||
// Create a Texture.
|
||||
@@ -374,8 +383,13 @@ TEST_F(LoadImageTest, UpdateImage2D) {
|
||||
api.draw2(0, 3, 1);
|
||||
api.endRenderPass();
|
||||
|
||||
EXPECT_IMAGE(defaultRenderTarget,
|
||||
ScreenshotParams(kTexSize, kTexSize, t.name, expectedHash));
|
||||
EXPECT_IMAGE(defaultRenderTarget, ScreenshotParams::Builder()
|
||||
.width(kTexSize)
|
||||
.height(kTexSize)
|
||||
.fileName(t.name)
|
||||
.expectedPixelHash(expectedHash)
|
||||
.forceAlphaValue(1.0f)
|
||||
.build());
|
||||
|
||||
api.commit(swapChain);
|
||||
api.endFrame(0);
|
||||
|
||||
@@ -69,12 +69,12 @@ TEST_F(BackendTest, TextureViewLod) {
|
||||
Shader whiteShader = SharedShaders::makeShader(api, cleanup, ShaderRequest {
|
||||
.mVertexType = VertexShaderType::Textured,
|
||||
.mFragmentType = FragmentShaderType::White,
|
||||
.mUniformType = ShaderUniformType::Sampler
|
||||
.mUniformType = ShaderUniformType::Sampler2D
|
||||
});
|
||||
|
||||
// Create a program that samples a texture.
|
||||
std::string vertexShader = SharedShaders::getVertexShaderText(
|
||||
VertexShaderType::Textured, ShaderUniformType::Sampler);
|
||||
VertexShaderType::Textured, ShaderUniformType::Sampler2D);
|
||||
filament::SamplerInterfaceBlock::SamplerInfo samplerInfo {
|
||||
"backend_test", "sib_tex", 0,
|
||||
SamplerType::SAMPLER_2D, SamplerFormat::FLOAT, Precision::HIGH, false };
|
||||
|
||||
@@ -40,7 +40,7 @@ Shader createShader(DriverApi& api, Cleanup& cleanup, Backend backend) {
|
||||
return SharedShaders::makeShader(api, cleanup, ShaderRequest{
|
||||
.mVertexType = VertexShaderType::Textured,
|
||||
.mFragmentType = FragmentShaderType::Textured,
|
||||
.mUniformType = ShaderUniformType::Sampler
|
||||
.mUniformType = ShaderUniformType::Sampler2D
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user