Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit dd29370

Browse files
vontureCommit Bot
authored andcommitted
Include the fragment output locations in the program cache key.
If the user rebinds the output locations and relinks a program, the wrong program may be loaded from the cache. TEST=gl_tests: TranslatorVariants/EXTBlendFuncExtended* BUG=angleproject:4535 Change-Id: If9a9c2ad935ea4d01c3fe4313810d221e9c9ce38 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2131252 Commit-Queue: Geoff Lang <[email protected]> Reviewed-by: Courtney Goeltzenleuchter <[email protected]>
1 parent a053f34 commit dd29370

File tree

4 files changed

+70
-5
lines changed

4 files changed

+70
-5
lines changed

src/libANGLE/MemoryProgramCache.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ void MemoryProgramCache::ComputeHash(const Context *context,
116116

117117
// Hash pre-link program properties.
118118
hashStream << program->getAttributeBindings() << program->getUniformLocationBindings()
119+
<< program->getFragmentOutputLocations() << program->getFragmentOutputIndexes()
119120
<< program->getState().getTransformFeedbackVaryingNames()
120121
<< program->getState().getTransformFeedbackBufferMode()
121122
<< program->getState().getOutputLocations()

src/libANGLE/Program.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2371,6 +2371,18 @@ const ProgramAliasedBindings &Program::getUniformLocationBindings() const
23712371
return mState.mUniformLocationBindings;
23722372
}
23732373

2374+
const gl::ProgramAliasedBindings &Program::getFragmentOutputLocations() const
2375+
{
2376+
ASSERT(mLinkResolved);
2377+
return mFragmentOutputLocations;
2378+
}
2379+
2380+
const gl::ProgramAliasedBindings &Program::getFragmentOutputIndexes() const
2381+
{
2382+
ASSERT(mLinkResolved);
2383+
return mFragmentOutputIndexes;
2384+
}
2385+
23742386
ComponentTypeMask Program::getDrawBufferTypeMask() const
23752387
{
23762388
ASSERT(mLinkResolved);

src/libANGLE/Program.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,8 @@ class Program final : angle::NonCopyable, public LabeledObject
807807

808808
const ProgramBindings &getAttributeBindings() const;
809809
const ProgramAliasedBindings &getUniformLocationBindings() const;
810+
const ProgramAliasedBindings &getFragmentOutputLocations() const;
811+
const ProgramAliasedBindings &getFragmentOutputIndexes() const;
810812

811813
int getNumViews() const
812814
{

src/tests/egl_tests/EGLBlobCacheTest.cpp

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,7 @@ class EGLBlobCacheTest : public ANGLETest
108108

109109
void testTearDown() override { gApplicationCache.clear(); }
110110

111-
bool programBinaryAvailable()
112-
{
113-
return (getClientMajorVersion() >= 3 || IsGLExtensionEnabled("GL_OES_get_program_binary"));
114-
}
111+
bool programBinaryAvailable() { return IsGLExtensionEnabled("GL_OES_get_program_binary"); }
115112

116113
bool mHasBlobCache;
117114
};
@@ -232,4 +229,57 @@ TEST_P(EGLBlobCacheTest, NegativeAPI)
232229
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
233230
}
234231

235-
ANGLE_INSTANTIATE_TEST_ES2(EGLBlobCacheTest);
232+
// Regression test for including the fragment output locatins in the program key.
233+
// http://anglebug.com/4535
234+
TEST_P(EGLBlobCacheTest, FragmentOutputLocationKey)
235+
{
236+
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_blend_func_extended") ||
237+
getClientMajorVersion() < 3);
238+
239+
EGLDisplay display = getEGLWindow()->getDisplay();
240+
241+
EXPECT_TRUE(mHasBlobCache);
242+
eglSetBlobCacheFuncsANDROID(display, SetBlob, GetBlob);
243+
ASSERT_EGL_SUCCESS();
244+
245+
// Compile a shader so it puts something in the cache
246+
if (programBinaryAvailable())
247+
{
248+
constexpr char kFragmentShaderSrc[] = R"(#version 300 es
249+
#extension GL_EXT_blend_func_extended : require
250+
precision mediump float;
251+
uniform vec4 src;
252+
uniform vec4 src1;
253+
out vec4 FragData;
254+
out vec4 SecondaryFragData;
255+
void main() {
256+
FragData = src;
257+
SecondaryFragData = src1;
258+
})";
259+
260+
constexpr char kVertexShaderSrc[] = R"(#version 300 es
261+
in vec4 position;
262+
void main() {
263+
gl_Position = position;
264+
})";
265+
266+
GLuint program = CompileProgram(kVertexShaderSrc, kFragmentShaderSrc, [](GLuint p) {
267+
glBindFragDataLocationEXT(p, 0, "FragData[0]");
268+
glBindFragDataLocationIndexedEXT(p, 0, 1, "SecondaryFragData[0]");
269+
});
270+
ASSERT_NE(0u, program);
271+
EXPECT_EQ(CacheOpResult::SetSuccess, gLastCacheOpResult);
272+
gLastCacheOpResult = CacheOpResult::ValueNotSet;
273+
274+
// Re-link the program with different fragment output bindings
275+
program = CompileProgram(kVertexShaderSrc, kFragmentShaderSrc, [](GLuint p) {
276+
glBindFragDataLocationEXT(p, 0, "FragData");
277+
glBindFragDataLocationIndexedEXT(p, 0, 1, "SecondaryFragData");
278+
});
279+
ASSERT_NE(0u, program);
280+
EXPECT_EQ(CacheOpResult::SetSuccess, gLastCacheOpResult);
281+
gLastCacheOpResult = CacheOpResult::ValueNotSet;
282+
}
283+
}
284+
285+
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(EGLBlobCacheTest);

0 commit comments

Comments
 (0)