OSDN Git Service

Fill vertex routine state for fuzzer.
authorNicolas Capens <capn@google.com>
Fri, 27 Oct 2017 18:36:52 +0000 (14:36 -0400)
committerNicolas Capens <nicolascapens@google.com>
Fri, 27 Oct 2017 21:02:41 +0000 (21:02 +0000)
Bug swiftshader:86

Change-Id: I8339f3882163daa078ac71034aaf37147e51d725
Reviewed-on: https://swiftshader-review.googlesource.com/13349
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
tests/fuzzers/VertexRoutineFuzzer.cpp

index 986f839..af6dc4b 100644 (file)
@@ -62,68 +62,135 @@ class FakeVS : public glsl::Shader {
                        return bytecode;
                }
 
-
        private:
                sw::VertexShader* bytecode;
 };
 
-// Keep the compiler-related objects between fuzzer runs to speed up the iteration speed.
-std::unique_ptr<ScopedPoolAllocatorAndTLS> allocatorAndTLS;
-std::unique_ptr<sw::VertexShader> bytecodeShader;
-std::unique_ptr<FakeVS> fakeVS;
-std::unique_ptr<TranslatorASM> glslCompiler;
-
 } // anonymous namespace
 
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-       if (allocatorAndTLS == nullptr) {
-               allocatorAndTLS.reset(new ScopedPoolAllocatorAndTLS);
-       }
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
+{
+       std::unique_ptr<ScopedPoolAllocatorAndTLS> allocatorAndTLS(new ScopedPoolAllocatorAndTLS);
+       std::unique_ptr<sw::VertexShader> shader(new sw::VertexShader);
+       std::unique_ptr<FakeVS> fakeVS(new FakeVS(shader.get()));
+       
+       std::unique_ptr<TranslatorASM> glslCompiler(new TranslatorASM(fakeVS.get(), GL_VERTEX_SHADER));
+
+       // TODO(cwallez@google.com): have a function to init to default values somewhere
+       ShBuiltInResources resources;
+       resources.MaxVertexAttribs = sw::MAX_VERTEX_INPUTS;
+       resources.MaxVertexUniformVectors = sw::VERTEX_UNIFORM_VECTORS - 3;
+       resources.MaxVaryingVectors = MIN(sw::MAX_VERTEX_OUTPUTS, sw::MAX_VERTEX_INPUTS);
+       resources.MaxVertexTextureImageUnits = sw::VERTEX_TEXTURE_IMAGE_UNITS;
+       resources.MaxCombinedTextureImageUnits = sw::TEXTURE_IMAGE_UNITS + sw::VERTEX_TEXTURE_IMAGE_UNITS;
+       resources.MaxTextureImageUnits = sw::TEXTURE_IMAGE_UNITS;
+       resources.MaxFragmentUniformVectors = sw::FRAGMENT_UNIFORM_VECTORS - 3;
+       resources.MaxDrawBuffers = sw::RENDERTARGETS;
+       resources.MaxVertexOutputVectors = 16; // ???
+       resources.MaxFragmentInputVectors = 15; // ???
+       resources.MinProgramTexelOffset = sw::MIN_PROGRAM_TEXEL_OFFSET;
+       resources.MaxProgramTexelOffset = sw::MAX_PROGRAM_TEXEL_OFFSET;
+       resources.OES_standard_derivatives = 1;
+       resources.OES_fragment_precision_high = 1;
+       resources.OES_EGL_image_external = 1;
+       resources.EXT_draw_buffers = 1;
+       resources.MaxCallStackDepth = 16;
+
+       glslCompiler->Init(resources);
 
-       if (bytecodeShader == nullptr) {
-               bytecodeShader.reset(new sw::VertexShader);
+       const char* glslSource = "void main() {gl_Position = vec4(1.0);}";
+       
+       if (!glslCompiler->compile(&glslSource, 1, SH_OBJECT_CODE))
+       {
+               return 0;
        }
 
-       if (fakeVS == nullptr) {
-               fakeVS.reset(new FakeVS(bytecodeShader.get()));
-       }
+       std::unique_ptr<sw::VertexShader> bytecodeShader(new sw::VertexShader(fakeVS->getVertexShader()));
+
+       sw::VertexProcessor::State state;
 
-       if (glslCompiler == nullptr) {
-               glslCompiler.reset(new TranslatorASM(fakeVS.get(), GL_VERTEX_SHADER));
-
-               // TODO(cwallez@google.com): have a function to init to default values somewhere
-               ShBuiltInResources resources;
-               resources.MaxVertexAttribs = sw::MAX_VERTEX_INPUTS;
-               resources.MaxVertexUniformVectors = sw::VERTEX_UNIFORM_VECTORS - 3;
-               resources.MaxVaryingVectors = MIN(sw::MAX_VERTEX_OUTPUTS, sw::MAX_VERTEX_INPUTS);
-               resources.MaxVertexTextureImageUnits = sw::VERTEX_TEXTURE_IMAGE_UNITS;
-               resources.MaxCombinedTextureImageUnits = sw::TEXTURE_IMAGE_UNITS + sw::VERTEX_TEXTURE_IMAGE_UNITS;
-               resources.MaxTextureImageUnits = sw::TEXTURE_IMAGE_UNITS;
-               resources.MaxFragmentUniformVectors = sw::FRAGMENT_UNIFORM_VECTORS - 3;
-               resources.MaxDrawBuffers = sw::RENDERTARGETS;
-               resources.MaxVertexOutputVectors = 16; // ???
-               resources.MaxFragmentInputVectors = 15; // ???
-               resources.MinProgramTexelOffset = sw::MIN_PROGRAM_TEXEL_OFFSET;
-               resources.MaxProgramTexelOffset = sw::MAX_PROGRAM_TEXEL_OFFSET;
-               resources.OES_standard_derivatives = 1;
-               resources.OES_fragment_precision_high = 1;
-               resources.OES_EGL_image_external = 1;
-               resources.EXT_draw_buffers = 1;
-               resources.MaxCallStackDepth = 16;
-
-               glslCompiler->Init(resources);
+       // Data layout:
+       //
+       // byte: boolean states
+       // {
+       //   byte: stream type
+       //   byte: stream count and normalized
+       // } [MAX_VERTEX_INPUTS]
+       // {
+       //   byte[32]: reserved sampler state
+       // } [VERTEX_TEXTURE_IMAGE_UNITS]
+
+       const int state_size = 1 + 2 * sw::MAX_VERTEX_INPUTS + 32 * sw::VERTEX_TEXTURE_IMAGE_UNITS;
+
+       if(size < state_size)
+       {
+               return 0;
        }
 
-       sw::VertexProcessor::State state;
+       state.textureSampling = bytecodeShader->containsTextureSampling();
+       state.positionRegister = bytecodeShader->getPositionRegister();
+       state.pointSizeRegister = bytecodeShader->getPointSizeRegister();
 
-       // TODO fill in the state
+       state.preTransformed = (data[0] & 0x01) != 0;
+       state.superSampling = (data[0] & 0x02) != 0;
+       state.multiSampling = (data[0] & 0x04) != 0;
 
-       const char* glslSource = "void main() {gl_Position = vec4(1.0);}";
+       state.transformFeedbackQueryEnabled = (data[0] & 0x08) != 0;
+       state.transformFeedbackEnabled = (data[0] & 0x10) != 0;
+       state.verticesPerPrimitive = 1 + ((data[0] & 0x20) != 0) + ((data[0] & 0x40) != 0);
 
-       if (!glslCompiler->compile(&glslSource, 1, SH_OBJECT_CODE)) {
+       if((data[0] & 0x80) != 0)   // Unused/reserved.
+       {
                return 0;
        }
 
+       struct Stream
+       {
+               uint8_t count : BITS(sw::STREAMTYPE_LAST);
+               bool normalized;
+               uint8_t reserved : 8 - BITS(sw::STREAMTYPE_LAST) - 1;
+       };
+
+       for(int i = 0; i < sw::MAX_VERTEX_INPUTS; i++)
+       {
+               sw::StreamType type = (sw::StreamType)data[1 + 2 * i + 0];
+               Stream stream = (Stream&)data[1 + 2 * i + 1];
+
+               if(type > sw::STREAMTYPE_LAST) return 0;
+               if(stream.count > 4) return 0;
+               if(stream.reserved != 0) return 0;
+
+               state.input[i].type = type;
+               state.input[i].count = stream.count;
+               state.input[i].normalized = stream.normalized;
+               state.input[i].attribType = bytecodeShader->getAttribType(i);
+       }
+
+       for(unsigned int i = 0; i < sw::VERTEX_TEXTURE_IMAGE_UNITS; i++)
+       {
+               // TODO
+       //      if(bytecodeShader->usesSampler(i))
+       //      {
+       //              state.samplerState[i] = context->sampler[sw::TEXTURE_IMAGE_UNITS + i].samplerState();
+       //      }
+
+               for(int j = 0; j < 32; j++)
+               {
+                       if(data[1 + 2 * sw::MAX_VERTEX_INPUTS + 32 * i + j] != 0)
+                       {
+                               return 0;
+                       }
+               }
+       }
+
+       for(int i = 0; i < sw::MAX_VERTEX_OUTPUTS; i++)
+       {
+               state.output[i].xWrite = bytecodeShader->getOutput(i, 0).active();
+               state.output[i].yWrite = bytecodeShader->getOutput(i, 1).active();
+               state.output[i].zWrite = bytecodeShader->getOutput(i, 2).active();
+               state.output[i].wWrite = bytecodeShader->getOutput(i, 3).active();
+       }
+
        sw::VertexProgram program(state, bytecodeShader.get());
        program.generate();