Commit b6f0e40b by Nicolas Capens Committed by Nicolas Capens

Fill vertex routine state for fuzzer.

Bug swiftshader:86 Change-Id: I8339f3882163daa078ac71034aaf37147e51d725 Reviewed-on: https://swiftshader-review.googlesource.com/13349Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 73082975
...@@ -62,68 +62,135 @@ class FakeVS : public glsl::Shader { ...@@ -62,68 +62,135 @@ class FakeVS : public glsl::Shader {
return bytecode; return bytecode;
} }
private: private:
sw::VertexShader* bytecode; 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 } // anonymous namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
if (allocatorAndTLS == nullptr) { {
allocatorAndTLS.reset(new ScopedPoolAllocatorAndTLS); 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) { const char* glslSource = "void main() {gl_Position = vec4(1.0);}";
bytecodeShader.reset(new sw::VertexShader);
if (!glslCompiler->compile(&glslSource, 1, SH_OBJECT_CODE))
{
return 0;
} }
if (fakeVS == nullptr) { std::unique_ptr<sw::VertexShader> bytecodeShader(new sw::VertexShader(fakeVS->getVertexShader()));
fakeVS.reset(new FakeVS(bytecodeShader.get()));
} sw::VertexProcessor::State state;
if (glslCompiler == nullptr) { // Data layout:
glslCompiler.reset(new TranslatorASM(fakeVS.get(), GL_VERTEX_SHADER)); //
// byte: boolean states
// TODO(cwallez@google.com): have a function to init to default values somewhere // {
ShBuiltInResources resources; // byte: stream type
resources.MaxVertexAttribs = sw::MAX_VERTEX_INPUTS; // byte: stream count and normalized
resources.MaxVertexUniformVectors = sw::VERTEX_UNIFORM_VECTORS - 3; // } [MAX_VERTEX_INPUTS]
resources.MaxVaryingVectors = MIN(sw::MAX_VERTEX_OUTPUTS, sw::MAX_VERTEX_INPUTS); // {
resources.MaxVertexTextureImageUnits = sw::VERTEX_TEXTURE_IMAGE_UNITS; // byte[32]: reserved sampler state
resources.MaxCombinedTextureImageUnits = sw::TEXTURE_IMAGE_UNITS + sw::VERTEX_TEXTURE_IMAGE_UNITS; // } [VERTEX_TEXTURE_IMAGE_UNITS]
resources.MaxTextureImageUnits = sw::TEXTURE_IMAGE_UNITS;
resources.MaxFragmentUniformVectors = sw::FRAGMENT_UNIFORM_VECTORS - 3; const int state_size = 1 + 2 * sw::MAX_VERTEX_INPUTS + 32 * sw::VERTEX_TEXTURE_IMAGE_UNITS;
resources.MaxDrawBuffers = sw::RENDERTARGETS;
resources.MaxVertexOutputVectors = 16; // ??? if(size < state_size)
resources.MaxFragmentInputVectors = 15; // ??? {
resources.MinProgramTexelOffset = sw::MIN_PROGRAM_TEXEL_OFFSET; return 0;
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);
} }
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; 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()); sw::VertexProgram program(state, bytecodeShader.get());
program.generate(); program.generate();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment