Hash :
0cb6dc4c
Author :
Date :
2018-04-16T10:36:39
Vulkan: Fix texture descriptor set alloc count. We were reserving half the required descriptor sets for our pool. This fixes the counting and ensures we won't regress by adding a test. Also enables the cube map texture sample, and removes an UNIMPLEMENTED warning that was spurious. Bug: angleproject:2318 Change-Id: I371cd7c5b42e1ce980cce7bb0ef04885db72b614 Reviewed-on: https://chromium-review.googlesource.com/1014165 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Luc Ferron <lucferron@chromium.org> Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
//
// Copyright 2018 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.
//
// vk_helpers:
// Helper utilitiy classes that manage Vulkan resources.
#ifndef LIBANGLE_RENDERER_VULKAN_VK_HELPERS_H_
#define LIBANGLE_RENDERER_VULKAN_VK_HELPERS_H_
#include "libANGLE/renderer/vulkan/CommandGraph.h"
#include "libANGLE/renderer/vulkan/vk_utils.h"
namespace gl
{
class ImageIndex;
} // namespace gl;
namespace rx
{
namespace vk
{
// A dynamic buffer is conceptually an infinitely long buffer. Each time you write to the buffer,
// you will always write to a previously unused portion. After a series of writes, you must flush
// the buffer data to the device. Buffer lifetime currently assumes that each new allocation will
// last as long or longer than each prior allocation.
//
// Dynamic buffers are used to implement a variety of data streaming operations in Vulkan, such
// as for immediate vertex array and element array data, uniform updates, and other dynamic data.
class DynamicBuffer : angle::NonCopyable
{
public:
DynamicBuffer(VkBufferUsageFlags usage, size_t minSize);
~DynamicBuffer();
// Init is called after the buffer creation so that the alignment can be specified later.
void init(size_t alignment);
bool valid();
// This call will allocate a new region at the end of the buffer. It internally may trigger
// a new buffer to be created (which is returned in 'newBufferAllocatedOut'. This param may
// be nullptr.
Error allocate(RendererVk *renderer,
size_t sizeInBytes,
uint8_t **ptrOut,
VkBuffer *handleOut,
uint32_t *offsetOut,
bool *newBufferAllocatedOut);
// After a sequence of writes, call flush to ensure the data is visible to the device.
Error flush(VkDevice device);
// This releases resources when they might currently be in use.
void release(RendererVk *renderer);
// This frees resources immediately.
void destroy(VkDevice device);
VkBuffer getCurrentBufferHandle() const;
// For testing only!
void setMinimumSizeForTesting(size_t minSize);
private:
VkBufferUsageFlags mUsage;
size_t mMinSize;
Buffer mBuffer;
DeviceMemory mMemory;
uint32_t mNextWriteOffset;
uint32_t mLastFlushOffset;
size_t mSize;
size_t mAlignment;
uint8_t *mMappedMemory;
};
// Uses DescriptorPool to allocate descriptor sets as needed. If the descriptor pool
// is full, we simply allocate a new pool to keep allocating descriptor sets as needed and
// leave the renderer take care of the life time of the pools that become unused.
enum DescriptorPoolIndex : uint8_t
{
UniformBufferIndex = 0,
TextureIndex = 1,
DescriptorPoolIndexCount = 2
};
class DynamicDescriptorPool final : angle::NonCopyable
{
public:
DynamicDescriptorPool();
~DynamicDescriptorPool();
void destroy(RendererVk *rendererVk);
Error init(const VkDevice &device,
uint32_t uniformBufferDescriptorsPerSet,
uint32_t combinedImageSamplerDescriptorsPerSet);
// It is an undefined behavior to pass a different descriptorSetLayout from call to call.
Error allocateDescriptorSets(ContextVk *contextVk,
const VkDescriptorSetLayout *descriptorSetLayout,
uint32_t descriptorSetCount,
VkDescriptorSet *descriptorSetsOut);
// For testing only!
void setMaxSetsPerPoolForTesting(uint32_t maxSetsPerPool);
private:
Error allocateNewPool(const VkDevice &device);
uint32_t mMaxSetsPerPool;
DescriptorPool mCurrentDescriptorSetPool;
size_t mCurrentAllocatedDescriptorSetCount;
uint32_t mUniformBufferDescriptorsPerSet;
uint32_t mCombinedImageSamplerDescriptorsPerSet;
};
// This class' responsibility is to create index buffers needed to support line loops in Vulkan.
// In the setup phase of drawing, the createIndexBuffer method should be called with the
// current draw call parameters. If an element array buffer is bound for an indexed draw, use
// createIndexBufferFromElementArrayBuffer.
//
// If the user wants to draw a loop between [v1, v2, v3], we will create an indexed buffer with
// these indexes: [0, 1, 2, 3, 0] to emulate the loop.
class LineLoopHelper final : public vk::CommandGraphResource
{
public:
LineLoopHelper();
~LineLoopHelper();
gl::Error getIndexBufferForDrawArrays(RendererVk *renderer,
const gl::DrawCallParams &drawCallParams,
VkBuffer *bufferHandleOut,
VkDeviceSize *offsetOut);
gl::Error getIndexBufferForElementArrayBuffer(RendererVk *renderer,
BufferVk *elementArrayBufferVk,
VkIndexType indexType,
int indexCount,
intptr_t elementArrayOffset,
VkBuffer *bufferHandleOut,
VkDeviceSize *bufferOffsetOut);
gl::Error getIndexBufferForClientElementArray(RendererVk *renderer,
const void *indicesInput,
VkIndexType indexType,
int indexCount,
VkBuffer *bufferHandleOut,
VkDeviceSize *bufferOffsetOut);
void destroy(VkDevice device);
static void Draw(int count, CommandBuffer *commandBuffer);
private:
DynamicBuffer mDynamicIndexBuffer;
};
class ImageHelper final : angle::NonCopyable
{
public:
ImageHelper();
ImageHelper(ImageHelper &&other);
~ImageHelper();
bool valid() const;
Error init(VkDevice device,
gl::TextureType textureType,
const gl::Extents &extents,
const Format &format,
GLint samples,
VkImageUsageFlags usage);
Error initMemory(VkDevice device,
const MemoryProperties &memoryProperties,
VkMemoryPropertyFlags flags);
Error initImageView(VkDevice device,
gl::TextureType textureType,
VkImageAspectFlags aspectMask,
const gl::SwizzleState &swizzleMap,
ImageView *imageViewOut);
Error init2DStaging(VkDevice device,
const MemoryProperties &memoryProperties,
const Format &format,
const gl::Extents &extent,
StagingUsage usage);
void release(Serial serial, RendererVk *renderer);
void destroy(VkDevice device);
void dumpResources(Serial serial, std::vector<GarbageObject> *garbageQueue);
void init2DWeakReference(VkImage handle,
const gl::Extents &extents,
const Format &format,
GLint samples);
void resetImageWeakReference();
const Image &getImage() const;
const DeviceMemory &getDeviceMemory() const;
const gl::Extents &getExtents() const;
const Format &getFormat() const;
GLint getSamples() const;
size_t getAllocatedMemorySize() const;
VkImageLayout getCurrentLayout() const { return mCurrentLayout; }
void updateLayout(VkImageLayout layout) { mCurrentLayout = layout; }
void changeLayoutWithStages(VkImageAspectFlags aspectMask,
VkImageLayout newLayout,
VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
CommandBuffer *commandBuffer);
void clearColor(const VkClearColorValue &color, CommandBuffer *commandBuffer);
void clearDepthStencil(VkImageAspectFlags aspectFlags,
const VkClearDepthStencilValue &depthStencil,
CommandBuffer *commandBuffer);
static void Copy(ImageHelper *srcImage,
ImageHelper *dstImage,
const gl::Offset &srcOffset,
const gl::Offset &dstOffset,
const gl::Extents ©Size,
VkImageAspectFlags aspectMask,
CommandBuffer *commandBuffer);
private:
// Vulkan objects.
Image mImage;
DeviceMemory mDeviceMemory;
// Image properties.
gl::Extents mExtents;
const Format *mFormat;
GLint mSamples;
size_t mAllocatedMemorySize;
// Current state.
VkImageLayout mCurrentLayout;
// Cached properties.
uint32_t mLayerCount;
};
} // namespace vk
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_VK_HELPERS_H_