Commit 996628a4 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Add support for VkPipelineCache

The cache is initialized from the application's blob cache and is occasionally written back to it for disk storage. Bug: angleproject:2516 Change-Id: I4cba4b00a7b9641c2983ef07159bc62cd10a5519 Reviewed-on: https://chromium-review.googlesource.com/1241373Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent 5ddbdbf7
......@@ -956,7 +956,7 @@ if (is_android) {
}
android_apk("angle_apk") {
deps = [
":angle_apk_assets"
":angle_apk_assets",
]
if (build_apk_secondary_abi && android_64bit_target_cpu) {
secondary_abi_shared_libraries = [
......
......@@ -15,10 +15,6 @@ namespace angle
{
// MemoryBuffer implementation.
MemoryBuffer::MemoryBuffer() : mSize(0), mData(nullptr)
{
}
MemoryBuffer::~MemoryBuffer()
{
free(mData);
......
......@@ -20,7 +20,8 @@ namespace angle
class MemoryBuffer final : NonCopyable
{
public:
MemoryBuffer();
MemoryBuffer() = default;
MemoryBuffer(size_t size) { resize(size); }
~MemoryBuffer();
MemoryBuffer(MemoryBuffer &&other);
......@@ -51,8 +52,8 @@ class MemoryBuffer final : NonCopyable
void fill(uint8_t datum);
private:
size_t mSize;
uint8_t *mData;
size_t mSize = 0;
uint8_t *mData = nullptr;
};
class ScratchBuffer final : NonCopyable
......
......@@ -52,6 +52,14 @@ void BlobCache::put(const BlobCache::Key &key, angle::MemoryBuffer &&value)
}
}
void BlobCache::putApplication(const BlobCache::Key &key, const angle::MemoryBuffer &value)
{
if (areBlobCacheFuncsSet())
{
mSetBlobFunc(key.data(), key.size(), value.data(), value.size());
}
}
void BlobCache::populate(const BlobCache::Key &key, angle::MemoryBuffer &&value, CacheSource source)
{
CacheEntry newEntry;
......@@ -66,7 +74,7 @@ void BlobCache::populate(const BlobCache::Key &key, angle::MemoryBuffer &&value,
}
}
bool BlobCache::get(const gl::Context *context,
bool BlobCache::get(angle::ScratchBuffer *scratchBuffer,
const BlobCache::Key &key,
BlobCache::Value *valueOut)
{
......@@ -79,19 +87,19 @@ bool BlobCache::get(const gl::Context *context,
return false;
}
angle::MemoryBuffer *scratchBuffer;
bool result = context->getScratchBuffer(valueSize, &scratchBuffer);
angle::MemoryBuffer *scratchMemory;
bool result = scratchBuffer->get(valueSize, &scratchMemory);
if (!result)
{
ERR() << "Failed to allocate memory for binary blob";
return false;
}
valueSize = mGetBlobFunc(key.data(), key.size(), scratchBuffer->data(), valueSize);
valueSize = mGetBlobFunc(key.data(), key.size(), scratchMemory->data(), valueSize);
// Make sure the key/value pair still exists/is unchanged after the second call
// (modifications to the application cache by another thread are a possibility)
if (static_cast<size_t>(valueSize) != scratchBuffer->size())
if (static_cast<size_t>(valueSize) != scratchMemory->size())
{
// This warning serves to find issues with the application cache, none of which are
// currently known to be thread-safe. If such a use ever arises, this WARN can be
......@@ -100,7 +108,7 @@ bool BlobCache::get(const gl::Context *context,
return false;
}
*valueOut = BlobCache::Value(scratchBuffer->data(), scratchBuffer->size());
*valueOut = BlobCache::Value(scratchMemory->data(), scratchMemory->size());
return true;
}
......
......@@ -61,7 +61,7 @@ class BlobCache final : angle::NonCopyable
Value(const uint8_t *ptr, size_t sz) : mPtr(ptr), mSize(sz) {}
// A very basic struct to hold the pointer and size together. The objects of this class
// doesn't own the memory.
// don't own the memory.
const uint8_t *data() { return mPtr; }
size_t size() { return mSize; }
......@@ -88,6 +88,9 @@ class BlobCache final : angle::NonCopyable
// will be used. Otherwise the value is cached in this object.
void put(const BlobCache::Key &key, angle::MemoryBuffer &&value);
// Store a key-blob pair in the application cache, only if application callbacks are set.
void putApplication(const BlobCache::Key &key, const angle::MemoryBuffer &value);
// Store a key-blob pair in the cache without making callbacks to the application. This is used
// to repopulate this object's cache on startup without generating callback calls.
void populate(const BlobCache::Key &key,
......@@ -96,10 +99,14 @@ class BlobCache final : angle::NonCopyable
// Check if the cache contains the blob corresponding to this key. If application callbacks are
// set, those will be used. Otherwise they key is looked up in this object's cache.
bool get(const gl::Context *context, const BlobCache::Key &key, BlobCache::Value *valueOut);
ANGLE_NO_DISCARD bool get(angle::ScratchBuffer *scratchBuffer,
const BlobCache::Key &key,
BlobCache::Value *valueOut);
// For querying the contents of the cache.
bool getAt(size_t index, const BlobCache::Key **keyOut, BlobCache::Value *valueOut);
ANGLE_NO_DISCARD bool getAt(size_t index,
const BlobCache::Key **keyOut,
BlobCache::Value *valueOut);
// Evict a blob from the binary cache.
void remove(const BlobCache::Key &key);
......
......@@ -1543,6 +1543,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
angle::MemoryBuffer **scratchBufferOut) const;
ANGLE_NO_DISCARD bool getZeroFilledBuffer(size_t requstedSizeBytes,
angle::MemoryBuffer **zeroBufferOut) const;
angle::ScratchBuffer *getScratchBuffer() const { return &mScratchBuffer; }
Error prepareForDispatch();
......
......@@ -447,6 +447,8 @@ void Display::setAttributes(rx::DisplayImpl *impl, const AttributeMap &attribMap
Error Display::initialize()
{
mImplementation->setBlobCache(&mBlobCache);
// TODO(jmadill): Store Platform in Display and init here.
const angle::PlatformMethods *platformMethods =
reinterpret_cast<const angle::PlatformMethods *>(
......
......@@ -113,13 +113,13 @@ namespace angle
{
Result::operator gl::Error() const
{
if (mStop)
if (mResult == ResultValue::kContinue)
{
return gl::Error(GL_INTERNAL_ERROR_ANGLEX);
return gl::NoError();
}
else
{
return gl::NoError();
return gl::Error(GL_INTERNAL_ERROR_ANGLEX);
}
}
} // namespace angle
......@@ -241,16 +241,15 @@ inline Error NoError()
// TODO(jmadill): Remove this once refactor is complete. http://anglebug.com/2491
#define ANGLE_TRY_HANDLE(CONTEXT, EXPR) \
\
{ \
{ \
auto ANGLE_LOCAL_VAR = (EXPR); \
if (ANGLE_UNLIKELY(ANGLE_LOCAL_VAR.isError())) \
{ \
CONTEXT->handleError(ANGLE_LOCAL_VAR); \
return angle::Result::Stop(); \
} \
\
}
} \
ANGLE_EMPTY_STATEMENT
#define ANGLE_TRY_RESULT(EXPR, RESULT) \
{ \
......@@ -281,15 +280,20 @@ inline Error NoError()
namespace angle
{
// Result signals if calling code should continue running or early exit. A value of Stop() can
// either indicate and Error or a non-Error early exit condition such as a detected no-op.
// either indicate an Error or a non-Error early exit condition such as a detected no-op. A few
// other values exist to signal special cases that are neither success nor failure but require
// special attention.
class ANGLE_NO_DISCARD Result
{
public:
// TODO(jmadill): Rename when refactor is complete. http://anglebug.com/2491
bool isError() const { return mStop; }
bool isError() const { return mResult == ResultValue::kStop; }
Result getError() { return *this; }
Result getResult() { return *this; }
static Result Stop() { return Result(true); }
static Result Continue() { return Result(false); }
static Result Continue() { return Result(ResultValue::kContinue); }
static Result Stop() { return Result(ResultValue::kStop); }
static Result Incomplete() { return Result(ResultValue::kIncomplete); }
// TODO(jmadill): Remove when refactor is complete. http://anglebug.com/2491
operator gl::Error() const;
......@@ -301,13 +305,20 @@ class ANGLE_NO_DISCARD Result
return operator gl::Error();
}
bool operator==(Result other) const { return mStop == other.mStop; }
bool operator==(Result other) const { return mResult == other.mResult; }
bool operator!=(Result other) const { return mStop != other.mStop; }
bool operator!=(Result other) const { return mResult != other.mResult; }
private:
Result(bool stop) : mStop(stop) {}
bool mStop;
enum class ResultValue
{
kContinue = 0,
kStop,
kIncomplete,
};
Result(ResultValue stop) : mResult(stop) {}
ResultValue mResult;
};
} // namespace angle
......
......@@ -681,7 +681,7 @@ bool MemoryProgramCache::get(const Context *context,
const egl::BlobCache::Key &programHash,
egl::BlobCache::Value *programOut)
{
return mBlobCache.get(context, programHash, programOut);
return mBlobCache.get(context->getScratchBuffer(), programHash, programOut);
}
bool MemoryProgramCache::getAt(size_t index,
......
......@@ -15,7 +15,7 @@ namespace rx
{
DisplayImpl::DisplayImpl(const egl::DisplayState &state)
: mState(state), mExtensionsInitialized(false), mCapsInitialized(false)
: mState(state), mExtensionsInitialized(false), mCapsInitialized(false), mBlobCache(nullptr)
{
}
......
......@@ -23,6 +23,7 @@
namespace egl
{
class AttributeMap;
class BlobCache;
class Display;
struct DisplayState;
struct Config;
......@@ -79,6 +80,9 @@ class DisplayImpl : public EGLImplFactory
const egl::DisplayExtensions &getExtensions() const;
void setBlobCache(egl::BlobCache *blobCache) { mBlobCache = blobCache; }
egl::BlobCache *getBlobCache() const { return mBlobCache; }
protected:
const egl::DisplayState &mState;
......@@ -91,6 +95,8 @@ class DisplayImpl : public EGLImplFactory
mutable bool mCapsInitialized;
mutable egl::Caps mCaps;
egl::BlobCache *mBlobCache;
};
}
......
......@@ -150,6 +150,8 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
mDirtyBits = mNewCommandBufferDirtyBits;
}
#undef INIT
ContextVk::~ContextVk() = default;
void ContextVk::onDestroy(const gl::Context *context)
......
......@@ -20,7 +20,7 @@ namespace rx
{
DisplayVk::DisplayVk(const egl::DisplayState &state)
: DisplayImpl(state), vk::Context(new RendererVk())
: DisplayImpl(state), vk::Context(new RendererVk()), mScratchBuffer(1000u)
{
}
......@@ -181,6 +181,12 @@ void DisplayVk::generateCaps(egl::Caps *outCaps) const
outCaps->textureNPOT = true;
}
bool DisplayVk::getScratchBuffer(size_t requstedSizeBytes,
angle::MemoryBuffer **scratchBufferOut) const
{
return mScratchBuffer.get(requstedSizeBytes, scratchBufferOut);
}
void DisplayVk::handleError(VkResult result, const char *file, unsigned int line)
{
std::stringstream errorStream;
......
......@@ -10,6 +10,7 @@
#ifndef LIBANGLE_RENDERER_VULKAN_DISPLAYVK_H_
#define LIBANGLE_RENDERER_VULKAN_DISPLAYVK_H_
#include "common/MemoryBuffer.h"
#include "libANGLE/renderer/DisplayImpl.h"
#include "libANGLE/renderer/vulkan/vk_utils.h"
......@@ -74,6 +75,10 @@ class DisplayVk : public DisplayImpl, public vk::Context
// returning a bool to indicate if the config should be supported.
virtual bool checkConfigSupport(egl::Config *config) = 0;
ANGLE_NO_DISCARD bool getScratchBuffer(size_t requestedSizeBytes,
angle::MemoryBuffer **scratchBufferOut) const;
angle::ScratchBuffer *getScratchBuffer() const { return &mScratchBuffer; }
void handleError(VkResult result, const char *file, unsigned int line) override;
// TODO(jmadill): Remove this once refactor is done. http://anglebug.com/2491
......@@ -87,6 +92,8 @@ class DisplayVk : public DisplayImpl, public vk::Context
void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
void generateCaps(egl::Caps *outCaps) const override;
mutable angle::ScratchBuffer mScratchBuffer;
std::string mStoredErrorString;
};
......
......@@ -14,6 +14,7 @@
#include <memory>
#include "common/angleutils.h"
#include "libANGLE/BlobCache.h"
#include "libANGLE/Caps.h"
#include "libANGLE/renderer/vulkan/CommandGraph.h"
#include "libANGLE/renderer/vulkan/FeaturesVk.h"
......@@ -23,10 +24,12 @@
namespace egl
{
class AttributeMap;
class BlobCache;
}
namespace rx
{
class DisplayVk;
class FramebufferVk;
namespace vk
......@@ -40,7 +43,7 @@ class RendererVk : angle::NonCopyable
RendererVk();
~RendererVk();
angle::Result initialize(vk::Context *context,
angle::Result initialize(DisplayVk *displayVk,
const egl::AttributeMap &attribs,
const char *wsiName);
void onDestroy(vk::Context *context);
......@@ -57,7 +60,7 @@ class RendererVk : angle::NonCopyable
VkQueue getQueue() const { return mQueue; }
VkDevice getDevice() const { return mDevice; }
angle::Result selectPresentQueueForSurface(vk::Context *context,
angle::Result selectPresentQueueForSurface(DisplayVk *displayVk,
VkSurfaceKHR surface,
uint32_t *presentQueueOut);
......@@ -132,6 +135,8 @@ class RendererVk : angle::NonCopyable
const vk::DescriptorSetLayoutPointerArray &descriptorSetLayouts,
vk::BindingPointer<vk::PipelineLayout> *pipelineLayoutOut);
angle::Result syncPipelineCacheVk(DisplayVk *displayVk);
// This should only be called from ResourceVk.
// TODO(jmadill): Keep in ContextVk to enable threaded rendering.
vk::CommandGraph *getCommandGraph();
......@@ -143,7 +148,7 @@ class RendererVk : angle::NonCopyable
const FeaturesVk &getFeatures() const { return mFeatures; }
private:
angle::Result initializeDevice(vk::Context *context, uint32_t queueFamilyIndex);
angle::Result initializeDevice(DisplayVk *displayVk, uint32_t queueFamilyIndex);
void ensureCapsInitialized() const;
angle::Result submitFrame(vk::Context *context,
const VkSubmitInfo &submitInfo,
......@@ -152,6 +157,8 @@ class RendererVk : angle::NonCopyable
void freeAllInFlightResources();
angle::Result flushCommandGraph(vk::Context *context, vk::CommandBuffer *commandBatch);
void initFeatures();
void initPipelineCacheVkKey();
angle::Result initPipelineCacheVk(DisplayVk *display);
mutable bool mCapsInitialized;
mutable gl::Caps mNativeCaps;
......@@ -198,6 +205,10 @@ class RendererVk : angle::NonCopyable
RenderPassCache mRenderPassCache;
PipelineCache mPipelineCache;
vk::PipelineCache mPipelineCacheVk;
egl::BlobCache::Key mPipelineCacheVkBlobKey;
uint32_t mPipelineCacheVkUpdateTimeout;
// See CommandGraph.h for a desription of the Command Graph.
vk::CommandGraph mCommandGraph;
......
......@@ -588,6 +588,8 @@ angle::Result WindowSurfaceVk::swapImpl(DisplayVk *displayVk)
// Get the next available swapchain image.
ANGLE_TRY(nextSwapchainImage(displayVk));
ANGLE_TRY(renderer->syncPipelineCacheVk(displayVk));
return angle::Result::Continue();
}
......
......@@ -11,7 +11,7 @@
#include "libANGLE/renderer/vulkan/vk_cache_utils.h"
#include "common/aligned_memory.h"
#include "libANGLE/SizedMRUCache.h"
#include "libANGLE/BlobCache.h"
#include "libANGLE/VertexAttribute.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h"
#include "libANGLE/renderer/vulkan/ProgramVk.h"
......@@ -436,6 +436,7 @@ void PipelineDesc::initDefaults()
}
angle::Result PipelineDesc::initializePipeline(vk::Context *context,
const vk::PipelineCache &pipelineCacheVk,
const RenderPass &compatibleRenderPass,
const PipelineLayout &pipelineLayout,
const gl::AttributesMask &activeAttribLocationsMask,
......@@ -617,7 +618,7 @@ angle::Result PipelineDesc::initializePipeline(vk::Context *context,
createInfo.basePipelineHandle = VK_NULL_HANDLE;
createInfo.basePipelineIndex = 0;
ANGLE_TRY(pipelineOut->initGraphics(context, createInfo));
ANGLE_TRY(pipelineOut->initGraphics(context, createInfo, pipelineCacheVk));
return angle::Result::Continue();
}
......@@ -1125,6 +1126,7 @@ void PipelineCache::destroy(VkDevice device)
}
angle::Result PipelineCache::getPipeline(vk::Context *context,
const vk::PipelineCache &pipelineCacheVk,
const vk::RenderPass &compatibleRenderPass,
const vk::PipelineLayout &pipelineLayout,
const gl::AttributesMask &activeAttribLocationsMask,
......@@ -1145,9 +1147,9 @@ angle::Result PipelineCache::getPipeline(vk::Context *context,
// This "if" is left here for the benefit of VulkanPipelineCachePerfTest.
if (context != nullptr)
{
ANGLE_TRY(desc.initializePipeline(context, compatibleRenderPass, pipelineLayout,
activeAttribLocationsMask, vertexModule, fragmentModule,
&newPipeline));
ANGLE_TRY(desc.initializePipeline(context, pipelineCacheVk, compatibleRenderPass,
pipelineLayout, activeAttribLocationsMask, vertexModule,
fragmentModule, &newPipeline));
}
// The Serial will be updated outside of this query.
......
......@@ -344,6 +344,7 @@ class PipelineDesc final
void initDefaults();
angle::Result initializePipeline(vk::Context *context,
const vk::PipelineCache &pipelineCacheVk,
const RenderPass &compatibleRenderPass,
const PipelineLayout &pipelineLayout,
const gl::AttributesMask &activeAttribLocationsMask,
......@@ -612,6 +613,7 @@ class PipelineCache final : angle::NonCopyable
void populate(const vk::PipelineDesc &desc, vk::Pipeline &&pipeline);
angle::Result getPipeline(vk::Context *context,
const vk::PipelineCache &pipelineCacheVk,
const vk::RenderPass &compatibleRenderPass,
const vk::PipelineLayout &pipelineLayout,
const gl::AttributesMask &activeAttribLocationsMask,
......
......@@ -826,48 +826,92 @@ angle::Result ShaderModule::init(Context *context, const VkShaderModuleCreateInf
return angle::Result::Continue();
}
// Pipeline implementation.
Pipeline::Pipeline()
// PipelineLayout implementation.
PipelineLayout::PipelineLayout()
{
}
void Pipeline::destroy(VkDevice device)
void PipelineLayout::destroy(VkDevice device)
{
if (valid())
{
vkDestroyPipeline(device, mHandle, nullptr);
vkDestroyPipelineLayout(device, mHandle, nullptr);
mHandle = VK_NULL_HANDLE;
}
}
angle::Result Pipeline::initGraphics(Context *context,
const VkGraphicsPipelineCreateInfo &createInfo)
angle::Result PipelineLayout::init(Context *context, const VkPipelineLayoutCreateInfo &createInfo)
{
ASSERT(!valid());
ANGLE_VK_TRY(context, vkCreateGraphicsPipelines(context->getDevice(), VK_NULL_HANDLE, 1,
&createInfo, nullptr, &mHandle));
ANGLE_VK_TRY(context,
vkCreatePipelineLayout(context->getDevice(), &createInfo, nullptr, &mHandle));
return angle::Result::Continue();
}
// PipelineLayout implementation.
PipelineLayout::PipelineLayout()
// PipelineCache implementation.
PipelineCache::PipelineCache()
{
}
void PipelineLayout::destroy(VkDevice device)
void PipelineCache::destroy(VkDevice device)
{
if (valid())
{
vkDestroyPipelineLayout(device, mHandle, nullptr);
vkDestroyPipelineCache(device, mHandle, nullptr);
mHandle = VK_NULL_HANDLE;
}
}
angle::Result PipelineLayout::init(Context *context, const VkPipelineLayoutCreateInfo &createInfo)
angle::Result PipelineCache::init(Context *context, const VkPipelineCacheCreateInfo &createInfo)
{
ASSERT(!valid());
// Note: if we are concerned with memory usage of this cache, we should give it custom
// allocators. Also, failure of this function is of little importance.
ANGLE_VK_TRY(context,
vkCreatePipelineLayout(context->getDevice(), &createInfo, nullptr, &mHandle));
vkCreatePipelineCache(context->getDevice(), &createInfo, nullptr, &mHandle));
return angle::Result::Continue();
}
angle::Result PipelineCache::getCacheData(Context *context, size_t *cacheSize, void *cacheData)
{
ASSERT(valid());
// Note: vkGetPipelineCacheData can return VK_INCOMPLETE if cacheSize is smaller than actual
// size. There are two usages of this function. One is with *cacheSize == 0 to query the size
// of the cache, and one is with an appropriate buffer to retrieve the cache contents.
// VK_INCOMPLETE in the first case is an expected output. In the second case, VK_INCOMPLETE is
// also acceptable and the resulting buffer will contain valid value by spec. Angle currently
// ensures *cacheSize to be either 0 or of enough size, therefore VK_INCOMPLETE is not expected.
angle::Result result = angle::Result::Stop();
ANGLE_VK_TRY_ALLOW_INCOMPLETE(
context, vkGetPipelineCacheData(context->getDevice(), mHandle, cacheSize, cacheData),
result);
return result;
}
// Pipeline implementation.
Pipeline::Pipeline()
{
}
void Pipeline::destroy(VkDevice device)
{
if (valid())
{
vkDestroyPipeline(device, mHandle, nullptr);
mHandle = VK_NULL_HANDLE;
}
}
angle::Result Pipeline::initGraphics(Context *context,
const VkGraphicsPipelineCreateInfo &createInfo,
const PipelineCache &pipelineCacheVk)
{
ASSERT(!valid());
ANGLE_VK_TRY(context,
vkCreateGraphicsPipelines(context->getDevice(), pipelineCacheVk.getHandle(), 1,
&createInfo, nullptr, &mHandle));
return angle::Result::Continue();
}
......
......@@ -94,7 +94,7 @@ namespace vk
{
struct Format;
// Abstracts error handling. Implemented by both ContextVk for GL and RendererVk for EGL errors.
// Abstracts error handling. Implemented by both ContextVk for GL and DisplayVk for EGL errors.
class Context : angle::NonCopyable
{
public:
......@@ -531,22 +531,34 @@ class ShaderModule final : public WrappedObject<ShaderModule, VkShaderModule>
angle::Result init(Context *context, const VkShaderModuleCreateInfo &createInfo);
};
class Pipeline final : public WrappedObject<Pipeline, VkPipeline>
class PipelineLayout final : public WrappedObject<PipelineLayout, VkPipelineLayout>
{
public:
Pipeline();
PipelineLayout();
void destroy(VkDevice device);
angle::Result initGraphics(Context *context, const VkGraphicsPipelineCreateInfo &createInfo);
angle::Result init(Context *context, const VkPipelineLayoutCreateInfo &createInfo);
};
class PipelineLayout final : public WrappedObject<PipelineLayout, VkPipelineLayout>
class PipelineCache final : public WrappedObject<PipelineCache, VkPipelineCache>
{
public:
PipelineLayout();
PipelineCache();
void destroy(VkDevice device);
angle::Result init(Context *context, const VkPipelineLayoutCreateInfo &createInfo);
angle::Result init(Context *context, const VkPipelineCacheCreateInfo &createInfo);
angle::Result getCacheData(Context *context, size_t *cacheSize, void *cacheData);
};
class Pipeline final : public WrappedObject<Pipeline, VkPipeline>
{
public:
Pipeline();
void destroy(VkDevice device);
angle::Result initGraphics(Context *context,
const VkGraphicsPipelineCreateInfo &createInfo,
const PipelineCache &pipelineCacheVk);
};
class DescriptorSetLayout final : public WrappedObject<DescriptorSetLayout, VkDescriptorSetLayout>
......@@ -757,6 +769,19 @@ VkColorComponentFlags GetColorComponentFlags(bool red, bool green, bool blue, bo
} \
ANGLE_EMPTY_STATEMENT
#define ANGLE_VK_TRY_ALLOW_INCOMPLETE(context, command, result) \
{ \
auto ANGLE_LOCAL_VAR = command; \
if (ANGLE_UNLIKELY(ANGLE_LOCAL_VAR != VK_SUCCESS && ANGLE_LOCAL_VAR != VK_INCOMPLETE)) \
{ \
context->handleError(ANGLE_LOCAL_VAR, __FILE__, __LINE__); \
return angle::Result::Stop(); \
} \
result = ANGLE_LOCAL_VAR == VK_INCOMPLETE ? angle::Result::Incomplete() \
: angle::Result::Continue(); \
} \
ANGLE_EMPTY_STATEMENT
#define ANGLE_VK_CHECK(context, test, error) ANGLE_VK_TRY(context, test ? VK_SUCCESS : error)
#define ANGLE_VK_CHECK_MATH(context, result) \
......
......@@ -80,6 +80,7 @@ void VulkanPipelineCachePerfTest::step()
{
vk::RenderPass rp;
vk::PipelineLayout pl;
vk::PipelineCache pc;
vk::ShaderModule sm;
vk::PipelineAndSerial *result = nullptr;
gl::AttributesMask am;
......@@ -88,7 +89,7 @@ void VulkanPipelineCachePerfTest::step()
{
for (const auto &hit : mCacheHits)
{
(void)mCache.getPipeline(VK_NULL_HANDLE, rp, pl, am, sm, sm, hit, &result);
(void)mCache.getPipeline(VK_NULL_HANDLE, pc, rp, pl, am, sm, sm, hit, &result);
}
}
......@@ -96,7 +97,7 @@ void VulkanPipelineCachePerfTest::step()
++missCount, ++mMissIndex)
{
const auto &miss = mCacheMisses[mMissIndex];
(void)mCache.getPipeline(VK_NULL_HANDLE, rp, pl, am, sm, sm, miss, &result);
(void)mCache.getPipeline(VK_NULL_HANDLE, pc, rp, pl, am, sm, sm, miss, &result);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment