mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-14 07:36:15 +00:00
Consolidate unittests in one binary
This commit is contained in:
committed by
Corentin Wallez
parent
314f3852a3
commit
0a58812f34
@@ -120,16 +120,3 @@ if (APPLE)
|
||||
endif()
|
||||
target_include_directories(nxt_backend PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
SetCXX14(nxt_backend)
|
||||
|
||||
add_executable(backend_unittests
|
||||
${TESTS_DIR}/BitSetIteratorTests.cpp
|
||||
${TESTS_DIR}/CommandAllocatorTests.cpp
|
||||
${TESTS_DIR}/MathTests.cpp
|
||||
${TESTS_DIR}/PerStageTests.cpp
|
||||
${TESTS_DIR}/RefCountedTests.cpp
|
||||
${TESTS_DIR}/ToBackendTests.cpp
|
||||
${TESTS_DIR}/UnittestsMain.cpp
|
||||
)
|
||||
target_link_libraries(backend_unittests nxt_backend gtest)
|
||||
target_include_directories(backend_unittests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
SetCXX14(backend_unittests)
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
// Copyright 2017 The NXT 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 <gtest/gtest.h>
|
||||
|
||||
#include "common/BitSetIterator.h"
|
||||
|
||||
// This is ANGLE's BitSetIterator_unittests.cpp file.
|
||||
|
||||
using namespace backend;
|
||||
|
||||
class BitSetIteratorTest : public testing::Test {
|
||||
protected:
|
||||
std::bitset<40> mStateBits;
|
||||
};
|
||||
|
||||
// Simple iterator test.
|
||||
TEST_F(BitSetIteratorTest, Iterator) {
|
||||
std::set<unsigned long> originalValues;
|
||||
originalValues.insert(2);
|
||||
originalValues.insert(6);
|
||||
originalValues.insert(8);
|
||||
originalValues.insert(35);
|
||||
|
||||
for (unsigned long value : originalValues) {
|
||||
mStateBits.set(value);
|
||||
}
|
||||
|
||||
std::set<unsigned long> readValues;
|
||||
for (unsigned long bit : IterateBitSet(mStateBits)) {
|
||||
EXPECT_EQ(1u, originalValues.count(bit));
|
||||
EXPECT_EQ(0u, readValues.count(bit));
|
||||
readValues.insert(bit);
|
||||
}
|
||||
|
||||
EXPECT_EQ(originalValues.size(), readValues.size());
|
||||
}
|
||||
|
||||
// Test an empty iterator.
|
||||
TEST_F(BitSetIteratorTest, EmptySet) {
|
||||
// We don't use the FAIL gtest macro here since it returns immediately,
|
||||
// causing an unreachable code warning in MSVS
|
||||
bool sawBit = false;
|
||||
for (unsigned long bit : IterateBitSet(mStateBits)) {
|
||||
sawBit = true;
|
||||
}
|
||||
EXPECT_FALSE(sawBit);
|
||||
}
|
||||
|
||||
// Test iterating a result of combining two bitsets.
|
||||
TEST_F(BitSetIteratorTest, NonLValueBitset) {
|
||||
std::bitset<40> otherBits;
|
||||
|
||||
mStateBits.set(1);
|
||||
mStateBits.set(2);
|
||||
mStateBits.set(3);
|
||||
mStateBits.set(4);
|
||||
|
||||
otherBits.set(0);
|
||||
otherBits.set(1);
|
||||
otherBits.set(3);
|
||||
otherBits.set(5);
|
||||
|
||||
std::set<unsigned long> seenBits;
|
||||
|
||||
for (unsigned long bit : IterateBitSet(mStateBits & otherBits)) {
|
||||
EXPECT_EQ(0u, seenBits.count(bit));
|
||||
seenBits.insert(bit);
|
||||
EXPECT_TRUE(mStateBits[bit]);
|
||||
EXPECT_TRUE(otherBits[bit]);
|
||||
}
|
||||
|
||||
EXPECT_EQ((mStateBits & otherBits).count(), seenBits.size());
|
||||
}
|
||||
@@ -1,361 +0,0 @@
|
||||
// Copyright 2017 The NXT 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 <gtest/gtest.h>
|
||||
|
||||
#include "common/CommandAllocator.h"
|
||||
|
||||
using namespace backend;
|
||||
|
||||
// Definition of the command types used in the tests
|
||||
enum class CommandType {
|
||||
Draw,
|
||||
Pipeline,
|
||||
PushConstants,
|
||||
Big,
|
||||
Small,
|
||||
};
|
||||
|
||||
struct CommandDraw {
|
||||
uint32_t first;
|
||||
uint32_t count;
|
||||
};
|
||||
|
||||
struct CommandPipeline {
|
||||
uint64_t pipeline;
|
||||
uint32_t attachmentPoint;
|
||||
};
|
||||
|
||||
struct CommandPushConstants {
|
||||
uint8_t size;
|
||||
uint8_t offset;
|
||||
};
|
||||
|
||||
constexpr int kBigBufferSize = 65536;
|
||||
|
||||
struct CommandBig {
|
||||
uint32_t buffer[kBigBufferSize];
|
||||
};
|
||||
|
||||
struct CommandSmall {
|
||||
uint16_t data;
|
||||
};
|
||||
|
||||
// Test allocating nothing works
|
||||
TEST(CommandAllocator, DoNothingAllocator) {
|
||||
CommandAllocator allocator;
|
||||
}
|
||||
|
||||
// Test iterating over nothing works
|
||||
TEST(CommandAllocator, DoNothingAllocatorWithIterator) {
|
||||
CommandAllocator allocator;
|
||||
CommandIterator iterator(std::move(allocator));
|
||||
iterator.DataWasDestroyed();
|
||||
}
|
||||
|
||||
// Test basic usage of allocator + iterator
|
||||
TEST(CommandAllocator, Basic) {
|
||||
CommandAllocator allocator;
|
||||
|
||||
uint64_t myPipeline = 0xDEADBEEFBEEFDEAD;
|
||||
uint32_t myAttachmentPoint = 2;
|
||||
uint32_t myFirst = 42;
|
||||
uint32_t myCount = 16;
|
||||
|
||||
{
|
||||
CommandPipeline* pipeline = allocator.Allocate<CommandPipeline>(CommandType::Pipeline);
|
||||
pipeline->pipeline = myPipeline;
|
||||
pipeline->attachmentPoint = myAttachmentPoint;
|
||||
|
||||
CommandDraw* draw = allocator.Allocate<CommandDraw>(CommandType::Draw);
|
||||
draw->first = myFirst;
|
||||
draw->count = myCount;
|
||||
}
|
||||
|
||||
{
|
||||
CommandIterator iterator(std::move(allocator));
|
||||
CommandType type;
|
||||
|
||||
bool hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_TRUE(hasNext);
|
||||
ASSERT_EQ(type, CommandType::Pipeline);
|
||||
|
||||
CommandPipeline* pipeline = iterator.NextCommand<CommandPipeline>();
|
||||
ASSERT_EQ(pipeline->pipeline, myPipeline);
|
||||
ASSERT_EQ(pipeline->attachmentPoint, myAttachmentPoint);
|
||||
|
||||
hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_TRUE(hasNext);
|
||||
ASSERT_EQ(type, CommandType::Draw);
|
||||
|
||||
CommandDraw* draw = iterator.NextCommand<CommandDraw>();
|
||||
ASSERT_EQ(draw->first, myFirst);
|
||||
ASSERT_EQ(draw->count, myCount);
|
||||
|
||||
hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_FALSE(hasNext);
|
||||
|
||||
iterator.DataWasDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
// Test basic usage of allocator + iterator with data
|
||||
TEST(CommandAllocator, BasicWithData) {
|
||||
CommandAllocator allocator;
|
||||
|
||||
uint8_t mySize = 8;
|
||||
uint8_t myOffset = 3;
|
||||
uint32_t myValues[5] = {6, 42, 0xFFFFFFFF, 0, 54};
|
||||
|
||||
{
|
||||
CommandPushConstants* pushConstants = allocator.Allocate<CommandPushConstants>(CommandType::PushConstants);
|
||||
pushConstants->size = mySize;
|
||||
pushConstants->offset = myOffset;
|
||||
|
||||
uint32_t* values = allocator.AllocateData<uint32_t>(5);
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
values[i] = myValues[i];
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
CommandIterator iterator(std::move(allocator));
|
||||
CommandType type;
|
||||
|
||||
bool hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_TRUE(hasNext);
|
||||
ASSERT_EQ(type, CommandType::PushConstants);
|
||||
|
||||
CommandPushConstants* pushConstants = iterator.NextCommand<CommandPushConstants>();
|
||||
ASSERT_EQ(pushConstants->size, mySize);
|
||||
ASSERT_EQ(pushConstants->offset, myOffset);
|
||||
|
||||
uint32_t* values = iterator.NextData<uint32_t>(5);
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
ASSERT_EQ(values[i], myValues[i]);
|
||||
}
|
||||
|
||||
hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_FALSE(hasNext);
|
||||
|
||||
iterator.DataWasDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
// Test basic iterating several times
|
||||
TEST(CommandAllocator, MultipleIterations) {
|
||||
CommandAllocator allocator;
|
||||
|
||||
uint32_t myFirst = 42;
|
||||
uint32_t myCount = 16;
|
||||
|
||||
CommandDraw* draw = allocator.Allocate<CommandDraw>(CommandType::Draw);
|
||||
draw->first = myFirst;
|
||||
draw->count = myCount;
|
||||
|
||||
{
|
||||
CommandIterator iterator(std::move(allocator));
|
||||
CommandType type;
|
||||
|
||||
// First iteration
|
||||
bool hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_TRUE(hasNext);
|
||||
ASSERT_EQ(type, CommandType::Draw);
|
||||
|
||||
CommandDraw* draw = iterator.NextCommand<CommandDraw>();
|
||||
ASSERT_EQ(draw->first, myFirst);
|
||||
ASSERT_EQ(draw->count, myCount);
|
||||
|
||||
hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_FALSE(hasNext);
|
||||
|
||||
// Second iteration
|
||||
hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_TRUE(hasNext);
|
||||
ASSERT_EQ(type, CommandType::Draw);
|
||||
|
||||
draw = iterator.NextCommand<CommandDraw>();
|
||||
ASSERT_EQ(draw->first, myFirst);
|
||||
ASSERT_EQ(draw->count, myCount);
|
||||
|
||||
hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_FALSE(hasNext);
|
||||
|
||||
iterator.DataWasDestroyed();
|
||||
}
|
||||
}
|
||||
// Test large commands work
|
||||
TEST(CommandAllocator, LargeCommands) {
|
||||
CommandAllocator allocator;
|
||||
|
||||
const int kCommandCount = 5;
|
||||
|
||||
int count = 0;
|
||||
for (int i = 0; i < kCommandCount; i++) {
|
||||
CommandBig* big = allocator.Allocate<CommandBig>(CommandType::Big);
|
||||
for (int j = 0; j < kBigBufferSize; j++) {
|
||||
big->buffer[j] = count ++;
|
||||
}
|
||||
}
|
||||
|
||||
CommandIterator iterator(std::move(allocator));
|
||||
CommandType type;
|
||||
count = 0;
|
||||
int numCommands = 0;
|
||||
while (iterator.NextCommandId(&type)) {
|
||||
ASSERT_EQ(type, CommandType::Big);
|
||||
|
||||
CommandBig* big = iterator.NextCommand<CommandBig>();
|
||||
for (int i = 0; i < kBigBufferSize; i++) {
|
||||
ASSERT_EQ(big->buffer[i], count);
|
||||
count ++;
|
||||
}
|
||||
numCommands ++;
|
||||
}
|
||||
ASSERT_EQ(numCommands, kCommandCount);
|
||||
|
||||
iterator.DataWasDestroyed();
|
||||
}
|
||||
|
||||
// Test many small commands work
|
||||
TEST(CommandAllocator, ManySmallCommands) {
|
||||
CommandAllocator allocator;
|
||||
|
||||
// Stay under max representable uint16_t
|
||||
const int kCommandCount = 50000;
|
||||
|
||||
int count = 0;
|
||||
for (int i = 0; i < kCommandCount; i++) {
|
||||
CommandSmall* small = allocator.Allocate<CommandSmall>(CommandType::Small);
|
||||
small->data = count ++;
|
||||
}
|
||||
|
||||
CommandIterator iterator(std::move(allocator));
|
||||
CommandType type;
|
||||
count = 0;
|
||||
int numCommands = 0;
|
||||
while (iterator.NextCommandId(&type)) {
|
||||
ASSERT_EQ(type, CommandType::Small);
|
||||
|
||||
CommandSmall* small = iterator.NextCommand<CommandSmall>();
|
||||
ASSERT_EQ(small->data, count);
|
||||
count ++;
|
||||
numCommands ++;
|
||||
}
|
||||
ASSERT_EQ(numCommands, kCommandCount);
|
||||
|
||||
iterator.DataWasDestroyed();
|
||||
}
|
||||
|
||||
// ________
|
||||
// / \
|
||||
// | POUIC! |
|
||||
// \_ ______/
|
||||
// v
|
||||
// ()_()
|
||||
// (O.o)
|
||||
// (> <)o
|
||||
|
||||
// Test usage of iterator.Reset
|
||||
TEST(CommandAllocator, IteratorReset) {
|
||||
CommandAllocator allocator;
|
||||
|
||||
uint64_t myPipeline = 0xDEADBEEFBEEFDEAD;
|
||||
uint32_t myAttachmentPoint = 2;
|
||||
uint32_t myFirst = 42;
|
||||
uint32_t myCount = 16;
|
||||
|
||||
{
|
||||
CommandPipeline* pipeline = allocator.Allocate<CommandPipeline>(CommandType::Pipeline);
|
||||
pipeline->pipeline = myPipeline;
|
||||
pipeline->attachmentPoint = myAttachmentPoint;
|
||||
|
||||
CommandDraw* draw = allocator.Allocate<CommandDraw>(CommandType::Draw);
|
||||
draw->first = myFirst;
|
||||
draw->count = myCount;
|
||||
}
|
||||
|
||||
{
|
||||
CommandIterator iterator(std::move(allocator));
|
||||
CommandType type;
|
||||
|
||||
bool hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_TRUE(hasNext);
|
||||
ASSERT_EQ(type, CommandType::Pipeline);
|
||||
|
||||
CommandPipeline* pipeline = iterator.NextCommand<CommandPipeline>();
|
||||
ASSERT_EQ(pipeline->pipeline, myPipeline);
|
||||
ASSERT_EQ(pipeline->attachmentPoint, myAttachmentPoint);
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_TRUE(hasNext);
|
||||
ASSERT_EQ(type, CommandType::Pipeline);
|
||||
|
||||
pipeline = iterator.NextCommand<CommandPipeline>();
|
||||
ASSERT_EQ(pipeline->pipeline, myPipeline);
|
||||
ASSERT_EQ(pipeline->attachmentPoint, myAttachmentPoint);
|
||||
|
||||
hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_TRUE(hasNext);
|
||||
ASSERT_EQ(type, CommandType::Draw);
|
||||
|
||||
CommandDraw* draw = iterator.NextCommand<CommandDraw>();
|
||||
ASSERT_EQ(draw->first, myFirst);
|
||||
ASSERT_EQ(draw->count, myCount);
|
||||
|
||||
hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_FALSE(hasNext);
|
||||
|
||||
iterator.DataWasDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
// Test iterating empty iterators
|
||||
TEST(CommandAllocator, EmptyIterator) {
|
||||
{
|
||||
CommandAllocator allocator;
|
||||
CommandIterator iterator(std::move(allocator));
|
||||
|
||||
CommandType type;
|
||||
bool hasNext = iterator.NextCommandId(&type);
|
||||
ASSERT_FALSE(hasNext);
|
||||
|
||||
iterator.DataWasDestroyed();
|
||||
}
|
||||
{
|
||||
CommandAllocator allocator;
|
||||
CommandIterator iterator1(std::move(allocator));
|
||||
CommandIterator iterator2(std::move(iterator1));
|
||||
|
||||
CommandType type;
|
||||
bool hasNext = iterator2.NextCommandId(&type);
|
||||
ASSERT_FALSE(hasNext);
|
||||
|
||||
iterator1.DataWasDestroyed();
|
||||
iterator2.DataWasDestroyed();
|
||||
}
|
||||
{
|
||||
CommandIterator iterator1;
|
||||
CommandIterator iterator2(std::move(iterator1));
|
||||
|
||||
CommandType type;
|
||||
bool hasNext = iterator2.NextCommandId(&type);
|
||||
ASSERT_FALSE(hasNext);
|
||||
|
||||
iterator1.DataWasDestroyed();
|
||||
iterator2.DataWasDestroyed();
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
// Copyright 2017 The NXT 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 <gtest/gtest.h>
|
||||
|
||||
#include "common/Math.h"
|
||||
|
||||
using namespace backend;
|
||||
|
||||
// Tests for ScanForward
|
||||
TEST(Math, ScanForward) {
|
||||
// Test extrema
|
||||
ASSERT_EQ(ScanForward(1), 0);
|
||||
ASSERT_EQ(ScanForward(0x8000000000000000), 63);
|
||||
|
||||
// Test with more than one bit set.
|
||||
ASSERT_EQ(ScanForward(256), 8);
|
||||
ASSERT_EQ(ScanForward(256 + 32), 5);
|
||||
ASSERT_EQ(ScanForward(1024 + 256 + 32), 5);
|
||||
}
|
||||
|
||||
// Tests for Log2
|
||||
TEST(Math, Log2) {
|
||||
// Test extrema
|
||||
ASSERT_EQ(Log2(1), 0);
|
||||
ASSERT_EQ(Log2(0xFFFFFFFF), 31);
|
||||
|
||||
// Test boundary between two logs
|
||||
ASSERT_EQ(Log2(0x80000000), 31);
|
||||
ASSERT_EQ(Log2(0x7FFFFFFF), 30);
|
||||
|
||||
ASSERT_EQ(Log2(16), 4);
|
||||
ASSERT_EQ(Log2(15), 3);
|
||||
}
|
||||
|
||||
// Tests for IsPowerOfTwo
|
||||
TEST(Math, IsPowerOfTwo) {
|
||||
ASSERT_TRUE(IsPowerOfTwo(1));
|
||||
ASSERT_TRUE(IsPowerOfTwo(2));
|
||||
ASSERT_FALSE(IsPowerOfTwo(3));
|
||||
|
||||
ASSERT_TRUE(IsPowerOfTwo(0x8000000));
|
||||
ASSERT_FALSE(IsPowerOfTwo(0x8000400));
|
||||
}
|
||||
|
||||
// Tests for Align
|
||||
TEST(Math, Align) {
|
||||
constexpr size_t kTestAlignment = 8;
|
||||
|
||||
char buffer[kTestAlignment * 4];
|
||||
|
||||
for (size_t i = 0; i < 2 * kTestAlignment; ++i) {
|
||||
char* unaligned = &buffer[i];
|
||||
char* aligned = Align(unaligned, kTestAlignment);
|
||||
|
||||
ASSERT_GE(aligned - unaligned, 0);
|
||||
ASSERT_LT(aligned - unaligned, kTestAlignment);
|
||||
ASSERT_EQ(reinterpret_cast<intptr_t>(aligned) & (kTestAlignment -1), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests for IsAligned
|
||||
TEST(Math, IsAligned) {
|
||||
constexpr size_t kTestAlignment = 8;
|
||||
|
||||
char buffer[kTestAlignment * 4];
|
||||
|
||||
for (size_t i = 0; i < 2 * kTestAlignment; ++i) {
|
||||
char* unaligned = &buffer[i];
|
||||
char* aligned = Align(unaligned, kTestAlignment);
|
||||
|
||||
ASSERT_EQ(IsAligned(unaligned, kTestAlignment), unaligned == aligned);
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
// Copyright 2017 The NXT 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 <gtest/gtest.h>
|
||||
|
||||
#include "common/PerStage.h"
|
||||
|
||||
using namespace backend;
|
||||
|
||||
// Tests for StageBit
|
||||
TEST(PerStage, StageBit) {
|
||||
ASSERT_EQ(StageBit(nxt::ShaderStage::Vertex), nxt::ShaderStageBit::Vertex);
|
||||
ASSERT_EQ(StageBit(nxt::ShaderStage::Fragment), nxt::ShaderStageBit::Fragment);
|
||||
ASSERT_EQ(StageBit(nxt::ShaderStage::Compute), nxt::ShaderStageBit::Compute);
|
||||
}
|
||||
|
||||
// Basic test for the PerStage container
|
||||
TEST(PerStage, PerStage) {
|
||||
PerStage<int> data;
|
||||
|
||||
// Store data using nxt::ShaderStage
|
||||
data[nxt::ShaderStage::Vertex] = 42;
|
||||
data[nxt::ShaderStage::Fragment] = 3;
|
||||
data[nxt::ShaderStage::Compute] = -1;
|
||||
|
||||
// Load it using nxt::ShaderStageBit
|
||||
ASSERT_EQ(data[nxt::ShaderStageBit::Vertex], 42);
|
||||
ASSERT_EQ(data[nxt::ShaderStageBit::Fragment], 3);
|
||||
ASSERT_EQ(data[nxt::ShaderStageBit::Compute], -1);
|
||||
}
|
||||
|
||||
// Test IterateStages with kAllStages
|
||||
TEST(PerStage, IterateAllStages) {
|
||||
PerStage<int> counts;
|
||||
counts[nxt::ShaderStage::Vertex] = 0;
|
||||
counts[nxt::ShaderStage::Fragment] = 0;
|
||||
counts[nxt::ShaderStage::Compute] = 0;
|
||||
|
||||
for (auto stage : IterateStages(kAllStages)) {
|
||||
counts[stage] ++;
|
||||
}
|
||||
|
||||
ASSERT_EQ(counts[nxt::ShaderStageBit::Vertex], 1);
|
||||
ASSERT_EQ(counts[nxt::ShaderStageBit::Fragment], 1);
|
||||
ASSERT_EQ(counts[nxt::ShaderStageBit::Compute], 1);
|
||||
}
|
||||
|
||||
// Test IterateStages with one stage
|
||||
TEST(PerStage, IterateOneStage) {
|
||||
PerStage<int> counts;
|
||||
counts[nxt::ShaderStage::Vertex] = 0;
|
||||
counts[nxt::ShaderStage::Fragment] = 0;
|
||||
counts[nxt::ShaderStage::Compute] = 0;
|
||||
|
||||
for (auto stage : IterateStages(nxt::ShaderStageBit::Fragment)) {
|
||||
counts[stage] ++;
|
||||
}
|
||||
|
||||
ASSERT_EQ(counts[nxt::ShaderStageBit::Vertex], 0);
|
||||
ASSERT_EQ(counts[nxt::ShaderStageBit::Fragment], 1);
|
||||
ASSERT_EQ(counts[nxt::ShaderStageBit::Compute], 0);
|
||||
}
|
||||
|
||||
// Test IterateStages with no stage
|
||||
TEST(PerStage, IterateNoStages) {
|
||||
PerStage<int> counts;
|
||||
counts[nxt::ShaderStage::Vertex] = 0;
|
||||
counts[nxt::ShaderStage::Fragment] = 0;
|
||||
counts[nxt::ShaderStage::Compute] = 0;
|
||||
|
||||
for (auto stage : IterateStages(nxt::ShaderStageBit::Fragment & nxt::ShaderStageBit::Vertex)) {
|
||||
counts[stage] ++;
|
||||
}
|
||||
|
||||
ASSERT_EQ(counts[nxt::ShaderStageBit::Vertex], 0);
|
||||
ASSERT_EQ(counts[nxt::ShaderStageBit::Fragment], 0);
|
||||
ASSERT_EQ(counts[nxt::ShaderStageBit::Compute], 0);
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
// Copyright 2017 The NXT 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 <gtest/gtest.h>
|
||||
|
||||
#include "common/RefCounted.h"
|
||||
|
||||
using namespace backend;
|
||||
|
||||
struct RCTest : public RefCounted {
|
||||
RCTest() {
|
||||
}
|
||||
|
||||
RCTest(bool* deleted): deleted(deleted) {
|
||||
}
|
||||
|
||||
~RCTest() override {
|
||||
if (deleted != nullptr) {
|
||||
*deleted = true;
|
||||
}
|
||||
}
|
||||
|
||||
RCTest* GetThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
bool* deleted = nullptr;
|
||||
};
|
||||
|
||||
// Test that RCs start with one external ref, and removing it destroys the object.
|
||||
TEST(RefCounted, StartsWithOneExternalRef) {
|
||||
bool deleted = false;
|
||||
auto test = new RCTest(&deleted);
|
||||
|
||||
test->Release();
|
||||
ASSERT_TRUE(deleted);
|
||||
}
|
||||
|
||||
// Test internal refs keep the RC alive.
|
||||
TEST(RefCounted, InternalRefKeepsAlive) {
|
||||
bool deleted = false;
|
||||
auto test = new RCTest(&deleted);
|
||||
|
||||
test->ReferenceInternal();
|
||||
test->Release();
|
||||
ASSERT_FALSE(deleted);
|
||||
|
||||
test->ReleaseInternal();
|
||||
ASSERT_TRUE(deleted);
|
||||
}
|
||||
|
||||
// Test Ref remove internal reference when going out of scope
|
||||
TEST(Ref, EndOfScopeRemovesInternalRef) {
|
||||
bool deleted = false;
|
||||
{
|
||||
Ref<RCTest> test(new RCTest(&deleted));
|
||||
test->Release();
|
||||
}
|
||||
ASSERT_TRUE(deleted);
|
||||
}
|
||||
|
||||
// Test getting pointer out of the Ref
|
||||
TEST(Ref, Gets) {
|
||||
RCTest* original = new RCTest;
|
||||
Ref<RCTest> test(original);
|
||||
test->Release();
|
||||
|
||||
ASSERT_EQ(test.Get(), original);
|
||||
ASSERT_EQ(&*test, original);
|
||||
ASSERT_EQ(test->GetThis(), original);
|
||||
}
|
||||
|
||||
// Test Refs default to null
|
||||
TEST(Ref, DefaultsToNull) {
|
||||
Ref<RCTest> test;
|
||||
|
||||
ASSERT_EQ(test.Get(), nullptr);
|
||||
ASSERT_EQ(&*test, nullptr);
|
||||
ASSERT_EQ(test->GetThis(), nullptr);
|
||||
}
|
||||
|
||||
// Test Refs can be used inside ifs
|
||||
TEST(Ref, BoolConversion) {
|
||||
Ref<RCTest> empty;
|
||||
Ref<RCTest> full(new RCTest);
|
||||
full->Release();
|
||||
|
||||
if (!full || empty) {
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Test Ref's copy constructor
|
||||
TEST(Ref, CopyConstructor) {
|
||||
bool deleted;
|
||||
RCTest* original = new RCTest(&deleted);
|
||||
|
||||
Ref<RCTest> source(original);
|
||||
Ref<RCTest> destination(source);
|
||||
original->Release();
|
||||
|
||||
ASSERT_EQ(source.Get(), original);
|
||||
ASSERT_EQ(destination.Get(), original);
|
||||
|
||||
source = nullptr;
|
||||
ASSERT_FALSE(deleted);
|
||||
destination = nullptr;
|
||||
ASSERT_TRUE(deleted);
|
||||
}
|
||||
|
||||
// Test Ref's copy assignment
|
||||
TEST(Ref, CopyAssignment) {
|
||||
bool deleted;
|
||||
RCTest* original = new RCTest(&deleted);
|
||||
|
||||
Ref<RCTest> source(original);
|
||||
original->Release();
|
||||
|
||||
Ref<RCTest> destination;
|
||||
destination = source;
|
||||
|
||||
ASSERT_EQ(source.Get(), original);
|
||||
ASSERT_EQ(destination.Get(), original);
|
||||
|
||||
source = nullptr;
|
||||
// This fails when address sanitizer is turned on
|
||||
ASSERT_FALSE(deleted);
|
||||
|
||||
destination = nullptr;
|
||||
ASSERT_TRUE(deleted);
|
||||
}
|
||||
|
||||
// Test Ref's move constructor
|
||||
TEST(Ref, MoveConstructor) {
|
||||
bool deleted;
|
||||
RCTest* original = new RCTest(&deleted);
|
||||
|
||||
Ref<RCTest> source(original);
|
||||
Ref<RCTest> destination(std::move(source));
|
||||
original->Release();
|
||||
|
||||
ASSERT_EQ(source.Get(), nullptr);
|
||||
ASSERT_EQ(destination.Get(), original);
|
||||
ASSERT_FALSE(deleted);
|
||||
|
||||
destination = nullptr;
|
||||
ASSERT_TRUE(deleted);
|
||||
}
|
||||
|
||||
// Test Ref's move assignment
|
||||
TEST(Ref, MoveAssignment) {
|
||||
bool deleted;
|
||||
RCTest* original = new RCTest(&deleted);
|
||||
|
||||
Ref<RCTest> source(original);
|
||||
original->Release();
|
||||
|
||||
Ref<RCTest> destination;
|
||||
destination = std::move(source);
|
||||
|
||||
ASSERT_EQ(source.Get(), nullptr);
|
||||
ASSERT_EQ(destination.Get(), original);
|
||||
ASSERT_FALSE(deleted);
|
||||
|
||||
destination = nullptr;
|
||||
ASSERT_TRUE(deleted);
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
// Copyright 2017 The NXT 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 <gtest/gtest.h>
|
||||
|
||||
#include "common/RefCounted.h"
|
||||
#include "common/ToBackend.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
// Make our own Base - Backend object pair, reusing the CommandBuffer name
|
||||
namespace backend {
|
||||
class CommandBufferBase : public RefCounted {
|
||||
};
|
||||
}
|
||||
|
||||
using namespace backend;
|
||||
|
||||
class MyCommandBuffer : public CommandBufferBase {
|
||||
};
|
||||
|
||||
struct MyBackendTraits {
|
||||
using CommandBufferType = MyCommandBuffer;
|
||||
};
|
||||
|
||||
// Instanciate ToBackend for our "backend"
|
||||
template<typename T>
|
||||
auto ToBackend(T&& common) -> decltype(ToBackendBase<MyBackendTraits>(common)) {
|
||||
return ToBackendBase<MyBackendTraits>(common);
|
||||
}
|
||||
|
||||
// Test that ToBackend correctly converts pointers to base classes.
|
||||
TEST(ToBackend, Pointers) {
|
||||
{
|
||||
MyCommandBuffer* cmdBuf = new MyCommandBuffer;
|
||||
const CommandBufferBase* base = cmdBuf;
|
||||
|
||||
auto backendCmdBuf = ToBackend(base);
|
||||
static_assert(std::is_same<decltype(backendCmdBuf), const MyCommandBuffer*>::value, "");
|
||||
ASSERT_EQ(cmdBuf, backendCmdBuf);
|
||||
|
||||
cmdBuf->Release();
|
||||
}
|
||||
{
|
||||
MyCommandBuffer* cmdBuf = new MyCommandBuffer;
|
||||
CommandBufferBase* base = cmdBuf;
|
||||
|
||||
auto backendCmdBuf = ToBackend(base);
|
||||
static_assert(std::is_same<decltype(backendCmdBuf), MyCommandBuffer*>::value, "");
|
||||
ASSERT_EQ(cmdBuf, backendCmdBuf);
|
||||
|
||||
cmdBuf->Release();
|
||||
}
|
||||
}
|
||||
|
||||
// Test that ToBackend correctly converts Refs to base classes.
|
||||
TEST(ToBackend, Ref) {
|
||||
{
|
||||
MyCommandBuffer* cmdBuf = new MyCommandBuffer;
|
||||
const Ref<CommandBufferBase> base(cmdBuf);
|
||||
|
||||
const auto& backendCmdBuf = ToBackend(base);
|
||||
static_assert(std::is_same<decltype(ToBackend(base)), const Ref<MyCommandBuffer>&>::value, "");
|
||||
ASSERT_EQ(cmdBuf, backendCmdBuf.Get());
|
||||
|
||||
cmdBuf->Release();
|
||||
}
|
||||
{
|
||||
MyCommandBuffer* cmdBuf = new MyCommandBuffer;
|
||||
Ref<CommandBufferBase> base(cmdBuf);
|
||||
|
||||
auto backendCmdBuf = ToBackend(base);
|
||||
static_assert(std::is_same<decltype(ToBackend(base)), Ref<MyCommandBuffer>&>::value, "");
|
||||
ASSERT_EQ(cmdBuf, backendCmdBuf.Get());
|
||||
|
||||
cmdBuf->Release();
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright 2017 The NXT 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 <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in New Issue
Block a user