diff options
author | dan sinclair <dj2@everburning.com> | 2019-04-16 09:55:45 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-16 09:55:45 -0400 |
commit | ac70df3cd57b9b34a42035e8f9c96c889a123a13 (patch) | |
tree | 14ff47631af6bd34fb74693fd4ee524f37064de2 | |
parent | d26ee22dd7faab1845a531d410f7ec1db407402a (diff) | |
download | amber-ac70df3cd57b9b34a42035e8f9c96c889a123a13.tar.gz |
Merge Data and Format buffers. (#466)
This Cl removes the two buffer subclasses and uses the buffer class
directly everywhere. This removes the restriction on what types of
things can be done with a given buffer.
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/amber.cc | 4 | ||||
-rw-r--r-- | src/amberscript/parser.cc | 30 | ||||
-rw-r--r-- | src/amberscript/parser.h | 10 | ||||
-rw-r--r-- | src/amberscript/parser_bind_test.cc | 49 | ||||
-rw-r--r-- | src/amberscript/parser_buffer_test.cc | 9 | ||||
-rw-r--r-- | src/amberscript/parser_pipeline_test.cc | 1 | ||||
-rw-r--r-- | src/buffer.cc | 87 | ||||
-rw-r--r-- | src/buffer.h | 90 | ||||
-rw-r--r-- | src/buffer_test.cc | 52 | ||||
-rw-r--r-- | src/executor.cc | 4 | ||||
-rw-r--r-- | src/format.cc | 10 | ||||
-rw-r--r-- | src/format.h | 3 | ||||
-rw-r--r-- | src/format_test.cc | 80 | ||||
-rw-r--r-- | src/pipeline.cc | 8 | ||||
-rw-r--r-- | src/pipeline_test.cc | 8 | ||||
-rw-r--r-- | src/script_test.cc | 18 | ||||
-rw-r--r-- | src/vkscript/command_parser.cc | 4 | ||||
-rw-r--r-- | src/vkscript/parser.cc | 11 | ||||
-rw-r--r-- | src/vkscript/parser_test.cc | 6 | ||||
-rw-r--r-- | src/vulkan/engine_vulkan.cc | 4 | ||||
-rw-r--r-- | src/vulkan/vertex_buffer_test.cc | 4 |
22 files changed, 193 insertions, 300 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5129739..42c229d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -98,6 +98,7 @@ if (${AMBER_ENABLE_TESTS}) descriptor_set_and_binding_parser_test.cc executor_test.cc format_parser_test.cc + format_test.cc pipeline_test.cc result_test.cc script_test.cc diff --git a/src/amber.cc b/src/amber.cc index feeabce..ba96957 100644 --- a/src/amber.cc +++ b/src/amber.cc @@ -43,8 +43,8 @@ Result GetFrameBuffer(Buffer* buffer, std::vector<Value>* values) { if (!cpu_memory) return Result("GetFrameBuffer missing memory pointer"); - const auto texel_stride = buffer->AsFormatBuffer()->GetTexelStride(); - const auto row_stride = buffer->AsFormatBuffer()->GetRowStride(); + const auto texel_stride = buffer->GetTexelStride(); + const auto row_stride = buffer->GetRowStride(); for (uint32_t y = 0; y < buffer->GetHeight(); ++y) { for (uint32_t x = 0; x < buffer->GetWidth(); ++x) { diff --git a/src/amberscript/parser.cc b/src/amberscript/parser.cc index b437bd1..642b317 100644 --- a/src/amberscript/parser.cc +++ b/src/amberscript/parser.cc @@ -578,9 +578,6 @@ Result Parser::ParsePipelineBind(Pipeline* pipeline) { return Result("invalid token for BUFFER type"); if (token->AsString() == "color") { - if (!buffer->IsFormatBuffer()) - return Result("color buffer must be a FORMAT buffer"); - token = tokenizer_->NextToken(); if (!token->IsString() || token->AsString() != "LOCATION") return Result("BIND missing LOCATION"); @@ -595,9 +592,6 @@ Result Parser::ParsePipelineBind(Pipeline* pipeline) { if (!r.IsSuccess()) return r; } else if (token->AsString() == "depth_stencil") { - if (!buffer->IsFormatBuffer()) - return Result("depth buffer must be a FORMAT buffer"); - buffer->SetBufferType(BufferType::kDepth); Result r = pipeline->SetDepthBuffer(buffer); if (!r.IsSuccess()) @@ -693,9 +687,9 @@ Result Parser::ParseBuffer() { std::unique_ptr<Buffer> buffer; auto& cmd = token->AsString(); if (cmd == "DATA_TYPE") { - buffer = MakeUnique<DataBuffer>(); + buffer = MakeUnique<Buffer>(); - Result r = ParseBufferInitializer(buffer->AsDataBuffer()); + Result r = ParseBufferInitializer(buffer.get()); if (!r.IsSuccess()) return r; } else if (cmd == "FORMAT") { @@ -703,14 +697,14 @@ Result Parser::ParseBuffer() { if (!token->IsString()) return Result("BUFFER FORMAT must be a string"); - buffer = MakeUnique<FormatBuffer>(); + buffer = MakeUnique<Buffer>(); FormatParser fmt_parser; auto fmt = fmt_parser.Parse(token->AsString()); if (fmt == nullptr) return Result("invalid BUFFER FORMAT"); - buffer->AsFormatBuffer()->SetFormat(std::move(fmt)); + buffer->SetFormat(std::move(fmt)); } else { return Result("unknown BUFFER command provided: " + cmd); } @@ -723,7 +717,7 @@ Result Parser::ParseBuffer() { return {}; } -Result Parser::ParseBufferInitializer(DataBuffer* buffer) { +Result Parser::ParseBufferInitializer(Buffer* buffer) { auto token = tokenizer_->NextToken(); if (!token->IsString()) return Result("BUFFER invalid data type"); @@ -733,7 +727,7 @@ Result Parser::ParseBufferInitializer(DataBuffer* buffer) { if (!r.IsSuccess()) return r; - buffer->SetDatumType(type); + buffer->SetFormat(type.AsFormat()); token = tokenizer_->NextToken(); if (!token->IsString()) @@ -747,7 +741,7 @@ Result Parser::ParseBufferInitializer(DataBuffer* buffer) { return Result("unknown initializer for BUFFER"); } -Result Parser::ParseBufferInitializerSize(DataBuffer* buffer) { +Result Parser::ParseBufferInitializerSize(Buffer* buffer) { auto token = tokenizer_->NextToken(); if (token->IsEOS() || token->IsEOL()) return Result("BUFFER size missing"); @@ -769,7 +763,7 @@ Result Parser::ParseBufferInitializerSize(DataBuffer* buffer) { return Result("invalid BUFFER initializer provided"); } -Result Parser::ParseBufferInitializerFill(DataBuffer* buffer, +Result Parser::ParseBufferInitializerFill(Buffer* buffer, uint32_t size_in_items) { auto token = tokenizer_->NextToken(); if (token->IsEOS() || token->IsEOL()) @@ -795,7 +789,7 @@ Result Parser::ParseBufferInitializerFill(DataBuffer* buffer, return ValidateEndOfStatement("BUFFER fill command"); } -Result Parser::ParseBufferInitializerSeries(DataBuffer* buffer, +Result Parser::ParseBufferInitializerSeries(Buffer* buffer, uint32_t size_in_items) { auto token = tokenizer_->NextToken(); if (token->IsEOS() || token->IsEOL()) @@ -844,7 +838,7 @@ Result Parser::ParseBufferInitializerSeries(DataBuffer* buffer, return ValidateEndOfStatement("BUFFER series_from command"); } -Result Parser::ParseBufferInitializerData(DataBuffer* buffer) { +Result Parser::ParseBufferInitializerData(Buffer* buffer) { auto fmt = buffer->GetFormat(); bool is_double_type = fmt->IsFloat() || fmt->IsDouble(); @@ -1199,13 +1193,11 @@ Result Parser::ParseExpect() { } else if (token->IsString() && IsComparator(token->AsString())) { if (has_y_val) return Result("Y value not needed for non-color comparator"); - if (!buffer->IsDataBuffer()) - return Result("comparator must be provided a data buffer"); auto probe = MakeUnique<ProbeSSBOCommand>(buffer); probe->SetLine(line); probe->SetComparator(ToComparator(token->AsString())); - probe->SetFormat(buffer->AsDataBuffer()->GetDatumType().AsFormat()); + probe->SetFormat(MakeUnique<Format>(*buffer->GetFormat())); probe->SetOffset(static_cast<uint32_t>(x)); std::vector<Value> values; diff --git a/src/amberscript/parser.h b/src/amberscript/parser.h index 7f641d4..9f3af01 100644 --- a/src/amberscript/parser.h +++ b/src/amberscript/parser.h @@ -48,11 +48,11 @@ class Parser : public amber::Parser { Result ValidateEndOfStatement(const std::string& name); Result ParseBuffer(); - Result ParseBufferInitializer(DataBuffer*); - Result ParseBufferInitializerSize(DataBuffer*); - Result ParseBufferInitializerFill(DataBuffer*, uint32_t); - Result ParseBufferInitializerSeries(DataBuffer*, uint32_t); - Result ParseBufferInitializerData(DataBuffer*); + Result ParseBufferInitializer(Buffer*); + Result ParseBufferInitializerSize(Buffer*); + Result ParseBufferInitializerFill(Buffer*, uint32_t); + Result ParseBufferInitializerSeries(Buffer*, uint32_t); + Result ParseBufferInitializerData(Buffer*); Result ParseShaderBlock(); Result ParsePipelineBlock(); Result ParsePipelineAttach(Pipeline*); diff --git a/src/amberscript/parser_bind_test.cc b/src/amberscript/parser_bind_test.cc index 9952dc6..f1754e6 100644 --- a/src/amberscript/parser_bind_test.cc +++ b/src/amberscript/parser_bind_test.cc @@ -202,27 +202,6 @@ END)"; EXPECT_EQ("12: extra parameters after BIND command", r.Error()); } -TEST_F(AmberScriptParserTest, BindColorBufferNonFormatBuffer) { - std::string in = R"( -SHADER vertex my_shader PASSTHROUGH -SHADER fragment my_fragment GLSL -# GLSL Shader -END -BUFFER my_fb DATA_TYPE int32 SIZE 500 FILL 0 - -PIPELINE graphics my_pipeline - ATTACH my_shader - ATTACH my_fragment - - BIND BUFFER my_fb AS color LOCATION 0 -END)"; - - Parser parser; - Result r = parser.Parse(in); - ASSERT_FALSE(r.IsSuccess()); - EXPECT_EQ("12: color buffer must be a FORMAT buffer", r.Error()); -} - TEST_F(AmberScriptParserTest, BindColorBufferDuplicateLocation) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH @@ -437,27 +416,6 @@ END)"; EXPECT_EQ(90 * 180 * 4 * sizeof(float), buf.buffer->GetSizeInBytes()); } -TEST_F(AmberScriptParserTest, BindDepthBufferNonFormatBuffer) { - std::string in = R"( -SHADER vertex my_shader PASSTHROUGH -SHADER fragment my_fragment GLSL -# GLSL Shader -END -BUFFER my_buf DATA_TYPE int32 SIZE 500 FILL 0 - -PIPELINE graphics my_pipeline - ATTACH my_shader - ATTACH my_fragment - - BIND BUFFER my_buf AS depth_stencil -END)"; - - Parser parser; - Result r = parser.Parse(in); - ASSERT_FALSE(r.IsSuccess()); - EXPECT_EQ("12: depth buffer must be a FORMAT buffer", r.Error()); -} - TEST_F(AmberScriptParserTest, BindDepthBufferExtraParams) { std::string in = R"( SHADER vertex my_shader PASSTHROUGH @@ -596,8 +554,8 @@ SHADER vertex my_shader PASSTHROUGH SHADER fragment my_fragment GLSL # GLSL Shader END -BUFFER my_buf DATA_TYPE int8 SIZE 50 FILL 5 -BUFFER my_buf2 DATA_TYPE int8 SIZE 50 FILL 5 +BUFFER my_buf DATA_TYPE int8 SIZE 5 FILL 5 +BUFFER my_buf2 DATA_TYPE int8 SIZE 5 FILL 5 PIPELINE graphics my_pipeline ATTACH my_shader @@ -621,12 +579,10 @@ END)"; const auto& info1 = vertex_buffers[0]; ASSERT_TRUE(info1.buffer != nullptr); - EXPECT_TRUE(info1.buffer->IsDataBuffer()); EXPECT_EQ(0, info1.location); const auto& info2 = vertex_buffers[1]; ASSERT_TRUE(info2.buffer != nullptr); - EXPECT_TRUE(info2.buffer->IsDataBuffer()); EXPECT_EQ(1, info2.location); } @@ -807,7 +763,6 @@ END)"; const auto* pipeline = pipelines[0].get(); const auto* buf = pipeline->GetIndexBuffer(); ASSERT_TRUE(buf != nullptr); - EXPECT_TRUE(buf->IsDataBuffer()); } TEST_F(AmberScriptParserTest, BindIndexataMissingBuffer) { diff --git a/src/amberscript/parser_buffer_test.cc b/src/amberscript/parser_buffer_test.cc index 17cedcc..b639afc 100644 --- a/src/amberscript/parser_buffer_test.cc +++ b/src/amberscript/parser_buffer_test.cc @@ -94,9 +94,8 @@ TEST_F(AmberScriptParserTest, BufferDataFloat) { ASSERT_TRUE(buffers[0] != nullptr); EXPECT_EQ("my_buffer", buffers[0]->GetName()); - ASSERT_TRUE(buffers[0]->IsDataBuffer()); - auto* buffer = buffers[0]->AsDataBuffer(); - EXPECT_TRUE(buffer->GetDatumType().IsFloat()); + auto* buffer = buffers[0].get(); + EXPECT_TRUE(buffer->GetFormat()->IsFloat()); EXPECT_EQ(4U, buffer->ElementCount()); EXPECT_EQ(4U, buffer->ValueCount()); EXPECT_EQ(4U * sizeof(float), buffer->GetSizeInBytes()); @@ -362,7 +361,8 @@ END EXPECT_EQ(12U, buffer->ValueCount()); EXPECT_EQ(16U * sizeof(int32_t), buffer->GetSizeInBytes()); - std::vector<int32_t> results0 = {2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9}; + std::vector<int32_t> results0 = {2, 3, 3, 0, 4, 5, 5, 0, + 6, 7, 7, 0, 8, 9, 9, 0}; const auto* data0 = buffer->GetValues<int32_t>(); for (size_t i = 0; i < results0.size(); ++i) { EXPECT_EQ(results0[i], data0[i]); @@ -416,7 +416,6 @@ TEST_F(AmberScriptParserTest, BufferFormat) { ASSERT_EQ(1U, buffers.size()); ASSERT_TRUE(buffers[0] != nullptr); - ASSERT_TRUE(buffers[0]->IsFormatBuffer()); auto* buffer = buffers[0].get(); EXPECT_EQ("my_buf", buffer->GetName()); diff --git a/src/amberscript/parser_pipeline_test.cc b/src/amberscript/parser_pipeline_test.cc index 6d1d91a..3860660 100644 --- a/src/amberscript/parser_pipeline_test.cc +++ b/src/amberscript/parser_pipeline_test.cc @@ -197,7 +197,6 @@ END)"; ASSERT_TRUE(buf1.buffer != nullptr); Buffer* buffer1 = buf1.buffer; - ASSERT_TRUE(buffer1->IsFormatBuffer()); EXPECT_EQ(FormatType::kB8G8R8A8_UNORM, buffer1->GetFormat()->GetFormatType()); EXPECT_EQ(0, buf1.location); EXPECT_EQ(250 * 250, buffer1->ElementCount()); diff --git a/src/buffer.cc b/src/buffer.cc index f9f9318..d8cfd8b 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -60,14 +60,6 @@ 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); -} - Result Buffer::CopyTo(Buffer* buffer) const { if (buffer->width_ != width_) return Result("Buffer::CopyBaseFields() buffers have a different width"); @@ -75,7 +67,7 @@ Result Buffer::CopyTo(Buffer* buffer) const { return Result("Buffer::CopyBaseFields() buffers have a different height"); if (buffer->element_count_ != element_count_) return Result("Buffer::CopyBaseFields() buffers have a different size"); - buffer->values_ = values_; + buffer->bytes_ = bytes_; return {}; } @@ -88,19 +80,19 @@ Result Buffer::IsEqual(Buffer* buffer) const { return Result{"Buffers have a different width"}; if (buffer->height_ != height_) return Result{"Buffers have a different height"}; - if (buffer->values_.size() != values_.size()) + if (buffer->bytes_.size() != bytes_.size()) return Result{"Buffers have a different number of values"}; uint32_t num_different = 0; uint32_t first_different_index = 0; uint8_t first_different_left = 0; uint8_t first_different_right = 0; - for (uint32_t i = 0; i < values_.size(); ++i) { - if (values_[i] != buffer->values_[i]) { + for (uint32_t i = 0; i < bytes_.size(); ++i) { + if (bytes_[i] != buffer->bytes_[i]) { if (num_different == 0) { first_different_index = i; - first_different_left = values_[i]; - first_different_right = buffer->values_[i]; + first_different_left = bytes_[i]; + first_different_right = buffer->bytes_[i]; } num_different++; } @@ -118,72 +110,11 @@ Result Buffer::IsEqual(Buffer* buffer) const { return {}; } -DataBuffer::DataBuffer() = default; - -DataBuffer::DataBuffer(BufferType type) : Buffer(type) {} - -DataBuffer::~DataBuffer() = default; - -Result DataBuffer::SetData(const std::vector<Value>& data) { - SetValueCount(static_cast<uint32_t>(data.size())); - values_.resize(GetSizeInBytes()); - return CopyData(data); -} - -Result DataBuffer::CopyData(const std::vector<Value>& data) { - uint8_t* values = values_.data(); - - for (const auto& val : data) { - if (datum_type_.IsInt8()) { - *(ValuesAs<int8_t>(values)) = val.AsInt8(); - values += sizeof(int8_t); - } else if (datum_type_.IsInt16()) { - *(ValuesAs<int16_t>(values)) = val.AsInt16(); - values += sizeof(int16_t); - } else if (datum_type_.IsInt32()) { - *(ValuesAs<int32_t>(values)) = val.AsInt32(); - values += sizeof(int32_t); - } else if (datum_type_.IsInt64()) { - *(ValuesAs<int64_t>(values)) = val.AsInt64(); - values += sizeof(int64_t); - } else if (datum_type_.IsUint8()) { - *(ValuesAs<uint8_t>(values)) = val.AsUint8(); - values += sizeof(uint8_t); - } else if (datum_type_.IsUint16()) { - *(ValuesAs<uint16_t>(values)) = val.AsUint16(); - values += sizeof(uint16_t); - } else if (datum_type_.IsUint32()) { - *(ValuesAs<uint32_t>(values)) = val.AsUint32(); - values += sizeof(uint32_t); - } else if (datum_type_.IsUint64()) { - *(ValuesAs<uint64_t>(values)) = val.AsUint64(); - values += sizeof(uint64_t); - } else if (datum_type_.IsFloat()) { - *(ValuesAs<float>(values)) = val.AsFloat(); - values += sizeof(float); - } else if (datum_type_.IsDouble()) { - *(ValuesAs<double>(values)) = val.AsDouble(); - values += sizeof(double); - } - } - return {}; -} - -FormatBuffer::FormatBuffer() = default; - -FormatBuffer::FormatBuffer(BufferType type) : Buffer(type) {} - -FormatBuffer::~FormatBuffer() = default; - -Result FormatBuffer::SetData(const std::vector<Value>& data) { +Result Buffer::SetData(const std::vector<Value>& data) { SetValueCount(static_cast<uint32_t>(data.size())); - values_.resize(GetSizeInBytes()); - return CopyData(data); -} - -Result FormatBuffer::CopyData(const std::vector<Value>& data) { - uint8_t* ptr = values_.data(); + bytes_.resize(GetSizeInBytes()); + uint8_t* ptr = bytes_.data(); for (uint32_t i = 0; i < data.size();) { const auto pack_size = format_->GetPackSize(); if (pack_size) { diff --git a/src/buffer.h b/src/buffer.h index 77e0dc1..ca00c57 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -28,9 +28,6 @@ namespace amber { -class DataBuffer; -class FormatBuffer; - /// Types of buffers which can be created. enum class BufferType : int8_t { /// Unknown buffer type @@ -57,22 +54,12 @@ enum class BufferType : int8_t { /// maybe created as needed. A buffer must have a unique name. class Buffer { public: + /// Create a buffer of unknown type. + Buffer(); /// Create a buffer of |type_|. explicit Buffer(BufferType type); - 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(); + ~Buffer(); /// Returns the BufferType of this buffer. BufferType GetBufferType() const { return buffer_type_; } @@ -138,16 +125,23 @@ class Buffer { return ElementCount() * format_->SizeInBytes(); } + uint32_t GetTexelStride() { return format_->SizeInBytes(); } + + // When copying the image to the host buffer, we specify a row length of 0 + // which results in tight packing of rows. So the row stride is the product + // of the texel stride and the number of texels in a row. + uint32_t GetRowStride() { return GetTexelStride() * GetWidth(); } + /// Sets the data into the buffer. The size will also be updated to be the /// size of the data provided. - virtual Result SetData(const std::vector<Value>& data) = 0; + Result SetData(const std::vector<Value>& data); - std::vector<uint8_t>* ValuePtr() { return &values_; } - const std::vector<uint8_t>* ValuePtr() const { return &values_; } + std::vector<uint8_t>* ValuePtr() { return &bytes_; } + const std::vector<uint8_t>* ValuePtr() const { return &bytes_; } template <typename T> const T* GetValues() const { - return reinterpret_cast<const T*>(values_.data()); + return reinterpret_cast<const T*>(bytes_.data()); } /// Copies the buffer values to an other one @@ -156,12 +150,6 @@ class Buffer { /// Succeeds only if both buffer contents are equal Result IsEqual(Buffer* buffer) const; - protected: - Buffer(); - - std::vector<uint8_t> values_; - std::unique_ptr<Format> format_; - private: BufferType buffer_type_ = BufferType::kUnknown; std::string name_; @@ -169,54 +157,8 @@ class Buffer { uint32_t width_ = 0; uint32_t height_ = 0; uint8_t location_ = 0; -}; - -/// A buffer class where the data is described by a |DatumType| object. -class DataBuffer : public Buffer { - public: - DataBuffer(); - explicit DataBuffer(BufferType type); - ~DataBuffer() override; - - // Buffer - bool IsDataBuffer() const override { return true; } - Result SetData(const std::vector<Value>& data) override; - - /// Sets the DatumType of the buffer to |type|. - void SetDatumType(const DatumType& type) { - datum_type_ = type; - format_ = datum_type_.AsFormat(); - } - /// Returns the DatumType describing the buffer data. - const DatumType GetDatumType() const { return datum_type_; } - - private: - Result CopyData(const std::vector<Value>& data); - - DatumType datum_type_; -}; - -/// A buffer class where the data is described by a |format| object. -class FormatBuffer : public Buffer { - public: - FormatBuffer(); - explicit FormatBuffer(BufferType type); - ~FormatBuffer() override; - - // Buffer - bool IsFormatBuffer() const override { return true; } - - Result SetData(const std::vector<Value>& data) override; - - uint32_t GetTexelStride() { return format_->SizeInBytes(); } - - // When copying the image to the host buffer, we specify a row length of 0 - // which results in tight packing of rows. So the row stride is the product - // of the texel stride and the number of texels in a row. - uint32_t GetRowStride() { return GetTexelStride() * GetWidth(); } - - private: - Result CopyData(const std::vector<Value>& data); + std::vector<uint8_t> bytes_; + std::unique_ptr<Format> format_; }; } // namespace amber diff --git a/src/buffer_test.cc b/src/buffer_test.cc index e5eb712..d8717b7 100644 --- a/src/buffer_test.cc +++ b/src/buffer_test.cc @@ -17,71 +17,65 @@ #include <utility> #include "gtest/gtest.h" +#include "src/format_parser.h" namespace amber { using BufferTest = testing::Test; -TEST_F(BufferTest, DataBufferEmptyByDefault) { - DataBuffer b(BufferType::kColor); +TEST_F(BufferTest, EmptyByDefault) { + Buffer b(BufferType::kColor); EXPECT_EQ(static_cast<size_t>(0U), b.ElementCount()); EXPECT_EQ(static_cast<size_t>(0U), b.ValueCount()); EXPECT_EQ(static_cast<size_t>(0U), b.GetSizeInBytes()); } -TEST_F(BufferTest, DataBufferSize) { - DatumType type; - type.SetType(DataType::kInt16); - - DataBuffer b(BufferType::kColor); - b.SetDatumType(type); +TEST_F(BufferTest, Size) { + FormatParser fp; + Buffer b(BufferType::kColor); + b.SetFormat(fp.Parse("R16_SINT")); b.SetElementCount(10); EXPECT_EQ(10, b.ElementCount()); EXPECT_EQ(10, b.ValueCount()); EXPECT_EQ(10 * sizeof(int16_t), b.GetSizeInBytes()); } -TEST_F(BufferTest, DataBufferSizeFromData) { - DatumType type; - type.SetType(DataType::kInt16); - +TEST_F(BufferTest, SizeFromData) { std::vector<Value> values; values.resize(5); - DataBuffer b(BufferType::kColor); - b.SetDatumType(type); + FormatParser fp; + Buffer b(BufferType::kColor); + b.SetFormat(fp.Parse("R32_SFLOAT")); b.SetData(std::move(values)); EXPECT_EQ(5, b.ElementCount()); EXPECT_EQ(5, b.ValueCount()); - EXPECT_EQ(5 * sizeof(int16_t), b.GetSizeInBytes()); + EXPECT_EQ(5 * sizeof(float), b.GetSizeInBytes()); } -TEST_F(BufferTest, DataBufferSizeFromDataOverrideSize) { - DatumType type; - type.SetType(DataType::kInt16); - +TEST_F(BufferTest, SizeFromDataOverrideSize) { std::vector<Value> values; values.resize(5); - DataBuffer b(BufferType::kColor); - b.SetDatumType(type); + FormatParser fp; + Buffer b(BufferType::kColor); + b.SetFormat(fp.Parse("R32_SFLOAT")); b.SetElementCount(20); b.SetData(std::move(values)); EXPECT_EQ(5, b.ElementCount()); EXPECT_EQ(5, b.ValueCount()); - EXPECT_EQ(5 * sizeof(int16_t), b.GetSizeInBytes()); + EXPECT_EQ(5 * sizeof(float), b.GetSizeInBytes()); } -TEST_F(BufferTest, DataBufferSizeMatrix) { - DatumType type; - type.SetType(DataType::kInt16); - type.SetRowCount(2); - type.SetColumnCount(3); +TEST_F(BufferTest, SizeMatrix) { + FormatParser fp; + auto fmt = fp.Parse("R16G16_SINT"); + fmt->SetColumnCount(3); - DataBuffer b(BufferType::kColor); - b.SetDatumType(type); + Buffer b(BufferType::kColor); + b.SetFormat(std::move(fmt)); b.SetElementCount(10); EXPECT_EQ(10, b.ElementCount()); diff --git a/src/executor.cc b/src/executor.cc index 840d7ec..59bc86d 100644 --- a/src/executor.cc +++ b/src/executor.cc @@ -79,9 +79,7 @@ Result Executor::Execute(Engine* engine, Result Executor::ExecuteCommand(Engine* engine, Command* cmd) { if (cmd->IsProbe()) { - assert(cmd->AsProbe()->GetBuffer()->IsFormatBuffer()); - - auto* buffer = cmd->AsProbe()->GetBuffer()->AsFormatBuffer(); + auto* buffer = cmd->AsProbe()->GetBuffer(); assert(buffer); Format* fmt = buffer->GetFormat(); diff --git a/src/format.cc b/src/format.cc index 47f0990..1a836c4 100644 --- a/src/format.cc +++ b/src/format.cc @@ -14,6 +14,8 @@ #include "src/format.h" +#include "src/make_unique.h" + namespace amber { Format::Format() = default; @@ -22,7 +24,7 @@ Format::Format(const Format&) = default; Format::~Format() = default; -uint32_t Format::SizeInBytes() const { +uint32_t Format::SizeInBytesPerRow() const { uint32_t bits = 0; for (const auto& comp : components_) bits += comp.num_bits; @@ -35,7 +37,11 @@ uint32_t Format::SizeInBytes() const { if ((bits % 8) != 0) bytes_per_element += 1; - return bytes_per_element * column_count_; + return bytes_per_element; +} + +uint32_t Format::SizeInBytes() const { + return SizeInBytesPerRow() * column_count_; } bool Format::AreAllComponents(FormatMode mode, uint32_t bits) const { diff --git a/src/format.h b/src/format.h index 5b4fe48..b0f5316 100644 --- a/src/format.h +++ b/src/format.h @@ -16,6 +16,7 @@ #define SRC_FORMAT_H_ #include <cstdint> +#include <memory> #include <vector> #include "src/format_data.h" @@ -97,6 +98,8 @@ class Format { const std::vector<Component>& GetComponents() const { return components_; } uint32_t SizeInBytes() const; + uint32_t SizeInBytesPerRow() const; + bool IsFormatKnown() const { return type_ != FormatType::kUnknown; } bool HasStencilComponent() const { return type_ == FormatType::kD24_UNORM_S8_UINT || diff --git a/src/format_test.cc b/src/format_test.cc new file mode 100644 index 0000000..382dee0 --- /dev/null +++ b/src/format_test.cc @@ -0,0 +1,80 @@ +// Copyright 2019 The Amber 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 "src/format.h" + +#include "gtest/gtest.h" +#include "src/format_parser.h" +#include "src/make_unique.h" + +namespace amber { + +using FormatTest = testing::Test; + +TEST_F(FormatTest, Copy) { + Format fmt; + fmt.SetIsStd140(); + fmt.SetColumnCount(1); + fmt.SetFormatType(FormatType::kR32G32B32_SFLOAT); + fmt.AddComponent(FormatComponentType::kR, FormatMode::kSFloat, 32); + fmt.AddComponent(FormatComponentType::kG, FormatMode::kSFloat, 32); + fmt.AddComponent(FormatComponentType::kB, FormatMode::kSFloat, 32); + + auto copy = MakeUnique<Format>(fmt); + EXPECT_TRUE(copy->IsFloat()); + EXPECT_EQ(16U, copy->SizeInBytes()); + EXPECT_EQ(3U, copy->GetComponents().size()); + EXPECT_TRUE(copy->IsStd140()); + EXPECT_EQ(FormatType::kR32G32B32_SFLOAT, copy->GetFormatType()); + + auto& comp = copy->GetComponents(); + EXPECT_EQ(FormatComponentType::kR, comp[0].type); + EXPECT_EQ(FormatMode::kSFloat, comp[0].mode); + EXPECT_EQ(32U, comp[0].num_bits); + EXPECT_EQ(FormatComponentType::kG, comp[1].type); + EXPECT_EQ(FormatMode::kSFloat, comp[1].mode); + EXPECT_EQ(32U, comp[1].num_bits); + EXPECT_EQ(FormatComponentType::kB, comp[2].type); + EXPECT_EQ(FormatMode::kSFloat, comp[2].mode); + EXPECT_EQ(32U, comp[2].num_bits); +} + +TEST_F(FormatTest, SizeInBytesVector) { + FormatParser fp; + auto fmt = fp.Parse("R32G32B32_SFLOAT"); + ASSERT_TRUE(fmt != nullptr); + + EXPECT_EQ(12U, fmt->SizeInBytes()); + EXPECT_EQ(12U, fmt->SizeInBytesPerRow()); +} + +TEST_F(FormatTest, SizeInBytesMatrix) { + FormatParser fp; + auto fmt = fp.Parse("R32G32B32_SFLOAT"); + ASSERT_TRUE(fmt != nullptr); + fmt->SetColumnCount(3); + + EXPECT_EQ(36U, fmt->SizeInBytes()); + EXPECT_EQ(12U, fmt->SizeInBytesPerRow()); +} + +TEST_F(FormatTest, RowCount) { + FormatParser fp; + auto fmt = fp.Parse("R32G32B32_SFLOAT"); + ASSERT_TRUE(fmt != nullptr); + + EXPECT_EQ(3U, fmt->RowCount()); +} + +} // namespace amber diff --git a/src/pipeline.cc b/src/pipeline.cc index 956b15a..8f2dc05 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -281,18 +281,18 @@ Result Pipeline::AddVertexBuffer(Buffer* buf, uint32_t location) { std::unique_ptr<Buffer> Pipeline::GenerateDefaultColorAttachmentBuffer() const { FormatParser fp; - std::unique_ptr<Buffer> buf = MakeUnique<FormatBuffer>(BufferType::kColor); + std::unique_ptr<Buffer> buf = MakeUnique<Buffer>(BufferType::kColor); buf->SetName(kGeneratedColorBuffer); - buf->AsFormatBuffer()->SetFormat(fp.Parse(kDefaultColorBufferFormat)); + buf->SetFormat(fp.Parse(kDefaultColorBufferFormat)); return buf; } std::unique_ptr<Buffer> Pipeline::GenerateDefaultDepthAttachmentBuffer() const { FormatParser fp; - std::unique_ptr<Buffer> buf = MakeUnique<FormatBuffer>(BufferType::kDepth); + std::unique_ptr<Buffer> buf = MakeUnique<Buffer>(BufferType::kDepth); buf->SetName(kGeneratedDepthBuffer); - buf->AsFormatBuffer()->SetFormat(fp.Parse(kDefaultDepthBufferFormat)); + buf->SetFormat(fp.Parse(kDefaultDepthBufferFormat)); return buf; } diff --git a/src/pipeline_test.cc b/src/pipeline_test.cc index bd61375..5928e71 100644 --- a/src/pipeline_test.cc +++ b/src/pipeline_test.cc @@ -384,19 +384,19 @@ TEST_F(PipelineTest, Clone) { p.AddShader(&v, kShaderTypeVertex); p.SetShaderEntryPoint(&v, "my_main"); - auto vtex_buf = MakeUnique<DataBuffer>(BufferType::kVertex); + auto vtex_buf = MakeUnique<Buffer>(BufferType::kVertex); vtex_buf->SetName("vertex_buffer"); p.AddVertexBuffer(vtex_buf.get(), 1); - auto idx_buf = MakeUnique<DataBuffer>(BufferType::kIndex); + auto idx_buf = MakeUnique<Buffer>(BufferType::kIndex); idx_buf->SetName("Index Buffer"); p.SetIndexBuffer(idx_buf.get()); - auto buf1 = MakeUnique<DataBuffer>(BufferType::kStorage); + auto buf1 = MakeUnique<Buffer>(BufferType::kStorage); buf1->SetName("buf1"); p.AddBuffer(buf1.get(), 1, 1); - auto buf2 = MakeUnique<DataBuffer>(BufferType::kStorage); + auto buf2 = MakeUnique<Buffer>(BufferType::kStorage); buf2->SetName("buf2"); p.AddBuffer(buf2.get(), 1, 2); diff --git a/src/script_test.cc b/src/script_test.cc index 07388f5..e8f7294 100644 --- a/src/script_test.cc +++ b/src/script_test.cc @@ -215,8 +215,8 @@ TEST_F(ScriptTest, GetPipelines) { EXPECT_EQ(ptr2, pipelines[1].get()); } -TEST_F(ScriptTest, AddDataBuffer) { - auto buffer = MakeUnique<DataBuffer>(BufferType::kStorage); +TEST_F(ScriptTest, AddBuffer) { + auto buffer = MakeUnique<Buffer>(BufferType::kStorage); buffer->SetName("my_buffer"); Script s; @@ -224,15 +224,15 @@ TEST_F(ScriptTest, AddDataBuffer) { ASSERT_TRUE(r.IsSuccess()) << r.Error(); } -TEST_F(ScriptTest, AddDuplicateDataBuffer) { - auto buffer1 = MakeUnique<DataBuffer>(BufferType::kStorage); +TEST_F(ScriptTest, AddDuplicateBuffer) { + auto buffer1 = MakeUnique<Buffer>(BufferType::kStorage); buffer1->SetName("my_buffer"); Script s; Result r = s.AddBuffer(std::move(buffer1)); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto buffer2 = MakeUnique<DataBuffer>(BufferType::kUniform); + auto buffer2 = MakeUnique<Buffer>(BufferType::kUniform); buffer2->SetName("my_buffer"); r = s.AddBuffer(std::move(buffer2)); @@ -240,8 +240,8 @@ TEST_F(ScriptTest, AddDuplicateDataBuffer) { EXPECT_EQ("duplicate buffer name provided", r.Error()); } -TEST_F(ScriptTest, GetDataBuffer) { - auto buffer = MakeUnique<DataBuffer>(BufferType::kStorage); +TEST_F(ScriptTest, GetBuffer) { + auto buffer = MakeUnique<Buffer>(BufferType::kStorage); buffer->SetName("my_buffer"); const auto* ptr = buffer.get(); @@ -265,7 +265,7 @@ TEST_F(ScriptTest, GetBuffersEmpty) { } TEST_F(ScriptTest, GetBuffers) { - auto buffer1 = MakeUnique<DataBuffer>(BufferType::kStorage); + auto buffer1 = MakeUnique<Buffer>(BufferType::kStorage); buffer1->SetName("my_buffer1"); const auto* ptr1 = buffer1.get(); @@ -274,7 +274,7 @@ TEST_F(ScriptTest, GetBuffers) { Result r = s.AddBuffer(std::move(buffer1)); ASSERT_TRUE(r.IsSuccess()) << r.Error(); - auto buffer2 = MakeUnique<DataBuffer>(BufferType::kUniform); + auto buffer2 = MakeUnique<Buffer>(BufferType::kUniform); buffer2->SetName("my_buffer2"); const auto* ptr2 = buffer2.get(); diff --git a/src/vkscript/command_parser.cc b/src/vkscript/command_parser.cc index 7963eaa..b25b89e 100644 --- a/src/vkscript/command_parser.cc +++ b/src/vkscript/command_parser.cc @@ -591,7 +591,7 @@ Result CommandParser::ProcessSSBO() { auto* buffer = pipeline_->GetBufferForBinding(set, binding); if (!buffer) { - auto b = MakeUnique<DataBuffer>(BufferType::kStorage); + auto b = MakeUnique<Buffer>(BufferType::kStorage); b->SetName("AutoBuf-" + std::to_string(script_->GetBuffers().size())); buffer = b.get(); script_->AddBuffer(std::move(b)); @@ -737,7 +737,7 @@ Result CommandParser::ProcessUniform() { auto* buffer = pipeline_->GetBufferForBinding(set, binding); if (!buffer) { - auto b = MakeUnique<DataBuffer>(BufferType::kUniform); + auto b = MakeUnique<Buffer>(BufferType::kUniform); b->SetName("AutoBuf-" + std::to_string(script_->GetBuffers().size())); buffer = b.get(); script_->AddBuffer(std::move(b)); diff --git a/src/vkscript/parser.cc b/src/vkscript/parser.cc index cda97d4..3a19b03 100644 --- a/src/vkscript/parser.cc +++ b/src/vkscript/parser.cc @@ -170,8 +170,7 @@ Result Parser::ProcessRequireBlock(const SectionParser::Section& section) { } script_->GetPipeline(kDefaultPipelineName) ->GetColorAttachments()[0] - .buffer->AsFormatBuffer() - ->SetFormat(std::move(fmt)); + .buffer->SetFormat(std::move(fmt)); } else if (str == "depthstencil") { token = tokenizer.NextToken(); @@ -192,7 +191,7 @@ Result Parser::ProcessRequireBlock(const SectionParser::Section& section) { // Generate and add a depth buffer auto depth_buf = pipeline->GenerateDefaultDepthAttachmentBuffer(); - depth_buf->AsFormatBuffer()->SetFormat(std::move(fmt)); + depth_buf->SetFormat(std::move(fmt)); Result r = pipeline->SetDepthBuffer(depth_buf.get()); if (!r.IsSuccess()) return r; @@ -283,10 +282,10 @@ Result Parser::ProcessIndicesBlock(const SectionParser::Section& section) { DatumType type; type.SetType(DataType::kUint32); - auto b = MakeUnique<DataBuffer>(BufferType::kIndex); + auto b = MakeUnique<Buffer>(BufferType::kIndex); auto* buf = b.get(); b->SetName("indices"); - b->SetDatumType(type); + b->SetFormat(type.AsFormat()); b->SetData(std::move(indices)); Result r = script_->AddBuffer(std::move(b)); if (!r.IsSuccess()) @@ -410,7 +409,7 @@ Result Parser::ProcessVertexDataBlock(const SectionParser::Section& section) { auto* pipeline = script_->GetPipeline(kDefaultPipelineName); for (size_t i = 0; i < headers.size(); ++i) { - auto buffer = MakeUnique<FormatBuffer>(BufferType::kVertex); + auto buffer = MakeUnique<Buffer>(BufferType::kVertex); auto* buf = buffer.get(); buffer->SetName("Vertices" + std::to_string(i)); buffer->SetFormat(std::move(headers[i].format)); diff --git a/src/vkscript/parser_test.cc b/src/vkscript/parser_test.cc index 36eb2f5..8849fea 100644 --- a/src/vkscript/parser_test.cc +++ b/src/vkscript/parser_test.cc @@ -131,7 +131,6 @@ TEST_F(VkScriptParserTest, RequireBlockFramebuffer) { const auto& buffers = script->GetBuffers(); ASSERT_EQ(1U, buffers.size()); EXPECT_EQ(BufferType::kColor, buffers[0]->GetBufferType()); - EXPECT_TRUE(buffers[0]->IsFormatBuffer()); EXPECT_EQ(FormatType::kR32G32B32A32_SFLOAT, buffers[0]->GetFormat()->GetFormatType()); } @@ -147,7 +146,6 @@ TEST_F(VkScriptParserTest, RequireBlockDepthStencil) { const auto& buffers = script->GetBuffers(); ASSERT_EQ(2U, buffers.size()); EXPECT_EQ(BufferType::kDepth, buffers[1]->GetBufferType()); - EXPECT_TRUE(buffers[1]->IsFormatBuffer()); EXPECT_EQ(FormatType::kD24_UNORM_S8_UINT, buffers[1]->GetFormat()->GetFormatType()); } @@ -230,12 +228,10 @@ inheritedQueries # line comment const auto& buffers = script->GetBuffers(); ASSERT_EQ(2U, buffers.size()); EXPECT_EQ(BufferType::kColor, buffers[0]->GetBufferType()); - EXPECT_TRUE(buffers[0]->IsFormatBuffer()); EXPECT_EQ(FormatType::kR32G32B32A32_SFLOAT, buffers[0]->GetFormat()->GetFormatType()); EXPECT_EQ(BufferType::kDepth, buffers[1]->GetBufferType()); - EXPECT_TRUE(buffers[1]->IsFormatBuffer()); EXPECT_EQ(FormatType::kD24_UNORM_S8_UINT, buffers[1]->GetFormat()->GetFormatType()); @@ -257,8 +253,6 @@ TEST_F(VkScriptParserTest, IndicesBlock) { ASSERT_EQ(BufferType::kIndex, buffers[1]->GetBufferType()); auto buffer_ptr = buffers[1].get(); - ASSERT_TRUE(buffer_ptr->IsDataBuffer()); - auto buffer = buffer_ptr; EXPECT_TRUE(buffer->GetFormat()->IsUint32()); EXPECT_EQ(3U, buffer->ElementCount()); diff --git a/src/vulkan/engine_vulkan.cc b/src/vulkan/engine_vulkan.cc index c32d14b..f0ccaf2 100644 --- a/src/vulkan/engine_vulkan.cc +++ b/src/vulkan/engine_vulkan.cc @@ -198,7 +198,7 @@ Result EngineVulkan::CreatePipeline(amber::Pipeline* pipeline) { info.vertex_buffer = MakeUnique<VertexBuffer>(device_.get()); info.vertex_buffer->SetData(static_cast<uint8_t>(vtex_info.location), - vtex_info.buffer->AsFormatBuffer()); + vtex_info.buffer); } if (pipeline->GetIndexBuffer()) { @@ -358,7 +358,7 @@ Result EngineVulkan::DoDrawRect(const DrawRectCommand* command) { format->AddComponent(FormatComponentType::kR, FormatMode::kSFloat, 32); format->AddComponent(FormatComponentType::kG, FormatMode::kSFloat, 32); - auto buf = MakeUnique<FormatBuffer>(); + auto buf = MakeUnique<Buffer>(); buf->SetFormat(std::move(format)); buf->SetData(std::move(values)); diff --git a/src/vulkan/vertex_buffer_test.cc b/src/vulkan/vertex_buffer_test.cc index 66384b0..aa18661 100644 --- a/src/vulkan/vertex_buffer_test.cc +++ b/src/vulkan/vertex_buffer_test.cc @@ -57,7 +57,7 @@ class VertexBufferTest : public testing::Test { Result SetIntData(uint8_t location, std::unique_ptr<Format> format, std::vector<Value> values) { - auto buffer = MakeUnique<FormatBuffer>(); + auto buffer = MakeUnique<Buffer>(); buffer->SetFormat(std::move(format)); buffer->SetData(std::move(values)); @@ -68,7 +68,7 @@ class VertexBufferTest : public testing::Test { Result SetDoubleData(uint8_t location, std::unique_ptr<Format> format, std::vector<Value> values) { - auto buffer = MakeUnique<FormatBuffer>(); + auto buffer = MakeUnique<Buffer>(); buffer->SetFormat(std::move(format)); buffer->SetData(std::move(values)); |