boolean r300_pick_fragment_shader(struct r300_context* r300) { struct r300_fragment_shader* fs = r300_fs(r300); struct r300_fragment_program_external_state state = {{{ 0 }}}; struct r300_fragment_shader_code* ptr; get_external_state(r300, &state); if (!fs->first) { /* Build the fragment shader for the first time. */ fs->first = fs->shader = CALLOC_STRUCT(r300_fragment_shader_code); memcpy(&fs->shader->compare_state, &state, sizeof(struct r300_fragment_program_external_state)); r300_translate_fragment_shader(r300, fs->shader, fs->state.tokens); return TRUE; } else { /* Check if the currently-bound shader has been compiled * with the texture-compare state we need. */ if (memcmp(&fs->shader->compare_state, &state, sizeof(state)) != 0) { /* Search for the right shader. */ ptr = fs->first; while (ptr) { if (memcmp(&ptr->compare_state, &state, sizeof(state)) == 0) { if (fs->shader != ptr) { fs->shader = ptr; return TRUE; } /* The currently-bound one is OK. */ return FALSE; } ptr = ptr->next; } /* Not found, gotta compile a new one. */ ptr = CALLOC_STRUCT(r300_fragment_shader_code); ptr->next = fs->first; fs->first = fs->shader = ptr; ptr->compare_state = state; r300_translate_fragment_shader(r300, ptr, fs->state.tokens); return TRUE; } } return FALSE; }
/* Bind fragment shader state. */ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) { struct r300_context* r300 = r300_context(pipe); struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; if (fs == NULL) { r300->fs = NULL; return; } else if (!fs->translated) { r300_translate_fragment_shader(r300, fs); } r300->fs = fs; r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS; }
static void r300_dummy_fragment_shader( struct r300_context* r300, struct r300_fragment_shader_code* shader) { struct pipe_shader_state state; struct ureg_program *ureg; struct ureg_dst out; struct ureg_src imm; /* Make a simple fragment shader which outputs (0, 0, 0, 1) */ ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); imm = ureg_imm4f(ureg, 0, 0, 0, 1); ureg_MOV(ureg, out, imm); ureg_END(ureg); state.tokens = ureg_finalize(ureg); shader->dummy = TRUE; r300_translate_fragment_shader(r300, shader, state.tokens); ureg_destroy(ureg); }