aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordan sinclair <dj2@everburning.com>2019-04-16 09:55:45 -0400
committerGitHub <noreply@github.com>2019-04-16 09:55:45 -0400
commitac70df3cd57b9b34a42035e8f9c96c889a123a13 (patch)
tree14ff47631af6bd34fb74693fd4ee524f37064de2
parentd26ee22dd7faab1845a531d410f7ec1db407402a (diff)
downloadamber-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.txt1
-rw-r--r--src/amber.cc4
-rw-r--r--src/amberscript/parser.cc30
-rw-r--r--src/amberscript/parser.h10
-rw-r--r--src/amberscript/parser_bind_test.cc49
-rw-r--r--src/amberscript/parser_buffer_test.cc9
-rw-r--r--src/amberscript/parser_pipeline_test.cc1
-rw-r--r--src/buffer.cc87
-rw-r--r--src/buffer.h90
-rw-r--r--src/buffer_test.cc52
-rw-r--r--src/executor.cc4
-rw-r--r--src/format.cc10
-rw-r--r--src/format.h3
-rw-r--r--src/format_test.cc80
-rw-r--r--src/pipeline.cc8
-rw-r--r--src/pipeline_test.cc8
-rw-r--r--src/script_test.cc18
-rw-r--r--src/vkscript/command_parser.cc4
-rw-r--r--src/vkscript/parser.cc11
-rw-r--r--src/vkscript/parser_test.cc6
-rw-r--r--src/vulkan/engine_vulkan.cc4
-rw-r--r--src/vulkan/vertex_buffer_test.cc4
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));