diff options
48 files changed, 310 insertions, 278 deletions
@@ -302,7 +302,7 @@ EXTENSION_MAPPING = # case of backward compatibilities issues. # The default value is: YES. -MARKDOWN_SUPPORT = NO +MARKDOWN_SUPPORT = YES # When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up # to that level are automatically included in the table of contents, even if @@ -875,7 +875,7 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded diff --git a/docs/vulkan_resource_and_descriptor.md b/docs/vulkan_resource_and_descriptor.md deleted file mode 100644 index a8439da..0000000 --- a/docs/vulkan_resource_and_descriptor.md +++ /dev/null @@ -1,66 +0,0 @@ -# Classes for Vulkan resources and descriptors - * DRAFT - -Vulkan has many resource and descriptor types. -Since it is complicated to manage them e.g., -create/allocate/map/read/write/destory, we create several classes to -provide an abstraction. This document briefly explains those classes. - - -### Resource class -Represents a main resource i.e., VkBuffer or VkImage (See -[Resources in Vulkan spec]( -https://www.khronos.org/registry/vulkan/specs/1.1/html/vkspec.html#resources)) -in GPU device and an additional VkBuffer to allow read/write to the -main resource from CPU. - -If the main resource is accessible from CPU, the additional -VkBuffer is not needed and it will be `VK_NULL_HANDLE`. -Otherwise, the additional VkBuffer has the same size with the main -resource and we must copy the main resource to the VkBuffer or -copy the VkBuffer to the main resource when reading from/write to -the main resource. - -The Resource class has Buffer and Image sub-classes. - -#### Buffer class -Abstracts VkBuffer and creates/allocates/maps/destorys -VkBuffer and VkBufferView resources. - -#### Image class -Abstracts VkImage and creates/allocates/maps/destorys -VkImage and VkImageView resources. - - -### Sampler class - * TODO: Not implementated yet - * Represent [VkSampler]( - https://www.khronos.org/registry/vulkan/specs/1.1/html/vkspec.html#samplers) - - -### Descriptor class -Represents [Descriptor Types]( -https://www.khronos.org/registry/vulkan/specs/1.1/html/vkspec.html#descriptorsets-types). -There are 11 Descriptor Types and they need different resources. -For example, a Combined Image Sampler needs both Image and -Sampler objects while Storage Buffer needs only a Buffer object. - -* TODO: Describe 11 sub-classes of Descriptor for those Descriptor Types. - - -### FrameBuffer class -Abstracts [VkFrameBuffer]( -https://www.khronos.org/registry/vulkan/specs/1.1/html/vkspec.html#_framebuffers) -for attachments and an Image for the FrameBuffer. -The usage of the Image is `VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT`. - - -### VertexBuffer class -Manages vertices data and a Buffer whose usage is -`VK_BUFFER_USAGE_VERTEX_BUFFER_BIT`. - - -### IndexBuffer class - * TODO: Not implementated yet - * Manages indices data and a Buffer whose usage is - `VK_BUFFER_USAGE_INDEX_BUFFER_BIT`. diff --git a/include/amber/amber.h b/include/amber/amber.h index 694b40b..a8977e6 100644 --- a/include/amber/amber.h +++ b/include/amber/amber.h @@ -43,6 +43,7 @@ struct EngineConfig { virtual ~EngineConfig(); }; +/// Stores information for a biffer. struct BufferInfo { BufferInfo(); BufferInfo(const BufferInfo&); @@ -75,6 +76,7 @@ class Delegate { virtual uint64_t GetTimestampNs() const = 0; }; +/// Stores configuration options for Amber. struct Options { Options(); ~Options(); diff --git a/include/amber/shader_info.h b/include/amber/shader_info.h index 9dc5553..367c385 100644 --- a/include/amber/shader_info.h +++ b/include/amber/shader_info.h @@ -38,8 +38,11 @@ enum ShaderType { kShaderTypeMulti, }; +/// Stores information for a shader. struct ShaderInfo { + /// The format of the shader. ShaderFormat format; + /// The type of shader. ShaderType type; /// This is a unique name for this shader. The name is produced from the /// input script, possibly with extra prefix contents. This name, if used diff --git a/include/amber/value.h b/include/amber/value.h index 5bda540..633d1ab 100644 --- a/include/amber/value.h +++ b/include/amber/value.h @@ -19,6 +19,8 @@ namespace amber { +/// Wrapper for a single value. The value will be either an integer or a +/// floating point value. class Value { public: Value(); diff --git a/samples/config_helper.h b/samples/config_helper.h index 06c0c27..cc351d6 100644 --- a/samples/config_helper.h +++ b/samples/config_helper.h @@ -23,15 +23,15 @@ namespace sample { -// Proof of concept implementation showing how to provide and use -// EngineConfig within sample amber program. +/// Proof of concept implementation showing how to provide and use +/// EngineConfig within sample amber program. class ConfigHelperImpl { public: virtual ~ConfigHelperImpl(); - // Create instance and device and return them as amber::EngineConfig. - // |required_features| and |required_extensions| contain lists of - // required features and required extensions, respectively. + /// Create instance and device and return them as amber::EngineConfig. + /// |required_features| and |required_extensions| contain lists of + /// required features and required extensions, respectively. virtual amber::Result CreateConfig( uint32_t engine_major, uint32_t engine_minor, @@ -43,17 +43,17 @@ class ConfigHelperImpl { std::unique_ptr<amber::EngineConfig>* config) = 0; }; -// Wrapper of ConfigHelperImpl. +/// Wrapper of ConfigHelperImpl. class ConfigHelper { public: ConfigHelper(); ~ConfigHelper(); - // Create instance and device and return them as amber::EngineConfig. - // |required_features| and |required_extensions| contain lists of - // required features and required extensions, respectively. |engine| - // indicates whether the caller required VulkanEngineConfig or - // DawnEngineConfig. + /// Create instance and device and return them as amber::EngineConfig. + /// |required_features| and |required_extensions| contain lists of + /// required features and required extensions, respectively. |engine| + /// indicates whether the caller required VulkanEngineConfig or + /// DawnEngineConfig. amber::Result CreateConfig( amber::EngineType engine, uint32_t engine_major, diff --git a/samples/config_helper_dawn.cc b/samples/config_helper_dawn.cc index e733b88..c633f97 100644 --- a/samples/config_helper_dawn.cc +++ b/samples/config_helper_dawn.cc @@ -16,7 +16,6 @@ #include <iostream> -#include "samples/dawn_device_metal.h" namespace sample { ConfigHelperDawn::ConfigHelperDawn() = default; diff --git a/samples/config_helper_dawn.h b/samples/config_helper_dawn.h index 7b8b598..1f0fdff 100644 --- a/samples/config_helper_dawn.h +++ b/samples/config_helper_dawn.h @@ -24,19 +24,18 @@ #include "amber/amber_dawn.h" #include "dawn_native/DawnNative.h" #include "samples/config_helper.h" -#include "samples/dawn_device_metal.h" namespace sample { -// Child class of ConfigHelperImpl for Dawn. +/// Child class of ConfigHelperImpl for Dawn. class ConfigHelperDawn : public ConfigHelperImpl { public: ConfigHelperDawn(); ~ConfigHelperDawn() override; - // Create a Dawn instance and device and return them as - // amber::DawnEngineConfig. Engine version number and features - // and extension lists are ignored. + /// Create a Dawn instance and device and return them as + /// amber::DawnEngineConfig. Engine version number and features + /// and extension lists are ignored. amber::Result CreateConfig( uint32_t engine_major, uint32_t engine_minor, diff --git a/samples/config_helper_vulkan.h b/samples/config_helper_vulkan.h index b195972..d0d312d 100644 --- a/samples/config_helper_vulkan.h +++ b/samples/config_helper_vulkan.h @@ -31,16 +31,16 @@ namespace sample { -// Child class of ConfigHelperImpl for Vulkan. +/// Child class of ConfigHelperImpl for Vulkan. class ConfigHelperVulkan : public ConfigHelperImpl { public: ConfigHelperVulkan(); ~ConfigHelperVulkan() override; - // Create Vulkan instance and device and return them as - // amber::VulkanEngineConfig. Required Vulkan device features and - // extensions are given in |required_features| and - // |required_extensions|, respectively. + /// Create Vulkan instance and device and return them as + /// amber::VulkanEngineConfig. Required Vulkan device features and + /// extensions are given in |required_features| and + /// |required_extensions|, respectively. amber::Result CreateConfig( uint32_t engine_major, uint32_t engine_minor, @@ -52,42 +52,42 @@ class ConfigHelperVulkan : public ConfigHelperImpl { std::unique_ptr<amber::EngineConfig>* config) override; private: - // Create Vulkan instance. + /// Create Vulkan instance. amber::Result CreateVulkanInstance( uint32_t engine_major, uint32_t engine_minor, std::vector<std::string> required_instance_extensions, bool disable_validation_layer); - // Create |vulkan_callback_| that reports validation layer errors - // via debugCallback() function in config_helper_vulkan.cc. + /// Create |vulkan_callback_| that reports validation layer errors + /// via debugCallback() function in config_helper_vulkan.cc. amber::Result CreateDebugReportCallback(); - // Choose Vulkan physical device that supports both - // |required_features| and |required_extensions|. + /// Choose Vulkan physical device that supports both + /// |required_features| and |required_extensions|. amber::Result ChooseVulkanPhysicalDevice( const std::vector<std::string>& required_features, const std::vector<std::string>& required_extensions); - // Create Vulkan logical device that enables both - // |required_features| and |required_extensions|. + /// Create Vulkan logical device that enables both + /// |required_features| and |required_extensions|. amber::Result CreateVulkanDevice( const std::vector<std::string>& required_features, const std::vector<std::string>& required_extensions); - // Sets up the device creation to use VkPhysicalDeviceFeatures. + /// Sets up the device creation to use VkPhysicalDeviceFeatures. amber::Result CreateDeviceWithFeatures1( const std::vector<std::string>& required_features, VkDeviceCreateInfo* info); - // Sets up the device creation to use VkPhysicalDeviceFeatures2KHR. + /// Sets up the device creation to use VkPhysicalDeviceFeatures2KHR. amber::Result CreateDeviceWithFeatures2( const std::vector<std::string>& required_features, VkDeviceCreateInfo* info); - // Creates the physical device given the device |info|. + /// Creates the physical device given the device |info|. amber::Result DoCreateDevice(VkDeviceCreateInfo* info); - // Writes information related to the vulkan instance to stdout. + /// Writes information related to the vulkan instance to stdout. void DumpPhysicalDeviceInfo(); VkInstance vulkan_instance_ = VK_NULL_HANDLE; diff --git a/samples/dawn_device_metal.h b/samples/dawn_device_metal.h deleted file mode 100644 index ccdd186..0000000 --- a/samples/dawn_device_metal.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2018 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. - -#ifndef SAMPLES_DAWN_DEVICE_METAL_H_ -#define SAMPLES_DAWN_DEVICE_METAL_H_ - -#if AMBER_DAWN_METAL - -#include "amber/result.h" -#include "dawn/dawncpp.h" -#include "dawn_native/DawnNative.h" - -namespace sample { -namespace dawn { - -amber::Result CreateMetalDevice(::dawn_native::Instance*, ::dawn::Device*); - -} // namespace dawn -} // namespace sample - -#endif // AMBER_DAWN_METAL - -#endif // SAMPLES_DAWN_DEVICE_METAL_H_ diff --git a/samples/log.h b/samples/log.h index ff9b316..5b5f53b 100644 --- a/samples/log.h +++ b/samples/log.h @@ -19,7 +19,7 @@ namespace sample { -// This method is used for debug reports from Vulkan validation layers. +/// This method is used for debug reports from Vulkan validation layers. void LogError(const std::string& msg); } // namespace sample diff --git a/src/amberscript/parser.h b/src/amberscript/parser.h index 9f3af01..2034e11 100644 --- a/src/amberscript/parser.h +++ b/src/amberscript/parser.h @@ -30,6 +30,7 @@ class Tokenizer; namespace amberscript { +/// Parser for the `AmberScript` format. class Parser : public amber::Parser { public: Parser(); @@ -74,10 +75,10 @@ class Parser : public amber::Parser { Result ParsePipelineBody(const std::string& cmd_name, std::unique_ptr<Pipeline> pipeline); - // Parses a set of values out of the token stream. |name| is the name of the - // current command we're parsing for error purposes. The |type| is the type - // of data we expect for the current buffer. |values| will be appended to with - // the parsed values. + /// Parses a set of values out of the token stream. |name| is the name of the + /// current command we're parsing for error purposes. The |type| is the type + /// of data we expect for the current buffer. |values| will be appended to + /// with the parsed values. Result ParseValues(const std::string& name, Format* fmt, std::vector<Value>* values); diff --git a/src/buffer.h b/src/buffer.h index ca00c57..0309bd2 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -63,6 +63,7 @@ class Buffer { /// Returns the BufferType of this buffer. BufferType GetBufferType() const { return buffer_type_; } + /// Sets the BufferType for this buffer. void SetBufferType(BufferType type) { buffer_type_ = type; } /// Set the location binding value for the buffer. @@ -82,9 +83,13 @@ class Buffer { /// Returns the name of the buffer. std::string GetName() const { return name_; } + /// Gets the number of elements this buffer is wide. uint32_t GetWidth() const { return width_; } + /// Set the number of elements wide for the buffer. void SetWidth(uint32_t width) { width_ = width; } + /// Get the number of elements this buffer is high. uint32_t GetHeight() const { return height_; } + /// Set the number of elements high for the buffer. void SetHeight(uint32_t height) { height_ = height; } // | ---------- Element ---------- | ElementCount == 1 @@ -96,6 +101,7 @@ class Buffer { /// Sets the number of elements in the buffer. void SetElementCount(uint32_t count) { element_count_ = count; } + /// Returns the number of elements in the buffer. uint32_t ElementCount() const { return element_count_; } /// Sets the number of values in the buffer. @@ -109,6 +115,7 @@ class Buffer { else element_count_ = count / format_->ValuesPerElement(); } + /// Returns the number of values in the buffer. uint32_t ValueCount() const { if (!format_) return 0; @@ -125,20 +132,21 @@ class Buffer { return ElementCount() * format_->SizeInBytes(); } + /// Returns the number of bytes for one element in the buffer. 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. + /// Returns the number of bytes for one row of elements in the buffer. 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. + /// Sets the data into the buffer. Result SetData(const std::vector<Value>& data); + /// Returns a pointer to the internal storage of the buffer. std::vector<uint8_t>* ValuePtr() { return &bytes_; } + /// Returns a pointer to the internal storage of the buffer. const std::vector<uint8_t>* ValuePtr() const { return &bytes_; } + /// Returns a casted pointer to the internal storage of the buffer. template <typename T> const T* GetValues() const { return reinterpret_cast<const T*>(bytes_.data()); diff --git a/src/command.h b/src/command.h index d00b727..55e6efb 100644 --- a/src/command.h +++ b/src/command.h @@ -46,6 +46,7 @@ class ProbeCommand; class ProbeSSBOCommand; class RepeatCommand; +/// Base class for all commands. class Command { public: enum class Type : uint8_t { @@ -105,7 +106,9 @@ class Command { BufferCommand* AsBuffer(); RepeatCommand* AsRepeat(); + /// Sets the input file line number this command is declared on. void SetLine(size_t line) { line_ = line; } + /// Returns the input file line this command was declared on. size_t GetLine() const { return line_; } protected: @@ -115,6 +118,7 @@ class Command { size_t line_ = 1; }; +/// Base class for commands which contain a pipeline. class PipelineCommand : public Command { public: ~PipelineCommand() override; @@ -124,9 +128,10 @@ class PipelineCommand : public Command { protected: explicit PipelineCommand(Type type, Pipeline* pipeline); - Pipeline* pipeline_; + Pipeline* pipeline_ = nullptr; }; +/// Command to draw a rectangle on screen. class DrawRectCommand : public PipelineCommand { public: explicit DrawRectCommand(Pipeline* pipeline, PipelineData data); @@ -162,6 +167,7 @@ class DrawRectCommand : public PipelineCommand { float height_ = 0.0; }; +/// Command to draw from a vertex and index buffer. class DrawArraysCommand : public PipelineCommand { public: explicit DrawArraysCommand(Pipeline* pipeline, PipelineData data); @@ -197,6 +203,7 @@ class DrawArraysCommand : public PipelineCommand { uint32_t instance_count_ = 0; }; +/// A command to compare two buffers. class CompareBufferCommand : public Command { public: CompareBufferCommand(Buffer* buffer_1, Buffer* buffer_2); @@ -210,6 +217,7 @@ class CompareBufferCommand : public Command { Buffer* buffer_2_; }; +/// Command to execute a compute command. class ComputeCommand : public PipelineCommand { public: explicit ComputeCommand(Pipeline* pipeline); @@ -230,6 +238,7 @@ class ComputeCommand : public PipelineCommand { uint32_t z_ = 0; }; +/// Command to copy data from one buffer to another. class CopyCommand : public Command { public: CopyCommand(Buffer* buffer_from, Buffer* buffer_to); @@ -243,8 +252,10 @@ class CopyCommand : public Command { Buffer* buffer_to_; }; +/// Base class for probe commands. class Probe : public Command { public: + /// Wrapper around tolerance information for the probe. struct Tolerance { Tolerance(bool percent, double val) : is_percent(percent), value(val) {} @@ -268,6 +279,7 @@ class Probe : public Command { std::vector<Tolerance> tolerances_; }; +/// Command to probe an image buffer. class ProbeCommand : public Probe { public: explicit ProbeCommand(Buffer* buffer); @@ -332,6 +344,7 @@ class ProbeCommand : public Probe { float a_ = 0.0; }; +/// Command to probe a data buffer. class ProbeSSBOCommand : public Probe { public: enum class Comparator { @@ -374,6 +387,7 @@ class ProbeSSBOCommand : public Probe { std::vector<Value> values_; }; +/// Command to set the size of a buffer, or update a buffers contents. class BufferCommand : public PipelineCommand { public: enum class BufferType { @@ -428,12 +442,14 @@ class BufferCommand : public PipelineCommand { std::vector<Value> values_; }; +/// Command to clear the colour attachments. class ClearCommand : public PipelineCommand { public: explicit ClearCommand(Pipeline* pipeline); ~ClearCommand() override; }; +/// Command to set the colour for the clear command. class ClearColorCommand : public PipelineCommand { public: explicit ClearColorCommand(Pipeline* pipeline); @@ -459,6 +475,7 @@ class ClearColorCommand : public PipelineCommand { float a_ = 0.0; }; +/// Command to set the depth value for the clear command. class ClearDepthCommand : public PipelineCommand { public: explicit ClearDepthCommand(Pipeline* pipeline); @@ -471,6 +488,7 @@ class ClearDepthCommand : public PipelineCommand { float value_ = 0.0; }; +/// Command to set the stencil value for the clear command. class ClearStencilCommand : public PipelineCommand { public: explicit ClearStencilCommand(Pipeline* pipeline); @@ -483,6 +501,7 @@ class ClearStencilCommand : public PipelineCommand { uint32_t value_ = 0; }; +/// Command to set the patch parameter vertices. class PatchParameterVerticesCommand : public PipelineCommand { public: explicit PatchParameterVerticesCommand(Pipeline* pipeline); @@ -495,6 +514,7 @@ class PatchParameterVerticesCommand : public PipelineCommand { uint32_t control_point_count_ = 0; }; +/// Command to set the entry point to use for a given shader type. class EntryPointCommand : public PipelineCommand { public: explicit EntryPointCommand(Pipeline* pipeline); @@ -511,6 +531,7 @@ class EntryPointCommand : public PipelineCommand { std::string entry_point_name_; }; +/// Command to repeat the given set of commands a number of times. class RepeatCommand : public Command { public: explicit RepeatCommand(uint32_t count); @@ -518,12 +539,10 @@ class RepeatCommand : public Command { uint32_t GetCount() const { return count_; } - /// Sets |cmds| to the list of commands to execute against the engine. void SetCommands(std::vector<std::unique_ptr<Command>> cmds) { commands_ = std::move(cmds); } - /// Retrieves the list of commands to execute against the engine. const std::vector<std::unique_ptr<Command>>& GetCommands() const { return commands_; } diff --git a/src/datum_type.h b/src/datum_type.h index 5dd83b6..c182aed 100644 --- a/src/datum_type.h +++ b/src/datum_type.h @@ -36,6 +36,9 @@ enum class DataType { kDouble, }; +/// Stores information on a given type of data. This class should only be used +/// as a simple way to create format objects. DatumType should not appear as a +/// member of any classes. class DatumType { public: DatumType(); diff --git a/src/dawn/engine_dawn.h b/src/dawn/engine_dawn.h index 9c7c3c0..4c4ef2d 100644 --- a/src/dawn/engine_dawn.h +++ b/src/dawn/engine_dawn.h @@ -29,6 +29,7 @@ namespace amber { namespace dawn { +/// Engine implementation using the Dawn API. class EngineDawn : public Engine { public: EngineDawn(); diff --git a/src/dawn/pipeline_info.h b/src/dawn/pipeline_info.h index 2c8ffa2..d455d63 100644 --- a/src/dawn/pipeline_info.h +++ b/src/dawn/pipeline_info.h @@ -27,6 +27,7 @@ namespace amber { namespace dawn { +/// Stores information relating to a graphics pipeline in Dawn. struct RenderPipelineInfo { RenderPipelineInfo() {} RenderPipelineInfo(::amber::Pipeline* the_pipeline, @@ -42,28 +43,29 @@ struct RenderPipelineInfo { float clear_depth_value = 1.0f; uint32_t clear_stencil_value = 0; - // The framebuffer color render target. This resides on the GPU. + /// The framebuffer color render target. This resides on the GPU. ::dawn::Texture fb_texture; - // The depth and stencil target. This resides on the GPU. + /// The depth and stencil target. This resides on the GPU. ::dawn::Texture depth_stencil_texture; - // The buffer to which we will copy the rendered pixel values, for - // use on the host. + /// The buffer to which we will copy the rendered pixel values, for + /// use on the host. ::dawn::Buffer fb_buffer; - // The number of bytes between successive texels in framebuffer host-side - // buffer. + /// The number of bytes between successive texels in framebuffer host-side + /// buffer. uint32_t fb_texel_stride = 0; - // The number of bytes between successive rows of texels in framebuffer - // host-side buffer. + /// The number of bytes between successive rows of texels in framebuffer + /// host-side buffer. uint32_t fb_row_stride = 0; - // The number of rows in the framebuffer. + /// The number of rows in the framebuffer. uint32_t fb_num_rows = 0; - // The number of data bytes in the framebuffer host-side buffer. + /// The number of data bytes in the framebuffer host-side buffer. uint32_t fb_size = 0; // TODO(dneto): Record index data // TODO(dneto): Record buffer data }; +/// Stores information relating to a compute pipeline in Dawn. struct ComputePipelineInfo { ComputePipelineInfo() {} ComputePipelineInfo(::amber::Pipeline* the_pipeline, @@ -74,7 +76,7 @@ struct ComputePipelineInfo { ::dawn::ShaderModule compute_shader; }; -// Holds either a render or compute pipeline. +/// Holds either a render or compute pipeline. struct Pipeline { std::unique_ptr<RenderPipelineInfo> render_pipeline; std::unique_ptr<ComputePipelineInfo> compute_pipeline; diff --git a/src/engine.h b/src/engine.h index 219ca92..4eecb0c 100644 --- a/src/engine.h +++ b/src/engine.h @@ -35,6 +35,22 @@ struct EngineData { }; /// Abstract class which describes a backing engine for Amber. +/// +/// The engine class has a defined lifecycle. +/// 1. The engine is created through Engine::Create. +/// 2. Engine::Initialize is called to provide the engine with the configured +/// graphics device. +/// 3. Engine::CreatePipeline is called for each pipeline. The pipelines are +/// fully specified at this point and include: +/// * All compiled shader binaries +/// * Vertex, Index, Storage, Uniform, Push Constant buffers +/// * Colour attachment, and depth/stencil attachment buffers. +/// * Extra engine data. +/// The buffers all may have default values to be loaded into the device. +/// 4. Engine::Do* is called for each command. +/// Note, it is assumed that the amber::Buffers are updated at the end of +/// each Do* command and can be used immediately for comparisons. +/// 5. Engine destructor is called. class Engine { public: /// Creates a new engine of the requested |type|. diff --git a/src/format.h b/src/format.h index b0f5316..bf2c55d 100644 --- a/src/format.h +++ b/src/format.h @@ -35,50 +35,69 @@ class Format { FormatMode mode; uint8_t num_bits; + /// Is this component represented by an 8 bit signed integer. (This includes + /// int, scaled, rgb and norm values). bool IsInt8() const { return (mode == FormatMode::kSInt || mode == FormatMode::kSNorm || mode == FormatMode::kSScaled || mode == FormatMode::kSRGB) && num_bits == 8; } + /// Is this component represented by a 16 bit signed integer. (This includes + /// int and norm values) bool IsInt16() const { return (mode == FormatMode::kSInt || mode == FormatMode::kSNorm) && num_bits == 16; } + /// Is this component represented by a 32 bit signed integer. bool IsInt32() const { return mode == FormatMode::kSInt && num_bits == 32; } + /// Is this component represented by a 64 bit signed integer. bool IsInt64() const { return mode == FormatMode::kSInt && num_bits == 64; } + /// Is this component represented by an 8 bit unsigned integer. (This + /// includes uint, unorm and uscaled values). bool IsUint8() const { return (mode == FormatMode::kUInt || mode == FormatMode::kUNorm || mode == FormatMode::kUScaled) && num_bits == 8; } + /// Is this component represented by a 16 bit unsigned integer. bool IsUint16() const { return mode == FormatMode::kUInt && num_bits == 16; } + /// Is this component represented by a 32 bit unsigned integer. bool IsUint32() const { return mode == FormatMode::kUInt && num_bits == 32; } + /// Is this component represented by a 64 bit unsigned integer. bool IsUint64() const { return mode == FormatMode::kUInt && num_bits == 64; } + /// Is this component represented by a 16 bit floating point value. bool IsFloat16() const { return mode == FormatMode::kSFloat && num_bits == 16; } + /// Is this component represented by a 32 bit floating point value bool IsFloat() const { return mode == FormatMode::kSFloat && num_bits == 32; } + /// Is this component represented by a 64 bit floating point value bool IsDouble() const { return mode == FormatMode::kSFloat && num_bits == 64; } }; + /// Creates a format of unknown type. Format(); Format(const Format&); ~Format(); Format& operator=(const Format&) = default; + /// Returns true if |b| describes the same format as this object. bool Equal(const Format* b) const; + /// Sets the type of the format. For image types this maps closely to the + /// list of Vulkan formats. For data types, this maybe Unknown if the data + /// type can not be represented by the image format (e.g. matrix types) void SetFormatType(FormatType type) { type_ = type; } FormatType GetFormatType() const { return type_; } @@ -97,7 +116,9 @@ class Format { } const std::vector<Component>& GetComponents() const { return components_; } + /// Returns the number of bytes this format requires. uint32_t SizeInBytes() const; + /// Returns the number of bytes per single row this format requires. uint32_t SizeInBytesPerRow() const; bool IsFormatKnown() const { return type_ != FormatType::kUnknown; } @@ -108,7 +129,7 @@ class Format { type_ == FormatType::kS8_UINT; } - /// Returns the number of unique numbers for each instance of this format. + /// Returns the number of values for each instance of this format. uint32_t ValuesPerElement() const { return RowCount() * column_count_; } uint32_t RowCount() const { @@ -117,15 +138,25 @@ class Format { uint32_t ColumnCount() const { return column_count_; } void SetColumnCount(uint32_t c) { column_count_ = c; } + /// Returns true if all components of this format are an 8 bit signed int. bool IsInt8() const { return AreAllComponents(FormatMode::kSInt, 8); } + /// Returns true if all components of this format are a 16 bit signed int. bool IsInt16() const { return AreAllComponents(FormatMode::kSInt, 16); } + /// Returns true if all components of this format are a 32 bit signed int. bool IsInt32() const { return AreAllComponents(FormatMode::kSInt, 32); } + /// Returns true if all components of this format are a 64 bit signed int. bool IsInt64() const { return AreAllComponents(FormatMode::kSInt, 64); } + /// Returns true if all components of this format are a 8 bit unsigned int. bool IsUint8() const { return AreAllComponents(FormatMode::kUInt, 8); } + /// Returns true if all components of this format are a 16 bit unsigned int. bool IsUint16() const { return AreAllComponents(FormatMode::kUInt, 16); } + /// Returns true if all components of this format are a 32 bit unsigned int. bool IsUint32() const { return AreAllComponents(FormatMode::kUInt, 32); } + /// Returns true if all components of this format are a 64 bit unsigned int. bool IsUint64() const { return AreAllComponents(FormatMode::kUInt, 64); } + /// Returns true if all components of this format are a 32 bit float. bool IsFloat() const { return AreAllComponents(FormatMode::kSFloat, 32); } + /// Returns true if all components of this format are a 64 bit float. bool IsDouble() const { return AreAllComponents(FormatMode::kSFloat, 64); } private: diff --git a/src/format_parser.h b/src/format_parser.h index e99d956..9457130 100644 --- a/src/format_parser.h +++ b/src/format_parser.h @@ -25,6 +25,7 @@ namespace amber { class Format; +/// Parses a Vulkan image string into a format object. class FormatParser { public: FormatParser(); diff --git a/src/pipeline.h b/src/pipeline.h index cb6ded3..b6fecee 100644 --- a/src/pipeline.h +++ b/src/pipeline.h @@ -28,8 +28,10 @@ namespace amber { enum class PipelineType { kCompute = 0, kGraphics }; +/// Stores all information related to a pipeline. class Pipeline { public: + /// Information on a shader attached to this pipeline. class ShaderInfo { public: ShaderInfo(Shader*, ShaderType type); @@ -65,6 +67,10 @@ class Pipeline { std::vector<uint32_t> data_; }; + /// Information on a buffer attached to the pipeline. + /// + /// The BufferInfo will have either (descriptor_set, binding) or location + /// attached. struct BufferInfo { BufferInfo() = default; explicit BufferInfo(Buffer* buf) : buffer(buf) {} @@ -85,6 +91,7 @@ class Pipeline { bool IsGraphics() const { return pipeline_type_ == PipelineType::kGraphics; } bool IsCompute() const { return pipeline_type_ == PipelineType::kCompute; } + PipelineType GetType() const { return pipeline_type_; } void SetName(const std::string& name) { name_ = name; } @@ -102,41 +109,66 @@ class Pipeline { } uint32_t GetFramebufferHeight() const { return fb_height_; } - Result AddShader(Shader*, ShaderType); + /// Adds |shader| of |type| to the pipeline. + Result AddShader(Shader* shader, ShaderType type); + /// Returns information on all bound shaders in this pipeline. std::vector<ShaderInfo>& GetShaders() { return shaders_; } + /// Returns information on all bound shaders in this pipeline. const std::vector<ShaderInfo>& GetShaders() const { return shaders_; } + /// Sets the |type| of |shader| in the pipeline. Result SetShaderType(const Shader* shader, ShaderType type); + /// Sets the entry point |name| for |shader| in this pipeline. Result SetShaderEntryPoint(const Shader* shader, const std::string& name); + /// Sets the optimizations (|opts|) for |shader| in this pipeline. Result SetShaderOptimizations(const Shader* shader, const std::vector<std::string>& opts); + /// Returns a list of all colour attachments in this pipeline. const std::vector<BufferInfo>& GetColorAttachments() const { return color_attachments_; } + /// Adds |buf| as a colour attachment at |location| in the pipeline. Result AddColorAttachment(Buffer* buf, uint32_t location); + /// Retrieves the location that |buf| is bound to in the pipeline. The + /// location will be written to |loc|. An error result will be return if + /// something goes wrong. Result GetLocationForColorAttachment(Buffer* buf, uint32_t* loc) const; + /// Sets |buf| as the depth buffer for this pipeline. Result SetDepthBuffer(Buffer* buf); + /// Returns information on the depth buffer bound to the pipeline. If no + /// depth buffer is bound the |BufferInfo::buffer| parameter will be nullptr. const BufferInfo& GetDepthBuffer() const { return depth_buffer_; } + /// Returns information on all vertex buffers bound to the pipeline. const std::vector<BufferInfo>& GetVertexBuffers() const { return vertex_buffers_; } + /// Adds |buf| as a vertex buffer at |location| in the pipeline. Result AddVertexBuffer(Buffer* buf, uint32_t location); + /// Binds |buf| as the index buffer for this pipeline. Result SetIndexBuffer(Buffer* buf); + /// Returns the index buffer bound to this pipeline or nullptr if no index + /// buffer bound. Buffer* GetIndexBuffer() const { return index_buffer_; } + /// Adds |buf| to the pipeline at the given |descriptor_set| and |binding|. void AddBuffer(Buffer* buf, uint32_t descriptor_set, uint32_t binding); + /// Returns information on all buffers in this pipeline. const std::vector<BufferInfo>& GetBuffers() const { return buffers_; } + /// Returns the buffer which is currently bound to this pipeline at + /// |descriptor_set| and |binding|. Buffer* GetBufferForBinding(uint32_t descriptor_set, uint32_t binding) const; - // Validates that the pipeline has been created correctly. + /// Validates that the pipeline has been created correctly. Result Validate() const; + /// Generates a default color attachment in B8G8R8A8_UNORM. std::unique_ptr<Buffer> GenerateDefaultColorAttachmentBuffer() const; + /// Generates a default depth attachment in D32_SFLOAT_S8_UINT format. std::unique_ptr<Buffer> GenerateDefaultDepthAttachmentBuffer() const; private: diff --git a/src/pipeline_data.h b/src/pipeline_data.h index 90a807a..a65690e 100644 --- a/src/pipeline_data.h +++ b/src/pipeline_data.h @@ -21,6 +21,7 @@ namespace amber { +/// Stores information used to configure a pipeline. class PipelineData { public: PipelineData(); diff --git a/src/shader.h b/src/shader.h index 3b1dee8..653924b 100644 --- a/src/shader.h +++ b/src/shader.h @@ -36,7 +36,9 @@ class Shader { void SetFormat(ShaderFormat fmt) { shader_format_ = fmt; } ShaderFormat GetFormat() const { return shader_format_; } + /// Sets the compiled shader to |data|. void SetData(const std::string& data) { data_ = data; } + /// Returns the compiled shader source. const std::string& GetData() const { return data_; } private: diff --git a/src/shader_compiler.h b/src/shader_compiler.h index 6b89a74..e60b02d 100644 --- a/src/shader_compiler.h +++ b/src/shader_compiler.h @@ -25,12 +25,17 @@ namespace amber { +/// Class to wrap the compilation of shaders. class ShaderCompiler { public: ShaderCompiler(); explicit ShaderCompiler(const std::string& env); ~ShaderCompiler(); + /// Returns a result code and a compilation of the given shader. + /// If the |shader| has a corresponding entry in the |shader_map|, then the + /// compilation result is copied from that entry. Otherwise a compiler is + /// invoked to produce the compilation result. std::pair<Result, std::vector<uint32_t>> Compile( const Shader* shader, const ShaderMap& shader_map) const; diff --git a/src/sleep.h b/src/sleep.h index f73189c..384cf6b 100644 --- a/src/sleep.h +++ b/src/sleep.h @@ -19,7 +19,7 @@ namespace amber { -// Pause execution for the given number of microseconds, or longer. +/// Pause execution for the given number of microseconds, or longer. void USleep(uint32_t microseconds); } // namespace amber diff --git a/src/tokenizer.h b/src/tokenizer.h index d878c1a..7349c68 100644 --- a/src/tokenizer.h +++ b/src/tokenizer.h @@ -32,6 +32,7 @@ enum class TokenType : uint8_t { kHex, }; +/// A token read from the input source. class Token { public: explicit Token(TokenType type); @@ -95,6 +96,7 @@ class Token { bool is_negative_ = false; }; +/// Splits the provided input into a stream of tokens. class Tokenizer { public: explicit Tokenizer(const std::string& data); diff --git a/src/vkscript/command_parser.h b/src/vkscript/command_parser.h index 769a106..15d7053 100644 --- a/src/vkscript/command_parser.h +++ b/src/vkscript/command_parser.h @@ -34,6 +34,8 @@ class Token; namespace vkscript { +/// Parses the contents of the [test] section of a VkScript file into individual +/// commands. class CommandParser { public: CommandParser(Script* script, diff --git a/src/vkscript/datum_type_parser.h b/src/vkscript/datum_type_parser.h index 16369b6..b85bfd9 100644 --- a/src/vkscript/datum_type_parser.h +++ b/src/vkscript/datum_type_parser.h @@ -23,6 +23,7 @@ namespace amber { namespace vkscript { +/// Parses a data description on the VkScript format into a DatumType object. class DatumTypeParser { public: DatumTypeParser(); diff --git a/src/vkscript/parser.h b/src/vkscript/parser.h index 70e30d1..d3498ca 100644 --- a/src/vkscript/parser.h +++ b/src/vkscript/parser.h @@ -28,6 +28,7 @@ namespace amber { namespace vkscript { +/// Parser for the `VkScript` data format. class Parser : public amber::Parser { public: Parser(); diff --git a/src/vkscript/section_parser.h b/src/vkscript/section_parser.h index 3d898c3..9a37cac 100644 --- a/src/vkscript/section_parser.h +++ b/src/vkscript/section_parser.h @@ -34,8 +34,11 @@ enum class NodeType : uint8_t { kTest, }; +/// Parses the VkScript into the general sections. This includes things like +/// the [test], [indices], [vertex data], etc. class SectionParser { public: + /// Structure describing a single section of the VkScript document. struct Section { NodeType section_type; ShaderType shader_type; // Only valid when section_type == kShader diff --git a/src/vulkan/buffer_descriptor.h b/src/vulkan/buffer_descriptor.h index d63e16f..1e938a6 100644 --- a/src/vulkan/buffer_descriptor.h +++ b/src/vulkan/buffer_descriptor.h @@ -39,8 +39,8 @@ enum class DescriptorType : uint8_t { kUniformBuffer, }; -// Among Vulkan descriptor types, this class handles Storage Buffers -// and Uniform Buffers. +/// Stores descriptor set and binding information for storage and uniform +/// buffers. class BufferDescriptor { public: BufferDescriptor(Buffer* buffer, diff --git a/src/vulkan/command_buffer.h b/src/vulkan/command_buffer.h index b096dc0..6bd0d68 100644 --- a/src/vulkan/command_buffer.h +++ b/src/vulkan/command_buffer.h @@ -21,8 +21,7 @@ namespace amber { namespace vulkan { -// Command buffer states based on "5.1. Command Buffer Lifecycle" of Vulkan -// spec +/// Command buffer states. enum class CommandBufferState : uint8_t { kInitial = 0, kRecording, @@ -35,6 +34,8 @@ class CommandBufferGuard; class CommandPool; class Device; +/// Wrapper around a Vulkan command buffer. This is designed to not be used +/// directly, but should always be used through the `CommandBufferGuard` class. class CommandBuffer { public: CommandBuffer(Device* device, CommandPool* pool); @@ -57,14 +58,30 @@ class CommandBuffer { VkFence fence_ = VK_NULL_HANDLE; }; +/// Wrapper around a `CommandBuffer`. +/// +/// Usage follows the pattern: +/// ``` +/// CommandBufferGuard guard(cb); +/// if (!guard.IsRecording()) +/// return guard.GetResult(); +/// ... +/// Result r = guard.Submit(timeout); +/// if (!r.IsSuccess()) +/// return r; +/// ``` class CommandBufferGuard { public: + /// Creates a command buffer guard and sets the command buffer to recording. explicit CommandBufferGuard(CommandBuffer* buffer); ~CommandBufferGuard(); + /// Returns true if the command buffer was successfully set to recording. bool IsRecording() const { return result_.IsSuccess(); } + /// Returns the result object if the command buffer recording failed. Result GetResult() { return result_; } + /// Submits and resets the internal command buffer. Result Submit(uint32_t timeout_ms); private: diff --git a/src/vulkan/command_pool.h b/src/vulkan/command_pool.h index be56f33..dfc8716 100644 --- a/src/vulkan/command_pool.h +++ b/src/vulkan/command_pool.h @@ -23,6 +23,8 @@ namespace vulkan { class Device; +/// Wrapper around a Vulkan command pool. The `Initialize` method must be called +/// before using the command pool. class CommandPool { public: explicit CommandPool(Device* device); diff --git a/src/vulkan/compute_pipeline.h b/src/vulkan/compute_pipeline.h index 4b33b62..750b004 100644 --- a/src/vulkan/compute_pipeline.h +++ b/src/vulkan/compute_pipeline.h @@ -24,6 +24,7 @@ namespace amber { namespace vulkan { +/// Pipepline to handle compute commands. class ComputePipeline : public Pipeline { public: ComputePipeline( diff --git a/src/vulkan/device.h b/src/vulkan/device.h index 28c9b81..700e6e8 100644 --- a/src/vulkan/device.h +++ b/src/vulkan/device.h @@ -33,6 +33,7 @@ struct VulkanPtrs { #include "vk-wrappers.h" // NOLINT(build/include) }; +/// Wrapper around a Vulkan Device object. class Device { public: Device(VkInstance instance, @@ -50,6 +51,8 @@ class Device { const VkPhysicalDeviceFeatures2KHR& available_features2, const std::vector<std::string>& available_extensions); + /// Returns true if |format| and the |buffer|s buffer type combination is + /// supported by the physical device. bool IsFormatSupportedByPhysicalDevice(const Format& format, Buffer* buffer); VkDevice GetVkDevice() const { return device_; } @@ -59,13 +62,19 @@ class Device { uint32_t GetQueueFamilyIndex() const { return queue_family_index_; } uint32_t GetMaxPushConstants() const; + /// Returns true if the given |descriptor_set| is within the bounds of + /// this device. bool IsDescriptorSetInBounds(uint32_t descriptor_set) const; + /// Returns true if the memory at |memory_type_index| has |flags| set. bool HasMemoryFlags(uint32_t memory_type_index, const VkMemoryPropertyFlags flags) const; + /// Returns true if the memory at |memory_type_index| is host accessible. bool IsMemoryHostAccessible(uint32_t memory_type_index) const; + /// Returns true if the memory at |memory_type_index| is host corherent. bool IsMemoryHostCoherent(uint32_t memory_type_index) const; + /// Returns the pointers to the Vulkan API methods. const VulkanPtrs* GetPtrs() const { return &ptrs_; } private: diff --git a/src/vulkan/engine_vulkan.h b/src/vulkan/engine_vulkan.h index 5ea1cfc..470ddd2 100644 --- a/src/vulkan/engine_vulkan.h +++ b/src/vulkan/engine_vulkan.h @@ -34,6 +34,7 @@ namespace amber { namespace vulkan { +/// Engine implementation based on Vulkan. class EngineVulkan : public Engine { public: EngineVulkan(); diff --git a/src/vulkan/frame_buffer.h b/src/vulkan/frame_buffer.h index c101bf5..d5abc55 100644 --- a/src/vulkan/frame_buffer.h +++ b/src/vulkan/frame_buffer.h @@ -27,6 +27,7 @@ namespace vulkan { class CommandBuffer; class Device; +/// Wrapper around a Vulkan FrameBuffer object. class FrameBuffer { public: FrameBuffer( diff --git a/src/vulkan/graphics_pipeline.h b/src/vulkan/graphics_pipeline.h index a57f645..2130e0f 100644 --- a/src/vulkan/graphics_pipeline.h +++ b/src/vulkan/graphics_pipeline.h @@ -36,6 +36,7 @@ namespace vulkan { class CommandPool; +/// Wrapper around a graphics pipeline. class GraphicsPipeline : public Pipeline { public: GraphicsPipeline( @@ -76,26 +77,15 @@ class GraphicsPipeline : public Pipeline { const VertexBuffer* vertex_buffer, const VkPipelineLayout& pipeline_layout, VkPipeline* pipeline); - Result CreateRenderPass(); - Result SendVertexBufferDataIfNeeded(VertexBuffer* vertex_buffer); - // TODO(jaebaek): Implement image/ssbo probe. - Result SubmitProbeCommand(); - Result VerifyPixels(const uint32_t x, - const uint32_t y, - const uint32_t width, - const uint32_t height, - const ProbeCommand* command); - VkPipelineDepthStencilStateCreateInfo GetVkPipelineDepthStencilInfo( const PipelineData* pipeline_data); VkPipelineColorBlendAttachmentState GetVkPipelineColorBlendAttachmentState( const PipelineData* pipeline_data); VkRenderPass render_pass_ = VK_NULL_HANDLE; - std::unique_ptr<FrameBuffer> frame_; // color buffers are owned by the amber::Pipeline. diff --git a/src/vulkan/index_buffer.h b/src/vulkan/index_buffer.h index 0c221d9..2d21330 100644 --- a/src/vulkan/index_buffer.h +++ b/src/vulkan/index_buffer.h @@ -31,21 +31,16 @@ namespace vulkan { class CommandBuffer; class Device; -// A class providing abstraction for index buffer. Only a single -// instance of this class must exist as a member of GraphicsPipeline -// class. It must be created once when -// GraphicsPipeline::SetIndexBuffer() is called. +/// Stores information to be uploaded to the index buffer of the device. class IndexBuffer { public: explicit IndexBuffer(Device* device); ~IndexBuffer(); - // Assuming that |buffer_| is nullptr and |values| is not empty, - // it creates |buffer_| whose size is |sizeof(uint32_t) * values.size()| - // and coverts |values| as uint32 values and copies them to |buffer_|. + /// Copy the data in this index buffer to the device. Result SendIndexData(CommandBuffer* command, Buffer* buffer); - // Bind |buffer_| as index buffer if it is not nullptr. + /// Bind the index buffer if needed. Result BindToCommandBuffer(CommandBuffer* command); private: diff --git a/src/vulkan/pipeline.h b/src/vulkan/pipeline.h index 73d83e2..957ff88 100644 --- a/src/vulkan/pipeline.h +++ b/src/vulkan/pipeline.h @@ -38,6 +38,7 @@ class ComputePipeline; class Device; class GraphicsPipeline; +/// Base class for a pipeline in Vulkan. class Pipeline { public: virtual ~Pipeline(); @@ -50,8 +51,8 @@ class Pipeline { Result AddDescriptor(const BufferCommand*); - // Read back the contents of resources of all descriptors to a - // buffer data object and put it into buffer data queue in host. + /// Reads back the contents of resources of all descriptors to a + /// buffer data object and put it into buffer data queue in host. Result ReadbackDescriptorsToHostDataQueue(); void SetEntryPointName(VkShaderStageFlagBits stage, @@ -69,7 +70,7 @@ class Pipeline { uint32_t fence_timeout_ms, const std::vector<VkPipelineShaderStageCreateInfo>& shader_stage_info); - // Initialize the pipeline. + /// Initializes the pipeline. Result Initialize(CommandPool* pool); void UpdateDescriptorSetsIfNeeded(); @@ -77,7 +78,7 @@ class Pipeline { Result SendDescriptorDataToDeviceIfNeeded(); void BindVkDescriptorSets(const VkPipelineLayout& pipeline_layout); - // Record a Vulkan command for push contant. + /// Records a Vulkan command for push contant. Result RecordPushConstant(const VkPipelineLayout& pipeline_layout); const std::vector<VkPipelineShaderStageCreateInfo>& GetVkShaderStageInfo() @@ -102,16 +103,13 @@ class Pipeline { std::vector<std::unique_ptr<BufferDescriptor>> buffer_descriptors; }; - // Create Vulkan descriptor related objects i.e., - // VkDescriptorSetLayout, VkDescriptorPool, VkDescriptorSet if - // |descriptor_related_objects_already_created_| is false. + /// Creates Vulkan descriptor related objects. Result CreateVkDescriptorRelatedObjectsIfNeeded(); - Result CreateDescriptorSetLayouts(); Result CreateDescriptorPools(); Result CreateDescriptorSets(); - // Add information of how and what to do with push constant. + /// Adds push constant information. Result AddPushConstant(const BufferCommand* command); PipelineType pipeline_type_; diff --git a/src/vulkan/push_constant.h b/src/vulkan/push_constant.h index 0c03f11..c3f8db9 100644 --- a/src/vulkan/push_constant.h +++ b/src/vulkan/push_constant.h @@ -29,47 +29,31 @@ namespace vulkan { class CommandBuffer; class Device; -// Class to handle push constant. +/// Class to handle push constants. class PushConstant { public: - // |max_push_constant_size| must be the same value with - // maxPushConstantsSize of VkPhysicalDeviceLimits, which is an - // element of VkPhysicalDeviceProperties getting from - // vkGetPhysicalDeviceProperties(). explicit PushConstant(Device* device); ~PushConstant(); - // Return a VkPushConstantRange structure whose shader stage flag - // is VK_SHADER_STAGE_ALL, offset is minimum |offset| among elements - // in |push_constant_data_| rounded down by 4, and size is maximum - // |offset| + |size_in_bytes| among elements in |push_constant_data_| - // rounded up by 4. + /// Retrieves a `VkPushConstantRange` class describing our push constant + /// requirements. VkPushConstantRange GetVkPushConstantRange(); - // Call vkCmdPushConstants() to record a command for push constant - // if size in bytes of push constant is not larger than - // |max_push_constant_size_|. |command_buffer| is a Vulkan command - // buffer that keeps the recorded command and |pipeline_layout| is - // the graphics / compute pipeline that it currently uses. Result RecordPushConstantVkCommand(CommandBuffer* command, VkPipelineLayout pipeline_layout); - // Add a new set of values in an offset range to the push constants - // to be used on the next pipeline execution. + /// Adds data into the push constant buffer. Result AddBufferData(const BufferCommand* command); private: - // Fill memory from |offset| of |data| to |offset| + |size_in_bytes| - // of |data| with |values| of |data|. Result UpdateMemoryWithInput(const BufferInput& input); Device* device_; - // Keep the information of what and how to conduct push constant. - // These are applied from lowest index to highest index, so that - // if address ranges overlap, then the later values take effect. + /// Keeps the information of what and how to conduct push constant. + /// These are applied from lowest index to highest index, so that + /// if address ranges overlap, then the later values take effect. std::vector<BufferInput> push_constant_data_; - std::vector<uint8_t> memory_; }; diff --git a/src/vulkan/resource.cc b/src/vulkan/resource.cc index 99bd81a..f605f25 100644 --- a/src/vulkan/resource.cc +++ b/src/vulkan/resource.cc @@ -107,7 +107,7 @@ Result Resource::CreateVkBuffer(VkBuffer* buffer, VkBufferUsageFlags usage) { uint32_t Resource::ChooseMemory(uint32_t memory_type_bits, VkMemoryPropertyFlags flags, - bool force_flags) { + bool require_flags_found) { // Based on Vulkan spec about VkMemoryRequirements, N th bit of // |memory_type_bits| is 1 where N can be the proper memory type index. // This code is looking for the first non-zero bit whose memory type @@ -128,7 +128,7 @@ uint32_t Resource::ChooseMemory(uint32_t memory_type_bits, memory_type_bits >>= 1; } - if (force_flags) + if (require_flags_found) return std::numeric_limits<uint32_t>::max(); return first_non_zero; @@ -137,7 +137,7 @@ uint32_t Resource::ChooseMemory(uint32_t memory_type_bits, Result Resource::AllocateAndBindMemoryToVkBuffer(VkBuffer buffer, VkDeviceMemory* memory, VkMemoryPropertyFlags flags, - bool force_flags, + bool require_flags_found, uint32_t* memory_type_index) { if (memory_type_index == nullptr) { return Result( @@ -157,7 +157,7 @@ Result Resource::AllocateAndBindMemoryToVkBuffer(VkBuffer buffer, buffer, &requirement); *memory_type_index = - ChooseMemory(requirement.memoryTypeBits, flags, force_flags); + ChooseMemory(requirement.memoryTypeBits, flags, require_flags_found); if (*memory_type_index == std::numeric_limits<uint32_t>::max()) return Result("Vulkan::Find Proper Memory Fail"); @@ -202,7 +202,7 @@ void Resource::UnMapMemory(VkDeviceMemory memory) { device_->GetPtrs()->vkUnmapMemory(device_->GetVkDevice(), memory); } -void Resource::MemoryBarrier(CommandBuffer* command) { +void Resource::MemoryBarrier(CommandBuffer* command_buffer) { // TODO(jaebaek): Current memory barrier is natively implemented. // Update it with the following access flags: // (r = read, w = write) @@ -224,7 +224,7 @@ void Resource::MemoryBarrier(CommandBuffer* command) { // ReadOnly Descriptors host w shader r // transfer w transfer r device_->GetPtrs()->vkCmdPipelineBarrier( - command->GetVkCommandBuffer(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + command_buffer->GetVkCommandBuffer(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 1, &kMemoryBarrierForAll, 0, nullptr, 0, nullptr); } diff --git a/src/vulkan/resource.h b/src/vulkan/resource.h index 27aaec4..91e193f 100644 --- a/src/vulkan/resource.h +++ b/src/vulkan/resource.h @@ -31,26 +31,31 @@ namespace vulkan { class CommandBuffer; class Device; -// Contain information of filling memory -// [|offset|, |offset| + |size_in_bytes|) with |values| whose data -// type is |type|. This information is given by script. +/// Contains information for data to be added to a buffer. struct BufferInput { void UpdateBufferWithValues(void* buffer) const; + /// Offset into the buffer to write the data. uint32_t offset; + /// Number of bytes this data consumes. uint32_t size_in_bytes; + /// The format of the data. Format* format; + /// The actual data values. std::vector<Value> values; }; -// Class for Vulkan resources. Its children are Vulkan Buffer, Vulkan Image, -// and a class for push constant. +/// Class for Vulkan resources. class Resource { public: virtual ~Resource(); - virtual void CopyToHost(CommandBuffer* command) = 0; - virtual void CopyToDevice(CommandBuffer* command) = 0; + /// Records a command on |command_buffer| to copy the buffer contents from the + /// host to the device. + virtual void CopyToDevice(CommandBuffer* command_buffer) = 0; + /// Records a command on |command_buffer| to copy the buffer contents from the + /// device to the host. + virtual void CopyToHost(CommandBuffer* command_buffer) = 0; void* HostAccessibleMemoryPtr() const { return memory_ptr_; } @@ -68,19 +73,21 @@ class Resource { Result MapMemory(VkDeviceMemory memory); void UnMapMemory(VkDeviceMemory memory); - - // Set |memory_ptr_| as |ptr|. This must be used for only push constant. - // For Vulkan buffer and image i.e., Buffer and Image classes, we should - // not call this but uses MapMemory() method. void SetMemoryPtr(void* ptr) { memory_ptr_ = ptr; } - // Make all memory operations before calling this method effective i.e., - // prevent hazards caused by out-of-order execution. - void MemoryBarrier(CommandBuffer* command); + /// Records a memory barrier on |command_buffer|, to ensure prior writes to + /// this buffer have completed and are available to subsequent commands. + void MemoryBarrier(CommandBuffer* command_buffer); + /// Returns a memory index for the given Vulkan device, for a memory type + /// which has the given |flags| set. If no memory is found with the given + /// |flags| set then the first non-zero memory index is returned. If + /// |require_flags_found| is true then if no memory is found with the given + /// |flags| then the maximum uint32_t value is returned instead of the + /// first non-zero memory index. uint32_t ChooseMemory(uint32_t memory_type_bits, VkMemoryPropertyFlags flags, - bool force_flags); + bool require_flags_found); Result AllocateMemory(VkDeviceMemory* memory, VkDeviceSize size, uint32_t memory_type_index); diff --git a/src/vulkan/transfer_buffer.cc b/src/vulkan/transfer_buffer.cc index 9b62545..92f388f 100644 --- a/src/vulkan/transfer_buffer.cc +++ b/src/vulkan/transfer_buffer.cc @@ -59,16 +59,16 @@ Result TransferBuffer::Initialize(const VkBufferUsageFlags usage) { return MapMemory(memory_); } -void TransferBuffer::CopyToDevice(CommandBuffer* command) { +void TransferBuffer::CopyToDevice(CommandBuffer* command_buffer) { // This is redundant because this buffer is always host visible // and coherent and vkQueueSubmit will make writes from host // available (See chapter 6.9. "Host Write Ordering Guarantees" in // Vulkan spec), but we prefer to keep it to simplify our own code. - MemoryBarrier(command); + MemoryBarrier(command_buffer); } -void TransferBuffer::CopyToHost(CommandBuffer* command) { - MemoryBarrier(command); +void TransferBuffer::CopyToHost(CommandBuffer* command_buffer) { + MemoryBarrier(command_buffer); } void TransferBuffer::UpdateMemoryWithRawData( diff --git a/src/vulkan/transfer_buffer.h b/src/vulkan/transfer_buffer.h index 6085563..764c364 100644 --- a/src/vulkan/transfer_buffer.h +++ b/src/vulkan/transfer_buffer.h @@ -27,34 +27,23 @@ namespace vulkan { class CommandBuffer; class Device; -// Class managing Vulkan Buffer i.e., VkBuffer |buffer_|. |memory_| -// has VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and -// VK_MEMORY_PROPERTY_HOST_COHERENT_BIT properties and it is mapped -// to |buffer_|. +/// Wrapper around a Vulkan VkBuffer object. class TransferBuffer : public Resource { public: TransferBuffer(Device* device, uint32_t size_in_bytes); ~TransferBuffer() override; - // Create |buffer_| whose usage is |usage| and allocate |memory_| - // with VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and - // VK_MEMORY_PROPERTY_HOST_COHERENT_BIT properties. It also maps - // |memory_| to |buffer_| Result Initialize(const VkBufferUsageFlags usage); VkBuffer GetVkBuffer() const { return buffer_; } - // Since |buffer_| is mapped to host accessible and host coherent - // memory |memory_|, this method only conducts memory barrier to - // make it available to device domain. - void CopyToDevice(CommandBuffer* command) override; + /// Records a command on |command_buffer| to copy the buffer contents from the + /// host to the device. + void CopyToDevice(CommandBuffer* command_buffer) override; + /// Records a command on |command_buffer| to copy the buffer contents from the + /// device to the host. + void CopyToHost(CommandBuffer* command_buffer) override; - // Since |buffer_| is mapped to host accessible and host coherent - // memory |memory_|, this method only conducts memory barrier to - // make it available to host domain. - void CopyToHost(CommandBuffer* command) override; - - // Fill memory from 0 to |raw_data.size()| with |raw_data|. void UpdateMemoryWithRawData(const std::vector<uint8_t>& raw_data); private: diff --git a/src/vulkan/transfer_image.cc b/src/vulkan/transfer_image.cc index 46a9a6f..dbbb21b 100644 --- a/src/vulkan/transfer_image.cc +++ b/src/vulkan/transfer_image.cc @@ -173,28 +173,28 @@ VkBufferImageCopy TransferImage::CreateBufferImageCopy() { return copy_region; } -void TransferImage::CopyToHost(CommandBuffer* command) { +void TransferImage::CopyToHost(CommandBuffer* command_buffer) { auto copy_region = CreateBufferImageCopy(); device_->GetPtrs()->vkCmdCopyImageToBuffer( - command->GetVkCommandBuffer(), image_, + command_buffer->GetVkCommandBuffer(), image_, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, host_accessible_buffer_, 1, ©_region); - MemoryBarrier(command); + MemoryBarrier(command_buffer); } -void TransferImage::CopyToDevice(CommandBuffer* command) { +void TransferImage::CopyToDevice(CommandBuffer* command_buffer) { auto copy_region = CreateBufferImageCopy(); device_->GetPtrs()->vkCmdCopyBufferToImage( - command->GetVkCommandBuffer(), host_accessible_buffer_, image_, + command_buffer->GetVkCommandBuffer(), host_accessible_buffer_, image_, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region); - MemoryBarrier(command); + MemoryBarrier(command_buffer); } -void TransferImage::ImageBarrier(CommandBuffer* command, +void TransferImage::ImageBarrier(CommandBuffer* command_buffer, VkImageLayout to_layout, VkPipelineStageFlags to_stage) { if (to_layout == layout_ && to_stage == stage_) @@ -260,7 +260,7 @@ void TransferImage::ImageBarrier(CommandBuffer* command, break; } - device_->GetPtrs()->vkCmdPipelineBarrier(command->GetVkCommandBuffer(), + device_->GetPtrs()->vkCmdPipelineBarrier(command_buffer->GetVkCommandBuffer(), stage_, to_stage, 0, 0, NULL, 0, NULL, 1, &barrier); diff --git a/src/vulkan/transfer_image.h b/src/vulkan/transfer_image.h index 88ad3ce..bac7610 100644 --- a/src/vulkan/transfer_image.h +++ b/src/vulkan/transfer_image.h @@ -26,6 +26,7 @@ namespace vulkan { class CommandBuffer; class Device; +/// Wrapper around a Vulkan VkImage. class TransferImage : public Resource { public: TransferImage(Device* device, @@ -39,15 +40,16 @@ class TransferImage : public Resource { Result Initialize(VkImageUsageFlags usage); VkImageView GetVkImageView() const { return view_; } - void ImageBarrier(CommandBuffer* command, + void ImageBarrier(CommandBuffer* command_buffer, VkImageLayout to_layout, VkPipelineStageFlags to_stage); - // Only record the command for copying this image to its secondary - // host-accessible buffer. The actual submission of the command - // must be done later. - void CopyToHost(CommandBuffer* command) override; - void CopyToDevice(CommandBuffer* command) override; + /// Records a command on |command_buffer| to copy the buffer contents from the + /// host to the device. + void CopyToDevice(CommandBuffer* command_buffer) override; + /// Records a command on |command_buffer| to copy the buffer contents from the + /// device to the host. + void CopyToHost(CommandBuffer* command_buffer) override; private: Result CreateVkImageView(); @@ -58,6 +60,8 @@ class TransferImage : public Resource { uint32_t* memory_type_index); VkBufferImageCopy CreateBufferImageCopy(); + /// An extra `VkBuffer` is used to facilitate the transfer of data from the + /// host into the `VkImage` on the device. VkBuffer host_accessible_buffer_ = VK_NULL_HANDLE; VkDeviceMemory host_accessible_memory_ = VK_NULL_HANDLE; diff --git a/src/vulkan/vertex_buffer.h b/src/vulkan/vertex_buffer.h index e6de977..e7b216e 100644 --- a/src/vulkan/vertex_buffer.h +++ b/src/vulkan/vertex_buffer.h @@ -31,6 +31,7 @@ namespace vulkan { class CommandBuffer; class Device; +/// Wrapper around vertex data information. class VertexBuffer { public: explicit VertexBuffer(Device* device); @@ -63,13 +64,11 @@ class VertexBuffer { void BindToCommandBuffer(CommandBuffer* command); - // Must be used only for unit tests. void SetBufferForTest(std::unique_ptr<TransferBuffer> buffer); private: Result FillVertexBufferWithData(CommandBuffer* command); - // Return |stride_in_bytes_| rounded up by 4. uint32_t Get4BytesAlignedStride() const { return ((stride_in_bytes_ + 3) / 4) * 4; } @@ -82,7 +81,6 @@ class VertexBuffer { uint32_t stride_in_bytes_ = 0; std::vector<Buffer*> data_; - std::vector<VkVertexInputAttributeDescription> vertex_attr_desc_; }; |