aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan sinclair <dj2@everburning.com>2019-03-07 18:04:37 -0500
committerGitHub <noreply@github.com>2019-03-07 18:04:37 -0500
commitd9e823e5ab380fcf417452581721ad9c3bdcf60b (patch)
tree55a555e7e08ac044abbc230e904b7369ef8ce6ca /src
parent0d744484eba498e30ad02cfb91b35426df470ece (diff)
downloadamber-d9e823e5ab380fcf417452581721ad9c3bdcf60b.tar.gz
[vulkan] Support multiple colour attachments. (#340)
This CL updates the vulkan engine to allow having multiple image attachments. Currently the frontend code just works with the first image attachment.
Diffstat (limited to 'src')
-rw-r--r--src/amber.cc4
-rw-r--r--src/dawn/engine_dawn.cc4
-rw-r--r--src/dawn/engine_dawn.h8
-rw-r--r--src/engine.h5
-rw-r--r--src/executor.cc2
-rw-r--r--src/executor_test.cc8
-rw-r--r--src/pipeline.cc5
-rw-r--r--src/vulkan/engine_vulkan.cc32
-rw-r--r--src/vulkan/engine_vulkan.h3
-rw-r--r--src/vulkan/frame_buffer.cc63
-rw-r--r--src/vulkan/frame_buffer.h26
-rw-r--r--src/vulkan/graphics_pipeline.cc98
-rw-r--r--src/vulkan/graphics_pipeline.h22
13 files changed, 150 insertions, 130 deletions
diff --git a/src/amber.cc b/src/amber.cc
index 746f3ea..4b4da3f 100644
--- a/src/amber.cc
+++ b/src/amber.cc
@@ -131,13 +131,13 @@ amber::Result Amber::ExecuteWithShaderData(const amber::Recipe* recipe,
for (BufferInfo& buffer_info : opts->extractions) {
if (buffer_info.buffer_name == "framebuffer") {
ResourceInfo info;
- r = engine->GetFrameBufferInfo(pipeline, &info);
+ r = engine->GetFrameBufferInfo(pipeline, 0, &info);
if (!r.IsSuccess())
break;
buffer_info.width = info.image_info.width;
buffer_info.height = info.image_info.height;
- r = engine->GetFrameBuffer(pipeline, &(buffer_info.values));
+ r = engine->GetFrameBuffer(pipeline, 0, &(buffer_info.values));
if (!r.IsSuccess())
break;
diff --git a/src/dawn/engine_dawn.cc b/src/dawn/engine_dawn.cc
index 1e47b02..b6f3773 100644
--- a/src/dawn/engine_dawn.cc
+++ b/src/dawn/engine_dawn.cc
@@ -448,7 +448,7 @@ Result EngineDawn::CreateFramebufferIfNeeded() {
return {};
}
-Result EngineDawn::GetFrameBufferInfo(Pipeline*, ResourceInfo* info) {
+Result EngineDawn::GetFrameBufferInfo(Pipeline*, size_t, ResourceInfo* info) {
assert(info);
if (render_pipeline_info_.fb_data == nullptr)
@@ -466,7 +466,7 @@ Result EngineDawn::GetFrameBufferInfo(Pipeline*, ResourceInfo* info) {
return {};
}
-Result EngineDawn::GetFrameBuffer(Pipeline*, std::vector<Value>*) {
+Result EngineDawn::GetFrameBuffer(Pipeline*, size_t, std::vector<Value>*) {
return Result("Dawn::GetFrameBuffer not implemented");
}
diff --git a/src/dawn/engine_dawn.h b/src/dawn/engine_dawn.h
index e115ac6..93e27af 100644
--- a/src/dawn/engine_dawn.h
+++ b/src/dawn/engine_dawn.h
@@ -60,8 +60,12 @@ class EngineDawn : public Engine {
const PatchParameterVerticesCommand* cmd) override;
Result DoBuffer(const BufferCommand* cmd) override;
Result DoProcessCommands(Pipeline*) override;
- Result GetFrameBufferInfo(Pipeline*, ResourceInfo* info) override;
- Result GetFrameBuffer(Pipeline*, std::vector<Value>* values) override;
+ Result GetFrameBufferInfo(Pipeline*,
+ size_t attachment_idx,
+ ResourceInfo* info) override;
+ Result GetFrameBuffer(Pipeline*,
+ size_t attachment_idx,
+ std::vector<Value>* values) override;
Result GetDescriptorInfo(Pipeline*,
const uint32_t descriptor_set,
const uint32_t binding,
diff --git a/src/engine.h b/src/engine.h
index 6b46c6e..5eea840 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -137,11 +137,14 @@ class Engine {
/// the host address space. In particular, if we have run
/// DoProcessCommands() and since then no graphics pipeline drawing
/// commands have occurred e.g., DoClear, DoDrawArrays, DoDrawRect.
- virtual Result GetFrameBufferInfo(Pipeline* pipeline, ResourceInfo* info) = 0;
+ virtual Result GetFrameBufferInfo(Pipeline* pipeline,
+ size_t attachment_idx,
+ ResourceInfo* info) = 0;
/// Copy the content of the framebuffer into |values|, each value is a pixel
/// in R8G8B8A8 format.
virtual Result GetFrameBuffer(Pipeline* pipeline,
+ size_t attachment_idx,
std::vector<Value>* values) = 0;
/// Copy the contents of the resource bound to the given descriptor
diff --git a/src/executor.cc b/src/executor.cc
index 4823d6d..e5aba7d 100644
--- a/src/executor.cc
+++ b/src/executor.cc
@@ -80,7 +80,7 @@ Result Executor::Execute(Engine* engine,
// This must come after processing commands because we require
// the framebuffer data to be mapped into host memory and have
// a valid host-side pointer.
- r = engine->GetFrameBufferInfo(cmd->GetPipeline(), &info);
+ r = engine->GetFrameBufferInfo(cmd->GetPipeline(), 0, &info);
if (!r.IsSuccess())
return r;
assert(info.cpu_memory != nullptr);
diff --git a/src/executor_test.cc b/src/executor_test.cc
index f588c1b..e198bb5 100644
--- a/src/executor_test.cc
+++ b/src/executor_test.cc
@@ -160,8 +160,12 @@ class EngineStub : public Engine {
}
Result DoProcessCommands(Pipeline*) override { return {}; }
- Result GetFrameBufferInfo(Pipeline*, ResourceInfo*) override { return {}; }
- Result GetFrameBuffer(Pipeline*, std::vector<Value>*) override { return {}; }
+ Result GetFrameBufferInfo(Pipeline*, size_t, ResourceInfo*) override {
+ return {};
+ }
+ Result GetFrameBuffer(Pipeline*, size_t, std::vector<Value>*) override {
+ return {};
+ }
Result GetDescriptorInfo(Pipeline*,
const uint32_t,
const uint32_t,
diff --git a/src/pipeline.cc b/src/pipeline.cc
index 3cae869..d45dc05 100644
--- a/src/pipeline.cc
+++ b/src/pipeline.cc
@@ -125,9 +125,6 @@ Result Pipeline::SetShaderType(const Shader* shader, ShaderType type) {
}
Result Pipeline::Validate() const {
- if (color_attachments_.empty())
- return Result("PIPELINE missing color attachment");
-
size_t fb_size = fb_width_ * fb_height_;
for (const auto& attachment : color_attachments_) {
if (attachment.buffer->GetSize() != fb_size) {
@@ -147,6 +144,8 @@ Result Pipeline::Validate() const {
}
Result Pipeline::ValidateGraphics() const {
+ if (color_attachments_.empty())
+ return Result("PIPELINE missing color attachment");
if (shaders_.empty())
return Result("graphics pipeline requires vertex and fragment shaders");
diff --git a/src/vulkan/engine_vulkan.cc b/src/vulkan/engine_vulkan.cc
index 1321e31..85d569e 100644
--- a/src/vulkan/engine_vulkan.cc
+++ b/src/vulkan/engine_vulkan.cc
@@ -158,17 +158,6 @@ Result EngineVulkan::CreatePipeline(amber::Pipeline* pipeline) {
pipeline_map_[pipeline] = PipelineInfo();
auto& info = pipeline_map_[pipeline];
- // Set VK_FORMAT_B8G8R8A8_UNORM for color frame buffer by default.
- info.color_frame_format.SetFormatType(kDefaultFramebufferFormat);
- info.color_frame_format.AddComponent(FormatComponentType::kB,
- FormatMode::kUNorm, 8);
- info.color_frame_format.AddComponent(FormatComponentType::kG,
- FormatMode::kUNorm, 8);
- info.color_frame_format.AddComponent(FormatComponentType::kR,
- FormatMode::kUNorm, 8);
- info.color_frame_format.AddComponent(FormatComponentType::kA,
- FormatMode::kUNorm, 8);
-
for (const auto& shader_info : pipeline->GetShaders()) {
Result r =
SetShader(pipeline, shader_info.GetShaderType(), shader_info.GetData());
@@ -178,7 +167,6 @@ Result EngineVulkan::CreatePipeline(amber::Pipeline* pipeline) {
for (const auto& colour_info : pipeline->GetColorAttachments()) {
auto& fmt = colour_info.buffer->AsFormatBuffer()->GetFormat();
- info.color_frame_format = fmt;
if (!VerifyFormatAvailable(fmt, colour_info.type))
return Result("Vulkan color attachment format is not supported");
}
@@ -207,8 +195,7 @@ Result EngineVulkan::CreatePipeline(amber::Pipeline* pipeline) {
} else {
vk_pipeline = MakeUnique<GraphicsPipeline>(
device_.get(), device_->GetPhysicalDeviceProperties(),
- device_->GetPhysicalMemoryProperties(),
- ToVkFormat(info.color_frame_format.GetFormatType()),
+ device_->GetPhysicalMemoryProperties(), pipeline->GetColorAttachments(),
ToVkFormat(depth_buffer_format), engine_data.fence_timeout_ms,
GetShaderStageInfo(pipeline));
@@ -423,50 +410,55 @@ Result EngineVulkan::DoProcessCommands(amber::Pipeline* pipeline) {
}
Result EngineVulkan::GetFrameBufferInfo(amber::Pipeline* pipeline,
+ size_t attachment_idx,
ResourceInfo* resource_info) {
if (!resource_info)
return Result("Vulkan::GetFrameBufferInfo missing resource info");
auto& info = pipeline_map_[pipeline];
if (!info.vk_pipeline)
- return Result("Vulkan::GetFrameBufferIfno missing pipeline");
+ return Result("Vulkan::GetFrameBufferInfo missing pipeline");
if (!info.vk_pipeline->IsGraphics())
return Result("Vulkan::GetFrameBufferInfo for Non-Graphics Pipeline");
const auto graphics = info.vk_pipeline->AsGraphics();
const auto frame = graphics->GetFrame();
- const auto bytes_per_texel = info.color_frame_format.GetByteSize();
+ const auto& fmt = frame->GetFormatForAttachment(attachment_idx);
+ const auto bytes_per_texel = fmt.GetByteSize();
resource_info->type = ResourceInfoType::kImage;
resource_info->image_info.width = frame->GetWidth();
resource_info->image_info.height = frame->GetHeight();
resource_info->image_info.depth = 1U;
resource_info->image_info.texel_stride = bytes_per_texel;
- resource_info->image_info.texel_format = &info.color_frame_format;
+ resource_info->image_info.texel_format = &fmt;
// 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.
const auto row_stride = bytes_per_texel * frame->GetWidth();
resource_info->image_info.row_stride = row_stride;
resource_info->size_in_bytes = row_stride * frame->GetHeight();
- resource_info->cpu_memory = frame->GetColorBufferPtr();
+ resource_info->cpu_memory = frame->GetColorBufferPtr(attachment_idx);
return {};
}
Result EngineVulkan::GetFrameBuffer(amber::Pipeline* pipeline,
+ size_t attachment_idx,
std::vector<Value>* values) {
values->resize(0);
ResourceInfo resource_info;
- GetFrameBufferInfo(pipeline, &resource_info);
+ GetFrameBufferInfo(pipeline, attachment_idx, &resource_info);
if (resource_info.type != ResourceInfoType::kImage) {
return Result(
"Vulkan:GetFrameBuffer() is invalid for non-image framebuffer");
}
auto& info = pipeline_map_[pipeline];
+ const auto frame = info.vk_pipeline->AsGraphics()->GetFrame();
+ const auto& fmt = frame->GetFormatForAttachment(attachment_idx);
// TODO(jaebaek): Support other formats
- if (info.color_frame_format.GetFormatType() != kDefaultFramebufferFormat)
+ if (fmt.GetFormatType() != kDefaultFramebufferFormat)
return Result("Vulkan::GetFrameBuffer Unsupported buffer format");
Value pixel;
diff --git a/src/vulkan/engine_vulkan.h b/src/vulkan/engine_vulkan.h
index 5af738a..e6bd079 100644
--- a/src/vulkan/engine_vulkan.h
+++ b/src/vulkan/engine_vulkan.h
@@ -59,8 +59,10 @@ class EngineVulkan : public Engine {
Result DoBuffer(const BufferCommand* cmd) override;
Result DoProcessCommands(amber::Pipeline* pipeline) override;
Result GetFrameBufferInfo(amber::Pipeline* pipeline,
+ size_t attachment_idx,
ResourceInfo* info) override;
Result GetFrameBuffer(amber::Pipeline* pipeline,
+ size_t attachment_idx,
std::vector<Value>* values) override;
Result GetDescriptorInfo(amber::Pipeline* pipeline,
const uint32_t descriptor_set,
@@ -73,7 +75,6 @@ class EngineVulkan : public Engine {
std::unique_ptr<VertexBuffer> vertex_buffer;
std::unordered_map<ShaderType, VkShaderModule, CastHash<ShaderType>>
shaders;
- Format color_frame_format;
};
std::vector<VkPipelineShaderStageCreateInfo> GetShaderStageInfo(
diff --git a/src/vulkan/frame_buffer.cc b/src/vulkan/frame_buffer.cc
index a3d3039..f32f0e3 100644
--- a/src/vulkan/frame_buffer.cc
+++ b/src/vulkan/frame_buffer.cc
@@ -26,27 +26,36 @@
namespace amber {
namespace vulkan {
-FrameBuffer::FrameBuffer(Device* device, uint32_t width, uint32_t height)
- : device_(device), width_(width), height_(height) {}
+FrameBuffer::FrameBuffer(
+ Device* device,
+ const std::vector<const amber::Pipeline::BufferInfo*>& color_attachments,
+ uint32_t width,
+ uint32_t height)
+ : device_(device),
+ color_attachments_(color_attachments),
+ width_(width),
+ height_(height) {}
FrameBuffer::~FrameBuffer() = default;
Result FrameBuffer::Initialize(
VkRenderPass render_pass,
- VkFormat color_format,
VkFormat depth_format,
const VkPhysicalDeviceMemoryProperties& properties) {
std::vector<VkImageView> attachments;
- if (color_format != VK_FORMAT_UNDEFINED) {
- color_image_ =
- MakeUnique<Image>(device_, color_format, VK_IMAGE_ASPECT_COLOR_BIT,
- width_, height_, depth_, properties);
- Result r = color_image_->Initialize(VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
- VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
+ for (auto* info : color_attachments_) {
+ color_images_.push_back(MakeUnique<Image>(
+ device_,
+ ToVkFormat(info->buffer->AsFormatBuffer()->GetFormat().GetFormatType()),
+ VK_IMAGE_ASPECT_COLOR_BIT, width_, height_, depth_, properties));
+
+ Result r = color_images_.back()->Initialize(
+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
if (!r.IsSuccess())
return r;
- attachments.push_back(color_image_->GetVkImageView());
+
+ attachments.push_back(color_images_.back()->GetVkImageView());
}
if (depth_format != VK_FORMAT_UNDEFINED) {
@@ -57,6 +66,7 @@ Result FrameBuffer::Initialize(
? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT
: VK_IMAGE_ASPECT_DEPTH_BIT),
width_, height_, depth_, properties);
+
Result r =
depth_image_->Initialize(VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
@@ -100,12 +110,11 @@ Result FrameBuffer::ChangeFrameImageLayout(CommandBuffer* command,
"from kInit");
}
- if (color_image_) {
- color_image_->ChangeLayout(command,
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
- VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- VK_PIPELINE_STAGE_TRANSFER_BIT);
+ for (auto& img : color_images_) {
+ img->ChangeLayout(command, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ VK_PIPELINE_STAGE_TRANSFER_BIT);
}
if (depth_image_) {
depth_image_->ChangeLayout(
@@ -128,10 +137,10 @@ Result FrameBuffer::ChangeFrameImageLayout(CommandBuffer* command,
? VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
: VK_PIPELINE_STAGE_TRANSFER_BIT;
- if (color_image_) {
- color_image_->ChangeLayout(
- command, old_layout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- source_stage, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+ for (auto& img : color_images_) {
+ img->ChangeLayout(command, old_layout,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, source_stage,
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
}
if (depth_image_) {
depth_image_->ChangeLayout(
@@ -148,12 +157,22 @@ void FrameBuffer::Shutdown() {
nullptr);
}
- if (color_image_)
- color_image_->Shutdown();
+ for (auto& img : color_images_)
+ img->Shutdown();
if (depth_image_)
depth_image_->Shutdown();
}
+Result FrameBuffer::CopyColorImagesToHost(CommandBuffer* command) {
+ for (auto& img : color_images_) {
+ ChangeFrameImageLayout(command, FrameImageState::kProbe);
+ Result r = img->CopyToHost(command);
+ if (!r.IsSuccess())
+ return r;
+ }
+ return {};
+}
+
} // namespace vulkan
} // namespace amber
diff --git a/src/vulkan/frame_buffer.h b/src/vulkan/frame_buffer.h
index d4c2b2f..f420ea6 100644
--- a/src/vulkan/frame_buffer.h
+++ b/src/vulkan/frame_buffer.h
@@ -16,7 +16,9 @@
#define SRC_VULKAN_FRAME_BUFFER_H_
#include <memory>
+#include <vector>
+#include "src/pipeline.h"
#include "src/vulkan/image.h"
namespace amber {
@@ -33,11 +35,14 @@ class Device;
class FrameBuffer {
public:
- FrameBuffer(Device* device, uint32_t width, uint32_t height);
+ FrameBuffer(
+ Device* device,
+ const std::vector<const amber::Pipeline::BufferInfo*>& color_attachments,
+ uint32_t width,
+ uint32_t height);
~FrameBuffer();
Result Initialize(VkRenderPass render_pass,
- VkFormat color_format,
VkFormat depth_format,
const VkPhysicalDeviceMemoryProperties& properties);
void Shutdown();
@@ -45,26 +50,27 @@ class FrameBuffer {
Result ChangeFrameImageLayout(CommandBuffer* command, FrameImageState layout);
VkFramebuffer GetFrameBuffer() const { return frame_; }
- const void* GetColorBufferPtr() const {
- return color_image_->HostAccessibleMemoryPtr();
+ const void* GetColorBufferPtr(size_t idx) const {
+ return color_images_[idx]->HostAccessibleMemoryPtr();
+ }
+
+ const Format& GetFormatForAttachment(size_t idx) const {
+ return color_attachments_[idx]->buffer->AsFormatBuffer()->GetFormat();
}
- VkImage GetColorImage() const { return color_image_->GetVkImage(); }
// Only record the command for copying the image that backs this
// framebuffer to the host accessible buffer. The actual submission
// of the command must be done later.
- Result CopyColorImageToHost(CommandBuffer* command) {
- ChangeFrameImageLayout(command, FrameImageState::kProbe);
- return color_image_->CopyToHost(command);
- }
+ Result CopyColorImagesToHost(CommandBuffer* command);
uint32_t GetWidth() const { return width_; }
uint32_t GetHeight() const { return height_; }
private:
Device* device_ = nullptr;
+ std::vector<const amber::Pipeline::BufferInfo*> color_attachments_;
VkFramebuffer frame_ = VK_NULL_HANDLE;
- std::unique_ptr<Image> color_image_;
+ std::vector<std::unique_ptr<Image>> color_images_;
std::unique_ptr<Image> depth_image_;
uint32_t width_ = 0;
uint32_t height_ = 0;
diff --git a/src/vulkan/graphics_pipeline.cc b/src/vulkan/graphics_pipeline.cc
index 2a68978..1a36f86 100644
--- a/src/vulkan/graphics_pipeline.cc
+++ b/src/vulkan/graphics_pipeline.cc
@@ -352,7 +352,7 @@ GraphicsPipeline::GraphicsPipeline(
Device* device,
const VkPhysicalDeviceProperties& properties,
const VkPhysicalDeviceMemoryProperties& memory_properties,
- VkFormat color_format,
+ const std::vector<amber::Pipeline::BufferInfo>& color_buffers,
VkFormat depth_stencil_format,
uint32_t fence_timeout_ms,
const std::vector<VkPipelineShaderStageCreateInfo>& shader_stage_info)
@@ -362,8 +362,10 @@ GraphicsPipeline::GraphicsPipeline(
memory_properties,
fence_timeout_ms,
shader_stage_info),
- color_format_(color_format),
- depth_stencil_format_(depth_stencil_format) {}
+ depth_stencil_format_(depth_stencil_format) {
+ for (const auto& info : color_buffers)
+ color_buffers_.push_back(&info);
+}
GraphicsPipeline::~GraphicsPipeline() = default;
@@ -373,22 +375,26 @@ Result GraphicsPipeline::CreateRenderPass() {
std::vector<VkAttachmentDescription> attachment_desc;
- VkAttachmentReference color_refer = VkAttachmentReference();
+ std::vector<VkAttachmentReference> color_refer;
VkAttachmentReference depth_refer = VkAttachmentReference();
- if (color_format_ != VK_FORMAT_UNDEFINED) {
+ for (const auto* info : color_buffers_) {
attachment_desc.push_back(kDefaultAttachmentDesc);
- attachment_desc.back().format = color_format_;
+ attachment_desc.back().format =
+ ToVkFormat(info->buffer->AsFormatBuffer()->GetFormat().GetFormatType());
attachment_desc.back().initialLayout =
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachment_desc.back().finalLayout =
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- color_refer.attachment = static_cast<uint32_t>(attachment_desc.size() - 1);
- color_refer.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ VkAttachmentReference ref = VkAttachmentReference();
+ ref.attachment = static_cast<uint32_t>(attachment_desc.size() - 1);
+ ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ color_refer.push_back(ref);
- subpass_desc.colorAttachmentCount = 1;
- subpass_desc.pColorAttachments = &color_refer;
+ subpass_desc.colorAttachmentCount =
+ static_cast<uint32_t>(color_refer.size());
+ subpass_desc.pColorAttachments = color_refer.data();
}
if (depth_stencil_format_ != VK_FORMAT_UNDEFINED) {
@@ -535,14 +541,11 @@ Result GraphicsPipeline::CreateVkGraphicsPipeline(
input_assembly_info.primitiveRestartEnable =
pipeline_data->GetEnablePrimitiveRestart();
- VkViewport viewport = {0,
- 0,
- static_cast<float>(frame_->GetWidth()),
- static_cast<float>(frame_->GetHeight()),
- 0,
- 1};
+ VkViewport viewport = {
+ 0, 0, static_cast<float>(frame_width_), static_cast<float>(frame_height_),
+ 0, 1};
- VkRect2D scissor = {{0, 0}, {frame_->GetWidth(), frame_->GetHeight()}};
+ VkRect2D scissor = {{0, 0}, {frame_width_, frame_height_}};
VkPipelineViewportStateCreateInfo viewport_info =
VkPipelineViewportStateCreateInfo();
@@ -620,17 +623,16 @@ Result GraphicsPipeline::CreateVkGraphicsPipeline(
VkPipelineColorBlendStateCreateInfo colorblend_info =
VkPipelineColorBlendStateCreateInfo();
VkPipelineColorBlendAttachmentState colorblend_attachment;
- if (color_format_ != VK_FORMAT_UNDEFINED) {
- colorblend_attachment = GetPipelineColorBlendAttachmentState(pipeline_data);
-
- colorblend_info.sType =
- VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
- colorblend_info.logicOpEnable = pipeline_data->GetEnableLogicOp();
- colorblend_info.logicOp = ToVkLogicOp(pipeline_data->GetLogicOp());
- colorblend_info.attachmentCount = 1;
- colorblend_info.pAttachments = &colorblend_attachment;
- pipeline_info.pColorBlendState = &colorblend_info;
- }
+
+ colorblend_attachment = GetPipelineColorBlendAttachmentState(pipeline_data);
+
+ colorblend_info.sType =
+ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+ colorblend_info.logicOpEnable = pipeline_data->GetEnableLogicOp();
+ colorblend_info.logicOp = ToVkLogicOp(pipeline_data->GetLogicOp());
+ colorblend_info.attachmentCount = 1;
+ colorblend_info.pAttachments = &colorblend_attachment;
+ pipeline_info.pColorBlendState = &colorblend_info;
pipeline_info.layout = pipeline_layout;
pipeline_info.renderPass = render_pass_;
@@ -657,8 +659,8 @@ Result GraphicsPipeline::Initialize(uint32_t width,
if (!r.IsSuccess())
return r;
- frame_ = MakeUnique<FrameBuffer>(device_, width, height);
- r = frame_->Initialize(render_pass_, color_format_, depth_stencil_format_,
+ frame_ = MakeUnique<FrameBuffer>(device_, color_buffers_, width, height);
+ r = frame_->Initialize(render_pass_, depth_stencil_format_,
memory_properties_);
if (!r.IsSuccess())
return r;
@@ -742,11 +744,6 @@ void GraphicsPipeline::DeactivateRenderPassIfNeeded() {
}
Result GraphicsPipeline::SetClearColor(float r, float g, float b, float a) {
- if (color_format_ == VK_FORMAT_UNDEFINED) {
- return Result(
- "Vulkan::ClearColorCommand No Color Buffer for FrameBuffer Exists");
- }
-
clear_color_r_ = r;
clear_color_g_ = g;
clear_color_b_ = b;
@@ -777,29 +774,22 @@ Result GraphicsPipeline::SetClearDepth(float depth) {
}
Result GraphicsPipeline::Clear() {
- if (color_format_ == VK_FORMAT_UNDEFINED &&
- depth_stencil_format_ == VK_FORMAT_UNDEFINED) {
- return Result(
- "Vulkan::ClearColorCommand No Color nor DepthStencil Buffer for "
- "FrameBuffer Exists");
- }
+ VkClearValue colour_clear;
+ colour_clear.color = {
+ {clear_color_r_, clear_color_g_, clear_color_b_, clear_color_a_}};
- if (color_format_ != VK_FORMAT_UNDEFINED) {
- VkClearValue clear_value;
- clear_value.color = {
- {clear_color_r_, clear_color_g_, clear_color_b_, clear_color_a_}};
- Result r = ClearBuffer(clear_value, VK_IMAGE_ASPECT_COLOR_BIT);
- if (!r.IsSuccess())
- return r;
- }
+ Result r = ClearBuffer(colour_clear, VK_IMAGE_ASPECT_COLOR_BIT);
+ if (!r.IsSuccess())
+ return r;
if (depth_stencil_format_ == VK_FORMAT_UNDEFINED)
return {};
- VkClearValue clear_value;
- clear_value.depthStencil = {clear_depth_, clear_stencil_};
+ VkClearValue depth_clear;
+ depth_clear.depthStencil = {clear_depth_, clear_stencil_};
+
return ClearBuffer(
- clear_value, VkFormatHasStencilComponent(depth_stencil_format_)
+ depth_clear, VkFormatHasStencilComponent(depth_stencil_format_)
? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT
: VK_IMAGE_ASPECT_DEPTH_BIT);
}
@@ -829,7 +819,7 @@ Result GraphicsPipeline::ClearBuffer(const VkClearValue& clear_value,
DeactivateRenderPassIfNeeded();
- return frame_->CopyColorImageToHost(command_.get());
+ return frame_->CopyColorImagesToHost(command_.get());
}
Result GraphicsPipeline::Draw(const DrawArraysCommand* command,
@@ -923,7 +913,7 @@ Result GraphicsPipeline::Draw(const DrawArraysCommand* command,
DeactivateRenderPassIfNeeded();
- r = frame_->CopyColorImageToHost(command_.get());
+ r = frame_->CopyColorImagesToHost(command_.get());
if (!r.IsSuccess())
return r;
diff --git a/src/vulkan/graphics_pipeline.h b/src/vulkan/graphics_pipeline.h
index 89bdd79..baeb897 100644
--- a/src/vulkan/graphics_pipeline.h
+++ b/src/vulkan/graphics_pipeline.h
@@ -23,6 +23,7 @@
#include "amber/vulkan_header.h"
#include "src/buffer_data.h"
#include "src/format.h"
+#include "src/pipeline.h"
#include "src/vulkan/frame_buffer.h"
#include "src/vulkan/index_buffer.h"
#include "src/vulkan/pipeline.h"
@@ -38,13 +39,14 @@ class CommandPool;
class GraphicsPipeline : public Pipeline {
public:
- GraphicsPipeline(Device* device,
- const VkPhysicalDeviceProperties& properties,
- const VkPhysicalDeviceMemoryProperties& memory_properties,
- VkFormat color_format,
- VkFormat depth_stencil_format,
- uint32_t fence_timeout_ms,
- const std::vector<VkPipelineShaderStageCreateInfo>&);
+ GraphicsPipeline(
+ Device* device,
+ const VkPhysicalDeviceProperties& properties,
+ const VkPhysicalDeviceMemoryProperties& memory_properties,
+ const std::vector<amber::Pipeline::BufferInfo>& color_buffers,
+ VkFormat depth_stencil_format,
+ uint32_t fence_timeout_ms,
+ const std::vector<VkPipelineShaderStageCreateInfo>&);
~GraphicsPipeline() override;
Result Initialize(uint32_t width,
@@ -57,8 +59,6 @@ class GraphicsPipeline : public Pipeline {
Result Clear();
Result ClearBuffer(const VkClearValue& clear_value,
VkImageAspectFlags aspect);
- VkFormat GetColorFormat() const { return color_format_; }
- VkFormat GetDepthStencilFormat() const { return depth_stencil_format_; }
Result SetClearColor(float r, float g, float b, float a);
Result SetClearStencil(uint32_t stencil);
@@ -114,7 +114,9 @@ class GraphicsPipeline : public Pipeline {
RenderPassState render_pass_state_ = RenderPassState::kInactive;
std::unique_ptr<FrameBuffer> frame_;
- VkFormat color_format_;
+
+ // color buffers are owned by the amber::Pipeline.
+ std::vector<const amber::Pipeline::BufferInfo*> color_buffers_;
VkFormat depth_stencil_format_;
std::unique_ptr<IndexBuffer> index_buffer_;