|
@@ -0,0 +1,238 @@
|
|
|
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
+From: Jamie Madill <[email protected]>
|
|
|
+Date: Fri, 20 May 2022 10:26:15 -0400
|
|
|
+Subject: D3D: Fix race condition with parallel shader compile.
|
|
|
+
|
|
|
+Bug: chromium:1317673
|
|
|
+Change-Id: I0fb7c9a66248852e41e8700e80c295393ef941e8
|
|
|
+Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3651153
|
|
|
+Reviewed-by: Jie A Chen <[email protected]>
|
|
|
+Reviewed-by: Lingfeng Yang <[email protected]>
|
|
|
+Commit-Queue: Jamie Madill <[email protected]>
|
|
|
+(cherry picked from commit 4a20c9143abbf29c649cf643182735e8952089e3)
|
|
|
+Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3691050
|
|
|
+Bot-Commit: Rubber Stamper <[email protected]>
|
|
|
+
|
|
|
+diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
|
|
|
+index 59fe34fc46a1bfbc7b4be1aad6ad84b6da303b5b..3256357a80d69739661ec1fd32220d3037145875 100644
|
|
|
+--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
|
|
|
++++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
|
|
|
+@@ -1687,12 +1687,6 @@ class ProgramD3D::GetVertexExecutableTask : public ProgramD3D::GetExecutableTask
|
|
|
+ angle::Result run() override
|
|
|
+ {
|
|
|
+ ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetVertexExecutableTask::run");
|
|
|
+- if (!mProgram->mState.getAttachedShader(gl::ShaderType::Vertex))
|
|
|
+- {
|
|
|
+- return angle::Result::Continue;
|
|
|
+- }
|
|
|
+-
|
|
|
+- mProgram->updateCachedInputLayoutFromShader();
|
|
|
+
|
|
|
+ ANGLE_TRY(mProgram->getVertexExecutableForCachedInputLayout(this, &mExecutable, &mInfoLog));
|
|
|
+
|
|
|
+@@ -2147,6 +2141,11 @@ std::unique_ptr<LinkEvent> ProgramD3D::link(const gl::Context *context,
|
|
|
+
|
|
|
+ linkResources(resources);
|
|
|
+
|
|
|
++ if (mState.getAttachedShader(gl::ShaderType::Vertex))
|
|
|
++ {
|
|
|
++ updateCachedInputLayoutFromShader();
|
|
|
++ }
|
|
|
++
|
|
|
+ return compileProgramExecutables(context, infoLog);
|
|
|
+ }
|
|
|
+ }
|
|
|
+diff --git a/src/tests/gl_tests/ParallelShaderCompileTest.cpp b/src/tests/gl_tests/ParallelShaderCompileTest.cpp
|
|
|
+index bcd88ef01308759085c8244ad2058efe68686f2b..a98aff540c642617bba366b2e238519942d7e349 100644
|
|
|
+--- a/src/tests/gl_tests/ParallelShaderCompileTest.cpp
|
|
|
++++ b/src/tests/gl_tests/ParallelShaderCompileTest.cpp
|
|
|
+@@ -58,9 +58,10 @@ class ParallelShaderCompileTest : public ANGLETest
|
|
|
+ Task(int id) : mID(id) {}
|
|
|
+ virtual ~Task() {}
|
|
|
+
|
|
|
+- virtual bool compile() = 0;
|
|
|
+- virtual bool isCompileCompleted() = 0;
|
|
|
+- virtual bool link() = 0;
|
|
|
++ virtual bool compile() = 0;
|
|
|
++ virtual bool isCompileCompleted() = 0;
|
|
|
++ virtual bool link() = 0;
|
|
|
++ virtual void postLink() {}
|
|
|
+ virtual void runAndVerify(ParallelShaderCompileTest *test) = 0;
|
|
|
+
|
|
|
+ bool isLinkCompleted()
|
|
|
+@@ -71,7 +72,7 @@ class ParallelShaderCompileTest : public ANGLETest
|
|
|
+ }
|
|
|
+
|
|
|
+ protected:
|
|
|
+- std::string insertRandomString(const std::string &source)
|
|
|
++ static std::string InsertRandomString(const std::string &source)
|
|
|
+ {
|
|
|
+ RNG rng;
|
|
|
+ std::ostringstream ostream;
|
|
|
+@@ -80,7 +81,7 @@ class ParallelShaderCompileTest : public ANGLETest
|
|
|
+ return ostream.str();
|
|
|
+ }
|
|
|
+
|
|
|
+- GLuint CompileShader(GLenum type, const std::string &source)
|
|
|
++ static GLuint CompileShader(GLenum type, const std::string &source)
|
|
|
+ {
|
|
|
+ GLuint shader = glCreateShader(type);
|
|
|
+
|
|
|
+@@ -90,7 +91,14 @@ class ParallelShaderCompileTest : public ANGLETest
|
|
|
+ return shader;
|
|
|
+ }
|
|
|
+
|
|
|
+- bool checkShader(GLuint shader)
|
|
|
++ static void RecompileShader(GLuint shader, const std::string &source)
|
|
|
++ {
|
|
|
++ const char *sourceArray[1] = {source.c_str()};
|
|
|
++ glShaderSource(shader, 1, sourceArray, nullptr);
|
|
|
++ glCompileShader(shader);
|
|
|
++ }
|
|
|
++
|
|
|
++ static bool CheckShader(GLuint shader)
|
|
|
+ {
|
|
|
+ GLint compileResult;
|
|
|
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
|
|
|
+@@ -129,7 +137,7 @@ class ParallelShaderCompileTest : public ANGLETest
|
|
|
+ TaskRunner() {}
|
|
|
+ ~TaskRunner() {}
|
|
|
+
|
|
|
+- void run(ParallelShaderCompileTest *test)
|
|
|
++ void run(ParallelShaderCompileTest *test, unsigned int pollInterval)
|
|
|
+ {
|
|
|
+
|
|
|
+ std::vector<std::unique_ptr<T>> compileTasks;
|
|
|
+@@ -151,6 +159,7 @@ class ParallelShaderCompileTest : public ANGLETest
|
|
|
+ if (task->isCompileCompleted())
|
|
|
+ {
|
|
|
+ bool isLinking = task->link();
|
|
|
++ task->postLink();
|
|
|
+ ASSERT_TRUE(isLinking);
|
|
|
+ linkTasks.push_back(std::move(task));
|
|
|
+ compileTasks.erase(compileTasks.begin() + i);
|
|
|
+@@ -158,7 +167,10 @@ class ParallelShaderCompileTest : public ANGLETest
|
|
|
+ }
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+- angle::Sleep(kPollInterval);
|
|
|
++ if (pollInterval != 0)
|
|
|
++ {
|
|
|
++ angle::Sleep(pollInterval);
|
|
|
++ }
|
|
|
+ }
|
|
|
+
|
|
|
+ while (!linkTasks.empty())
|
|
|
+@@ -173,9 +185,16 @@ class ParallelShaderCompileTest : public ANGLETest
|
|
|
+ linkTasks.erase(linkTasks.begin() + i);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
++ else
|
|
|
++ {
|
|
|
++ task->postLink();
|
|
|
++ }
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+- angle::Sleep(kPollInterval);
|
|
|
++ if (pollInterval != 0)
|
|
|
++ {
|
|
|
++ angle::Sleep(pollInterval);
|
|
|
++ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+@@ -192,9 +211,9 @@ class ParallelShaderCompileTest : public ANGLETest
|
|
|
+ bool compile() override
|
|
|
+ {
|
|
|
+ mVertexShader =
|
|
|
+- CompileShader(GL_VERTEX_SHADER, insertRandomString(essl1_shaders::vs::Simple()));
|
|
|
++ CompileShader(GL_VERTEX_SHADER, InsertRandomString(essl1_shaders::vs::Simple()));
|
|
|
+ mFragmentShader = CompileShader(GL_FRAGMENT_SHADER,
|
|
|
+- insertRandomString(essl1_shaders::fs::UniformColor()));
|
|
|
++ InsertRandomString(essl1_shaders::fs::UniformColor()));
|
|
|
+ return (mVertexShader != 0 && mFragmentShader != 0);
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -213,7 +232,7 @@ class ParallelShaderCompileTest : public ANGLETest
|
|
|
+ bool link() override
|
|
|
+ {
|
|
|
+ mProgram = 0;
|
|
|
+- if (checkShader(mVertexShader) && checkShader(mFragmentShader))
|
|
|
++ if (CheckShader(mVertexShader) && CheckShader(mFragmentShader))
|
|
|
+ {
|
|
|
+ mProgram = glCreateProgram();
|
|
|
+ glAttachShader(mProgram, mVertexShader);
|
|
|
+@@ -244,10 +263,25 @@ class ParallelShaderCompileTest : public ANGLETest
|
|
|
+ ASSERT_GL_NO_ERROR();
|
|
|
+ }
|
|
|
+
|
|
|
++ protected:
|
|
|
++ void recompile()
|
|
|
++ {
|
|
|
++ RecompileShader(mVertexShader, essl1_shaders::vs::Simple());
|
|
|
++ RecompileShader(mFragmentShader, essl1_shaders::fs::UniformColor());
|
|
|
++ }
|
|
|
++
|
|
|
+ private:
|
|
|
+- GLColor mColor;
|
|
|
+ GLuint mVertexShader;
|
|
|
+ GLuint mFragmentShader;
|
|
|
++ GLColor mColor;
|
|
|
++ };
|
|
|
++
|
|
|
++ class ClearColorWithDrawRecompile : public ClearColorWithDraw
|
|
|
++ {
|
|
|
++ public:
|
|
|
++ ClearColorWithDrawRecompile(int taskID) : ClearColorWithDraw(taskID) {}
|
|
|
++
|
|
|
++ void postLink() override { recompile(); }
|
|
|
+ };
|
|
|
+
|
|
|
+ class ImageLoadStore : public Task
|
|
|
+@@ -268,7 +302,7 @@ void main()
|
|
|
+ imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
|
|
|
+ })";
|
|
|
+
|
|
|
+- mShader = CompileShader(GL_COMPUTE_SHADER, insertRandomString(kCSSource));
|
|
|
++ mShader = CompileShader(GL_COMPUTE_SHADER, InsertRandomString(kCSSource));
|
|
|
+ return mShader != 0;
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -282,7 +316,7 @@ void main()
|
|
|
+ bool link() override
|
|
|
+ {
|
|
|
+ mProgram = 0;
|
|
|
+- if (checkShader(mShader))
|
|
|
++ if (CheckShader(mShader))
|
|
|
+ {
|
|
|
+ mProgram = glCreateProgram();
|
|
|
+ glAttachShader(mProgram, mShader);
|
|
|
+@@ -370,7 +404,18 @@ TEST_P(ParallelShaderCompileTest, LinkAndDrawManyPrograms)
|
|
|
+ ANGLE_SKIP_TEST_IF(!ensureParallelShaderCompileExtensionAvailable());
|
|
|
+
|
|
|
+ TaskRunner<ClearColorWithDraw> runner;
|
|
|
+- runner.run(this);
|
|
|
++ runner.run(this, kPollInterval);
|
|
|
++}
|
|
|
++
|
|
|
++// Tests no crash in case that the Shader starts another compile while the Program being attached
|
|
|
++// to is still linking.
|
|
|
++// crbug.com/1317673
|
|
|
++TEST_P(ParallelShaderCompileTest, LinkProgramAndRecompileShader)
|
|
|
++{
|
|
|
++ ANGLE_SKIP_TEST_IF(!ensureParallelShaderCompileExtensionAvailable());
|
|
|
++
|
|
|
++ TaskRunner<ClearColorWithDrawRecompile> runner;
|
|
|
++ runner.run(this, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ class ParallelShaderCompileTestES31 : public ParallelShaderCompileTest
|
|
|
+@@ -389,7 +434,7 @@ TEST_P(ParallelShaderCompileTestES31, LinkAndDispatchManyPrograms)
|
|
|
+ ANGLE_SKIP_TEST_IF(!ensureParallelShaderCompileExtensionAvailable());
|
|
|
+
|
|
|
+ TaskRunner<ImageLoadStore> runner;
|
|
|
+- runner.run(this);
|
|
|
++ runner.run(this, kPollInterval);
|
|
|
+ }
|
|
|
+
|
|
|
+ ANGLE_INSTANTIATE_TEST_ES2(ParallelShaderCompileTest);
|