예제 #1
0
void MOJOSHADER_freeEffect(const MOJOSHADER_effect *_effect)
{
    MOJOSHADER_effect *effect = (MOJOSHADER_effect *) _effect;
    if ((effect == NULL) || (effect == &MOJOSHADER_out_of_mem_effect))
        return;  // no-op.

    MOJOSHADER_free f = effect->free;
    void *d = effect->malloc_data;
    int i, j;

    for (i = 0; i < effect->error_count; i++)
    {
        f((void *) effect->errors[i].error, d);
        f((void *) effect->errors[i].filename, d);
    } // for
    f((void *) effect->errors, d);

    f((void *) effect->profile, d);

    for (i = 0; i < effect->param_count; i++)
    {
        f((void *) effect->params[i].name, d);
        f((void *) effect->params[i].semantic, d);
    } // for
    f(effect->params, d);

    for (i = 0; i < effect->technique_count; i++)
    {
        MOJOSHADER_effectTechnique *technique = &effect->techniques[i];
        f((void *) technique->name, d);
        for (j = 0; j < technique->pass_count; j++)
        {
            f((void *) technique->passes[j].name, d);
            f(technique->passes[j].states, d);
        } // for
        f(technique->passes, d);
    } // for

    f(effect->techniques, d);

    for (i = 0; i < effect->texture_count; i++)
        f((void *) effect->textures[i].name, d);
    f(effect->textures, d);

    for (i = 0; i < effect->shader_count; i++)
        MOJOSHADER_freeParseData(effect->shaders[i].shader);
    f(effect->shaders, d);

    f(effect, d);
} // MOJOSHADER_freeEffect
static int assemble(const char *fname, const char *buf, int len,
                    const char *outfile,
                    const MOJOSHADER_preprocessorDefine *defs,
                    unsigned int defcount, FILE *io)
{
    const MOJOSHADER_parseData *pd;
    int retval = 0;

    pd = MOJOSHADER_assemble(fname, buf, len, NULL, 0, NULL, 0,
                             defs, defcount, open_include, close_include,
                             Malloc, Free, NULL);

    if (pd->error_count > 0)
    {
        int i;
        for (i = 0; i < pd->error_count; i++)
        {
            fprintf(stderr, "%s:%d: ERROR: %s\n",
                    pd->errors[i].filename ? pd->errors[i].filename : "???",
                    pd->errors[i].error_position,
                    pd->errors[i].error);
        } // for
    } // if
    else
    {
        if (pd->output != NULL)
        {
            const int len = pd->output_len;
            if ((len) && (fwrite(pd->output, len, 1, io) != 1))
                printf(" ... fwrite('%s') failed.\n", outfile);
            else if ((outfile != NULL) && (fclose(io) == EOF))
                printf(" ... fclose('%s') failed.\n", outfile);
            else
                retval = 1;
        } // if
    } // else
    MOJOSHADER_freeParseData(pd);

    return retval;
} // assemble
void ShaderVariation::ParseParameters(unsigned char* bufData, unsigned bufSize)
{
    MOJOSHADER_parseData const* parseData = MOJOSHADER_parse("bytecode", bufData, bufSize, 0, 0, 0, 0, 0, 0, 0);

    for (int i = 0; i < parseData->symbol_count; i++)
    {
        MOJOSHADER_symbol const& symbol = parseData->symbols[i];

        String name(symbol.name);
        unsigned reg = symbol.register_index;
        unsigned regCount = symbol.register_count;

        // Check if the parameter is a constant or a texture sampler
        bool isSampler = (name[0] == 's');
        name = name.Substring(1);

        if (isSampler)
        {
            // Skip if it's a G-buffer sampler, which are aliases for the standard texture units
            if (reg < MAX_TEXTURE_UNITS)
            {
                if (name != "AlbedoBuffer" && name != "NormalBuffer" && name != "DepthBuffer" && name != "LightBuffer")
                    useTextureUnit_[reg] = true;
            }
        }
        else
        {
            ShaderParameter parameter;
            parameter.type_ = type_;
            parameter.name_ = name;
            parameter.register_ = reg;
            parameter.regCount_ = regCount;
            parameters_[StringHash(name)] = parameter;
        }
    }

    MOJOSHADER_freeParseData(parseData);
}
예제 #4
0
static int do_file(const char *profile, const char *dname, const char *fn, int *total)
{
    int do_quit = 0;

    #if FINDERRORS_COMPILE_SHADERS
    SDL_Event e;  // pump event queue to keep OS happy.
    while (SDL_PollEvent(&e))
    {
        if (e.type == SDL_QUIT)
            do_quit = 1;
    } // while
    SDL_GL_SwapBuffers();
    #endif

    if (do_quit)
    {
        report("FAIL: user requested quit!\n");
        return 0;
    } // if

    int assembly = 0;
    if (strstr(fn, ".bytecode") != NULL)
        assembly = 0;
    else if (strstr(fn, ".disasm") != NULL)
        assembly = 1;
    else
        return 1;

    (*total)++;

    char *fname = (char *) alloca(strlen(fn) + strlen(dname) + 1);
    sprintf(fname, "%s/%s", dname, fn);
    FILE *io = fopen(fname, "rb");
    if (io == NULL)
    {
        report("FAIL: %s fopen() failed.\n", fname);
        return 1;
    } // if

    static unsigned char buf[1024 * 256];
    int rc = fread(buf, 1, sizeof (buf), io);
    fclose(io);
    if (rc == -1)
    {
        report("FAIL: %s %s\n", fname, strerror(errno));
        return 1;
    } // if

    if (assembly)
    {
        const MOJOSHADER_parseData *a;

        buf[rc] = '\0';  // make sure the source is null-terminated.
        a = MOJOSHADER_assemble(fname, (char *) buf, rc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

        if (a->error_count > 0)
        {
            report("FAIL: %s (line %d) %s\n",
                a->errors[0].filename ? a->errors[0].filename : "???",
                a->errors[0].error_position,
                a->errors[0].error);
            return 1;
        } // if

        else if (a->output_len > sizeof (buf))
        {
            report("FAIL: %s buffer overflow in finderrors.c\n", fname);
            return 1;
        } // if

        rc = a->output_len;
        memcpy(buf, a->output, rc);
        MOJOSHADER_freeParseData(a);
    } // if

    #if FINDERRORS_COMPILE_SHADERS
    MOJOSHADER_glShader *shader = MOJOSHADER_glCompileShader(buf, rc, NULL, 0);
    if (shader == NULL)
        report("FAIL: %s %s\n", fname, MOJOSHADER_glGetError());
    else
    {
        const MOJOSHADER_parseData *pd = MOJOSHADER_glGetShaderParseData(shader);
        MOJOSHADER_glShader *v = (pd->shader_type == MOJOSHADER_TYPE_VERTEX) ? shader : NULL;
        MOJOSHADER_glShader *p = (pd->shader_type == MOJOSHADER_TYPE_PIXEL) ? shader : NULL;
        MOJOSHADER_glProgram *program = MOJOSHADER_glLinkProgram(v, p);
        if (program == NULL)
            report("FAIL: %s %s\n", fname, MOJOSHADER_glGetError());
        else
        {
            report("PASS: %s\n", fname);
            MOJOSHADER_glDeleteProgram(program);
        } // else
        MOJOSHADER_glDeleteShader(shader);
    }
    #else
    const MOJOSHADER_parseData *pd = MOJOSHADER_parse(profile, buf, rc, NULL, 0, NULL, NULL, NULL);
    if (pd->error_count == 0)
        report("PASS: %s\n", fname);
	else
	{
		int i;
		for (i = 0; i < pd->error_count; i++)
		{
			report("FAIL: %s (position %d) %s\n", pd->errors[i].filename,
			       pd->errors[i].error_position, pd->errors[i].error);
		} // for
	} // else
    MOJOSHADER_freeParseData(pd);
    #endif

    return 1;
} // do_file