diff options
-rw-r--r-- | src/amberscript/parser.cc | 14 | ||||
-rw-r--r-- | src/amberscript/parser.h | 12 | ||||
-rw-r--r-- | src/amberscript/parser_test.cc | 155 | ||||
-rw-r--r-- | src/amberscript/script_test.cc | 18 | ||||
-rw-r--r-- | src/buffer.cc | 16 | ||||
-rw-r--r-- | src/buffer.h | 94 | ||||
-rw-r--r-- | src/buffer_test.cc | 20 | ||||
-rw-r--r-- | src/vkscript/executor.cc | 20 | ||||
-rw-r--r-- | src/vkscript/nodes.cc | 12 | ||||
-rw-r--r-- | src/vkscript/nodes.h | 29 | ||||
-rw-r--r-- | src/vkscript/parser.cc | 21 | ||||
-rw-r--r-- | src/vkscript/parser_test.cc | 91 | ||||
-rw-r--r-- | src/vkscript/script.cc | 5 | ||||
-rw-r--r-- | src/vkscript/script.h | 2 |
14 files changed, 278 insertions, 231 deletions
diff --git a/src/amberscript/parser.cc b/src/amberscript/parser.cc index c11d3fb..d45c52a 100644 --- a/src/amberscript/parser.cc +++ b/src/amberscript/parser.cc @@ -432,7 +432,7 @@ Result Parser::ParseBuffer() { if (!r.IsSuccess()) return r; - auto buffer = MakeUnique<Buffer>(type); + auto buffer = MakeUnique<DataBuffer>(type); token = tokenizer_->NextToken(); if (!token->IsString()) @@ -474,7 +474,7 @@ Result Parser::ParseBuffer() { return {}; } -Result Parser::ParseBufferFramebuffer(Buffer* buffer) { +Result Parser::ParseBufferFramebuffer(DataBuffer* buffer) { auto token = tokenizer_->NextToken(); if (token->IsEOL() || token->IsEOS()) return Result("BUFFER framebuffer missing DIMS values"); @@ -506,7 +506,7 @@ Result Parser::ParseBufferFramebuffer(Buffer* buffer) { return ValidateEndOfStatement("BUFFER framebuffer command"); } -Result Parser::ParseBufferInitializer(Buffer* buffer) { +Result Parser::ParseBufferInitializer(DataBuffer* buffer) { auto token = tokenizer_->NextToken(); if (!token->IsString()) return Result("BUFFER invalid data type"); @@ -530,7 +530,7 @@ Result Parser::ParseBufferInitializer(Buffer* buffer) { return Result("unknown initializer for BUFFER"); } -Result Parser::ParseBufferInitializerSize(Buffer* buffer) { +Result Parser::ParseBufferInitializerSize(DataBuffer* buffer) { auto token = tokenizer_->NextToken(); if (token->IsEOS() || token->IsEOL()) return Result("BUFFER size missing"); @@ -552,7 +552,7 @@ Result Parser::ParseBufferInitializerSize(Buffer* buffer) { return Result("invalid BUFFER initializer provided"); } -Result Parser::ParseBufferInitializerFill(Buffer* buffer, +Result Parser::ParseBufferInitializerFill(DataBuffer* buffer, uint32_t size_in_items) { auto token = tokenizer_->NextToken(); if (token->IsEOS() || token->IsEOL()) @@ -578,7 +578,7 @@ Result Parser::ParseBufferInitializerFill(Buffer* buffer, return ValidateEndOfStatement("BUFFER fill command"); } -Result Parser::ParseBufferInitializerSeries(Buffer* buffer, +Result Parser::ParseBufferInitializerSeries(DataBuffer* buffer, uint32_t size_in_items) { auto token = tokenizer_->NextToken(); if (token->IsEOS() || token->IsEOL()) @@ -627,7 +627,7 @@ Result Parser::ParseBufferInitializerSeries(Buffer* buffer, return ValidateEndOfStatement("BUFFER series_from command"); } -Result Parser::ParseBufferInitializerData(Buffer* buffer) { +Result Parser::ParseBufferInitializerData(DataBuffer* buffer) { auto token = tokenizer_->NextToken(); if (!token->IsEOL()) return Result("extra parameters after BUFFER data command"); diff --git a/src/amberscript/parser.h b/src/amberscript/parser.h index aa86e19..7e4b764 100644 --- a/src/amberscript/parser.h +++ b/src/amberscript/parser.h @@ -51,12 +51,12 @@ class Parser : public amber::Parser { Result ValidateEndOfStatement(const std::string& name); Result ParseBuffer(); - Result ParseBufferInitializer(Buffer*); - Result ParseBufferInitializerSize(Buffer*); - Result ParseBufferInitializerFill(Buffer*, uint32_t); - Result ParseBufferInitializerSeries(Buffer*, uint32_t); - Result ParseBufferInitializerData(Buffer*); - Result ParseBufferFramebuffer(Buffer*); + Result ParseBufferInitializer(DataBuffer*); + Result ParseBufferInitializerSize(DataBuffer*); + Result ParseBufferInitializerFill(DataBuffer*, uint32_t); + Result ParseBufferInitializerSeries(DataBuffer*, uint32_t); + Result ParseBufferInitializerData(DataBuffer*); + Result ParseBufferFramebuffer(DataBuffer*); Result ParseShaderBlock(); Result ParsePipelineBlock(); Result ParsePipelineAttach(Pipeline*); diff --git a/src/amberscript/parser_test.cc b/src/amberscript/parser_test.cc index 5d19139..fd57a5d 100644 --- a/src/amberscript/parser_test.cc +++ b/src/amberscript/parser_test.cc @@ -957,12 +957,15 @@ END)"; ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); EXPECT_EQ(BufferType::kStorage, buffers[0]->GetBufferType()); - EXPECT_TRUE(buffers[0]->GetDatumType().IsUint32()); - EXPECT_EQ(7U, buffers[0]->GetSize()); - EXPECT_EQ(7U * sizeof(uint32_t), buffers[0]->GetSizeInBytes()); + + ASSERT_TRUE(buffers[0]->IsDataBuffer()); + auto* buffer = buffers[0]->AsDataBuffer(); + EXPECT_TRUE(buffer->GetDatumType().IsUint32()); + EXPECT_EQ(7U, buffer->GetSize()); + EXPECT_EQ(7U * sizeof(uint32_t), buffer->GetSizeInBytes()); std::vector<uint32_t> results = {1, 2, 3, 4, 55, 99, 1234}; - const auto& data = buffers[0]->GetData(); + const auto& data = buffer->GetData(); ASSERT_EQ(results.size(), data.size()); for (size_t i = 0; i < results.size(); ++i) { ASSERT_TRUE(data[i].IsInteger()); @@ -983,14 +986,16 @@ TEST_F(AmberScriptParserTest, BufferFill) { ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); - EXPECT_EQ("my_buffer", buffers[0]->GetName()); - EXPECT_EQ(BufferType::kColor, buffers[0]->GetBufferType()); - EXPECT_TRUE(buffers[0]->GetDatumType().IsUint8()); - EXPECT_EQ(5U, buffers[0]->GetSize()); - EXPECT_EQ(5U * sizeof(uint8_t), buffers[0]->GetSizeInBytes()); + ASSERT_TRUE(buffers[0]->IsDataBuffer()); + auto* buffer = buffers[0]->AsDataBuffer(); + EXPECT_EQ("my_buffer", buffer->GetName()); + EXPECT_EQ(BufferType::kColor, buffer->GetBufferType()); + EXPECT_TRUE(buffer->GetDatumType().IsUint8()); + EXPECT_EQ(5U, buffer->GetSize()); + EXPECT_EQ(5U * sizeof(uint8_t), buffer->GetSizeInBytes()); std::vector<uint32_t> results = {5, 5, 5, 5, 5}; - const auto& data = buffers[0]->GetData(); + const auto& data = buffer->GetData(); ASSERT_EQ(results.size(), data.size()); for (size_t i = 0; i < results.size(); ++i) { ASSERT_TRUE(data[i].IsInteger()); @@ -1011,14 +1016,16 @@ TEST_F(AmberScriptParserTest, BufferFillFloat) { ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); - EXPECT_EQ("my_buffer", buffers[0]->GetName()); - EXPECT_EQ(BufferType::kColor, buffers[0]->GetBufferType()); - EXPECT_TRUE(buffers[0]->GetDatumType().IsFloat()); - EXPECT_EQ(5U, buffers[0]->GetSize()); - EXPECT_EQ(5U * sizeof(float), buffers[0]->GetSizeInBytes()); + ASSERT_TRUE(buffers[0]->IsDataBuffer()); + auto* buffer = buffers[0]->AsDataBuffer(); + EXPECT_EQ("my_buffer", buffer->GetName()); + EXPECT_EQ(BufferType::kColor, buffer->GetBufferType()); + EXPECT_TRUE(buffer->GetDatumType().IsFloat()); + EXPECT_EQ(5U, buffer->GetSize()); + EXPECT_EQ(5U * sizeof(float), buffer->GetSizeInBytes()); std::vector<float> results = {5.2f, 5.2f, 5.2f, 5.2f, 5.2f}; - const auto& data = buffers[0]->GetData(); + const auto& data = buffer->GetData(); ASSERT_EQ(results.size(), data.size()); for (size_t i = 0; i < results.size(); ++i) { ASSERT_TRUE(data[i].IsFloat()); @@ -1040,14 +1047,16 @@ TEST_F(AmberScriptParserTest, BufferSeries) { ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); - EXPECT_EQ("my_buffer", buffers[0]->GetName()); - EXPECT_EQ(BufferType::kColor, buffers[0]->GetBufferType()); - EXPECT_TRUE(buffers[0]->GetDatumType().IsUint8()); - EXPECT_EQ(5U, buffers[0]->GetSize()); - EXPECT_EQ(5U * sizeof(uint8_t), buffers[0]->GetSizeInBytes()); + ASSERT_TRUE(buffers[0]->IsDataBuffer()); + auto* buffer = buffers[0]->AsDataBuffer(); + EXPECT_EQ("my_buffer", buffer->GetName()); + EXPECT_EQ(BufferType::kColor, buffer->GetBufferType()); + EXPECT_TRUE(buffer->GetDatumType().IsUint8()); + EXPECT_EQ(5U, buffer->GetSize()); + EXPECT_EQ(5U * sizeof(uint8_t), buffer->GetSizeInBytes()); std::vector<uint8_t> results = {2, 3, 4, 5, 6}; - const auto& data = buffers[0]->GetData(); + const auto& data = buffer->GetData(); ASSERT_EQ(results.size(), data.size()); for (size_t i = 0; i < results.size(); ++i) { ASSERT_TRUE(data[i].IsInteger()); @@ -1070,14 +1079,16 @@ TEST_F(AmberScriptParserTest, BufferSeriesFloat) { ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); - EXPECT_EQ("my_buffer", buffers[0]->GetName()); - EXPECT_EQ(BufferType::kColor, buffers[0]->GetBufferType()); - EXPECT_TRUE(buffers[0]->GetDatumType().IsFloat()); - EXPECT_EQ(5U, buffers[0]->GetSize()); - EXPECT_EQ(5U * sizeof(float), buffers[0]->GetSizeInBytes()); + ASSERT_TRUE(buffers[0]->IsDataBuffer()); + auto* buffer = buffers[0]->AsDataBuffer(); + EXPECT_EQ("my_buffer", buffer->GetName()); + EXPECT_EQ(BufferType::kColor, buffer->GetBufferType()); + EXPECT_TRUE(buffer->GetDatumType().IsFloat()); + EXPECT_EQ(5U, buffer->GetSize()); + EXPECT_EQ(5U * sizeof(float), buffer->GetSizeInBytes()); std::vector<float> results = {2.2f, 3.3f, 4.4f, 5.5f, 6.6f}; - const auto& data = buffers[0]->GetData(); + const auto& data = buffer->GetData(); ASSERT_EQ(results.size(), data.size()); for (size_t i = 0; i < results.size(); ++i) { ASSERT_TRUE(data[i].IsFloat()); @@ -1098,12 +1109,14 @@ TEST_F(AmberScriptParserTest, BufferFramebuffer) { ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); - EXPECT_EQ("my_buffer", buffers[0]->GetName()); - EXPECT_EQ(BufferType::kFramebuffer, buffers[0]->GetBufferType()); - EXPECT_TRUE(buffers[0]->GetDatumType().IsUint32()); - EXPECT_EQ(4U, buffers[0]->GetDatumType().ColumnCount()); - EXPECT_EQ(800U * 600U, buffers[0]->GetSize()); - EXPECT_EQ(800U * 600U * 4U * sizeof(uint32_t), buffers[0]->GetSizeInBytes()); + ASSERT_TRUE(buffers[0]->IsDataBuffer()); + auto* buffer = buffers[0]->AsDataBuffer(); + EXPECT_EQ("my_buffer", buffer->GetName()); + EXPECT_EQ(BufferType::kFramebuffer, buffer->GetBufferType()); + EXPECT_TRUE(buffer->GetDatumType().IsUint32()); + EXPECT_EQ(4U, buffer->GetDatumType().ColumnCount()); + EXPECT_EQ(800U * 600U, buffer->GetSize()); + EXPECT_EQ(800U * 600U * 4U * sizeof(uint32_t), buffer->GetSizeInBytes()); } TEST_F(AmberScriptParserTest, BufferMultipleBuffers) { @@ -1124,14 +1137,16 @@ END)"; ASSERT_EQ(2U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); - EXPECT_EQ("color_buffer", buffers[0]->GetName()); - EXPECT_EQ(BufferType::kColor, buffers[0]->GetBufferType()); - EXPECT_TRUE(buffers[0]->GetDatumType().IsUint8()); - EXPECT_EQ(5U, buffers[0]->GetSize()); - EXPECT_EQ(5U * sizeof(uint8_t), buffers[0]->GetSizeInBytes()); + ASSERT_TRUE(buffers[0]->IsDataBuffer()); + auto* buffer = buffers[0]->AsDataBuffer(); + EXPECT_EQ("color_buffer", buffer->GetName()); + EXPECT_EQ(BufferType::kColor, buffer->GetBufferType()); + EXPECT_TRUE(buffer->GetDatumType().IsUint8()); + EXPECT_EQ(5U, buffer->GetSize()); + EXPECT_EQ(5U * sizeof(uint8_t), buffer->GetSizeInBytes()); std::vector<uint32_t> results0 = {5, 5, 5, 5, 5}; - const auto& data0 = buffers[0]->GetData(); + const auto& data0 = buffer->GetData(); ASSERT_EQ(results0.size(), data0.size()); for (size_t i = 0; i < results0.size(); ++i) { ASSERT_TRUE(data0[i].IsInteger()); @@ -1139,14 +1154,16 @@ END)"; } ASSERT_TRUE(buffers[1] != nullptr); - EXPECT_EQ("storage_buffer", buffers[1]->GetName()); - EXPECT_EQ(BufferType::kStorage, buffers[1]->GetBufferType()); - EXPECT_TRUE(buffers[1]->GetDatumType().IsUint32()); - EXPECT_EQ(7U, buffers[1]->GetSize()); - EXPECT_EQ(7U * sizeof(uint32_t), buffers[1]->GetSizeInBytes()); + ASSERT_TRUE(buffers[1]->IsDataBuffer()); + buffer = buffers[1]->AsDataBuffer(); + EXPECT_EQ("storage_buffer", buffer->GetName()); + EXPECT_EQ(BufferType::kStorage, buffer->GetBufferType()); + EXPECT_TRUE(buffer->GetDatumType().IsUint32()); + EXPECT_EQ(7U, buffer->GetSize()); + EXPECT_EQ(7U * sizeof(uint32_t), buffer->GetSizeInBytes()); std::vector<uint32_t> results1 = {1, 2, 3, 4, 55, 99, 1234}; - const auto& data1 = buffers[1]->GetData(); + const auto& data1 = buffer->GetData(); ASSERT_EQ(results1.size(), data1.size()); for (size_t i = 0; i < results1.size(); ++i) { ASSERT_TRUE(data1[i].IsInteger()); @@ -1168,14 +1185,16 @@ BUFFER index my_index_buffer DATA_TYPE vec2<int32> SIZE 5 FILL 2)"; ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); - EXPECT_EQ("my_index_buffer", buffers[0]->GetName()); - EXPECT_EQ(BufferType::kIndex, buffers[0]->GetBufferType()); - EXPECT_TRUE(buffers[0]->GetDatumType().IsInt32()); - EXPECT_EQ(5U, buffers[0]->GetSize()); - EXPECT_EQ(5U * 2 * sizeof(int32_t), buffers[0]->GetSizeInBytes()); + ASSERT_TRUE(buffers[0]->IsDataBuffer()); + auto* buffer = buffers[0]->AsDataBuffer(); + EXPECT_EQ("my_index_buffer", buffer->GetName()); + EXPECT_EQ(BufferType::kIndex, buffer->GetBufferType()); + EXPECT_TRUE(buffer->GetDatumType().IsInt32()); + EXPECT_EQ(5U, buffer->GetSize()); + EXPECT_EQ(5U * 2 * sizeof(int32_t), buffer->GetSizeInBytes()); std::vector<int32_t> results0 = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; - const auto& data0 = buffers[0]->GetData(); + const auto& data0 = buffer->GetData(); ASSERT_EQ(results0.size(), data0.size()); for (size_t i = 0; i < results0.size(); ++i) { ASSERT_TRUE(data0[i].IsInteger()); @@ -1203,14 +1222,16 @@ END ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); - EXPECT_EQ("my_index_buffer", buffers[0]->GetName()); - EXPECT_EQ(BufferType::kIndex, buffers[0]->GetBufferType()); - EXPECT_TRUE(buffers[0]->GetDatumType().IsInt32()); - EXPECT_EQ(4U, buffers[0]->GetSize()); - EXPECT_EQ(4U * 2 * sizeof(int32_t), buffers[0]->GetSizeInBytes()); + ASSERT_TRUE(buffers[0]->IsDataBuffer()); + auto* buffer = buffers[0]->AsDataBuffer(); + EXPECT_EQ("my_index_buffer", buffer->GetName()); + EXPECT_EQ(BufferType::kIndex, buffer->GetBufferType()); + EXPECT_TRUE(buffer->GetDatumType().IsInt32()); + EXPECT_EQ(4U, buffer->GetSize()); + EXPECT_EQ(4U * 2 * sizeof(int32_t), buffer->GetSizeInBytes()); std::vector<int32_t> results0 = {2, 3, 4, 5, 6, 7, 8, 9}; - const auto& data0 = buffers[0]->GetData(); + const auto& data0 = buffer->GetData(); ASSERT_EQ(results0.size(), data0.size()); for (size_t i = 0; i < results0.size(); ++i) { ASSERT_TRUE(data0[i].IsInteger()); @@ -1238,14 +1259,16 @@ END ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); - EXPECT_EQ("my_index_buffer", buffers[0]->GetName()); - EXPECT_EQ(BufferType::kIndex, buffers[0]->GetBufferType()); - EXPECT_TRUE(buffers[0]->GetDatumType().IsUint32()); - EXPECT_EQ(4U, buffers[0]->GetSize()); - EXPECT_EQ(4U * sizeof(uint32_t), buffers[0]->GetSizeInBytes()); + ASSERT_TRUE(buffers[0]->IsDataBuffer()); + auto* buffer = buffers[0]->AsDataBuffer(); + EXPECT_EQ("my_index_buffer", buffer->GetName()); + EXPECT_EQ(BufferType::kIndex, buffer->GetBufferType()); + EXPECT_TRUE(buffer->GetDatumType().IsUint32()); + EXPECT_EQ(4U, buffer->GetSize()); + EXPECT_EQ(4U * sizeof(uint32_t), buffer->GetSizeInBytes()); std::vector<uint32_t> results0 = {4278190080, 16711680, 65280, 255}; - const auto& data0 = buffers[0]->GetData(); + const auto& data0 = buffer->GetData(); ASSERT_EQ(results0.size(), data0.size()); for (size_t i = 0; i < results0.size(); ++i) { ASSERT_TRUE(data0[i].IsInteger()); @@ -1648,7 +1671,9 @@ TEST_P(AmberScriptParserBufferDataTypeTest, BufferTypes) { ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); - auto& datum = buffers[0]->GetDatumType(); + ASSERT_TRUE(buffers[0]->IsDataBuffer()); + auto* buffer = buffers[0]->AsDataBuffer(); + auto& datum = buffer->GetDatumType(); EXPECT_EQ(test_data.type, datum.GetType()); EXPECT_EQ(test_data.row_count, datum.RowCount()); EXPECT_EQ(test_data.column_count, datum.ColumnCount()); diff --git a/src/amberscript/script_test.cc b/src/amberscript/script_test.cc index 6110f88..2a2bd5e 100644 --- a/src/amberscript/script_test.cc +++ b/src/amberscript/script_test.cc @@ -171,8 +171,8 @@ TEST_F(ScriptTest, GetPipelines) { EXPECT_EQ(ptr2, pipelines[1].get()); } -TEST_F(ScriptTest, AddBuffer) { - auto buffer = MakeUnique<Buffer>(BufferType::kStorage); +TEST_F(ScriptTest, AddDataBuffer) { + auto buffer = MakeUnique<DataBuffer>(BufferType::kStorage); buffer->SetName("my_buffer"); Script s; @@ -180,15 +180,15 @@ TEST_F(ScriptTest, AddBuffer) { ASSERT_TRUE(r.IsSuccess()) << r.Error(); } -TEST_F(ScriptTest, AddDuplicateBuffer) { - auto buffer1 = MakeUnique<Buffer>(BufferType::kStorage); +TEST_F(ScriptTest, AddDuplicateDataBuffer) { + auto buffer1 = MakeUnique<DataBuffer>(BufferType::kStorage); buffer1->SetName("my_buffer"); Script s; Result r = s.AddBuffer(std::move(buffer1)); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto buffer2 = MakeUnique<Buffer>(BufferType::kUniform); + auto buffer2 = MakeUnique<DataBuffer>(BufferType::kUniform); buffer2->SetName("my_buffer"); r = s.AddBuffer(std::move(buffer2)); @@ -196,8 +196,8 @@ TEST_F(ScriptTest, AddDuplicateBuffer) { EXPECT_EQ("duplicate buffer name provided", r.Error()); } -TEST_F(ScriptTest, GetBuffer) { - auto buffer = MakeUnique<Buffer>(BufferType::kStorage); +TEST_F(ScriptTest, GetDataBuffer) { + auto buffer = MakeUnique<DataBuffer>(BufferType::kStorage); buffer->SetName("my_buffer"); const auto* ptr = buffer.get(); @@ -221,7 +221,7 @@ TEST_F(ScriptTest, GetBuffersEmpty) { } TEST_F(ScriptTest, GetBuffers) { - auto buffer1 = MakeUnique<Buffer>(BufferType::kStorage); + auto buffer1 = MakeUnique<DataBuffer>(BufferType::kStorage); buffer1->SetName("my_buffer1"); const auto* ptr1 = buffer1.get(); @@ -230,7 +230,7 @@ TEST_F(ScriptTest, GetBuffers) { Result r = s.AddBuffer(std::move(buffer1)); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto buffer2 = MakeUnique<Buffer>(BufferType::kUniform); + auto buffer2 = MakeUnique<DataBuffer>(BufferType::kUniform); buffer2->SetName("my_buffer2"); const auto* ptr2 = buffer2.get(); diff --git a/src/buffer.cc b/src/buffer.cc index 08e3ddd..e4736da 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -20,4 +20,20 @@ Buffer::Buffer(BufferType type) : buffer_type_(type) {} Buffer::~Buffer() = default; +DataBuffer* Buffer::AsDataBuffer() { + return static_cast<DataBuffer*>(this); +} + +FormatBuffer* Buffer::AsFormatBuffer() { + return static_cast<FormatBuffer*>(this); +} + +DataBuffer::DataBuffer(BufferType type) : Buffer(type) {} + +DataBuffer::~DataBuffer() = default; + +FormatBuffer::FormatBuffer(BufferType type) : Buffer(type) {} + +FormatBuffer::~FormatBuffer() = default; + } // namespace amber diff --git a/src/buffer.h b/src/buffer.h index edc1eba..771ff0c 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -16,60 +16,126 @@ #define SRC_BUFFER_H_ #include <cstdint> +#include <memory> #include <string> #include <utility> #include <vector> #include "src/buffer_data.h" #include "src/datum_type.h" +#include "src/format.h" #include "src/value.h" namespace amber { +class DataBuffer; +class FormatBuffer; + /// A buffer stores data. The buffer maybe provided from the input script, or /// maybe created as needed. A buffer must have a unique name. class Buffer { public: - /// Create a buffer of |type|. - explicit Buffer(BufferType type); - ~Buffer(); + virtual ~Buffer(); + + /// Returns |true| if this is a buffer described by a |DatumType|. + virtual bool IsDataBuffer() const { return false; } + /// Returns |true| if this is a buffer described by a |Format|. + virtual bool IsFormatBuffer() const { return false; } + + /// Converts the buffer to a |DataBuffer|. Note, |IsDataBuffer| must be true + /// for this method to be used. + DataBuffer* AsDataBuffer(); + /// Converts the buffer to a |FormatBuffer|. Note, |IsFormatBuffer| must be + /// true for this method to be used. + FormatBuffer* AsFormatBuffer(); /// Returns the BufferType of this buffer. BufferType GetBufferType() const { return buffer_type_; } + /// Set the location binding value for the buffer. + void SetLocation(uint8_t loc) { location_ = loc; } + /// Get the location binding value for the buffer. + uint8_t GetLocation() const { return location_; } + /// Sets the buffer |name|. void SetName(const std::string& name) { name_ = name; } /// Returns the name of the buffer. std::string GetName() const { return name_; } - /// Sets the DatumType of the buffer to |type|. - void SetDatumType(const DatumType& type) { datum_type_ = type; } - /// Returns the DatumType describing the buffer data. - const DatumType& GetDatumType() const { return datum_type_; } - /// Sets the buffer to |size| items. void SetSize(size_t size) { size_ = size; } /// Returns the number of items in the buffer. size_t GetSize() const { return size_; } /// Returns the number of bytes needed for the data in the buffer. - size_t GetSizeInBytes() const { return size_ * datum_type_.SizeInBytes(); } + virtual size_t GetSizeInBytes() const = 0; /// Sets the data into the buffer. The size will also be updated to be the /// size of the data provided. - void SetData(std::vector<Value>&& data) { - size_ = data.size() / datum_type_.ColumnCount() / datum_type_.RowCount(); - data_ = std::move(data); - } + virtual void SetData(std::vector<Value>&& data) { data_ = std::move(data); } /// Returns the vector of Values stored in the buffer. const std::vector<Value>& GetData() const { return data_; } + protected: + /// Create a buffer of |type|. + explicit Buffer(BufferType type); + private: BufferType buffer_type_; - DatumType datum_type_; std::vector<Value> data_; std::string name_; size_t size_ = 0; + uint8_t location_ = 0; +}; + +/// A buffer class where the data is described by a |DatumType| object. +class DataBuffer : public Buffer { + public: + explicit DataBuffer(BufferType type); + ~DataBuffer() override; + + bool IsDataBuffer() const override { return true; } + size_t GetSizeInBytes() const override { + return GetSize() * datum_type_.SizeInBytes(); + } + void SetData(std::vector<Value>&& data) override { + SetSize(data.size() / datum_type_.ColumnCount() / datum_type_.RowCount()); + Buffer::SetData(std::move(data)); + } + + /// Sets the DatumType of the buffer to |type|. + void SetDatumType(const DatumType& type) { datum_type_ = type; } + /// Returns the DatumType describing the buffer data. + const DatumType& GetDatumType() const { return datum_type_; } + + private: + DatumType datum_type_; +}; + +/// A buffer class where the data is described by a |format| object. +class FormatBuffer : public Buffer { + public: + explicit FormatBuffer(BufferType type); + ~FormatBuffer() override; + + bool IsFormatBuffer() const override { return true; } + size_t GetSizeInBytes() const override { + return GetSize() * format_->GetByteSize(); + } + void SetData(std::vector<Value>&& data) override { + SetSize(data.size()); + Buffer::SetData(std::move(data)); + } + + /// Sets the Format of the buffer to |format|. + void SetFormat(std::unique_ptr<Format> format) { + format_ = std::move(format); + } + /// Returns the Format describing the buffer data. + const Format& GetFormat() const { return *(format_.get()); } + + private: + std::unique_ptr<Format> format_; }; } // namespace amber diff --git a/src/buffer_test.cc b/src/buffer_test.cc index dedcaba..6bebdd6 100644 --- a/src/buffer_test.cc +++ b/src/buffer_test.cc @@ -21,31 +21,31 @@ namespace amber { using BufferTest = testing::Test; -TEST_F(BufferTest, BufferEmptyByDefault) { - Buffer b(BufferType::kColor); +TEST_F(BufferTest, DataBufferEmptyByDefault) { + DataBuffer b(BufferType::kColor); EXPECT_EQ(static_cast<size_t>(0U), b.GetSize()); EXPECT_EQ(static_cast<size_t>(0U), b.GetSizeInBytes()); } -TEST_F(BufferTest, BufferSize) { +TEST_F(BufferTest, DataBufferSize) { DatumType type; type.SetType(DataType::kInt16); - Buffer b(BufferType::kColor); + DataBuffer b(BufferType::kColor); b.SetDatumType(type); b.SetSize(10); EXPECT_EQ(10, b.GetSize()); EXPECT_EQ(2 * 10, b.GetSizeInBytes()); } -TEST_F(BufferTest, BufferSizeFromData) { +TEST_F(BufferTest, DataBufferSizeFromData) { DatumType type; type.SetType(DataType::kInt16); std::vector<Value> values; values.resize(5); - Buffer b(BufferType::kColor); + DataBuffer b(BufferType::kColor); b.SetDatumType(type); b.SetData(std::move(values)); @@ -53,14 +53,14 @@ TEST_F(BufferTest, BufferSizeFromData) { EXPECT_EQ(2 * 5, b.GetSizeInBytes()); } -TEST_F(BufferTest, BufferSizeFromDataOverrideSize) { +TEST_F(BufferTest, DataBufferSizeFromDataOverrideSize) { DatumType type; type.SetType(DataType::kInt16); std::vector<Value> values; values.resize(5); - Buffer b(BufferType::kColor); + DataBuffer b(BufferType::kColor); b.SetDatumType(type); b.SetSize(20); b.SetData(std::move(values)); @@ -69,13 +69,13 @@ TEST_F(BufferTest, BufferSizeFromDataOverrideSize) { EXPECT_EQ(2 * 5, b.GetSizeInBytes()); } -TEST_F(BufferTest, BufferSizeMatrix) { +TEST_F(BufferTest, DataBufferSizeMatrix) { DatumType type; type.SetType(DataType::kInt16); type.SetRowCount(2); type.SetColumnCount(3); - Buffer b(BufferType::kColor); + DataBuffer b(BufferType::kColor); b.SetDatumType(type); b.SetSize(10); EXPECT_EQ(10, b.GetSize()); diff --git a/src/vkscript/executor.cc b/src/vkscript/executor.cc index cf6de3a..f9ee422 100644 --- a/src/vkscript/executor.cc +++ b/src/vkscript/executor.cc @@ -75,23 +75,11 @@ Result Executor::Execute(Engine* engine, if (!r.IsSuccess()) return r; - // Process VertexData nodes - for (const auto& node : script->Nodes()) { - if (!node->IsVertexData()) - continue; - - const auto data = node->AsVertexData(); - for (size_t i = 0; i < data->SegmentCount(); ++i) { - const auto& header = data->GetHeader(i); - r = engine->SetBuffer(BufferType::kVertex, header.location, - *(header.format), data->GetSegment(i)); - if (!r.IsSuccess()) - return r; - } - } - for (const auto& buf : script->GetBuffers()) { - r = engine->SetBuffer(buf->GetBufferType(), 0, Format(), buf->GetData()); + r = engine->SetBuffer( + buf->GetBufferType(), buf->GetLocation(), + buf->IsFormatBuffer() ? buf->AsFormatBuffer()->GetFormat() : Format(), + buf->GetData()); if (!r.IsSuccess()) return r; } diff --git a/src/vkscript/nodes.cc b/src/vkscript/nodes.cc index 8bbc9c1..4ca2dec 100644 --- a/src/vkscript/nodes.cc +++ b/src/vkscript/nodes.cc @@ -28,10 +28,6 @@ RequireNode* Node::AsRequire() { return static_cast<RequireNode*>(this); } -VertexDataNode* Node::AsVertexData() { - return static_cast<VertexDataNode*>(this); -} - RequireNode::RequireNode() : Node(NodeType::kRequire) {} RequireNode::~RequireNode() = default; @@ -51,13 +47,5 @@ void RequireNode::AddRequirement(Feature feature, requirements_.emplace_back(feature, std::move(format)); } -VertexDataNode::VertexDataNode() : Node(NodeType::kVertexData) {} - -VertexDataNode::~VertexDataNode() = default; - -void VertexDataNode::SetSegment(Header&& header, std::vector<Value>&& data) { - data_.push_back({std::move(header), std::move(data)}); -} - } // namespace vkscript } // namespace amber diff --git a/src/vkscript/nodes.h b/src/vkscript/nodes.h index 0442d68..be8c5ee 100644 --- a/src/vkscript/nodes.h +++ b/src/vkscript/nodes.h @@ -31,17 +31,14 @@ namespace amber { namespace vkscript { class RequireNode; -class VertexDataNode; class Node { public: virtual ~Node(); bool IsRequire() const { return node_type_ == NodeType::kRequire; } - bool IsVertexData() const { return node_type_ == NodeType::kVertexData; } RequireNode* AsRequire(); - VertexDataNode* AsVertexData(); protected: explicit Node(NodeType type); @@ -78,32 +75,6 @@ class RequireNode : public Node { std::vector<Requirement> requirements_; }; -class VertexDataNode : public Node { - public: - struct Header { - uint8_t location; - std::unique_ptr<Format> format; - }; - - VertexDataNode(); - ~VertexDataNode() override; - - void SetSegment(Header&& header, std::vector<Value>&& data); - size_t SegmentCount() const { return data_.size(); } - - const Header& GetHeader(size_t idx) const { return data_[idx].header; } - const std::vector<Value>& GetSegment(size_t idx) const { - return data_[idx].buffer; - } - - private: - struct NodeData { - Header header; - std::vector<Value> buffer; - }; - std::vector<NodeData> data_; -}; - } // namespace vkscript } // namespace amber diff --git a/src/vkscript/parser.cc b/src/vkscript/parser.cc index 94635e6..01f4691 100644 --- a/src/vkscript/parser.cc +++ b/src/vkscript/parser.cc @@ -296,7 +296,7 @@ Result Parser::ProcessIndicesBlock(const std::string& data) { DatumType type; type.SetType(DataType::kUint16); - auto b = MakeUnique<Buffer>(BufferType::kIndex); + auto b = MakeUnique<DataBuffer>(BufferType::kIndex); b->SetName("indices"); b->SetDatumType(type); b->SetData(std::move(indices)); @@ -321,7 +321,11 @@ Result Parser::ProcessVertexDataBlock(const std::string& data) { return {}; // Process the header line. - std::vector<VertexDataNode::Header> headers; + struct Header { + uint8_t location; + std::unique_ptr<Format> format; + }; + std::vector<Header> headers; while (!token->IsEOL() && !token->IsEOS()) { // Because of the way the tokenizer works we'll see a number then a string // the string will start with a slash which we have to remove. @@ -397,11 +401,14 @@ Result Parser::ProcessVertexDataBlock(const std::string& data) { } } - auto node = MakeUnique<VertexDataNode>(); - for (size_t i = 0; i < headers.size(); ++i) - node->SetSegment(std::move(headers[i]), std::move(values[i])); - - script_->AddVertexData(std::move(node)); + for (size_t i = 0; i < headers.size(); ++i) { + auto buffer = MakeUnique<FormatBuffer>(BufferType::kVertex); + buffer->SetName("Vertices" + std::to_string(i)); + buffer->SetFormat(std::move(headers[i].format)); + buffer->SetLocation(headers[i].location); + buffer->SetData(std::move(values[i])); + script_->AddBuffer(std::move(buffer)); + } return {}; } diff --git a/src/vkscript/parser_test.cc b/src/vkscript/parser_test.cc index 4f2bc10..4dc0ad4 100644 --- a/src/vkscript/parser_test.cc +++ b/src/vkscript/parser_test.cc @@ -231,7 +231,10 @@ TEST_F(VkScriptParserTest, IndicesBlock) { ASSERT_EQ(1U, buffers.size()); ASSERT_EQ(BufferType::kIndex, buffers[0]->GetBufferType()); - auto buffer = buffers[0].get(); + auto buffer_ptr = buffers[0].get(); + ASSERT_TRUE(buffer_ptr->IsDataBuffer()); + + auto buffer = buffer_ptr->AsDataBuffer(); EXPECT_TRUE(buffer->GetDatumType().IsUint16()); EXPECT_EQ(3U, buffer->GetSize()); auto& data = buffer->GetData(); @@ -309,24 +312,21 @@ TEST_F(VkScriptParserTest, VertexDataHeaderFormatString) { Result r = parser.ProcessVertexDataBlockForTesting(block); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto amber_script = parser.GetScript(); - auto& nodes = ToVkScript(amber_script.get())->Nodes(); - ASSERT_EQ(1U, nodes.size()); - ASSERT_TRUE(nodes[0]->IsVertexData()); - - auto* data = nodes[0]->AsVertexData(); - ASSERT_EQ(2U, data->SegmentCount()); + auto script = parser.GetScript(); + const auto& buffers = script->GetBuffers(); + ASSERT_EQ(2U, buffers.size()); - auto& header_0 = data->GetHeader(0); - EXPECT_EQ(static_cast<size_t>(0U), header_0.location); - EXPECT_EQ(FormatType::kR32G32_SFLOAT, header_0.format->GetFormatType()); - EXPECT_TRUE(data->GetSegment(0).empty()); + ASSERT_EQ(BufferType::kVertex, buffers[0]->GetBufferType()); + EXPECT_EQ(static_cast<uint8_t>(0U), buffers[0]->GetLocation()); + EXPECT_EQ(FormatType::kR32G32_SFLOAT, + buffers[0]->AsFormatBuffer()->GetFormat().GetFormatType()); + EXPECT_TRUE(buffers[0]->GetData().empty()); - auto& header_1 = data->GetHeader(1); - EXPECT_EQ(1U, header_1.location); + ASSERT_EQ(BufferType::kVertex, buffers[1]->GetBufferType()); + EXPECT_EQ(1U, buffers[1]->GetLocation()); EXPECT_EQ(FormatType::kA8B8G8R8_UNORM_PACK32, - header_1.format->GetFormatType()); - EXPECT_TRUE(data->GetSegment(1).empty()); + buffers[1]->AsFormatBuffer()->GetFormat().GetFormatType()); + EXPECT_TRUE(buffers[1]->GetData().empty()); } TEST_F(VkScriptParserTest, VertexDataHeaderGlslString) { @@ -336,34 +336,30 @@ TEST_F(VkScriptParserTest, VertexDataHeaderGlslString) { Result r = parser.ProcessVertexDataBlockForTesting(block); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto amber_script = parser.GetScript(); - auto& nodes = ToVkScript(amber_script.get())->Nodes(); - ASSERT_EQ(1U, nodes.size()); - ASSERT_TRUE(nodes[0]->IsVertexData()); - - auto* data = nodes[0]->AsVertexData(); - ASSERT_EQ(2U, data->SegmentCount()); - - auto& header_0 = data->GetHeader(0); - EXPECT_EQ(static_cast<size_t>(0U), header_0.location); - EXPECT_EQ(FormatType::kR32G32_SFLOAT, header_0.format->GetFormatType()); - EXPECT_TRUE(data->GetSegment(0).empty()); + auto script = parser.GetScript(); + const auto& buffers = script->GetBuffers(); + ASSERT_EQ(2U, buffers.size()); - auto& comps1 = header_0.format->GetComponents(); + ASSERT_EQ(BufferType::kVertex, buffers[0]->GetBufferType()); + EXPECT_EQ(static_cast<uint8_t>(0U), buffers[0]->GetLocation()); + EXPECT_EQ(FormatType::kR32G32_SFLOAT, + buffers[0]->AsFormatBuffer()->GetFormat().GetFormatType()); + auto& comps1 = buffers[0]->AsFormatBuffer()->GetFormat().GetComponents(); ASSERT_EQ(2U, comps1.size()); EXPECT_EQ(FormatMode::kSFloat, comps1[0].mode); EXPECT_EQ(FormatMode::kSFloat, comps1[1].mode); + EXPECT_TRUE(buffers[0]->GetData().empty()); - auto& header_1 = data->GetHeader(1); - EXPECT_EQ(1U, header_1.location); - EXPECT_EQ(FormatType::kR32G32B32_SINT, header_1.format->GetFormatType()); - EXPECT_TRUE(data->GetSegment(1).empty()); - - auto& comps2 = header_1.format->GetComponents(); + ASSERT_EQ(BufferType::kVertex, buffers[1]->GetBufferType()); + EXPECT_EQ(1U, buffers[1]->GetLocation()); + EXPECT_EQ(FormatType::kR32G32B32_SINT, + buffers[1]->AsFormatBuffer()->GetFormat().GetFormatType()); + auto& comps2 = buffers[1]->AsFormatBuffer()->GetFormat().GetComponents(); ASSERT_EQ(3U, comps2.size()); EXPECT_EQ(FormatMode::kSInt, comps2[0].mode); EXPECT_EQ(FormatMode::kSInt, comps2[1].mode); EXPECT_EQ(FormatMode::kSInt, comps2[2].mode); + EXPECT_TRUE(buffers[1]->GetData().empty()); } TEST_F(VkScriptParserTest, TestBlock) { @@ -410,23 +406,23 @@ TEST_F(VkScriptParserTest, VertexDataRows) { ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); - auto& nodes = ToVkScript(script.get())->Nodes(); - ASSERT_EQ(1U, nodes.size()); - ASSERT_TRUE(nodes[0]->IsVertexData()); + const auto& buffers = script->GetBuffers(); + ASSERT_EQ(2U, buffers.size()); - auto* data = nodes[0]->AsVertexData(); - ASSERT_EQ(2U, data->SegmentCount()); + ASSERT_EQ(BufferType::kVertex, buffers[0]->GetBufferType()); std::vector<float> seg_0 = {-1.f, -1.f, 0.25f, 0.25f, -1.f, 0.25f}; - const auto& values_0 = data->GetSegment(0); + const auto& values_0 = buffers[0]->GetData(); ASSERT_EQ(seg_0.size(), values_0.size()); for (size_t i = 0; i < seg_0.size(); ++i) { ASSERT_TRUE(values_0[i].IsFloat()); EXPECT_FLOAT_EQ(seg_0[i], values_0[i].AsFloat()); } + ASSERT_EQ(BufferType::kVertex, buffers[1]->GetBufferType()); + std::vector<uint8_t> seg_1 = {255, 0, 0, 255, 0, 255}; - const auto& values_1 = data->GetSegment(1); + const auto& values_1 = buffers[1]->GetData(); ASSERT_EQ(seg_1.size(), values_1.size()); for (size_t i = 0; i < seg_1.size(); ++i) { ASSERT_TRUE(values_1[i].IsInteger()); @@ -472,15 +468,12 @@ TEST_F(VkScriptParserTest, VertexDataRowsWithHex) { ASSERT_TRUE(r.IsSuccess()) << r.Error(); auto script = parser.GetScript(); - auto& nodes = ToVkScript(script.get())->Nodes(); - ASSERT_EQ(1U, nodes.size()); - ASSERT_TRUE(nodes[0]->IsVertexData()); - - auto* data = nodes[0]->AsVertexData(); - ASSERT_EQ(1U, data->SegmentCount()); + const auto& buffers = script->GetBuffers(); + ASSERT_EQ(1U, buffers.size()); + ASSERT_EQ(BufferType::kVertex, buffers[0]->GetBufferType()); std::vector<uint32_t> seg_0 = {0xff0000ff, 0xffff0000}; - const auto& values_0 = data->GetSegment(0); + const auto& values_0 = buffers[0]->GetData(); ASSERT_EQ(seg_0.size(), values_0.size()); for (size_t i = 0; i < seg_0.size(); ++i) { diff --git a/src/vkscript/script.cc b/src/vkscript/script.cc index 01f7e58..722ea79 100644 --- a/src/vkscript/script.cc +++ b/src/vkscript/script.cc @@ -36,10 +36,5 @@ void Script::AddRequireNode(std::unique_ptr<RequireNode> node) { test_nodes_.push_back(std::move(tn)); } -void Script::AddVertexData(std::unique_ptr<VertexDataNode> node) { - std::unique_ptr<Node> tn(node.release()); - test_nodes_.push_back(std::move(tn)); -} - } // namespace vkscript } // namespace amber diff --git a/src/vkscript/script.h b/src/vkscript/script.h index a60c773..fd3e3a9 100644 --- a/src/vkscript/script.h +++ b/src/vkscript/script.h @@ -29,7 +29,6 @@ namespace vkscript { class Node; class RequireNode; -class VertexDataNode; class Script : public amber::Script { public: @@ -37,7 +36,6 @@ class Script : public amber::Script { ~Script() override; void AddRequireNode(std::unique_ptr<RequireNode> node); - void AddVertexData(std::unique_ptr<VertexDataNode> node); const std::vector<std::unique_ptr<Node>>& Nodes() const { return test_nodes_; |