From: Nicolas Capens Date: Fri, 27 Oct 2017 18:36:52 +0000 (-0400) Subject: Fill vertex routine state for fuzzer. X-Git-Tag: android-x86-7.1-r3~329 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=b6f0e40bbe40613f6ba0ff4c13f4ff2c06d6517a;p=android-x86%2Fexternal-swiftshader.git Fill vertex routine state for fuzzer. Bug swiftshader:86 Change-Id: I8339f3882163daa078ac71034aaf37147e51d725 Reviewed-on: https://swiftshader-review.googlesource.com/13349 Tested-by: Nicolas Capens Reviewed-by: Alexis Hétu Reviewed-by: Nicolas Capens --- diff --git a/tests/fuzzers/VertexRoutineFuzzer.cpp b/tests/fuzzers/VertexRoutineFuzzer.cpp index 986f839d2..af6dc4b03 100644 --- a/tests/fuzzers/VertexRoutineFuzzer.cpp +++ b/tests/fuzzers/VertexRoutineFuzzer.cpp @@ -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 allocatorAndTLS; -std::unique_ptr bytecodeShader; -std::unique_ptr fakeVS; -std::unique_ptr 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 allocatorAndTLS(new ScopedPoolAllocatorAndTLS); + std::unique_ptr shader(new sw::VertexShader); + std::unique_ptr fakeVS(new FakeVS(shader.get())); + + std::unique_ptr 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 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();