|  | /* | 
|  | * Copyright 2021 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  | #ifndef GrDrawIndirectCommand_DEFINED | 
|  | #define GrDrawIndirectCommand_DEFINED | 
|  |  | 
|  | #include <stdint.h> | 
|  | #include <utility> | 
|  |  | 
|  | struct GrDrawIndirectCommand { | 
|  | uint32_t fVertexCount; | 
|  | uint32_t fInstanceCount; | 
|  | int32_t fBaseVertex; | 
|  | uint32_t fBaseInstance; | 
|  | }; | 
|  |  | 
|  | static_assert(sizeof(GrDrawIndirectCommand) == 16, "GrDrawIndirectCommand must be tightly packed"); | 
|  |  | 
|  | struct GrDrawIndexedIndirectCommand { | 
|  | uint32_t fIndexCount; | 
|  | uint32_t fInstanceCount; | 
|  | uint32_t fBaseIndex; | 
|  | int32_t fBaseVertex; | 
|  | uint32_t fBaseInstance; | 
|  | }; | 
|  |  | 
|  | static_assert(sizeof(GrDrawIndexedIndirectCommand) == 20, | 
|  | "GrDrawIndexedIndirectCommand must be tightly packed"); | 
|  |  | 
|  | // Helper for writing commands to an indirect draw buffer. Usage: | 
|  | // | 
|  | //    GrDrawIndirectWriter indirectWriter = target->makeDrawIndirectSpace(...); | 
|  | //    indirectWriter.write(...); | 
|  | //    indirectWriter.write(...); | 
|  | struct GrDrawIndirectWriter { | 
|  | public: | 
|  | GrDrawIndirectWriter() = default; | 
|  | GrDrawIndirectWriter(void* data) : fData(static_cast<GrDrawIndirectCommand*>(data)) {} | 
|  | GrDrawIndirectWriter(const GrDrawIndirectWriter&) = delete; | 
|  | GrDrawIndirectWriter(GrDrawIndirectWriter&& that) { *this = std::move(that); } | 
|  |  | 
|  | GrDrawIndirectWriter& operator=(const GrDrawIndirectWriter&) = delete; | 
|  | GrDrawIndirectWriter& operator=(GrDrawIndirectWriter&& that) { | 
|  | fData = that.fData; | 
|  | that.fData = nullptr; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | bool operator==(const GrDrawIndirectWriter& that) { return fData == that.fData; } | 
|  |  | 
|  | bool isValid() const { return fData != nullptr; } | 
|  |  | 
|  | GrDrawIndirectWriter makeOffset(int drawCount) const { return {fData + drawCount}; } | 
|  |  | 
|  | inline void write(uint32_t instanceCount, uint32_t baseInstance, uint32_t vertexCount, | 
|  | int32_t baseVertex) { | 
|  | *fData++ = {vertexCount, instanceCount, baseVertex, baseInstance}; | 
|  | } | 
|  |  | 
|  | private: | 
|  | GrDrawIndirectCommand* fData; | 
|  | }; | 
|  |  | 
|  | // Helper for writing commands to an indexed indirect draw buffer. Usage: | 
|  | // | 
|  | //    GrDrawIndexedIndirectWriter indirectWriter = target->makeDrawIndexedIndirectSpace(...); | 
|  | //    indirectWriter.writeIndexed(...); | 
|  | //    indirectWriter.writeIndexed(...); | 
|  | struct GrDrawIndexedIndirectWriter { | 
|  | public: | 
|  | GrDrawIndexedIndirectWriter() = default; | 
|  | GrDrawIndexedIndirectWriter(void* data) | 
|  | : fData(static_cast<GrDrawIndexedIndirectCommand*>(data)) {} | 
|  | GrDrawIndexedIndirectWriter(const GrDrawIndexedIndirectWriter&) = delete; | 
|  | GrDrawIndexedIndirectWriter(GrDrawIndexedIndirectWriter&& that) { *this = std::move(that); } | 
|  |  | 
|  | GrDrawIndexedIndirectWriter& operator=(const GrDrawIndexedIndirectWriter&) = delete; | 
|  | GrDrawIndexedIndirectWriter& operator=(GrDrawIndexedIndirectWriter&& that) { | 
|  | fData = that.fData; | 
|  | that.fData = nullptr; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | bool operator==(const GrDrawIndexedIndirectWriter& that) { return fData == that.fData; } | 
|  |  | 
|  | operator bool() const { return fData != nullptr; } | 
|  |  | 
|  | GrDrawIndexedIndirectWriter makeOffset(int drawCount) const { return {fData + drawCount}; } | 
|  |  | 
|  | inline void writeIndexed(uint32_t indexCount, uint32_t baseIndex, uint32_t instanceCount, | 
|  | uint32_t baseInstance, int32_t baseVertex) { | 
|  | *fData++ = {indexCount, instanceCount, baseIndex, baseVertex, baseInstance}; | 
|  | } | 
|  |  | 
|  | private: | 
|  | GrDrawIndexedIndirectCommand* fData; | 
|  | }; | 
|  |  | 
|  | #endif |