/* * 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 #include 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(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(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