aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan sinclair <dj2@everburning.com>2019-04-10 09:43:29 -0400
committerGitHub <noreply@github.com>2019-04-10 09:43:29 -0400
commitb322b20327af1d6665c606983c0de035ddee6c26 (patch)
tree4e5649645db9e8c459dc26ca7ad597338e7a653d /src
parent43248b29723575d27eb96187ef9ca594739140ed (diff)
downloadamber-b322b20327af1d6665c606983c0de035ddee6c26.tar.gz
[vulkan] Allow setting vertex buffer with a data buffer (#450)
This CL updates the vulkan engine to allow using a data buffer when setting the vertex buffer. The needed format string will be auto-generated from the data type set in the data buffer.
Diffstat (limited to 'src')
-rw-r--r--src/buffer.h4
-rw-r--r--src/datum_type.cc7
-rw-r--r--src/datum_type.h3
-rw-r--r--src/datum_type_test.cc3
-rw-r--r--src/executor.cc8
-rw-r--r--src/format_parser.cc18
-rw-r--r--src/verifier_test.cc4
-rw-r--r--src/vkscript/parser_test.cc9
-rw-r--r--src/vulkan/engine_vulkan.cc11
-rw-r--r--src/vulkan/vertex_buffer.cc29
-rw-r--r--src/vulkan/vertex_buffer.h4
11 files changed, 60 insertions, 40 deletions
diff --git a/src/buffer.h b/src/buffer.h
index fd14d4d..79cd72e 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -152,7 +152,7 @@ class DataBuffer : public Buffer {
/// 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_; }
+ const DatumType GetDatumType() const { return datum_type_; }
private:
Result CopyData(const std::vector<Value>& data);
@@ -179,7 +179,7 @@ class FormatBuffer : public Buffer {
format_ = std::move(format);
}
/// Returns the Format describing the buffer data.
- const Format& GetFormat() const { return *(format_.get()); }
+ const Format GetFormat() const { return *(format_.get()); }
uint32_t GetTexelStride() { return format_->GetByteSize(); }
diff --git a/src/datum_type.cc b/src/datum_type.cc
index 37634bc..ac1b68d 100644
--- a/src/datum_type.cc
+++ b/src/datum_type.cc
@@ -22,6 +22,8 @@ namespace amber {
DatumType::DatumType() = default;
+DatumType::DatumType(const DatumType&) = default;
+
DatumType::~DatumType() = default;
DatumType& DatumType::operator=(const DatumType&) = default;
@@ -56,7 +58,7 @@ uint32_t DatumType::SizeInBytes() const {
return bytes;
}
-std::unique_ptr<Format> DatumType::AsFormat() const {
+Format DatumType::AsFormat() const {
uint32_t bits_per_element = ElementSizeInBytes() * 8;
static const char* prefixes = "RGBA";
std::string name = "";
@@ -73,7 +75,8 @@ std::unique_ptr<Format> DatumType::AsFormat() const {
name += "UINT";
FormatParser fp;
- return fp.Parse(name);
+ auto fmt = fp.Parse(name);
+ return *(fmt.get());
}
} // namespace amber
diff --git a/src/datum_type.h b/src/datum_type.h
index 1d60f5f..2182116 100644
--- a/src/datum_type.h
+++ b/src/datum_type.h
@@ -39,6 +39,7 @@ enum class DataType {
class DatumType {
public:
DatumType();
+ DatumType(const DatumType&);
~DatumType();
DatumType& operator=(const DatumType&);
@@ -66,7 +67,7 @@ class DatumType {
uint32_t ElementSizeInBytes() const;
uint32_t SizeInBytes() const;
- std::unique_ptr<Format> AsFormat() const;
+ Format AsFormat() const;
private:
DataType type_ = DataType::kUint8;
diff --git a/src/datum_type_test.cc b/src/datum_type_test.cc
index ef20bed..e5e8e03 100644
--- a/src/datum_type_test.cc
+++ b/src/datum_type_test.cc
@@ -33,8 +33,7 @@ TEST_P(DatumTypeTestFormat, ToFormat) {
dt.SetRowCount(test_data.row_count);
auto fmt = dt.AsFormat();
- ASSERT_TRUE(fmt != nullptr);
- EXPECT_EQ(test_data.format_type, fmt->GetFormatType());
+ EXPECT_EQ(test_data.format_type, fmt.GetFormatType());
}
INSTANTIATE_TEST_CASE_P(
DatumTypeTestFormat,
diff --git a/src/executor.cc b/src/executor.cc
index fc9c70c..1e31ebf 100644
--- a/src/executor.cc
+++ b/src/executor.cc
@@ -84,10 +84,10 @@ Result Executor::ExecuteCommand(Engine* engine, Command* cmd) {
auto* buffer = cmd->AsProbe()->GetBuffer()->AsFormatBuffer();
assert(buffer);
- return verifier_.Probe(cmd->AsProbe(), &buffer->GetFormat(),
- buffer->GetTexelStride(), buffer->GetRowStride(),
- buffer->GetWidth(), buffer->GetHeight(),
- buffer->ValuePtr()->data());
+ Format fmt = buffer->GetFormat();
+ return verifier_.Probe(cmd->AsProbe(), &fmt, buffer->GetTexelStride(),
+ buffer->GetRowStride(), buffer->GetWidth(),
+ buffer->GetHeight(), buffer->ValuePtr()->data());
}
if (cmd->IsProbeSSBO()) {
auto probe_ssbo = cmd->AsProbeSSBO();
diff --git a/src/format_parser.cc b/src/format_parser.cc
index 982cbdb..03ebd2e 100644
--- a/src/format_parser.cc
+++ b/src/format_parser.cc
@@ -29,8 +29,6 @@ std::unique_ptr<Format> FormatParser::Parse(const std::string& data) {
if (data.empty())
return nullptr;
- auto fmt = MakeUnique<Format>();
-
// See if this is a custom glsl string format.
if (data.find('/', 0) != std::string::npos)
return ParseGlslFormat(data);
@@ -39,6 +37,7 @@ std::unique_ptr<Format> FormatParser::Parse(const std::string& data) {
if (type == FormatType::kUnknown)
return nullptr;
+ auto fmt = MakeUnique<Format>();
fmt->SetFormatType(type);
size_t cur_pos = 0;
@@ -477,15 +476,10 @@ std::unique_ptr<Format> FormatParser::ParseGlslFormat(const std::string& fmt) {
if (num_components > 4)
return nullptr;
- std::string new_name = "R" + std::to_string(bits);
- --num_components;
-
- if (num_components-- > 0)
- new_name += "G" + std::to_string(bits);
- if (num_components-- > 0)
- new_name += "B" + std::to_string(bits);
- if (num_components-- > 0)
- new_name += "A" + std::to_string(bits);
+ std::string new_name = "";
+ static const char* prefix = "RGBA";
+ for (int8_t i = 0; i < num_components; ++i)
+ new_name += prefix[i] + std::to_string(bits);
new_name += "_";
if (mode == FormatMode::kSInt)
@@ -494,8 +488,6 @@ std::unique_ptr<Format> FormatParser::ParseGlslFormat(const std::string& fmt) {
new_name += "UINT";
else if (mode == FormatMode::kSFloat)
new_name += "SFLOAT";
- else
- return nullptr;
return Parse(new_name);
}
diff --git a/src/verifier_test.cc b/src/verifier_test.cc
index 593488a..ab36da7 100644
--- a/src/verifier_test.cc
+++ b/src/verifier_test.cc
@@ -518,7 +518,7 @@ TEST_F(VerifierTest, HexFloatToFloatR16G11B10) {
probe.SetB(0.1171875f);
Format format;
- format.SetFormatType(FormatType::kB8G8R8A8_UNORM);
+ format.SetFormatType(FormatType::kR32G32B32_SFLOAT);
format.AddComponent(FormatComponentType::kR, FormatMode::kSFloat, 16);
format.AddComponent(FormatComponentType::kG, FormatMode::kUFloat, 11);
format.AddComponent(FormatComponentType::kB, FormatMode::kUFloat, 10);
@@ -559,7 +559,7 @@ TEST_F(VerifierTest, HexFloatToFloatR11G16B10) {
probe.SetB(0.1171875f);
Format format;
- format.SetFormatType(FormatType::kB8G8R8A8_UNORM);
+ format.SetFormatType(FormatType::kR32G32B32_SFLOAT);
format.AddComponent(FormatComponentType::kR, FormatMode::kSFloat, 11);
format.AddComponent(FormatComponentType::kG, FormatMode::kUFloat, 16);
format.AddComponent(FormatComponentType::kB, FormatMode::kUFloat, 10);
diff --git a/src/vkscript/parser_test.cc b/src/vkscript/parser_test.cc
index 14b55e1..7ed660f 100644
--- a/src/vkscript/parser_test.cc
+++ b/src/vkscript/parser_test.cc
@@ -359,9 +359,12 @@ TEST_F(VkScriptParserTest, VertexDataHeaderGlslString) {
ASSERT_EQ(BufferType::kVertex, buffers[1]->GetBufferType());
EXPECT_EQ(static_cast<uint8_t>(0U), buffers[1]->GetLocation());
+
EXPECT_EQ(FormatType::kR32G32_SFLOAT,
buffers[1]->AsFormatBuffer()->GetFormat().GetFormatType());
- auto& comps1 = buffers[1]->AsFormatBuffer()->GetFormat().GetComponents();
+
+ auto fmt = buffers[1]->AsFormatBuffer()->GetFormat();
+ auto& comps1 = fmt.GetComponents();
ASSERT_EQ(2U, comps1.size());
EXPECT_EQ(FormatMode::kSFloat, comps1[0].mode);
EXPECT_EQ(FormatMode::kSFloat, comps1[1].mode);
@@ -371,7 +374,9 @@ TEST_F(VkScriptParserTest, VertexDataHeaderGlslString) {
EXPECT_EQ(1U, buffers[2]->GetLocation());
EXPECT_EQ(FormatType::kR32G32B32_SINT,
buffers[2]->AsFormatBuffer()->GetFormat().GetFormatType());
- auto& comps2 = buffers[2]->AsFormatBuffer()->GetFormat().GetComponents();
+
+ auto fmt2 = buffers[2]->AsFormatBuffer()->GetFormat();
+ auto& comps2 = fmt2.GetComponents();
ASSERT_EQ(3U, comps2.size());
EXPECT_EQ(FormatMode::kSInt, comps2[0].mode);
EXPECT_EQ(FormatMode::kSInt, comps2[1].mode);
diff --git a/src/vulkan/engine_vulkan.cc b/src/vulkan/engine_vulkan.cc
index dc10f01..b0b6ae2 100644
--- a/src/vulkan/engine_vulkan.cc
+++ b/src/vulkan/engine_vulkan.cc
@@ -191,16 +191,15 @@ Result EngineVulkan::CreatePipeline(amber::Pipeline* pipeline) {
info.vk_pipeline = std::move(vk_pipeline);
for (const auto& vtex_info : pipeline->GetVertexBuffers()) {
- auto& fmt = vtex_info.buffer->IsFormatBuffer()
- ? vtex_info.buffer->AsFormatBuffer()->GetFormat()
- : Format();
+ auto fmt =
+ vtex_info.buffer->IsFormatBuffer()
+ ? vtex_info.buffer->AsFormatBuffer()->GetFormat()
+ : vtex_info.buffer->AsDataBuffer()->GetDatumType().AsFormat();
+
if (!device_->IsFormatSupportedByPhysicalDevice(fmt, vtex_info.buffer))
return Result("Vulkan vertex buffer format is not supported");
-
if (!info.vertex_buffer)
info.vertex_buffer = MakeUnique<VertexBuffer>(device_.get());
- if (!vtex_info.buffer->IsFormatBuffer())
- return Result("Vulkan vertex buffer is not a format buffer");
info.vertex_buffer->SetData(static_cast<uint8_t>(vtex_info.location),
vtex_info.buffer->AsFormatBuffer());
diff --git a/src/vulkan/vertex_buffer.cc b/src/vulkan/vertex_buffer.cc
index 9aa150b..3949782 100644
--- a/src/vulkan/vertex_buffer.cc
+++ b/src/vulkan/vertex_buffer.cc
@@ -28,15 +28,28 @@ VertexBuffer::VertexBuffer(Device* device) : device_(device) {}
VertexBuffer::~VertexBuffer() = default;
-void VertexBuffer::SetData(uint8_t location, FormatBuffer* buffer) {
+void VertexBuffer::SetData(uint8_t location, Buffer* buffer) {
+ uint32_t size_in_bytes = 0;
+ VkFormat fmt;
+
+ if (buffer->IsFormatBuffer()) {
+ auto format = buffer->AsFormatBuffer()->GetFormat();
+ size_in_bytes = format.GetByteSize();
+ fmt = device_->GetVkFormat(format);
+ } else {
+ auto format = buffer->AsDataBuffer()->GetDatumType().AsFormat();
+ size_in_bytes = format.GetByteSize();
+ fmt = device_->GetVkFormat(format);
+ }
+
vertex_attr_desc_.emplace_back();
// TODO(jaebaek): Support multiple binding
vertex_attr_desc_.back().binding = 0;
vertex_attr_desc_.back().location = location;
vertex_attr_desc_.back().offset = stride_in_bytes_;
- vertex_attr_desc_.back().format = device_->GetVkFormat(buffer->GetFormat());
+ vertex_attr_desc_.back().format = fmt;
- stride_in_bytes_ += buffer->GetFormat().GetByteSize();
+ stride_in_bytes_ += size_in_bytes;
data_.push_back(buffer);
}
@@ -47,7 +60,15 @@ Result VertexBuffer::FillVertexBufferWithData(CommandBuffer* command) {
for (uint32_t i = 0; i < GetVertexCount(); ++i) {
uint8_t* ptr = ptr_in_stride_begin;
for (uint32_t j = 0; j < data_.size(); ++j) {
- size_t bytes = data_[j]->GetFormat().GetByteSize();
+ size_t bytes = 0;
+ if (data_[j]->IsFormatBuffer()) {
+ auto& format = data_[j]->AsFormatBuffer()->GetFormat();
+ bytes = format.GetByteSize();
+ } else {
+ auto format = data_[j]->AsDataBuffer()->GetDatumType().AsFormat();
+ bytes = format.GetByteSize();
+ }
+
std::memcpy(ptr, data_[j]->GetValues<uint8_t>() + (i * bytes), bytes);
ptr += bytes;
}
diff --git a/src/vulkan/vertex_buffer.h b/src/vulkan/vertex_buffer.h
index 2c38c71..8e7d186 100644
--- a/src/vulkan/vertex_buffer.h
+++ b/src/vulkan/vertex_buffer.h
@@ -39,7 +39,7 @@ class VertexBuffer {
Result SendVertexData(CommandBuffer* command);
bool VertexDataSent() const { return !is_vertex_data_pending_; }
- void SetData(uint8_t location, FormatBuffer* buffer);
+ void SetData(uint8_t location, Buffer* buffer);
const std::vector<VkVertexInputAttributeDescription>& GetVkVertexInputAttr()
const {
@@ -81,7 +81,7 @@ class VertexBuffer {
std::unique_ptr<TransferBuffer> transfer_buffer_;
uint32_t stride_in_bytes_ = 0;
- std::vector<FormatBuffer*> data_;
+ std::vector<Buffer*> data_;
std::vector<VkVertexInputAttributeDescription> vertex_attr_desc_;
};