1 // Copyright 2018 The Amber Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef SRC_COMMAND_H_ 16 #define SRC_COMMAND_H_ 17 18 #include <cstdint> 19 #include <memory> 20 #include <string> 21 #include <utility> 22 #include <vector> 23 24 #include "amber/shader_info.h" 25 #include "amber/value.h" 26 #include "src/buffer.h" 27 #include "src/command_data.h" 28 #include "src/pipeline_data.h" 29 30 namespace amber { 31 32 class BufferCommand; 33 class ClearColorCommand; 34 class ClearCommand; 35 class ClearDepthCommand; 36 class ClearStencilCommand; 37 class CompareBufferCommand; 38 class ComputeCommand; 39 class CopyCommand; 40 class DrawArraysCommand; 41 class DrawRectCommand; 42 class EntryPointCommand; 43 class PatchParameterVerticesCommand; 44 class Pipeline; 45 class ProbeCommand; 46 class ProbeSSBOCommand; 47 class RepeatCommand; 48 49 /// Base class for all commands. 50 class Command { 51 public: 52 enum class Type : uint8_t { 53 kClear = 0, 54 kClearColor, 55 kClearDepth, 56 kClearStencil, 57 kCompute, 58 kCompareBuffer, 59 kCopy, 60 kDrawArrays, 61 kDrawRect, 62 kEntryPoint, 63 kPatchParameterVertices, 64 kPipelineProperties, 65 kProbe, 66 kProbeSSBO, 67 kBuffer, 68 kRepeat 69 }; 70 71 virtual ~Command(); 72 GetType()73 Command::Type GetType() const { return command_type_; } 74 IsDrawRect()75 bool IsDrawRect() const { return command_type_ == Type::kDrawRect; } IsDrawArrays()76 bool IsDrawArrays() const { return command_type_ == Type::kDrawArrays; } IsCompareBuffer()77 bool IsCompareBuffer() const { return command_type_ == Type::kCompareBuffer; } IsCompute()78 bool IsCompute() const { return command_type_ == Type::kCompute; } IsCopy()79 bool IsCopy() const { return command_type_ == Type::kCopy; } IsProbe()80 bool IsProbe() const { return command_type_ == Type::kProbe; } IsProbeSSBO()81 bool IsProbeSSBO() const { return command_type_ == Type::kProbeSSBO; } IsBuffer()82 bool IsBuffer() const { return command_type_ == Type::kBuffer; } IsClear()83 bool IsClear() const { return command_type_ == Type::kClear; } IsClearColor()84 bool IsClearColor() const { return command_type_ == Type::kClearColor; } IsClearDepth()85 bool IsClearDepth() const { return command_type_ == Type::kClearDepth; } IsClearStencil()86 bool IsClearStencil() const { return command_type_ == Type::kClearStencil; } IsPatchParameterVertices()87 bool IsPatchParameterVertices() const { 88 return command_type_ == Type::kPatchParameterVertices; 89 } IsEntryPoint()90 bool IsEntryPoint() const { return command_type_ == Type::kEntryPoint; } IsRepeat()91 bool IsRepeat() { return command_type_ == Type::kRepeat; } 92 93 ClearCommand* AsClear(); 94 ClearColorCommand* AsClearColor(); 95 ClearDepthCommand* AsClearDepth(); 96 ClearStencilCommand* AsClearStencil(); 97 CompareBufferCommand* AsCompareBuffer(); 98 ComputeCommand* AsCompute(); 99 CopyCommand* AsCopy(); 100 DrawArraysCommand* AsDrawArrays(); 101 DrawRectCommand* AsDrawRect(); 102 EntryPointCommand* AsEntryPoint(); 103 PatchParameterVerticesCommand* AsPatchParameterVertices(); 104 ProbeCommand* AsProbe(); 105 ProbeSSBOCommand* AsProbeSSBO(); 106 BufferCommand* AsBuffer(); 107 RepeatCommand* AsRepeat(); 108 109 virtual std::string ToString() const = 0; 110 111 /// Sets the input file line number this command is declared on. SetLine(size_t line)112 void SetLine(size_t line) { line_ = line; } 113 /// Returns the input file line this command was declared on. GetLine()114 size_t GetLine() const { return line_; } 115 116 protected: 117 explicit Command(Type type); 118 119 Type command_type_; 120 size_t line_ = 1; 121 }; 122 123 /// Base class for commands which contain a pipeline. 124 class PipelineCommand : public Command { 125 public: 126 ~PipelineCommand() override; 127 GetPipeline()128 Pipeline* GetPipeline() const { return pipeline_; } 129 130 protected: 131 explicit PipelineCommand(Type type, Pipeline* pipeline); 132 133 Pipeline* pipeline_ = nullptr; 134 }; 135 136 /// Command to draw a rectangle on screen. 137 class DrawRectCommand : public PipelineCommand { 138 public: 139 explicit DrawRectCommand(Pipeline* pipeline, PipelineData data); 140 ~DrawRectCommand() override; 141 GetPipelineData()142 const PipelineData* GetPipelineData() const { return &data_; } 143 EnableOrtho()144 void EnableOrtho() { is_ortho_ = true; } IsOrtho()145 bool IsOrtho() const { return is_ortho_; } 146 EnablePatch()147 void EnablePatch() { is_patch_ = true; } IsPatch()148 bool IsPatch() const { return is_patch_; } 149 SetX(float x)150 void SetX(float x) { x_ = x; } GetX()151 float GetX() const { return x_; } 152 SetY(float y)153 void SetY(float y) { y_ = y; } GetY()154 float GetY() const { return y_; } 155 SetWidth(float w)156 void SetWidth(float w) { width_ = w; } GetWidth()157 float GetWidth() const { return width_; } 158 SetHeight(float h)159 void SetHeight(float h) { height_ = h; } GetHeight()160 float GetHeight() const { return height_; } 161 ToString()162 std::string ToString() const override { return "DrawRectCommand"; } 163 164 private: 165 PipelineData data_; 166 bool is_ortho_ = false; 167 bool is_patch_ = false; 168 float x_ = 0.0; 169 float y_ = 0.0; 170 float width_ = 0.0; 171 float height_ = 0.0; 172 }; 173 174 /// Command to draw from a vertex and index buffer. 175 class DrawArraysCommand : public PipelineCommand { 176 public: 177 explicit DrawArraysCommand(Pipeline* pipeline, PipelineData data); 178 ~DrawArraysCommand() override; 179 GetPipelineData()180 const PipelineData* GetPipelineData() const { return &data_; } 181 EnableIndexed()182 void EnableIndexed() { is_indexed_ = true; } IsIndexed()183 bool IsIndexed() const { return is_indexed_; } 184 EnableInstanced()185 void EnableInstanced() { is_instanced_ = true; } IsInstanced()186 bool IsInstanced() const { return is_instanced_; } 187 SetTopology(Topology topo)188 void SetTopology(Topology topo) { topology_ = topo; } GetTopology()189 Topology GetTopology() const { return topology_; } 190 SetFirstVertexIndex(uint32_t idx)191 void SetFirstVertexIndex(uint32_t idx) { first_vertex_index_ = idx; } GetFirstVertexIndex()192 uint32_t GetFirstVertexIndex() const { return first_vertex_index_; } 193 SetVertexCount(uint32_t count)194 void SetVertexCount(uint32_t count) { vertex_count_ = count; } GetVertexCount()195 uint32_t GetVertexCount() const { return vertex_count_; } 196 SetInstanceCount(uint32_t count)197 void SetInstanceCount(uint32_t count) { instance_count_ = count; } GetInstanceCount()198 uint32_t GetInstanceCount() const { return instance_count_; } 199 ToString()200 std::string ToString() const override { return "DrawArraysCommand"; } 201 202 private: 203 PipelineData data_; 204 bool is_indexed_ = false; 205 bool is_instanced_ = false; 206 Topology topology_ = Topology::kUnknown; 207 uint32_t first_vertex_index_ = 0; 208 uint32_t vertex_count_ = 0; 209 uint32_t instance_count_ = 0; 210 }; 211 212 /// A command to compare two buffers. 213 class CompareBufferCommand : public Command { 214 public: 215 enum class Comparator { kEq, kRmse, kHistogramEmd }; 216 217 CompareBufferCommand(Buffer* buffer_1, Buffer* buffer_2); 218 ~CompareBufferCommand() override; 219 GetBuffer1()220 Buffer* GetBuffer1() const { return buffer_1_; } GetBuffer2()221 Buffer* GetBuffer2() const { return buffer_2_; } 222 SetComparator(Comparator type)223 void SetComparator(Comparator type) { comparator_ = type; } GetComparator()224 Comparator GetComparator() const { return comparator_; } 225 SetTolerance(float tolerance)226 void SetTolerance(float tolerance) { tolerance_ = tolerance; } GetTolerance()227 float GetTolerance() const { return tolerance_; } 228 ToString()229 std::string ToString() const override { return "CompareBufferCommand"; } 230 231 private: 232 Buffer* buffer_1_; 233 Buffer* buffer_2_; 234 float tolerance_ = 0.0; 235 Comparator comparator_ = Comparator::kEq; 236 }; 237 238 /// Command to execute a compute command. 239 class ComputeCommand : public PipelineCommand { 240 public: 241 explicit ComputeCommand(Pipeline* pipeline); 242 ~ComputeCommand() override; 243 SetX(uint32_t x)244 void SetX(uint32_t x) { x_ = x; } GetX()245 uint32_t GetX() const { return x_; } 246 SetY(uint32_t y)247 void SetY(uint32_t y) { y_ = y; } GetY()248 uint32_t GetY() const { return y_; } 249 SetZ(uint32_t z)250 void SetZ(uint32_t z) { z_ = z; } GetZ()251 uint32_t GetZ() const { return z_; } 252 ToString()253 std::string ToString() const override { return "ComputeCommand"; } 254 255 private: 256 uint32_t x_ = 0; 257 uint32_t y_ = 0; 258 uint32_t z_ = 0; 259 }; 260 261 /// Command to copy data from one buffer to another. 262 class CopyCommand : public Command { 263 public: 264 CopyCommand(Buffer* buffer_from, Buffer* buffer_to); 265 ~CopyCommand() override; 266 GetBufferFrom()267 Buffer* GetBufferFrom() const { return buffer_from_; } GetBufferTo()268 Buffer* GetBufferTo() const { return buffer_to_; } 269 ToString()270 std::string ToString() const override { return "CopyCommand"; } 271 272 private: 273 Buffer* buffer_from_; 274 Buffer* buffer_to_; 275 }; 276 277 /// Base class for probe commands. 278 class Probe : public Command { 279 public: 280 /// Wrapper around tolerance information for the probe. 281 struct Tolerance { ToleranceTolerance282 Tolerance(bool percent, double val) : is_percent(percent), value(val) {} 283 284 bool is_percent = false; 285 double value = 0.0; 286 }; 287 288 ~Probe() override; 289 GetBuffer()290 Buffer* GetBuffer() const { return buffer_; } 291 HasTolerances()292 bool HasTolerances() const { return !tolerances_.empty(); } SetTolerances(const std::vector<Tolerance> & t)293 void SetTolerances(const std::vector<Tolerance>& t) { tolerances_ = t; } GetTolerances()294 const std::vector<Tolerance>& GetTolerances() const { return tolerances_; } 295 296 protected: 297 explicit Probe(Type type, Buffer* buffer); 298 299 private: 300 Buffer* buffer_; 301 std::vector<Tolerance> tolerances_; 302 }; 303 304 /// Command to probe an image buffer. 305 class ProbeCommand : public Probe { 306 public: 307 explicit ProbeCommand(Buffer* buffer); 308 ~ProbeCommand() override; 309 SetWholeWindow()310 void SetWholeWindow() { is_whole_window_ = true; } IsWholeWindow()311 bool IsWholeWindow() const { return is_whole_window_; } 312 SetProbeRect()313 void SetProbeRect() { is_probe_rect_ = true; } IsProbeRect()314 bool IsProbeRect() const { return is_probe_rect_; } 315 SetRelative()316 void SetRelative() { is_relative_ = true; } IsRelative()317 bool IsRelative() const { return is_relative_; } 318 SetIsRGBA()319 void SetIsRGBA() { color_format_ = ColorFormat::kRGBA; } IsRGBA()320 bool IsRGBA() const { return color_format_ == ColorFormat::kRGBA; } 321 SetX(float x)322 void SetX(float x) { x_ = x; } GetX()323 float GetX() const { return x_; } 324 SetY(float y)325 void SetY(float y) { y_ = y; } GetY()326 float GetY() const { return y_; } 327 SetWidth(float w)328 void SetWidth(float w) { width_ = w; } GetWidth()329 float GetWidth() const { return width_; } 330 SetHeight(float h)331 void SetHeight(float h) { height_ = h; } GetHeight()332 float GetHeight() const { return height_; } 333 334 // Colours are stored in the range 0.0 - 1.0 SetR(float r)335 void SetR(float r) { r_ = r; } GetR()336 float GetR() const { return r_; } 337 SetG(float g)338 void SetG(float g) { g_ = g; } GetG()339 float GetG() const { return g_; } 340 SetB(float b)341 void SetB(float b) { b_ = b; } GetB()342 float GetB() const { return b_; } 343 SetA(float a)344 void SetA(float a) { a_ = a; } GetA()345 float GetA() const { return a_; } 346 ToString()347 std::string ToString() const override { return "ProbeCommand"; } 348 349 private: 350 enum class ColorFormat { 351 kRGB = 0, 352 kRGBA, 353 }; 354 355 bool is_whole_window_ = false; 356 bool is_probe_rect_ = false; 357 bool is_relative_ = false; 358 ColorFormat color_format_ = ColorFormat::kRGB; 359 360 float x_ = 0.0; 361 float y_ = 0.0; 362 float width_ = 1.0; 363 float height_ = 1.0; 364 365 float r_ = 0.0; 366 float g_ = 0.0; 367 float b_ = 0.0; 368 float a_ = 0.0; 369 }; 370 371 /// Command to probe a data buffer. 372 class ProbeSSBOCommand : public Probe { 373 public: 374 enum class Comparator { 375 kEqual, 376 kNotEqual, 377 kFuzzyEqual, 378 kLess, 379 kLessOrEqual, 380 kGreater, 381 kGreaterOrEqual 382 }; 383 384 explicit ProbeSSBOCommand(Buffer* buffer); 385 ~ProbeSSBOCommand() override; 386 SetComparator(Comparator comp)387 void SetComparator(Comparator comp) { comparator_ = comp; } GetComparator()388 Comparator GetComparator() const { return comparator_; } 389 SetDescriptorSet(uint32_t id)390 void SetDescriptorSet(uint32_t id) { descriptor_set_id_ = id; } GetDescriptorSet()391 uint32_t GetDescriptorSet() const { return descriptor_set_id_; } 392 SetBinding(uint32_t id)393 void SetBinding(uint32_t id) { binding_num_ = id; } GetBinding()394 uint32_t GetBinding() const { return binding_num_; } 395 SetOffset(uint32_t offset)396 void SetOffset(uint32_t offset) { offset_ = offset; } GetOffset()397 uint32_t GetOffset() const { return offset_; } 398 SetFormat(Format * fmt)399 void SetFormat(Format* fmt) { format_ = fmt; } GetFormat()400 Format* GetFormat() const { return format_; } 401 SetValues(std::vector<Value> && values)402 void SetValues(std::vector<Value>&& values) { values_ = std::move(values); } GetValues()403 const std::vector<Value>& GetValues() const { return values_; } 404 ToString()405 std::string ToString() const override { return "ProbeSSBOCommand"; } 406 407 private: 408 Comparator comparator_ = Comparator::kEqual; 409 uint32_t descriptor_set_id_ = 0; 410 uint32_t binding_num_ = 0; 411 uint32_t offset_ = 0; 412 Format* format_; 413 std::vector<Value> values_; 414 }; 415 416 /// Command to set the size of a buffer, or update a buffers contents. 417 class BufferCommand : public PipelineCommand { 418 public: 419 enum class BufferType { 420 kSSBO, 421 kUniform, 422 kPushConstant, 423 }; 424 425 explicit BufferCommand(BufferType type, Pipeline* pipeline); 426 ~BufferCommand() override; 427 IsSSBO()428 bool IsSSBO() const { return buffer_type_ == BufferType::kSSBO; } IsUniform()429 bool IsUniform() const { return buffer_type_ == BufferType::kUniform; } IsPushConstant()430 bool IsPushConstant() const { 431 return buffer_type_ == BufferType::kPushConstant; 432 } 433 SetIsSubdata()434 void SetIsSubdata() { is_subdata_ = true; } IsSubdata()435 bool IsSubdata() const { return is_subdata_; } 436 SetDescriptorSet(uint32_t set)437 void SetDescriptorSet(uint32_t set) { descriptor_set_ = set; } GetDescriptorSet()438 uint32_t GetDescriptorSet() const { return descriptor_set_; } 439 SetBinding(uint32_t num)440 void SetBinding(uint32_t num) { binding_num_ = num; } GetBinding()441 uint32_t GetBinding() const { return binding_num_; } 442 SetOffset(uint32_t offset)443 void SetOffset(uint32_t offset) { offset_ = offset; } GetOffset()444 uint32_t GetOffset() const { return offset_; } 445 SetValues(std::vector<Value> && values)446 void SetValues(std::vector<Value>&& values) { values_ = std::move(values); } GetValues()447 const std::vector<Value>& GetValues() const { return values_; } 448 SetBuffer(Buffer * buffer)449 void SetBuffer(Buffer* buffer) { buffer_ = buffer; } GetBuffer()450 Buffer* GetBuffer() const { return buffer_; } 451 ToString()452 std::string ToString() const override { return "BufferCommand"; } 453 454 private: 455 Buffer* buffer_ = nullptr; 456 BufferType buffer_type_; 457 bool is_subdata_ = false; 458 uint32_t descriptor_set_ = 0; 459 uint32_t binding_num_ = 0; 460 uint32_t offset_ = 0; 461 std::vector<Value> values_; 462 }; 463 464 /// Command to clear the colour attachments. 465 class ClearCommand : public PipelineCommand { 466 public: 467 explicit ClearCommand(Pipeline* pipeline); 468 ~ClearCommand() override; 469 ToString()470 std::string ToString() const override { return "ClearCommand"; } 471 }; 472 473 /// Command to set the colour for the clear command. 474 class ClearColorCommand : public PipelineCommand { 475 public: 476 explicit ClearColorCommand(Pipeline* pipeline); 477 ~ClearColorCommand() override; 478 479 // Colours are stored in the range 0.0 - 1.0 SetR(float r)480 void SetR(float r) { r_ = r; } GetR()481 float GetR() const { return r_; } 482 SetG(float g)483 void SetG(float g) { g_ = g; } GetG()484 float GetG() const { return g_; } 485 SetB(float b)486 void SetB(float b) { b_ = b; } GetB()487 float GetB() const { return b_; } 488 SetA(float a)489 void SetA(float a) { a_ = a; } GetA()490 float GetA() const { return a_; } 491 ToString()492 std::string ToString() const override { return "ClearColorCommand"; } 493 494 private: 495 float r_ = 0.0; 496 float g_ = 0.0; 497 float b_ = 0.0; 498 float a_ = 0.0; 499 }; 500 501 /// Command to set the depth value for the clear command. 502 class ClearDepthCommand : public PipelineCommand { 503 public: 504 explicit ClearDepthCommand(Pipeline* pipeline); 505 ~ClearDepthCommand() override; 506 SetValue(float val)507 void SetValue(float val) { value_ = val; } GetValue()508 float GetValue() const { return value_; } 509 ToString()510 std::string ToString() const override { return "ClearDepthCommand"; } 511 512 private: 513 float value_ = 0.0; 514 }; 515 516 /// Command to set the stencil value for the clear command. 517 class ClearStencilCommand : public PipelineCommand { 518 public: 519 explicit ClearStencilCommand(Pipeline* pipeline); 520 ~ClearStencilCommand() override; 521 SetValue(uint32_t val)522 void SetValue(uint32_t val) { value_ = val; } GetValue()523 uint32_t GetValue() const { return value_; } 524 ToString()525 std::string ToString() const override { return "ClearStencilCommand"; } 526 527 private: 528 uint32_t value_ = 0; 529 }; 530 531 /// Command to set the patch parameter vertices. 532 class PatchParameterVerticesCommand : public PipelineCommand { 533 public: 534 explicit PatchParameterVerticesCommand(Pipeline* pipeline); 535 ~PatchParameterVerticesCommand() override; 536 SetControlPointCount(uint32_t count)537 void SetControlPointCount(uint32_t count) { control_point_count_ = count; } GetControlPointCount()538 uint32_t GetControlPointCount() const { return control_point_count_; } 539 ToString()540 std::string ToString() const override { 541 return "PatchParameterVerticesCommand"; 542 } 543 544 private: 545 uint32_t control_point_count_ = 0; 546 }; 547 548 /// Command to set the entry point to use for a given shader type. 549 class EntryPointCommand : public PipelineCommand { 550 public: 551 explicit EntryPointCommand(Pipeline* pipeline); 552 ~EntryPointCommand() override; 553 SetShaderType(ShaderType type)554 void SetShaderType(ShaderType type) { shader_type_ = type; } GetShaderType()555 ShaderType GetShaderType() const { return shader_type_; } 556 SetEntryPointName(const std::string & name)557 void SetEntryPointName(const std::string& name) { entry_point_name_ = name; } GetEntryPointName()558 std::string GetEntryPointName() const { return entry_point_name_; } 559 ToString()560 std::string ToString() const override { return "EntryPointCommand"; } 561 562 private: 563 ShaderType shader_type_ = kShaderTypeVertex; 564 std::string entry_point_name_; 565 }; 566 567 /// Command to repeat the given set of commands a number of times. 568 class RepeatCommand : public Command { 569 public: 570 explicit RepeatCommand(uint32_t count); 571 ~RepeatCommand() override; 572 GetCount()573 uint32_t GetCount() const { return count_; } 574 SetCommands(std::vector<std::unique_ptr<Command>> cmds)575 void SetCommands(std::vector<std::unique_ptr<Command>> cmds) { 576 commands_ = std::move(cmds); 577 } 578 GetCommands()579 const std::vector<std::unique_ptr<Command>>& GetCommands() const { 580 return commands_; 581 } 582 ToString()583 std::string ToString() const override { return "RepeatCommand"; } 584 585 private: 586 uint32_t count_ = 0; 587 std::vector<std::unique_ptr<Command>> commands_; 588 }; 589 590 } // namespace amber 591 592 #endif // SRC_COMMAND_H_ 593