104 lines
4.8 KiB
C++
104 lines
4.8 KiB
C++
#if MLN_RENDER_BACKEND_METAL
|
|
|
|
#include <mbgl/mtl/context.hpp>
|
|
#include <mbgl/mtl/offscreen_texture.hpp>
|
|
#include <mbgl/mtl/render_pass.hpp>
|
|
#include <mbgl/mtl/renderable_resource.hpp>
|
|
#include <mbgl/mtl/renderer_backend.hpp>
|
|
|
|
#include <Foundation/Foundation.hpp>
|
|
#include <Metal/Metal.hpp>
|
|
#include <gtest/gtest.h>
|
|
#include <cstdlib>
|
|
|
|
using namespace mbgl;
|
|
|
|
namespace {
|
|
|
|
class TestMetalBackend final : public mtl::RendererBackend {
|
|
public:
|
|
TestMetalBackend() : RendererBackend(gfx::ContextMode::Unique) {}
|
|
|
|
gfx::Renderable& getDefaultRenderable() override { std::abort(); }
|
|
void updateAssumedState() override {}
|
|
|
|
private:
|
|
void activate() override {}
|
|
void deactivate() override {}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
TEST(MetalRetainedAttachments, ClearActionsApplyToCombinedDepthStencil) {
|
|
auto pool = NS::TransferPtr(NS::AutoreleasePool::alloc()->init());
|
|
auto device = NS::TransferPtr(MTL::CreateSystemDefaultDevice());
|
|
if (!device) GTEST_SKIP() << "Metal device unavailable";
|
|
|
|
auto colorDescriptor = MTL::TextureDescriptor::texture2DDescriptor(MTL::PixelFormatRGBA8Unorm, 4, 4, false);
|
|
auto combinedDescriptor =
|
|
MTL::TextureDescriptor::texture2DDescriptor(MTL::PixelFormatDepth32Float_Stencil8, 4, 4, false);
|
|
colorDescriptor->setUsage(MTL::TextureUsageRenderTarget);
|
|
combinedDescriptor->setUsage(MTL::TextureUsageRenderTarget);
|
|
auto colorTexture = NS::TransferPtr(device->newTexture(colorDescriptor));
|
|
auto combinedTexture = NS::TransferPtr(device->newTexture(combinedDescriptor));
|
|
if (!combinedTexture) GTEST_SKIP() << "Combined depth-stencil texture unavailable";
|
|
ASSERT_TRUE(colorTexture);
|
|
|
|
auto descriptor = NS::TransferPtr(MTL::RenderPassDescriptor::alloc()->init());
|
|
descriptor->colorAttachments()->object(0)->setTexture(colorTexture.get());
|
|
descriptor->depthAttachment()->setTexture(combinedTexture.get());
|
|
descriptor->stencilAttachment()->setTexture(combinedTexture.get());
|
|
|
|
const auto applied = mtl::detail::applyRenderPassClears(
|
|
*descriptor.get(), Color{0.2f, 0.3f, 0.4f, 0.5f}, 1.0f, 0);
|
|
EXPECT_TRUE(applied.color);
|
|
EXPECT_TRUE(applied.depth);
|
|
EXPECT_TRUE(applied.stencil);
|
|
EXPECT_EQ(descriptor->colorAttachments()->object(0)->loadAction(), MTL::LoadActionClear);
|
|
EXPECT_EQ(descriptor->depthAttachment()->loadAction(), MTL::LoadActionClear);
|
|
EXPECT_EQ(descriptor->stencilAttachment()->loadAction(), MTL::LoadActionClear);
|
|
EXPECT_EQ(descriptor->colorAttachments()->object(0)->storeAction(), MTL::StoreActionStore);
|
|
EXPECT_EQ(descriptor->depthAttachment()->storeAction(), MTL::StoreActionStore);
|
|
EXPECT_EQ(descriptor->stencilAttachment()->storeAction(), MTL::StoreActionStore);
|
|
EXPECT_DOUBLE_EQ(descriptor->depthAttachment()->clearDepth(), 1.0);
|
|
EXPECT_EQ(descriptor->stencilAttachment()->clearStencil(), 0u);
|
|
EXPECT_EQ(descriptor->depthAttachment()->texture(), descriptor->stencilAttachment()->texture());
|
|
}
|
|
|
|
TEST(MetalRetainedAttachments, OffscreenBindsRequestedAttachmentsAndSkipsAbsentOnes) {
|
|
auto pool = NS::TransferPtr(NS::AutoreleasePool::alloc()->init());
|
|
auto device = NS::TransferPtr(MTL::CreateSystemDefaultDevice());
|
|
if (!device) GTEST_SKIP() << "Metal device unavailable";
|
|
TestMetalBackend backend;
|
|
mtl::Context context{backend};
|
|
|
|
mtl::OffscreenTexture retained(context, {4, 4}, gfx::TextureChannelDataType::UnsignedByte, true, true);
|
|
ASSERT_TRUE(retained.isRenderable());
|
|
auto& retainedResource = retained.getResource<mtl::RenderableResource>();
|
|
retainedResource.bind();
|
|
const auto& retainedDescriptor = retainedResource.getRenderPassDescriptor();
|
|
ASSERT_TRUE(retainedDescriptor);
|
|
ASSERT_NE(retainedDescriptor->colorAttachments()->object(0)->texture(), nullptr);
|
|
ASSERT_NE(retainedDescriptor->depthAttachment()->texture(), nullptr);
|
|
ASSERT_NE(retainedDescriptor->stencilAttachment()->texture(), nullptr);
|
|
#if TARGET_OS_SIMULATOR || defined(__x86_64__)
|
|
EXPECT_EQ(retainedDescriptor->depthAttachment()->texture(), retainedDescriptor->stencilAttachment()->texture());
|
|
#else
|
|
EXPECT_NE(retainedDescriptor->depthAttachment()->texture(), retainedDescriptor->stencilAttachment()->texture());
|
|
#endif
|
|
|
|
mtl::OffscreenTexture colorOnly(context, {4, 4}, gfx::TextureChannelDataType::UnsignedByte, false, false);
|
|
ASSERT_TRUE(colorOnly.isRenderable());
|
|
auto& colorResource = colorOnly.getResource<mtl::RenderableResource>();
|
|
colorResource.bind();
|
|
const auto& colorDescriptor = colorResource.getRenderPassDescriptor();
|
|
ASSERT_TRUE(colorDescriptor);
|
|
EXPECT_EQ(colorDescriptor->depthAttachment()->texture(), nullptr);
|
|
EXPECT_EQ(colorDescriptor->stencilAttachment()->texture(), nullptr);
|
|
const auto applied = mtl::detail::applyRenderPassClears(*colorDescriptor.get(), std::nullopt, 1.0f, 0);
|
|
EXPECT_FALSE(applied.depth);
|
|
EXPECT_FALSE(applied.stencil);
|
|
}
|
|
|
|
#endif // MLN_RENDER_BACKEND_METAL
|