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); }
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