mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-13 10:51:35 +00:00
169 lines
6.2 KiB
C++
169 lines
6.2 KiB
C++
// Copyright 2017 The Dawn Authors
|
|
//
|
|
// 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 "tests/DawnTest.h"
|
|
|
|
#include "utils/DawnHelpers.h"
|
|
|
|
#include <array>
|
|
|
|
constexpr static unsigned int kRTSize = 16;
|
|
|
|
class DrawQuad {
|
|
public:
|
|
DrawQuad() {}
|
|
DrawQuad(dawn::Device* device, const char* vsSource, const char* fsSource)
|
|
: device(device) {
|
|
vsModule = utils::CreateShaderModule(*device, dawn::ShaderStage::Vertex, vsSource);
|
|
fsModule = utils::CreateShaderModule(*device, dawn::ShaderStage::Fragment, fsSource);
|
|
|
|
pipelineLayout = utils::MakeBasicPipelineLayout(*device, nullptr);
|
|
}
|
|
|
|
void Draw(dawn::CommandBufferBuilder* builder) {
|
|
auto renderPipeline = device->CreateRenderPipelineBuilder()
|
|
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
|
|
.SetLayout(pipelineLayout)
|
|
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
|
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
|
.GetResult();
|
|
|
|
builder->SetRenderPipeline(renderPipeline);
|
|
builder->DrawArrays(6, 1, 0, 0);
|
|
}
|
|
|
|
private:
|
|
dawn::Device* device = nullptr;
|
|
dawn::ShaderModule vsModule = {};
|
|
dawn::ShaderModule fsModule = {};
|
|
dawn::PipelineLayout pipelineLayout = {};
|
|
};
|
|
|
|
class RenderPassLoadOpTests : public DawnTest {
|
|
protected:
|
|
void SetUp() override {
|
|
DawnTest::SetUp();
|
|
|
|
renderTarget = device.CreateTextureBuilder()
|
|
.SetDimension(dawn::TextureDimension::e2D)
|
|
.SetExtent(kRTSize, kRTSize, 1)
|
|
.SetFormat(dawn::TextureFormat::R8G8B8A8Unorm)
|
|
.SetMipLevels(1)
|
|
.SetAllowedUsage(dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::TransferSrc)
|
|
.GetResult();
|
|
|
|
renderTargetView = renderTarget.CreateTextureViewBuilder().GetResult();
|
|
|
|
RGBA8 zero(0, 0, 0, 0);
|
|
std::fill(expectZero.begin(), expectZero.end(), zero);
|
|
|
|
RGBA8 green(0, 255, 0, 255);
|
|
std::fill(expectGreen.begin(), expectGreen.end(), green);
|
|
|
|
RGBA8 blue(0, 0, 255, 255);
|
|
std::fill(expectBlue.begin(), expectBlue.end(), blue);
|
|
|
|
// draws a blue quad on the right half of the screen
|
|
const char* vsSource = R"(
|
|
#version 450
|
|
void main() {
|
|
const vec2 pos[6] = vec2[6](
|
|
vec2(0, -1), vec2(1, -1), vec2(0, 1),
|
|
vec2(0, 1), vec2(1, -1), vec2(1, 1));
|
|
gl_Position = vec4(pos[gl_VertexIndex], 0.f, 1.f);
|
|
}
|
|
)";
|
|
const char* fsSource = R"(
|
|
#version 450
|
|
layout(location = 0) out vec4 color;
|
|
void main() {
|
|
color = vec4(0.f, 0.f, 1.f, 1.f);
|
|
}
|
|
)";
|
|
blueQuad = DrawQuad(&device, vsSource, fsSource);
|
|
}
|
|
|
|
dawn::Texture renderTarget;
|
|
dawn::TextureView renderTargetView;
|
|
|
|
std::array<RGBA8, kRTSize * kRTSize> expectZero;
|
|
std::array<RGBA8, kRTSize * kRTSize> expectGreen;
|
|
std::array<RGBA8, kRTSize * kRTSize> expectBlue;
|
|
|
|
DrawQuad blueQuad = {};
|
|
};
|
|
|
|
// Tests clearing, loading, and drawing into color attachments
|
|
TEST_P(RenderPassLoadOpTests, ColorClearThenLoadAndDraw) {
|
|
|
|
// Part 1: clear once, check to make sure it's cleared
|
|
|
|
auto renderPassClearZero = device.CreateRenderPassDescriptorBuilder()
|
|
.SetColorAttachment(0, renderTargetView, dawn::LoadOp::Clear)
|
|
.SetColorAttachmentClearColor(0, 0.0f, 0.0f, 0.0f, 0.0f)
|
|
.GetResult();
|
|
|
|
auto commandsClearZero = device.CreateCommandBufferBuilder()
|
|
.BeginRenderPass(renderPassClearZero)
|
|
// Clear should occur implicitly
|
|
// Store should occur implicitly
|
|
.EndRenderPass()
|
|
.GetResult();
|
|
|
|
auto renderPassClearGreen = device.CreateRenderPassDescriptorBuilder()
|
|
.SetColorAttachment(0, renderTargetView, dawn::LoadOp::Clear)
|
|
.SetColorAttachmentClearColor(0, 0.0f, 1.0f, 0.0f, 1.0f)
|
|
.GetResult();
|
|
|
|
auto commandsClearGreen = device.CreateCommandBufferBuilder()
|
|
.BeginRenderPass(renderPassClearGreen)
|
|
// Clear should occur implicitly
|
|
// Store should occur implicitly
|
|
.EndRenderPass()
|
|
.GetResult();
|
|
|
|
queue.Submit(1, &commandsClearZero);
|
|
EXPECT_TEXTURE_RGBA8_EQ(expectZero.data(), renderTarget, 0, 0, kRTSize, kRTSize, 0);
|
|
|
|
queue.Submit(1, &commandsClearGreen);
|
|
EXPECT_TEXTURE_RGBA8_EQ(expectGreen.data(), renderTarget, 0, 0, kRTSize, kRTSize, 0);
|
|
|
|
// Part 2: draw a blue quad into the right half of the render target, and check result
|
|
|
|
auto renderPassLoad = device.CreateRenderPassDescriptorBuilder()
|
|
.SetColorAttachment(0, renderTargetView, dawn::LoadOp::Load)
|
|
.GetResult();
|
|
|
|
dawn::CommandBuffer commandsLoad;
|
|
{
|
|
auto builder = device.CreateCommandBufferBuilder()
|
|
.BeginRenderPass(renderPassLoad)
|
|
// Load should occur implicitly
|
|
.Clone();
|
|
blueQuad.Draw(&builder);
|
|
commandsLoad = builder
|
|
// Store should occur implicitly
|
|
.EndRenderPass()
|
|
.GetResult();
|
|
}
|
|
|
|
queue.Submit(1, &commandsLoad);
|
|
// Left half should still be green
|
|
EXPECT_TEXTURE_RGBA8_EQ(expectGreen.data(), renderTarget, 0, 0, kRTSize / 2, kRTSize, 0);
|
|
// Right half should now be blue
|
|
EXPECT_TEXTURE_RGBA8_EQ(expectBlue.data(), renderTarget, kRTSize / 2, 0, kRTSize / 2, kRTSize, 0);
|
|
}
|
|
|
|
DAWN_INSTANTIATE_TEST(RenderPassLoadOpTests, D3D12Backend, MetalBackend, OpenGLBackend)
|