// // Copyright 2019 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // VertexArrayMtl.h: // Defines the class interface for VertexArrayMtl, implementing VertexArrayImpl. // #ifndef LIBANGLE_RENDERER_METAL_VERTEXARRAYMTL_H_ #define LIBANGLE_RENDERER_METAL_VERTEXARRAYMTL_H_ #include "libANGLE/renderer/VertexArrayImpl.h" #include "libANGLE/renderer/metal/BufferMtl.h" #include "libANGLE/renderer/metal/mtl_buffer_pool.h" #include "libANGLE/renderer/metal/mtl_command_buffer.h" #include "libANGLE/renderer/metal/mtl_context_device.h" #include "libANGLE/renderer/metal/mtl_format_utils.h" #include "libANGLE/renderer/metal/mtl_resources.h" namespace rx { class ContextMtl; class VertexArrayMtl : public VertexArrayImpl { public: VertexArrayMtl(const gl::VertexArrayState &state, ContextMtl *context); ~VertexArrayMtl() override; void destroy(const gl::Context *context) override; angle::Result syncState(const gl::Context *context, const gl::VertexArray::DirtyBits &dirtyBits, gl::VertexArray::DirtyAttribBitsArray *attribBits, gl::VertexArray::DirtyBindingBitsArray *bindingBits) override; // Feed client side's vertex/index data angle::Result updateClientAttribs(const gl::Context *context, GLint firstVertex, GLsizei vertexOrIndexCount, GLsizei instanceCount, gl::DrawElementsType indexTypeOrInvalid, const void *indices); // vertexDescChanged is both input and output, the input value if is true, will force new // mtl::VertexDesc to be returned via vertexDescOut. This typically happens when active shader // program is changed. // Otherwise, it is only returned when the vertex array is dirty. angle::Result setupDraw(const gl::Context *glContext, mtl::RenderCommandEncoder *cmdEncoder, bool *vertexDescChanged, mtl::VertexDesc *vertexDescOut); angle::Result getIndexBuffer(const gl::Context *glContext, gl::DrawElementsType indexType, size_t indexCount, const void *sourcePointer, mtl::BufferRef *idxBufferOut, size_t *idxBufferOffsetOut, gl::DrawElementsType *indexTypeOut); std::vector getDrawIndices(const gl::Context *glContext, gl::DrawElementsType originalIndexType, gl::DrawElementsType indexType, gl::PrimitiveMode primitiveMode, mtl::BufferRef idxBuffer, uint32_t indexCount, size_t offset); private: void reset(ContextMtl *context); angle::Result syncDirtyAttrib(const gl::Context *glContext, const gl::VertexAttribute &attrib, const gl::VertexBinding &binding, size_t attribIndex); angle::Result convertIndexBuffer(const gl::Context *glContext, gl::DrawElementsType indexType, size_t offset, mtl::BufferRef *idxBufferOut, size_t *idxBufferOffsetOut); angle::Result streamIndexBufferFromClient(const gl::Context *glContext, gl::DrawElementsType indexType, size_t indexCount, const void *sourcePointer, mtl::BufferRef *idxBufferOut, size_t *idxBufferOffsetOut); angle::Result convertIndexBufferGPU(const gl::Context *glContext, gl::DrawElementsType indexType, BufferMtl *idxBuffer, size_t offset, size_t indexCount, IndexConversionBufferMtl *conversion); angle::Result convertVertexBuffer(const gl::Context *glContext, BufferMtl *srcBuffer, const gl::VertexBinding &binding, size_t attribIndex, const mtl::VertexFormat &vertexFormat); angle::Result convertVertexBufferCPU(ContextMtl *contextMtl, BufferMtl *srcBuffer, const gl::VertexBinding &binding, size_t attribIndex, const mtl::VertexFormat &convertedFormat, GLuint targetStride, size_t vertexCount, ConversionBufferMtl *conversion); angle::Result convertVertexBufferGPU(const gl::Context *glContext, BufferMtl *srcBuffer, const gl::VertexBinding &binding, size_t attribIndex, const mtl::VertexFormat &convertedFormat, GLuint targetStride, size_t vertexCount, bool isExpandingComponents, ConversionBufferMtl *conversion); // These can point to real BufferMtl or converted buffer in mConvertedArrayBufferHolders gl::AttribArray mCurrentArrayBuffers; gl::AttribArray mConvertedArrayBufferHolders; gl::AttribArray mCurrentArrayBufferOffsets; // Size to be uploaded as inline constant data. Used for client vertex attribute's data that // is small enough that we can send directly as inline constant data instead of streaming // through a buffer. gl::AttribArray mCurrentArrayInlineDataSizes; // Array of host buffers storing converted data for client attributes that are small enough. gl::AttribArray mConvertedClientSmallArrays; gl::AttribArray mCurrentArrayInlineDataPointers; // Max size of inline constant data that can be used for client vertex attribute. size_t mInlineDataMaxSize; // Stride per vertex attribute gl::AttribArray mCurrentArrayBufferStrides; // Format per vertex attribute gl::AttribArray mCurrentArrayBufferFormats; const mtl::VertexFormat &mDefaultFloatVertexFormat; mtl::BufferPool mDynamicVertexData; mtl::BufferPool mDynamicIndexData; std::vector mEmulatedInstanceAttribs; bool mVertexArrayDirty = true; bool mVertexDataDirty = true; }; } // namespace rx #endif /* LIBANGLE_RENDERER_METAL_VERTEXARRAYMTL_H_ */