summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/MemoryProgramCache.cpp
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2020-05-18 15:16:30 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2020-05-26 15:11:40 +0200
commit752497910b67b2a1a80560840ca44548d8893434 (patch)
tree541501c9abfd97c3d2fa450d2e6abb60582c4420 /src/3rdparty/angle/src/libANGLE/MemoryProgramCache.cpp
parent7db527dbdd911c79f31425d099d1fc9c63e42453 (diff)
Remove ANGLE
This marks the end of EGL and OpenGL ES support on Windows. The concepts of -opengl dynamic, -opengl desktop, QT_OPENGL=software, etc. remain unchanged, with the exception of the disapperance of everything ANGLE related. CMake builds now work identically to qmake on Windows: they default to 'dynamic' OpenGL on Windows, unless -DINPUT_opengl=desktop is specified. On Windows, Qt 6 is expected to default to the "dynamic" OpenGL model by default, just like Qt 5.15. This can be changed by switching to "desktop" OpenGL, which will link to opengl32 (publicly, so other libs and applications will do so as well) and disallows using another OpenGL DLL. The "dynamic" mode is essential still because the fallback to a software rasterizer, such as the opengl32sw.dll we ship with the Qt packages, has to to work exactly like in Qt 5, the removal of ANGLE does not change this concept in any way (except of course that the middle option of using ANGLE is now gone) When it comes to the windows plugin's OpenGL blacklist feature, it works like before and accepts the ANGLE/D3D related keywords. They will then be ignored. Similarly, requesting QT_OPENGL=angle is ignored (but will show a warning). The D3D11 and DXGI configure time tests are removed: Qt 5.14 already depends on D3D 11.1 and DXGI 1.3 headers being available unconditionally on Win32 (in QRhi's D3D11 backend). No need to test for these. [ChangeLog][Windows] ANGLE is no longer included with Qt. Dynamic OpenGL builds work like before but ANGLE is no longer an option. OpenGL proper or an alternative opengl32 implementation are the two remaining options now. Attempting to set QT_OPENGL=angle or Qt::AA_UseOpenGLES will have no effect on Windows. Fixes: QTBUG-79103 Change-Id: Ia404e0d07f3fe191b27434d863c81180112ecb3b Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/MemoryProgramCache.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/MemoryProgramCache.cpp772
1 files changed, 0 insertions, 772 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/MemoryProgramCache.cpp b/src/3rdparty/angle/src/libANGLE/MemoryProgramCache.cpp
deleted file mode 100644
index 9eec12e3ea..0000000000
--- a/src/3rdparty/angle/src/libANGLE/MemoryProgramCache.cpp
+++ /dev/null
@@ -1,772 +0,0 @@
-//
-// Copyright 2017 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.
-//
-// MemoryProgramCache: Stores compiled and linked programs in memory so they don't
-// always have to be re-compiled. Can be used in conjunction with the platform
-// layer to warm up the cache from disk.
-
-#include "libANGLE/MemoryProgramCache.h"
-
-#include <GLSLANG/ShaderVars.h>
-#include <anglebase/sha1.h>
-
-#include "common/utilities.h"
-#include "common/version.h"
-#include "libANGLE/BinaryStream.h"
-#include "libANGLE/Context.h"
-#include "libANGLE/Uniform.h"
-#include "libANGLE/histogram_macros.h"
-#include "libANGLE/renderer/ProgramImpl.h"
-#include "platform/Platform.h"
-
-namespace gl
-{
-
-namespace
-{
-enum CacheResult
-{
- kCacheMiss,
- kCacheHitMemory,
- kCacheHitDisk,
- kCacheResultMax,
-};
-
-constexpr unsigned int kWarningLimit = 3;
-
-void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
-{
- stream->writeInt(var.type);
- stream->writeInt(var.precision);
- stream->writeString(var.name);
- stream->writeString(var.mappedName);
- stream->writeIntVector(var.arraySizes);
- stream->writeInt(var.staticUse);
- stream->writeString(var.structName);
- ASSERT(var.fields.empty());
-}
-
-void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var)
-{
- var->type = stream->readInt<GLenum>();
- var->precision = stream->readInt<GLenum>();
- var->name = stream->readString();
- var->mappedName = stream->readString();
- stream->readIntVector<unsigned int>(&var->arraySizes);
- var->staticUse = stream->readBool();
- var->structName = stream->readString();
-}
-
-void WriteShaderVariableBuffer(BinaryOutputStream *stream, const ShaderVariableBuffer &var)
-{
- stream->writeInt(var.binding);
- stream->writeInt(var.dataSize);
-
- stream->writeInt(var.vertexStaticUse);
- stream->writeInt(var.fragmentStaticUse);
- stream->writeInt(var.computeStaticUse);
-
- stream->writeInt(var.memberIndexes.size());
- for (unsigned int memberCounterIndex : var.memberIndexes)
- {
- stream->writeInt(memberCounterIndex);
- }
-}
-
-void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *var)
-{
- var->binding = stream->readInt<int>();
- var->dataSize = stream->readInt<unsigned int>();
- var->vertexStaticUse = stream->readBool();
- var->fragmentStaticUse = stream->readBool();
- var->computeStaticUse = stream->readBool();
-
- unsigned int numMembers = stream->readInt<unsigned int>();
- for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
- {
- var->memberIndexes.push_back(stream->readInt<unsigned int>());
- }
-}
-
-void WriteBufferVariable(BinaryOutputStream *stream, const BufferVariable &var)
-{
- WriteShaderVar(stream, var);
-
- stream->writeInt(var.bufferIndex);
- stream->writeInt(var.blockInfo.offset);
- stream->writeInt(var.blockInfo.arrayStride);
- stream->writeInt(var.blockInfo.matrixStride);
- stream->writeInt(var.blockInfo.isRowMajorMatrix);
- stream->writeInt(var.blockInfo.topLevelArrayStride);
- stream->writeInt(var.topLevelArraySize);
- stream->writeInt(var.vertexStaticUse);
- stream->writeInt(var.fragmentStaticUse);
- stream->writeInt(var.computeStaticUse);
-}
-
-void LoadBufferVariable(BinaryInputStream *stream, BufferVariable *var)
-{
- LoadShaderVar(stream, var);
-
- var->bufferIndex = stream->readInt<int>();
- var->blockInfo.offset = stream->readInt<int>();
- var->blockInfo.arrayStride = stream->readInt<int>();
- var->blockInfo.matrixStride = stream->readInt<int>();
- var->blockInfo.isRowMajorMatrix = stream->readBool();
- var->blockInfo.topLevelArrayStride = stream->readInt<int>();
- var->topLevelArraySize = stream->readInt<int>();
- var->vertexStaticUse = stream->readBool();
- var->fragmentStaticUse = stream->readBool();
- var->computeStaticUse = stream->readBool();
-}
-
-void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block)
-{
- stream->writeString(block.name);
- stream->writeString(block.mappedName);
- stream->writeInt(block.isArray);
- stream->writeInt(block.arrayElement);
-
- WriteShaderVariableBuffer(stream, block);
-}
-
-void LoadInterfaceBlock(BinaryInputStream *stream, InterfaceBlock *block)
-{
- block->name = stream->readString();
- block->mappedName = stream->readString();
- block->isArray = stream->readBool();
- block->arrayElement = stream->readInt<unsigned int>();
-
- LoadShaderVariableBuffer(stream, block);
-}
-
-class HashStream final : angle::NonCopyable
-{
- public:
- std::string str() { return mStringStream.str(); }
-
- template <typename T>
- HashStream &operator<<(T value)
- {
- mStringStream << value << kSeparator;
- return *this;
- }
-
- private:
- static constexpr char kSeparator = ':';
- std::ostringstream mStringStream;
-};
-
-HashStream &operator<<(HashStream &stream, const Shader *shader)
-{
- if (shader)
- {
- stream << shader->getSourceString().c_str() << shader->getSourceString().length()
- << shader->getCompilerResourcesString().c_str();
- }
- return stream;
-}
-
-HashStream &operator<<(HashStream &stream, const Program::Bindings &bindings)
-{
- for (const auto &binding : bindings)
- {
- stream << binding.first << binding.second;
- }
- return stream;
-}
-
-HashStream &operator<<(HashStream &stream, const std::vector<std::string> &strings)
-{
- for (const auto &str : strings)
- {
- stream << str;
- }
- return stream;
-}
-
-} // anonymous namespace
-
-MemoryProgramCache::MemoryProgramCache(size_t maxCacheSizeBytes)
- : mProgramBinaryCache(maxCacheSizeBytes), mIssuedWarnings(0)
-{
-}
-
-MemoryProgramCache::~MemoryProgramCache()
-{
-}
-
-// static
-LinkResult MemoryProgramCache::Deserialize(const Context *context,
- const Program *program,
- ProgramState *state,
- const uint8_t *binary,
- size_t length,
- InfoLog &infoLog)
-{
- BinaryInputStream stream(binary, length);
-
- unsigned char commitString[ANGLE_COMMIT_HASH_SIZE];
- stream.readBytes(commitString, ANGLE_COMMIT_HASH_SIZE);
- if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) !=
- 0)
- {
- infoLog << "Invalid program binary version.";
- return false;
- }
-
- int majorVersion = stream.readInt<int>();
- int minorVersion = stream.readInt<int>();
- if (majorVersion != context->getClientMajorVersion() ||
- minorVersion != context->getClientMinorVersion())
- {
- infoLog << "Cannot load program binaries across different ES context versions.";
- return false;
- }
-
- state->mComputeShaderLocalSize[0] = stream.readInt<int>();
- state->mComputeShaderLocalSize[1] = stream.readInt<int>();
- state->mComputeShaderLocalSize[2] = stream.readInt<int>();
-
- state->mNumViews = stream.readInt<int>();
-
- static_assert(MAX_VERTEX_ATTRIBS <= sizeof(unsigned long) * 8,
- "Too many vertex attribs for mask");
- state->mActiveAttribLocationsMask = stream.readInt<unsigned long>();
-
- unsigned int attribCount = stream.readInt<unsigned int>();
- ASSERT(state->mAttributes.empty());
- for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex)
- {
- sh::Attribute attrib;
- LoadShaderVar(&stream, &attrib);
- attrib.location = stream.readInt<int>();
- state->mAttributes.push_back(attrib);
- }
-
- unsigned int uniformCount = stream.readInt<unsigned int>();
- ASSERT(state->mUniforms.empty());
- for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; ++uniformIndex)
- {
- LinkedUniform uniform;
- LoadShaderVar(&stream, &uniform);
-
- uniform.bufferIndex = stream.readInt<int>();
- uniform.blockInfo.offset = stream.readInt<int>();
- uniform.blockInfo.arrayStride = stream.readInt<int>();
- uniform.blockInfo.matrixStride = stream.readInt<int>();
- uniform.blockInfo.isRowMajorMatrix = stream.readBool();
-
- uniform.typeInfo = &GetUniformTypeInfo(uniform.type);
-
- state->mUniforms.push_back(uniform);
- }
-
- const unsigned int uniformIndexCount = stream.readInt<unsigned int>();
- ASSERT(state->mUniformLocations.empty());
- for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount;
- uniformIndexIndex++)
- {
- VariableLocation variable;
- stream.readInt(&variable.arrayIndex);
- stream.readInt(&variable.index);
- stream.readBool(&variable.ignored);
-
- state->mUniformLocations.push_back(variable);
- }
-
- unsigned int uniformBlockCount = stream.readInt<unsigned int>();
- ASSERT(state->mUniformBlocks.empty());
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount;
- ++uniformBlockIndex)
- {
- InterfaceBlock uniformBlock;
- LoadInterfaceBlock(&stream, &uniformBlock);
- state->mUniformBlocks.push_back(uniformBlock);
-
- state->mActiveUniformBlockBindings.set(uniformBlockIndex, uniformBlock.binding != 0);
- }
-
- unsigned int bufferVariableCount = stream.readInt<unsigned int>();
- ASSERT(state->mBufferVariables.empty());
- for (unsigned int index = 0; index < bufferVariableCount; ++index)
- {
- BufferVariable bufferVariable;
- LoadBufferVariable(&stream, &bufferVariable);
- state->mBufferVariables.push_back(bufferVariable);
- }
-
- unsigned int shaderStorageBlockCount = stream.readInt<unsigned int>();
- ASSERT(state->mShaderStorageBlocks.empty());
- for (unsigned int shaderStorageBlockIndex = 0;
- shaderStorageBlockIndex < shaderStorageBlockCount; ++shaderStorageBlockIndex)
- {
- InterfaceBlock shaderStorageBlock;
- LoadInterfaceBlock(&stream, &shaderStorageBlock);
- state->mShaderStorageBlocks.push_back(shaderStorageBlock);
- }
-
- unsigned int atomicCounterBufferCount = stream.readInt<unsigned int>();
- ASSERT(state->mAtomicCounterBuffers.empty());
- for (unsigned int bufferIndex = 0; bufferIndex < atomicCounterBufferCount; ++bufferIndex)
- {
- AtomicCounterBuffer atomicCounterBuffer;
- LoadShaderVariableBuffer(&stream, &atomicCounterBuffer);
-
- state->mAtomicCounterBuffers.push_back(atomicCounterBuffer);
- }
-
- unsigned int transformFeedbackVaryingCount = stream.readInt<unsigned int>();
-
- // Reject programs that use transform feedback varyings if the hardware cannot support them.
- if (transformFeedbackVaryingCount > 0 &&
- context->getWorkarounds().disableProgramCachingForTransformFeedback)
- {
- infoLog << "Current driver does not support transform feedback in binary programs.";
- return false;
- }
-
- ASSERT(state->mLinkedTransformFeedbackVaryings.empty());
- for (unsigned int transformFeedbackVaryingIndex = 0;
- transformFeedbackVaryingIndex < transformFeedbackVaryingCount;
- ++transformFeedbackVaryingIndex)
- {
- sh::Varying varying;
- stream.readIntVector<unsigned int>(&varying.arraySizes);
- stream.readInt(&varying.type);
- stream.readString(&varying.name);
-
- GLuint arrayIndex = stream.readInt<GLuint>();
-
- state->mLinkedTransformFeedbackVaryings.emplace_back(varying, arrayIndex);
- }
-
- stream.readInt(&state->mTransformFeedbackBufferMode);
-
- unsigned int outputCount = stream.readInt<unsigned int>();
- ASSERT(state->mOutputVariables.empty());
- for (unsigned int outputIndex = 0; outputIndex < outputCount; ++outputIndex)
- {
- sh::OutputVariable output;
- LoadShaderVar(&stream, &output);
- output.location = stream.readInt<int>();
- state->mOutputVariables.push_back(output);
- }
-
- unsigned int outputVarCount = stream.readInt<unsigned int>();
- ASSERT(state->mOutputLocations.empty());
- for (unsigned int outputIndex = 0; outputIndex < outputVarCount; ++outputIndex)
- {
- VariableLocation locationData;
- stream.readInt(&locationData.arrayIndex);
- stream.readInt(&locationData.index);
- stream.readBool(&locationData.ignored);
- state->mOutputLocations.push_back(locationData);
- }
-
- unsigned int outputTypeCount = stream.readInt<unsigned int>();
- for (unsigned int outputIndex = 0; outputIndex < outputTypeCount; ++outputIndex)
- {
- state->mOutputVariableTypes.push_back(stream.readInt<GLenum>());
- }
- static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS < 8 * sizeof(uint32_t),
- "All bits of DrawBufferMask can be contained in an uint32_t");
- state->mActiveOutputVariables = stream.readInt<uint32_t>();
-
- unsigned int samplerRangeLow = stream.readInt<unsigned int>();
- unsigned int samplerRangeHigh = stream.readInt<unsigned int>();
- state->mSamplerUniformRange = RangeUI(samplerRangeLow, samplerRangeHigh);
- unsigned int samplerCount = stream.readInt<unsigned int>();
- for (unsigned int samplerIndex = 0; samplerIndex < samplerCount; ++samplerIndex)
- {
- GLenum textureType = stream.readInt<GLenum>();
- size_t bindingCount = stream.readInt<size_t>();
- bool unreferenced = stream.readBool();
- state->mSamplerBindings.emplace_back(
- SamplerBinding(textureType, bindingCount, unreferenced));
- }
-
- unsigned int imageRangeLow = stream.readInt<unsigned int>();
- unsigned int imageRangeHigh = stream.readInt<unsigned int>();
- state->mImageUniformRange = RangeUI(imageRangeLow, imageRangeHigh);
- unsigned int imageBindingCount = stream.readInt<unsigned int>();
- for (unsigned int imageIndex = 0; imageIndex < imageBindingCount; ++imageIndex)
- {
- unsigned int elementCount = stream.readInt<unsigned int>();
- ImageBinding imageBinding(elementCount);
- for (unsigned int i = 0; i < elementCount; ++i)
- {
- imageBinding.boundImageUnits[i] = stream.readInt<unsigned int>();
- }
- state->mImageBindings.emplace_back(imageBinding);
- }
-
- unsigned int atomicCounterRangeLow = stream.readInt<unsigned int>();
- unsigned int atomicCounterRangeHigh = stream.readInt<unsigned int>();
- state->mAtomicCounterUniformRange = RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh);
-
- static_assert(SHADER_TYPE_MAX <= sizeof(unsigned long) * 8, "Too many shader types");
- state->mLinkedShaderStages = stream.readInt<unsigned long>();
-
- return program->getImplementation()->load(context, infoLog, &stream);
-}
-
-// static
-void MemoryProgramCache::Serialize(const Context *context,
- const gl::Program *program,
- angle::MemoryBuffer *binaryOut)
-{
- BinaryOutputStream stream;
-
- stream.writeBytes(reinterpret_cast<const unsigned char *>(ANGLE_COMMIT_HASH),
- ANGLE_COMMIT_HASH_SIZE);
-
- // nullptr context is supported when computing binary length.
- if (context)
- {
- stream.writeInt(context->getClientVersion().major);
- stream.writeInt(context->getClientVersion().minor);
- }
- else
- {
- stream.writeInt(2);
- stream.writeInt(0);
- }
-
- const auto &state = program->getState();
-
- const auto &computeLocalSize = state.getComputeShaderLocalSize();
-
- stream.writeInt(computeLocalSize[0]);
- stream.writeInt(computeLocalSize[1]);
- stream.writeInt(computeLocalSize[2]);
-
- stream.writeInt(state.mNumViews);
-
- stream.writeInt(state.getActiveAttribLocationsMask().to_ulong());
-
- stream.writeInt(state.getAttributes().size());
- for (const sh::Attribute &attrib : state.getAttributes())
- {
- WriteShaderVar(&stream, attrib);
- stream.writeInt(attrib.location);
- }
-
- stream.writeInt(state.getUniforms().size());
- for (const LinkedUniform &uniform : state.getUniforms())
- {
- WriteShaderVar(&stream, uniform);
-
- // FIXME: referenced
-
- stream.writeInt(uniform.bufferIndex);
- stream.writeInt(uniform.blockInfo.offset);
- stream.writeInt(uniform.blockInfo.arrayStride);
- stream.writeInt(uniform.blockInfo.matrixStride);
- stream.writeInt(uniform.blockInfo.isRowMajorMatrix);
- }
-
- stream.writeInt(state.getUniformLocations().size());
- for (const auto &variable : state.getUniformLocations())
- {
- stream.writeInt(variable.arrayIndex);
- stream.writeIntOrNegOne(variable.index);
- stream.writeInt(variable.ignored);
- }
-
- stream.writeInt(state.getUniformBlocks().size());
- for (const InterfaceBlock &uniformBlock : state.getUniformBlocks())
- {
- WriteInterfaceBlock(&stream, uniformBlock);
- }
-
- stream.writeInt(state.getBufferVariables().size());
- for (const BufferVariable &bufferVariable : state.getBufferVariables())
- {
- WriteBufferVariable(&stream, bufferVariable);
- }
-
- stream.writeInt(state.getShaderStorageBlocks().size());
- for (const InterfaceBlock &shaderStorageBlock : state.getShaderStorageBlocks())
- {
- WriteInterfaceBlock(&stream, shaderStorageBlock);
- }
-
- stream.writeInt(state.mAtomicCounterBuffers.size());
- for (const auto &atomicCounterBuffer : state.mAtomicCounterBuffers)
- {
- WriteShaderVariableBuffer(&stream, atomicCounterBuffer);
- }
-
- // Warn the app layer if saving a binary with unsupported transform feedback.
- if (!state.getLinkedTransformFeedbackVaryings().empty() &&
- context->getWorkarounds().disableProgramCachingForTransformFeedback)
- {
- WARN() << "Saving program binary with transform feedback, which is not supported on this "
- "driver.";
- }
-
- stream.writeInt(state.getLinkedTransformFeedbackVaryings().size());
- for (const auto &var : state.getLinkedTransformFeedbackVaryings())
- {
- stream.writeIntVector(var.arraySizes);
- stream.writeInt(var.type);
- stream.writeString(var.name);
-
- stream.writeIntOrNegOne(var.arrayIndex);
- }
-
- stream.writeInt(state.getTransformFeedbackBufferMode());
-
- stream.writeInt(state.getOutputVariables().size());
- for (const sh::OutputVariable &output : state.getOutputVariables())
- {
- WriteShaderVar(&stream, output);
- stream.writeInt(output.location);
- }
-
- stream.writeInt(state.getOutputLocations().size());
- for (const auto &outputVar : state.getOutputLocations())
- {
- stream.writeInt(outputVar.arrayIndex);
- stream.writeIntOrNegOne(outputVar.index);
- stream.writeInt(outputVar.ignored);
- }
-
- stream.writeInt(state.mOutputVariableTypes.size());
- for (const auto &outputVariableType : state.mOutputVariableTypes)
- {
- stream.writeInt(outputVariableType);
- }
-
- static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS < 8 * sizeof(uint32_t),
- "All bits of DrawBufferMask can be contained in an uint32_t");
- stream.writeInt(static_cast<uint32_t>(state.mActiveOutputVariables.to_ulong()));
-
- stream.writeInt(state.getSamplerUniformRange().low());
- stream.writeInt(state.getSamplerUniformRange().high());
-
- stream.writeInt(state.getSamplerBindings().size());
- for (const auto &samplerBinding : state.getSamplerBindings())
- {
- stream.writeInt(samplerBinding.textureType);
- stream.writeInt(samplerBinding.boundTextureUnits.size());
- stream.writeInt(samplerBinding.unreferenced);
- }
-
- stream.writeInt(state.getImageUniformRange().low());
- stream.writeInt(state.getImageUniformRange().high());
-
- stream.writeInt(state.getImageBindings().size());
- for (const auto &imageBinding : state.getImageBindings())
- {
- stream.writeInt(imageBinding.boundImageUnits.size());
- for (size_t i = 0; i < imageBinding.boundImageUnits.size(); ++i)
- {
- stream.writeInt(imageBinding.boundImageUnits[i]);
- }
- }
-
- stream.writeInt(state.getAtomicCounterUniformRange().low());
- stream.writeInt(state.getAtomicCounterUniformRange().high());
-
- stream.writeInt(state.getLinkedShaderStages().to_ulong());
-
- program->getImplementation()->save(context, &stream);
-
- ASSERT(binaryOut);
- binaryOut->resize(stream.length());
- memcpy(binaryOut->data(), stream.data(), stream.length());
-}
-
-// static
-void MemoryProgramCache::ComputeHash(const Context *context,
- const Program *program,
- ProgramHash *hashOut)
-{
- const Shader *vertexShader = program->getAttachedVertexShader();
- const Shader *fragmentShader = program->getAttachedFragmentShader();
- const Shader *computeShader = program->getAttachedComputeShader();
-
- // Compute the program hash. Start with the shader hashes and resource strings.
- HashStream hashStream;
- hashStream << vertexShader << fragmentShader << computeShader;
-
- // Add some ANGLE metadata and Context properties, such as version and back-end.
- hashStream << ANGLE_COMMIT_HASH << context->getClientMajorVersion()
- << context->getClientMinorVersion() << context->getString(GL_RENDERER);
-
- // Hash pre-link program properties.
- hashStream << program->getAttributeBindings() << program->getUniformLocationBindings()
- << program->getFragmentInputBindings()
- << program->getState().getTransformFeedbackVaryingNames()
- << program->getState().getTransformFeedbackBufferMode();
-
- // Call the secure SHA hashing function.
- const std::string &programKey = hashStream.str();
- angle::base::SHA1HashBytes(reinterpret_cast<const unsigned char *>(programKey.c_str()),
- programKey.length(), hashOut->data());
-}
-
-LinkResult MemoryProgramCache::getProgram(const Context *context,
- const Program *program,
- ProgramState *state,
- ProgramHash *hashOut)
-{
- ComputeHash(context, program, hashOut);
- const angle::MemoryBuffer *binaryProgram = nullptr;
- LinkResult result(false);
- if (get(*hashOut, &binaryProgram))
- {
- InfoLog infoLog;
- ANGLE_TRY_RESULT(Deserialize(context, program, state, binaryProgram->data(),
- binaryProgram->size(), infoLog),
- result);
- ANGLE_HISTOGRAM_BOOLEAN("GPU.ANGLE.ProgramCache.LoadBinarySuccess", result.getResult());
- if (!result.getResult())
- {
- // Cache load failed, evict.
- if (mIssuedWarnings++ < kWarningLimit)
- {
- WARN() << "Failed to load binary from cache: " << infoLog.str();
-
- if (mIssuedWarnings == kWarningLimit)
- {
- WARN() << "Reaching warning limit for cache load failures, silencing "
- "subsequent warnings.";
- }
- }
- remove(*hashOut);
- }
- }
- return result;
-}
-
-bool MemoryProgramCache::get(const ProgramHash &programHash, const angle::MemoryBuffer **programOut)
-{
- const CacheEntry *entry = nullptr;
- if (!mProgramBinaryCache.get(programHash, &entry))
- {
- ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.ProgramCache.CacheResult", kCacheMiss,
- kCacheResultMax);
- return false;
- }
-
- if (entry->second == CacheSource::PutProgram)
- {
- ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.ProgramCache.CacheResult", kCacheHitMemory,
- kCacheResultMax);
- }
- else
- {
- ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.ProgramCache.CacheResult", kCacheHitDisk,
- kCacheResultMax);
- }
-
- *programOut = &entry->first;
- return true;
-}
-
-bool MemoryProgramCache::getAt(size_t index,
- ProgramHash *hashOut,
- const angle::MemoryBuffer **programOut)
-{
- const CacheEntry *entry = nullptr;
- if (!mProgramBinaryCache.getAt(index, hashOut, &entry))
- {
- return false;
- }
-
- *programOut = &entry->first;
- return true;
-}
-
-void MemoryProgramCache::remove(const ProgramHash &programHash)
-{
- bool result = mProgramBinaryCache.eraseByKey(programHash);
- ASSERT(result);
-}
-
-void MemoryProgramCache::putProgram(const ProgramHash &programHash,
- const Context *context,
- const Program *program)
-{
- CacheEntry newEntry;
- Serialize(context, program, &newEntry.first);
- newEntry.second = CacheSource::PutProgram;
-
- ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.ProgramCache.ProgramBinarySizeBytes",
- static_cast<int>(newEntry.first.size()));
-
- const CacheEntry *result =
- mProgramBinaryCache.put(programHash, std::move(newEntry), newEntry.first.size());
- if (!result)
- {
- ERR() << "Failed to store binary program in memory cache, program is too large.";
- }
- else
- {
- auto *platform = ANGLEPlatformCurrent();
- platform->cacheProgram(platform, programHash, result->first.size(), result->first.data());
- }
-}
-
-void MemoryProgramCache::updateProgram(const Context *context, const Program *program)
-{
- gl::ProgramHash programHash;
- ComputeHash(context, program, &programHash);
- putProgram(programHash, context, program);
-}
-
-void MemoryProgramCache::putBinary(const ProgramHash &programHash,
- const uint8_t *binary,
- size_t length)
-{
- // Copy the binary.
- CacheEntry newEntry;
- newEntry.first.resize(length);
- memcpy(newEntry.first.data(), binary, length);
- newEntry.second = CacheSource::PutBinary;
-
- // Store the binary.
- const CacheEntry *result = mProgramBinaryCache.put(programHash, std::move(newEntry), length);
- if (!result)
- {
- ERR() << "Failed to store binary program in memory cache, program is too large.";
- }
-}
-
-void MemoryProgramCache::clear()
-{
- mProgramBinaryCache.clear();
- mIssuedWarnings = 0;
-}
-
-void MemoryProgramCache::resize(size_t maxCacheSizeBytes)
-{
- mProgramBinaryCache.resize(maxCacheSizeBytes);
-}
-
-size_t MemoryProgramCache::entryCount() const
-{
- return mProgramBinaryCache.entryCount();
-}
-
-size_t MemoryProgramCache::trim(size_t limit)
-{
- return mProgramBinaryCache.shrinkToSize(limit);
-}
-
-size_t MemoryProgramCache::size() const
-{
- return mProgramBinaryCache.size();
-}
-
-size_t MemoryProgramCache::maxSize() const
-{
- return mProgramBinaryCache.maxSize();
-}
-
-} // namespace gl