1 // 2 // Copyright 2019 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // VertexArrayMtl.h: 7 // Defines the class interface for VertexArrayMtl, implementing VertexArrayImpl. 8 // 9 10 #ifndef LIBANGLE_RENDERER_METAL_VERTEXARRAYMTL_H_ 11 #define LIBANGLE_RENDERER_METAL_VERTEXARRAYMTL_H_ 12 13 #include "libANGLE/renderer/VertexArrayImpl.h" 14 #include "libANGLE/renderer/metal/BufferMtl.h" 15 #include "libANGLE/renderer/metal/mtl_buffer_pool.h" 16 #include "libANGLE/renderer/metal/mtl_command_buffer.h" 17 #include "libANGLE/renderer/metal/mtl_context_device.h" 18 #include "libANGLE/renderer/metal/mtl_format_utils.h" 19 #include "libANGLE/renderer/metal/mtl_resources.h" 20 21 namespace rx 22 { 23 class ContextMtl; 24 25 class VertexArrayMtl : public VertexArrayImpl 26 { 27 public: 28 VertexArrayMtl(const gl::VertexArrayState &state, ContextMtl *context); 29 ~VertexArrayMtl() override; 30 31 void destroy(const gl::Context *context) override; 32 33 angle::Result syncState(const gl::Context *context, 34 const gl::VertexArray::DirtyBits &dirtyBits, 35 gl::VertexArray::DirtyAttribBitsArray *attribBits, 36 gl::VertexArray::DirtyBindingBitsArray *bindingBits) override; 37 38 // Feed client side's vertex/index data 39 angle::Result updateClientAttribs(const gl::Context *context, 40 GLint firstVertex, 41 GLsizei vertexOrIndexCount, 42 GLsizei instanceCount, 43 gl::DrawElementsType indexTypeOrInvalid, 44 const void *indices); 45 46 // vertexDescChanged is both input and output, the input value if is true, will force new 47 // mtl::VertexDesc to be returned via vertexDescOut. This typically happens when active shader 48 // program is changed. 49 // Otherwise, it is only returned when the vertex array is dirty. 50 angle::Result setupDraw(const gl::Context *glContext, 51 mtl::RenderCommandEncoder *cmdEncoder, 52 bool *vertexDescChanged, 53 mtl::VertexDesc *vertexDescOut); 54 55 angle::Result getIndexBuffer(const gl::Context *glContext, 56 gl::DrawElementsType indexType, 57 size_t indexCount, 58 const void *sourcePointer, 59 mtl::BufferRef *idxBufferOut, 60 size_t *idxBufferOffsetOut, 61 gl::DrawElementsType *indexTypeOut); 62 63 std::vector<DrawCommandRange> getDrawIndices(const gl::Context *glContext, 64 gl::DrawElementsType originalIndexType, 65 gl::DrawElementsType indexType, 66 gl::PrimitiveMode primitiveMode, 67 mtl::BufferRef idxBuffer, 68 uint32_t indexCount, 69 size_t offset); 70 71 private: 72 void reset(ContextMtl *context); 73 74 angle::Result syncDirtyAttrib(const gl::Context *glContext, 75 const gl::VertexAttribute &attrib, 76 const gl::VertexBinding &binding, 77 size_t attribIndex); 78 79 angle::Result convertIndexBuffer(const gl::Context *glContext, 80 gl::DrawElementsType indexType, 81 size_t offset, 82 mtl::BufferRef *idxBufferOut, 83 size_t *idxBufferOffsetOut); 84 angle::Result streamIndexBufferFromClient(const gl::Context *glContext, 85 gl::DrawElementsType indexType, 86 size_t indexCount, 87 const void *sourcePointer, 88 mtl::BufferRef *idxBufferOut, 89 size_t *idxBufferOffsetOut); 90 91 angle::Result convertIndexBufferGPU(const gl::Context *glContext, 92 gl::DrawElementsType indexType, 93 BufferMtl *idxBuffer, 94 size_t offset, 95 size_t indexCount, 96 IndexConversionBufferMtl *conversion); 97 98 angle::Result convertVertexBuffer(const gl::Context *glContext, 99 BufferMtl *srcBuffer, 100 const gl::VertexBinding &binding, 101 size_t attribIndex, 102 const mtl::VertexFormat &vertexFormat); 103 104 angle::Result convertVertexBufferCPU(ContextMtl *contextMtl, 105 BufferMtl *srcBuffer, 106 const gl::VertexBinding &binding, 107 size_t attribIndex, 108 const mtl::VertexFormat &convertedFormat, 109 GLuint targetStride, 110 size_t vertexCount, 111 ConversionBufferMtl *conversion); 112 angle::Result convertVertexBufferGPU(const gl::Context *glContext, 113 BufferMtl *srcBuffer, 114 const gl::VertexBinding &binding, 115 size_t attribIndex, 116 const mtl::VertexFormat &convertedFormat, 117 GLuint targetStride, 118 size_t vertexCount, 119 bool isExpandingComponents, 120 ConversionBufferMtl *conversion); 121 122 // These can point to real BufferMtl or converted buffer in mConvertedArrayBufferHolders 123 gl::AttribArray<BufferHolderMtl *> mCurrentArrayBuffers; 124 gl::AttribArray<SimpleWeakBufferHolderMtl> mConvertedArrayBufferHolders; 125 gl::AttribArray<size_t> mCurrentArrayBufferOffsets; 126 127 // Size to be uploaded as inline constant data. Used for client vertex attribute's data that 128 // is small enough that we can send directly as inline constant data instead of streaming 129 // through a buffer. 130 gl::AttribArray<size_t> mCurrentArrayInlineDataSizes; 131 // Array of host buffers storing converted data for client attributes that are small enough. 132 gl::AttribArray<angle::MemoryBuffer> mConvertedClientSmallArrays; 133 gl::AttribArray<const uint8_t *> mCurrentArrayInlineDataPointers; 134 // Max size of inline constant data that can be used for client vertex attribute. 135 size_t mInlineDataMaxSize; 136 137 // Stride per vertex attribute 138 gl::AttribArray<GLuint> mCurrentArrayBufferStrides; 139 // Format per vertex attribute 140 gl::AttribArray<const mtl::VertexFormat *> mCurrentArrayBufferFormats; 141 142 const mtl::VertexFormat &mDefaultFloatVertexFormat; 143 144 mtl::BufferPool mDynamicVertexData; 145 mtl::BufferPool mDynamicIndexData; 146 147 std::vector<uint32_t> mEmulatedInstanceAttribs; 148 149 bool mVertexArrayDirty = true; 150 bool mVertexDataDirty = true; 151 }; 152 } // namespace rx 153 154 #endif /* LIBANGLE_RENDERER_METAL_VERTEXARRAYMTL_H_ */ 155