Compare commits
3 Commits
v1.48.0
...
pf/fix-fee
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7244464a3 | ||
|
|
b066678a37 | ||
|
|
b10d5c58aa |
@@ -397,8 +397,8 @@ install(DIRECTORY ${PUBLIC_HDR_DIR}/backend DESTINATION include)
|
||||
# ==================================================================================================
|
||||
option(INSTALL_BACKEND_TEST "Install the backend test library so it can be consumed on iOS" OFF)
|
||||
|
||||
if (APPLE)
|
||||
add_library(backend_test STATIC
|
||||
if (APPLE OR LINUX)
|
||||
set(BACKEND_TEST_SRC
|
||||
test/BackendTest.cpp
|
||||
test/ShaderGenerator.cpp
|
||||
test/TrianglePrimitive.cpp
|
||||
@@ -410,19 +410,26 @@ if (APPLE)
|
||||
test/test_BufferUpdates.cpp
|
||||
test/test_MRT.cpp
|
||||
test/test_LoadImage.cpp
|
||||
test/test_RenderExternalImage.cpp
|
||||
test/test_StencilBuffer.cpp
|
||||
test/test_Scissor.cpp
|
||||
test/test_MipLevels.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(backend_test PRIVATE
|
||||
)
|
||||
set(BACKEND_TEST_LIBS
|
||||
backend
|
||||
getopt
|
||||
gtest
|
||||
imageio
|
||||
filamat
|
||||
SPIRV
|
||||
spirv-cross-glsl)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
# TODO: we should expand this test to Linux and other platforms.
|
||||
list(APPEND BACKEND_TEST_SRC
|
||||
test/test_RenderExternalImage.cpp)
|
||||
add_library(backend_test STATIC ${BACKEND_TEST_SRC})
|
||||
target_link_libraries(backend_test PRIVATE ${BACKEND_TEST_LIBS})
|
||||
|
||||
set(BACKEND_TEST_DEPS
|
||||
OGLCompiler
|
||||
@@ -436,12 +443,11 @@ if (APPLE)
|
||||
glslang
|
||||
spirv-cross-core
|
||||
spirv-cross-glsl
|
||||
spirv-cross-msl
|
||||
)
|
||||
spirv-cross-msl)
|
||||
|
||||
if (NOT IOS)
|
||||
target_link_libraries(backend_test PRIVATE image imageio)
|
||||
list(APPEND BACKEND_TEST_DEPS image imageio)
|
||||
list(APPEND BACKEND_TEST_DEPS image)
|
||||
endif()
|
||||
|
||||
set(BACKEND_TEST_COMBINED_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libbackendtest_combined.a")
|
||||
@@ -455,15 +461,21 @@ if (APPLE)
|
||||
endif()
|
||||
|
||||
set_target_properties(backend_test PROPERTIES FOLDER Tests)
|
||||
|
||||
if (APPLE AND NOT IOS)
|
||||
add_executable(backend_test_mac test/mac_runner.mm)
|
||||
target_link_libraries(backend_test_mac PRIVATE "-framework Metal -framework AppKit -framework QuartzCore")
|
||||
# Because each test case is a separate file, the -force_load flag is necessary to prevent the
|
||||
# linker from removing "unused" symbols.
|
||||
target_link_libraries(backend_test_mac PRIVATE -force_load backend_test)
|
||||
set_target_properties(backend_test_mac PROPERTIES FOLDER Tests)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (APPLE AND NOT IOS)
|
||||
add_executable(backend_test_mac test/mac_runner.mm)
|
||||
target_link_libraries(backend_test_mac PRIVATE "-framework Metal -framework AppKit -framework QuartzCore")
|
||||
# Because each test case is a separate file, the -force_load flag is necessary to prevent the
|
||||
# linker from removing "unused" symbols.
|
||||
target_link_libraries(backend_test_mac PRIVATE -force_load backend_test)
|
||||
set_target_properties(backend_test_mac PROPERTIES FOLDER Tests)
|
||||
if (LINUX)
|
||||
add_executable(backend_test_linux test/linux_runner.cpp ${BACKEND_TEST_SRC})
|
||||
target_link_libraries(backend_test_linux PRIVATE ${BACKEND_TEST_LIBS})
|
||||
set_target_properties(backend_test_linux PROPERTIES FOLDER Tests)
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
@@ -18,11 +18,16 @@
|
||||
|
||||
#include <private/backend/PlatformFactory.h>
|
||||
|
||||
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include <backend/platforms/VulkanPlatform.h>
|
||||
#endif
|
||||
|
||||
#include "BackendTest.h"
|
||||
|
||||
#include <utils/Hash.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include "ShaderGenerator.h"
|
||||
#include "TrianglePrimitive.h"
|
||||
@@ -33,6 +38,25 @@ static constexpr size_t CONFIG_COMMAND_BUFFERS_SIZE = 3 * CONFIG_MIN_COMMAND
|
||||
using namespace filament;
|
||||
using namespace filament::backend;
|
||||
|
||||
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
namespace filament {
|
||||
class InternalVulkanPlatform : public VulkanPlatform {
|
||||
public:
|
||||
InternalVulkanPlatform() {
|
||||
mCustomization = {
|
||||
.gpu = { .index = 0 },
|
||||
};
|
||||
}
|
||||
|
||||
virtual VulkanPlatform::Customization getCustomization() const noexcept override {
|
||||
return mCustomization;
|
||||
}
|
||||
private:
|
||||
VulkanPlatform::Customization mCustomization;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef IOS
|
||||
#include <imageio/ImageEncoder.h>
|
||||
#include <image/ColorTransform.h>
|
||||
@@ -40,6 +64,11 @@ using namespace filament::backend;
|
||||
using namespace image;
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
std::string const SHADER_VULKAN_TAG = "// select(vulkan) ";
|
||||
std::string const SHADER_METAL_TAG = "// select(metal) ";
|
||||
}
|
||||
|
||||
namespace test {
|
||||
|
||||
Backend BackendTest::sBackend = Backend::NOOP;
|
||||
@@ -67,7 +96,14 @@ BackendTest::~BackendTest() {
|
||||
|
||||
void BackendTest::initializeDriver() {
|
||||
auto backend = static_cast<filament::backend::Backend>(sBackend);
|
||||
Platform* platform = PlatformFactory::create(&backend);
|
||||
|
||||
Platform* platform = nullptr;
|
||||
if (backend == filament::backend::Backend::VULKAN) {
|
||||
platform = new InternalVulkanPlatform();
|
||||
} else {
|
||||
platform = PlatformFactory::create(&backend);
|
||||
}
|
||||
|
||||
assert_invariant(static_cast<uint8_t>(backend) == static_cast<uint8_t>(sBackend));
|
||||
Platform::DriverConfig const driverConfig;
|
||||
driver = platform->createDriver(nullptr, driverConfig);
|
||||
@@ -93,6 +129,9 @@ void BackendTest::flushAndWait() {
|
||||
|
||||
Handle<HwSwapChain> BackendTest::createSwapChain() {
|
||||
const NativeView& view = getNativeView();
|
||||
if (!view.ptr) {
|
||||
return getDriverApi().createSwapChainHeadless(view.width, view.height, 0);
|
||||
}
|
||||
return getDriverApi().createSwapChain(view.ptr, 0);
|
||||
}
|
||||
|
||||
@@ -190,6 +229,32 @@ void BackendTest::readPixelsAndAssertHash(const char* testName, size_t width, si
|
||||
getDriverApi().readPixels(rt, 0, 0, width, height, std::move(pbd));
|
||||
}
|
||||
|
||||
std::string BackendTest::transformShaderText(std::string const& shader) const {
|
||||
std::string replacement;
|
||||
switch (sBackend) {
|
||||
case test::Backend::VULKAN:
|
||||
replacement = SHADER_VULKAN_TAG;
|
||||
break;
|
||||
case test::Backend::METAL:
|
||||
replacement = SHADER_METAL_TAG;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (replacement.size() == 0) {
|
||||
return shader;
|
||||
}
|
||||
std::string replaced = shader;
|
||||
while (true) {
|
||||
size_t pos = replaced.find(replacement);
|
||||
if (pos == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
replaced.replace(pos, replacement.length(), "");
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
|
||||
class Environment : public ::testing::Environment {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
@@ -212,4 +277,3 @@ int runTests() {
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
|
||||
|
||||
@@ -66,6 +66,8 @@ protected:
|
||||
filament::backend::DriverApi& getDriverApi() { return *commandStream; }
|
||||
filament::backend::Driver& getDriver() { return *driver; }
|
||||
|
||||
std::string transformShaderText(std::string const& shader) const;
|
||||
|
||||
private:
|
||||
|
||||
filament::backend::Driver* driver = nullptr;
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
|
||||
namespace test {
|
||||
|
||||
constexpr uint32_t const WINDOW_WIDTH = 512;
|
||||
constexpr uint32_t const WINDOW_HEIGHT = 512;
|
||||
|
||||
// To avoid a dependency on filabridge, the Backend enum is replicated here.
|
||||
enum class Backend : uint8_t {
|
||||
OPENGL = 1,
|
||||
|
||||
56
filament/backend/test/linux_runner.cpp
Normal file
56
filament/backend/test/linux_runner.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include "BackendTest.h"
|
||||
#include "PlatformRunner.h"
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
|
||||
namespace test {
|
||||
|
||||
test::NativeView getNativeView() {
|
||||
return {
|
||||
.ptr = nullptr,
|
||||
.width = WINDOW_WIDTH,
|
||||
.height = WINDOW_HEIGHT,
|
||||
};
|
||||
}
|
||||
|
||||
}// namespace test
|
||||
|
||||
namespace {
|
||||
|
||||
std::array<test::Backend, 2> const VALID_BACKENDS{
|
||||
test::Backend::OPENGL,
|
||||
test::Backend::VULKAN,
|
||||
};
|
||||
|
||||
}// namespace
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
auto backend = test::parseArgumentsForBackend(argc, argv);
|
||||
|
||||
if (!std::any_of(VALID_BACKENDS.begin(), VALID_BACKENDS.end(),
|
||||
[backend](test::Backend validBackend) { return backend == validBackend; })) {
|
||||
std::cerr << "Specified an invalid backend. Only GL and Vulkan are available" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
test::initTests(backend, false, argc, argv);
|
||||
return test::runTests();
|
||||
}
|
||||
@@ -58,7 +58,7 @@ test::NativeView getNativeView() {
|
||||
}
|
||||
|
||||
- (NSView*)createView {
|
||||
NSRect frame = NSMakeRect(0, 0, 512, 512);
|
||||
NSRect frame = NSMakeRect(0, 0, test::WINDOW_WIDTH, test::WINDOW_HEIGHT);
|
||||
NSWindow* window = [[NSWindow alloc] initWithContentRect:frame
|
||||
styleMask:NSWindowStyleMaskBorderless
|
||||
backing:NSBackingStoreBuffered
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
using namespace image;
|
||||
#endif
|
||||
|
||||
#define DUMP_INTERMEDIATE_SCREENSHOTS 1
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Shaders
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -42,6 +44,7 @@ layout(location = 0) in vec4 mesh_position;
|
||||
void main() {
|
||||
// Hack: move and scale triangle so that it covers entire viewport.
|
||||
gl_Position = vec4((mesh_position.xy + 0.5) * 5.0, 0.0, 1.0);
|
||||
// select(vulkan) gl_Position.y = - gl_Position.y;
|
||||
})";
|
||||
|
||||
static std::string fullscreenFs = R"(#version 450 core
|
||||
@@ -50,7 +53,7 @@ layout(location = 0) out vec4 fragColor;
|
||||
|
||||
// Filament's Vulkan backend requires a descriptor set index of 1 for all samplers.
|
||||
// This parameter is ignored for other backends.
|
||||
layout(location = 0, set = 1) uniform sampler2D test_tex;
|
||||
layout(binding = 0, set = 1) uniform sampler2D test_tex;
|
||||
|
||||
uniform Params {
|
||||
highp float fbWidth;
|
||||
@@ -60,7 +63,18 @@ uniform Params {
|
||||
} params;
|
||||
void main() {
|
||||
vec2 fbsize = vec2(params.fbWidth, params.fbHeight);
|
||||
vec2 uv = (gl_FragCoord.xy + 0.5) / fbsize;
|
||||
float offset = 0;
|
||||
// select(vulkan) offset = -offset;
|
||||
vec2 uv = (gl_FragCoord.xy + offset) / fbsize;
|
||||
// select(vulkan) uv.y = 1.0 - uv.y;
|
||||
vec4 oo = vec4(0, 0, 0, 0);
|
||||
if (uv.x > .5) {
|
||||
oo += vec4(0.5, 0.0, 0.0, 1.0);
|
||||
}
|
||||
if (uv.y > .5) {
|
||||
oo += vec4(0.0, 0.5, 0.0, 1.0);
|
||||
}
|
||||
// fragColor = oo;
|
||||
fragColor = textureLod(test_tex, uv, params.sourceLevel);
|
||||
})";
|
||||
|
||||
@@ -99,22 +113,58 @@ static void uploadUniforms(DriverApi& dapi, Handle<HwBufferObject> ubh, Material
|
||||
dapi.updateBufferObject(ubh, std::move(bd), 0);
|
||||
}
|
||||
|
||||
static void dumpScreenshot(DriverApi& dapi, Handle<HwRenderTarget> rt) {
|
||||
const size_t size = kTexWidth * kTexHeight * 4;
|
||||
static void readScreenshot(DriverApi& dapi, Handle<HwRenderTarget> renderTargets[kNumLevels],
|
||||
uint32_t target, std::function<void(void*)> output) {
|
||||
Handle<HwRenderTarget> rt = renderTargets[target];
|
||||
size_t const readWidth = kTexWidth >> target;
|
||||
size_t const readHeight = kTexHeight >> target;
|
||||
size_t const size = readWidth * readHeight * 4;
|
||||
void* buffer = calloc(1, size);
|
||||
auto cb = [](void* buffer, size_t size, void* user) {
|
||||
int w = kTexWidth, h = kTexHeight;
|
||||
const uint32_t* texels = (uint32_t*) buffer;
|
||||
sPixelHashResult = utils::hash::murmur3(texels, size / 4, 0);
|
||||
#ifndef IOS
|
||||
LinearImage image(w, h, 4);
|
||||
image = toLinearWithAlpha<uint8_t>(w, h, w * 4, (uint8_t*) buffer);
|
||||
std::ofstream pngstrm("feedback.png", std::ios::binary | std::ios::trunc);
|
||||
ImageEncoder::encode(pngstrm, ImageEncoder::Format::PNG, image, "", "feedback.png");
|
||||
#endif
|
||||
struct ReadPixelUserData {
|
||||
std::function<void(void*)> onRead;
|
||||
};
|
||||
PixelBufferDescriptor pb(buffer, size, PixelDataFormat::RGBA, PixelDataType::UBYTE, cb);
|
||||
dapi.readPixels(rt, 0, 0, kTexWidth, kTexHeight, std::move(pb));
|
||||
ReadPixelUserData* userdata = new ReadPixelUserData { output };
|
||||
auto cb = [](void* buffer, size_t size, void* user) {
|
||||
ReadPixelUserData* data = (ReadPixelUserData*) user;
|
||||
data->onRead(buffer);
|
||||
free(buffer);
|
||||
delete data;
|
||||
};
|
||||
PixelBufferDescriptor pb(buffer, size, PixelDataFormat::RGBA, PixelDataType::UBYTE, cb,
|
||||
userdata);
|
||||
dapi.readPixels(rt, 0, 0, readWidth, readHeight, std::move(pb));
|
||||
}
|
||||
|
||||
static void dumpScreenshot(DriverApi& dapi, Handle<HwRenderTarget> renderTargets[kNumLevels],
|
||||
uint32_t target, uint32_t numFrame, bool downscale, test::Backend backend,
|
||||
std::string fname="") {
|
||||
Handle<HwRenderTarget> rt = renderTargets[target];
|
||||
size_t const readWidth = kTexWidth >> target;
|
||||
size_t const readHeight = kTexHeight >> target;
|
||||
size_t const size = readWidth * readHeight * 4;
|
||||
if (fname.empty()) {
|
||||
std::string backendStr = "gl";
|
||||
if (backend == test::Backend::METAL) {
|
||||
backendStr = "mtl";
|
||||
} else if (backend == test::Backend::VULKAN) {
|
||||
backendStr = "vk";
|
||||
}
|
||||
std::string const down = downscale ? "down" : "up";
|
||||
fname = "feedback_" + backendStr + "_" + std::to_string(numFrame) + "_" + down + "_" +
|
||||
std::to_string(target) + ".png";
|
||||
}
|
||||
utils::slog.e <<"writing: " << fname << utils::io::endl;
|
||||
readScreenshot(dapi, renderTargets, target,
|
||||
[w = readWidth, h = readHeight, size, fname](void* buffer) {
|
||||
uint32_t const* texels = (uint32_t*) buffer;
|
||||
sPixelHashResult = utils::hash::murmur3(texels, size / 4, 0);
|
||||
#ifndef IOS
|
||||
LinearImage image(w, h, 4);
|
||||
image = toLinearWithAlpha<uint8_t>(w, h, w * 4, (uint8_t*) buffer);
|
||||
std::ofstream pngstrm(fname.c_str(), std::ios::binary | std::ios::trunc);
|
||||
ImageEncoder::encode(pngstrm, ImageEncoder::Format::PNG, image, "", fname.c_str());
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: This test needs work to get Metal and OpenGL to agree on results.
|
||||
@@ -130,6 +180,8 @@ TEST_F(BackendTest, FeedbackLoops) {
|
||||
auto swapChain = createSwapChain();
|
||||
api.makeCurrent(swapChain, swapChain);
|
||||
|
||||
bool const backendIsVulkan = sBackend == test::Backend::VULKAN;
|
||||
|
||||
// Create a program.
|
||||
ProgramHandle program;
|
||||
{
|
||||
@@ -138,10 +190,12 @@ TEST_F(BackendTest, FeedbackLoops) {
|
||||
.stageFlags(backend::ShaderStageFlags::ALL_SHADER_STAGE_FLAGS)
|
||||
.add( {{"tex", SamplerType::SAMPLER_2D, SamplerFormat::FLOAT, Precision::HIGH }} )
|
||||
.build();
|
||||
ShaderGenerator shaderGen(fullscreenVs, fullscreenFs, sBackend, sIsMobilePlatform, &sib);
|
||||
ShaderGenerator shaderGen(transformShaderText(fullscreenVs),
|
||||
transformShaderText(fullscreenFs), sBackend, sIsMobilePlatform, &sib);
|
||||
Program prog = shaderGen.getProgram(api);
|
||||
Program::Sampler psamplers[] = { utils::CString("test_tex"), 0 };
|
||||
prog.setSamplerGroup(0, ShaderStageFlags::ALL_SHADER_STAGE_FLAGS, psamplers, sizeof(psamplers) / sizeof(psamplers[0]));
|
||||
Program::Sampler psamplers[] = {utils::CString("test_tex"), 0};
|
||||
prog.setSamplerGroup(0, ShaderStageFlags::ALL_SHADER_STAGE_FLAGS, psamplers,
|
||||
sizeof(psamplers) / sizeof(psamplers[0]));
|
||||
prog.uniformBlockBindings({{"params", 1}});
|
||||
program = api.createProgram(std::move(prog));
|
||||
}
|
||||
@@ -166,10 +220,25 @@ TEST_F(BackendTest, FeedbackLoops) {
|
||||
const size_t size = kTexHeight * kTexWidth * 4;
|
||||
uint8_t* buffer = (uint8_t*) malloc(size);
|
||||
for (int r = 0, i = 0; r < kTexHeight; r++) {
|
||||
int const adjustedR = backendIsVulkan ? r : kTexHeight - r - 1;
|
||||
for (int c = 0; c < kTexWidth; c++, i += 4) {
|
||||
auto hval = 0x1f * c / (kTexWidth - 1);
|
||||
if (hval > 0x05) {
|
||||
hval = 0x1f;
|
||||
} else {
|
||||
hval = 0x00;
|
||||
}
|
||||
auto vval = 0x1f * adjustedR / (kTexHeight - 1);
|
||||
if (vval > 0x05) {
|
||||
vval = 0x1f;
|
||||
} else {
|
||||
vval = 0x00;
|
||||
}
|
||||
buffer[i + 0] = 0x10;
|
||||
buffer[i + 1] = 0x1f * r / (kTexHeight - 1);
|
||||
buffer[i + 1] = 0x1f * adjustedR / (kTexHeight - 1);
|
||||
// buffer[i + 1] = vval;
|
||||
buffer[i + 2] = 0x1f * c / (kTexWidth - 1);
|
||||
// buffer[i + 2] = hval;
|
||||
buffer[i + 3] = 0xf0;
|
||||
}
|
||||
}
|
||||
@@ -178,7 +247,6 @@ TEST_F(BackendTest, FeedbackLoops) {
|
||||
api.update3DImage(texture, 0, 0, 0, 0, kTexWidth, kTexHeight, 1, std::move(pb));
|
||||
|
||||
for (int frame = 0; frame < kNumFrames; frame++) {
|
||||
|
||||
// Prep for rendering.
|
||||
RenderPassParams params = {};
|
||||
params.flags.clear = TargetBufferFlags::NONE;
|
||||
@@ -190,8 +258,9 @@ TEST_F(BackendTest, FeedbackLoops) {
|
||||
state.program = program;
|
||||
SamplerGroup samplers(1);
|
||||
SamplerParams sparams = {};
|
||||
sparams.filterMag = SamplerMagFilter::LINEAR;
|
||||
sparams.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST;
|
||||
sparams.filterMag = SamplerMagFilter::NEAREST;
|
||||
// sparams.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST;
|
||||
sparams.filterMin = SamplerMinFilter::NEAREST;
|
||||
samplers.setSampler(0, { texture, sparams });
|
||||
auto sgroup =
|
||||
api.createSamplerGroup(samplers.getSize(), utils::FixedSizeString<32>("Test"));
|
||||
@@ -206,19 +275,24 @@ TEST_F(BackendTest, FeedbackLoops) {
|
||||
// Downsample passes
|
||||
params.flags.discardStart = TargetBufferFlags::ALL;
|
||||
state.rasterState.disableBlending();
|
||||
for (int targetLevel = 1; targetLevel < kNumLevels; targetLevel++) {
|
||||
const uint32_t sourceLevel = targetLevel - 1;
|
||||
params.viewport.width = kTexWidth >> targetLevel;
|
||||
params.viewport.height = kTexHeight >> targetLevel;
|
||||
getDriverApi().setMinMaxLevels(texture, sourceLevel, sourceLevel);
|
||||
uploadUniforms(getDriverApi(), ubuffer, {
|
||||
.fbWidth = float(params.viewport.width),
|
||||
.fbHeight = float(params.viewport.height),
|
||||
.sourceLevel = float(sourceLevel),
|
||||
});
|
||||
api.beginRenderPass(renderTargets[targetLevel], params);
|
||||
api.draw(state, triangle.getRenderPrimitive(), 1);
|
||||
api.endRenderPass();
|
||||
for (int targetLevel = 0; targetLevel < kNumLevels; targetLevel++) {
|
||||
if (targetLevel > 0) {
|
||||
const uint32_t sourceLevel = targetLevel - 1;
|
||||
params.viewport.width = kTexWidth >> targetLevel;
|
||||
params.viewport.height = kTexHeight >> targetLevel;
|
||||
getDriverApi().setMinMaxLevels(texture, sourceLevel, sourceLevel);
|
||||
uploadUniforms(getDriverApi(), ubuffer, {
|
||||
.fbWidth = float(params.viewport.width),
|
||||
.fbHeight = float(params.viewport.height),
|
||||
.sourceLevel = float(sourceLevel),
|
||||
});
|
||||
api.beginRenderPass(renderTargets[targetLevel], params);
|
||||
api.draw(state, triangle.getRenderPrimitive(), 1);
|
||||
api.endRenderPass();
|
||||
}
|
||||
#if DUMP_INTERMEDIATE_SCREENSHOTS
|
||||
dumpScreenshot(api, renderTargets, targetLevel, frame, true, sBackend);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Upsample passes
|
||||
@@ -238,16 +312,22 @@ TEST_F(BackendTest, FeedbackLoops) {
|
||||
api.beginRenderPass(renderTargets[targetLevel], params);
|
||||
api.draw(state, triangle.getRenderPrimitive(), 1);
|
||||
api.endRenderPass();
|
||||
|
||||
#if DUMP_INTERMEDIATE_SCREENSHOTS
|
||||
dumpScreenshot(api, renderTargets, targetLevel, frame, false, sBackend);
|
||||
#endif
|
||||
}
|
||||
|
||||
getDriverApi().setMinMaxLevels(texture, 0, 0x7f);
|
||||
getDriverApi().destroySamplerGroup(sgroup);
|
||||
getDriverApi().destroyBufferObject(ubuffer);
|
||||
|
||||
// Read back the render target corresponding to the base level.
|
||||
//
|
||||
// NOTE: Calling glReadPixels on any miplevel other than the base level
|
||||
// seems to be un-reliable on some GPU's.
|
||||
if (frame == kNumFrames - 1) {
|
||||
dumpScreenshot(api, renderTargets[0]);
|
||||
dumpScreenshot(api, renderTargets, 0, frame, false, sBackend, "Feedback.png");
|
||||
}
|
||||
|
||||
api.flush();
|
||||
|
||||
@@ -75,7 +75,7 @@ window.MonacoEnvironment = {
|
||||
};
|
||||
|
||||
const _validDict = (obj) => {
|
||||
return obj && Object.keys(obj) > 0;
|
||||
return obj && Object.keys(obj).length > 0;
|
||||
}
|
||||
|
||||
const _isMatInfoMode = (database) => {
|
||||
|
||||
Reference in New Issue
Block a user