OSDN Git Service

Fixed a crash using TransformFeedback with DrawArraysInstanced
authorAlexis Hetu <sugoi@google.com>
Thu, 10 Jan 2019 20:22:37 +0000 (15:22 -0500)
committerAlexis Hétu <sugoi@google.com>
Thu, 24 Jan 2019 19:03:45 +0000 (19:03 +0000)
When using TransformFeedback with DrawArraysInstanced, a crash
would occur if no varyings were set to use transform feedback
due to a null transform feedback buffer. Added a null pointer
check and an assert to fix this.

Bug b/117080493

Change-Id: Ieb226bfb70ae837bdb206bdbefe84f62dc1f2204
Reviewed-on: https://swiftshader-review.googlesource.com/c/23569
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Corentin Wallez <cwallez@google.com>
src/OpenGL/libGLESv2/Program.cpp
tests/GLESUnitTests/unittests.cpp

index dc64813..cc4c49c 100644 (file)
@@ -1261,10 +1261,14 @@ namespace es2
                        // In INTERLEAVED_ATTRIBS mode, the values of one or more output variables
                        // written by a vertex shader are written, interleaved, into the buffer object
                        // bound to the first transform feedback binding point (index = 0).
-                       sw::Resource* resource = transformFeedbackBuffers[0].get()->getResource();
+                       sw::Resource* resource = transformFeedbackBuffers[0].get() ?
+                                                transformFeedbackBuffers[0].get()->getResource() :
+                                                nullptr;
                        int componentStride = static_cast<int>(totalLinkedVaryingsComponents);
                        int baseOffset = transformFeedbackBuffers[0].getOffset() + (transformFeedback->vertexOffset() * componentStride * sizeof(float));
                        maxVaryings = sw::min(maxVaryings, (unsigned int)sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
+                       ASSERT(resource || (maxVaryings == 0));
+
                        int totalComponents = 0;
                        for(unsigned int index = 0; index < maxVaryings; ++index)
                        {
index a1ea0b6..4829b5d 100644 (file)
@@ -950,6 +950,50 @@ TEST_F(SwiftShaderTest, AtanCornerCases)
        Uninitialize();
 }
 
+TEST_F(SwiftShaderTest, TransformFeedback_DrawArraysInstanced)
+{
+       Initialize(3, false);
+
+       const char * data0[] =\r
+       {\r
+               "#version 300 es\n"\r
+               "in mediump vec2 vary;"\r
+               "out mediump vec4 color;"\r
+               "void main()"\r
+               "{\t"\r
+                       "color = vec4(vary, 0.0, 1.0);"\r
+               "}"\r
+       };\r
+       const char * data1[] =\r
+       {\r
+               "#version 300 es\n"\r
+               "layout(location=0) in mediump vec2 pos;"\r
+               "out mediump vec2 vary;"\r
+               "void main()"\r
+               "{\t"\r
+                       "vary = pos;\t"\r
+                       "gl_Position = vec4(pos, 0.0, 1.0);"\r
+               "}"\r
+       };\r
+\r
+       GLuint vert = glCreateShader(GL_VERTEX_SHADER);\r
+       GLuint frag = glCreateShader(GL_FRAGMENT_SHADER);\r
+       GLuint program = glCreateProgram();\r
+\r
+       glShaderSource(frag, 1, data0, (const GLint *)0);\r
+       glAttachShader(program, vert);\r
+       glCompileShader(frag);\r
+       glAttachShader(program, frag);\r
+       glShaderSource(vert, 1, data1, (const GLint *)0);\r
+       glCompileShader(vert);\r
+       glLinkProgram(program);\r
+       glUseProgram(program);\r
+       glBeginTransformFeedback(GL_POINTS);\r
+       glDrawArraysInstanced(GL_POINTS, 0, 1, 1);
+
+       Uninitialize();
+}
+
 // Test conditions that should result in a GL_OUT_OF_MEMORY and not crash
 TEST_F(SwiftShaderTest, OutOfMemory)
 {