blob: 9849eaac5be583608fbebcf8a78556e8e3ab2687 [file] [log] [blame]
//
// Copyright 2016 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.
//
// VertexArrayVk.h:
// Defines the class interface for VertexArrayVk, implementing VertexArrayImpl.
//
#ifndef LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_
#define LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_
#include "libANGLE/renderer/VertexArrayImpl.h"
#include "libANGLE/renderer/vulkan/UtilsVk.h"
#include "libANGLE/renderer/vulkan/vk_cache_utils.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
namespace rx
{
enum class BufferBindingDirty
{
No,
Yes,
};
class VertexArrayVk : public VertexArrayImpl
{
public:
VertexArrayVk(ContextVk *contextVk,
const gl::VertexArrayState &state,
const gl::VertexArrayBuffers &vertexArrayBuffers);
~VertexArrayVk() override;
void destroy(const gl::Context *context) override;
gl::VertexArray::DirtyBits checkBufferForDirtyBits(
const gl::Context *context,
const gl::VertexArrayBufferBindingMask bufferBindingMask) override;
angle::Result syncState(const gl::Context *context,
const gl::VertexArray::DirtyBits &dirtyBits,
gl::VertexArray::DirtyAttribBitsArray *attribBits,
gl::VertexArray::DirtyBindingBitsArray *bindingBits) override;
angle::Result updateDefaultAttrib(ContextVk *contextVk, size_t attribIndex);
angle::Result updateStreamedAttribs(const gl::Context *context,
GLint firstVertex,
GLsizei vertexOrIndexCount,
GLsizei instanceCount,
gl::DrawElementsType indexTypeOrInvalid,
const void *indices,
gl::AttributesMask *strideDirtyAttribMaskOut);
angle::Result handleLineLoop(ContextVk *contextVk,
GLint firstVertex,
GLsizei vertexOrIndexCount,
gl::DrawElementsType indexTypeOrInvalid,
const void *indices,
vk::BufferHelper **indexBufferOut,
uint32_t *indexCountOut);
angle::Result handleLineLoopIndexIndirect(ContextVk *contextVk,
gl::DrawElementsType glIndexType,
vk::BufferHelper *srcIndexBuffer,
vk::BufferHelper *srcIndirectBuffer,
VkDeviceSize indirectBufferOffset,
vk::BufferHelper **indexBufferOut,
vk::BufferHelper **indirectBufferOut);
angle::Result handleLineLoopIndirectDraw(const gl::Context *context,
vk::BufferHelper *indirectBufferVk,
VkDeviceSize indirectBufferOffset,
vk::BufferHelper **indexBufferOut,
vk::BufferHelper **indirectBufferOut);
const gl::AttribArray<VkBuffer> &getCurrentArrayBufferHandles() const
{
return mCurrentArrayBufferHandles;
}
const gl::AttribArray<VkDeviceSize> &getCurrentArrayBufferOffsets() const
{
return mCurrentArrayBufferOffsets;
}
const gl::AttribArray<VkDeviceSize> &getCurrentArrayBufferSizes() const
{
return mCurrentArrayBufferSizes;
}
const gl::AttribArray<VkVertexInputBindingDescription2EXT> &getVertexInputBindingDescs() const
{
return mVertexInputBindingDescs;
}
const gl::AttribArray<VkVertexInputAttributeDescription2EXT> &getVertexInputAttribDescs() const
{
return mVertexInputAttribDescs;
}
GLuint getCurrentArrayBufferRelativeOffset(size_t attribIndex) const
{
return mVertexInputAttribDescs[attribIndex].offset;
}
VkFormat getCurrentArrayBufferVkFormat(size_t attribIndex) const
{
return mVertexInputAttribDescs[attribIndex].format;
}
angle::FormatID getCurrentArrayBufferFormatID(size_t attribIndex) const
{
return mCurrentEnabledAttribsMask.test(attribIndex)
? mState.getVertexAttribute(attribIndex).format->id
: mDefaultAttribFormatIDs[attribIndex];
}
GLuint getCurrentArrayBufferStride(size_t attribIndex) const
{
return mVertexInputBindingDescs[attribIndex].stride;
}
GLuint getCurrentArrayBufferDivisor(size_t attribIndex) const
{
return mVertexInputBindingDescs[attribIndex].divisor;
}
// Update mCurrentElementArrayBuffer based on the vertex array state
void updateCurrentElementArrayBuffer();
vk::BufferHelper *getCurrentElementArrayBuffer() const { return mCurrentElementArrayBuffer; }
const gl::AttribArray<vk::BufferHelper *> &getCurrentArrayBuffers() const
{
return mCurrentArrayBuffers;
}
angle::Result convertIndexBufferGPU(ContextVk *contextVk,
BufferVk *bufferVk,
const void *indices);
angle::Result convertIndexBufferIndirectGPU(ContextVk *contextVk,
vk::BufferHelper *srcIndirectBuf,
VkDeviceSize srcIndirectBufOffset,
vk::BufferHelper **indirectBufferVkOut);
angle::Result convertIndexBufferCPU(ContextVk *contextVk,
gl::DrawElementsType indexType,
size_t indexCount,
const void *sourcePointer,
BufferBindingDirty *bufferBindingDirty);
gl::AttributesMask getStreamingVertexAttribsMask() const { return mStreamingVertexAttribsMask; }
gl::ComponentTypeMask getCurrentVertexAttributesTypeMask() const
{
return mCurrentVertexAttributesTypeMask;
}
gl::AttributesMask getCurrentEnabledAttribsMask() const { return mCurrentEnabledAttribsMask; }
private:
void setDefaultPackedInput(ContextVk *contextVk,
size_t attribIndex,
angle::FormatID *formatOut);
angle::Result convertVertexBufferGPU(ContextVk *contextVk,
BufferVk *srcBuffer,
VertexConversionBuffer *conversion,
const angle::Format &srcFormat,
const angle::Format &dstFormat);
angle::Result convertVertexBufferCPU(ContextVk *contextVk,
BufferVk *srcBuffer,
VertexConversionBuffer *conversion,
const angle::Format &srcFormat,
const angle::Format &dstFormat,
const VertexCopyFunction vertexLoadFunction);
angle::Result syncDirtyEnabledNonStreamingAttrib(
ContextVk *contextVk,
const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding,
size_t attribIndex,
const gl::VertexArray::DirtyAttribBits &dirtyAttribBits);
angle::Result syncDirtyEnabledStreamingAttrib(
ContextVk *contextVk,
const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding,
size_t attribIndex,
const gl::VertexArray::DirtyAttribBits &dirtyAttribBits);
angle::Result syncDirtyDisabledAttrib(ContextVk *contextVk,
const gl::VertexAttribute &attrib,
size_t attribIndex);
angle::Result syncNeedsConversionAttrib(ContextVk *contextVk,
const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding,
size_t attribIndex);
void setVertexInputAttribDescFormat(vk::Renderer *renderer,
size_t attribIndex,
angle::FormatID formatID);
void setVertexInputBindingDescDivisor(vk::Renderer *renderer,
size_t attribIndex,
GLuint divisor);
gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles;
gl::AttribArray<VkDeviceSize> mCurrentArrayBufferOffsets;
gl::AttribArray<VkDeviceSize> mCurrentArrayBufferSizes;
gl::AttribArray<vk::BufferHelper *> mCurrentArrayBuffers;
// Tracks BufferSerial of mCurrentArrayBuffers since they are always valid to access.
gl::AttribArray<vk::BufferSerial> mCurrentArrayBufferSerial;
// Tracks the default attribute format ID
gl::AttribArray<angle::FormatID> mDefaultAttribFormatIDs;
// These struct are defined by VK_EXT_vertex_input_dynamic_state, for convenience, we these to
// store offset/divisor even when vertexInputDynamicState not supported.
gl::AttribArray<VkVertexInputBindingDescription2EXT> mVertexInputBindingDescs;
gl::AttribArray<VkVertexInputAttributeDescription2EXT> mVertexInputAttribDescs;
vk::BufferHelper *mCurrentElementArrayBuffer;
// Cached element array buffers for improving performance.
vk::BufferHelperQueue mCachedStreamIndexBuffers;
ConversionBuffer mStreamedIndexData;
ConversionBuffer mTranslatedByteIndexData;
ConversionBuffer mTranslatedByteIndirectData;
LineLoopHelper mLineLoopHelper;
Optional<GLint> mLineLoopBufferFirstIndex;
Optional<size_t> mLineLoopBufferLastIndex;
bool mDirtyLineLoopTranslation;
gl::BufferBindingMask mDivisorExceedMaxSupportedValueBindingMask;
gl::AttributesMask mCurrentEnabledAttribsMask;
// Track client and/or emulated attribs that we have to stream their buffer contents
gl::AttributesMask mStreamingVertexAttribsMask;
gl::AttributesMask mNeedsConversionAttribsMask;
gl::ComponentTypeMask mCurrentVertexAttributesTypeMask;
// Divisor value if vertex inputRate is VK_VERTEX_INPUT_RATE_VERTEX. This maybe 0 or 1 depends
// on feature bit.
uint32_t mDivisorForVertexInputRateVertex;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_VERTEXARRAYVK_H_