#include "r300_context.h"
#include "r300_screen.h"
#include "r300_fs.h"
+#include "r300_reg.h"
#include "r300_tgsi_to_rc.h"
#include "radeon_code.h"
}
}
-static void get_compare_state(
+static void get_external_state(
struct r300_context* r300,
- struct r300_fragment_program_external_state* state,
- unsigned shadow_samplers)
+ struct r300_fragment_program_external_state* state)
{
- struct r300_textures_state *texstate =
- (struct r300_textures_state*)r300->textures_state.state;
-
- memset(state, 0, sizeof(*state));
+ struct r300_textures_state *texstate = r300->textures_state.state;
+ unsigned i;
- for (int i = 0; i < texstate->sampler_state_count; i++) {
+ for (i = 0; i < texstate->sampler_state_count; i++) {
struct r300_sampler_state* s = texstate->sampler_states[i];
- if (s && s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+ if (!s) {
+ continue;
+ }
+
+ if (s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
/* XXX Gallium doesn't provide us with any information regarding
* this mode, so we are screwed. I'm setting 0 = LUMINANCE. */
state->unit[i].depth_texture_mode = 0;
/* Fortunately, no need to translate this. */
state->unit[i].texture_compare_func = s->state.compare_func;
}
+
+ if (texstate->sampler_views[i]) {
+ struct r300_texture *t;
+ t = (struct r300_texture*)texstate->sampler_views[i]->base.texture;
+
+ state->unit[i].fake_npot = t->uses_pitch;
+ }
+ state->unit[i].non_normalized_coords = !s->state.normalized_coords;
+
+ /* XXX this should probably take into account STR, not just S. */
+ switch (s->state.wrap_s) {
+ case PIPE_TEX_WRAP_REPEAT:
+ state->unit[i].wrap_mode = RC_WRAP_REPEAT;
+ break;
+ case PIPE_TEX_WRAP_CLAMP:
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+ state->unit[i].wrap_mode = RC_WRAP_CLAMP;
+ break;
+ case PIPE_TEX_WRAP_MIRROR_REPEAT:
+ case PIPE_TEX_WRAP_MIRROR_CLAMP:
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
+ state->unit[i].wrap_mode = RC_WRAP_MIRROR;
+ break;
+ default:
+ state->unit[i].wrap_mode = RC_WRAP_NONE;
+ break;
+ }
}
}
r300_tgsi_to_rc(&ttr, tokens);
- shader->shadow_samplers = compiler.Base.Program.ShadowSamplers;
-
/**
* Transform the program to support WPOS.
*
"Giving up...\n");
abort();
}
+
+ rc_destroy(&compiler.Base);
r300_dummy_fragment_shader(r300, shader);
+ return;
}
/* Initialize numbers of constants for each type. */
}
}
+ /* Setup shader depth output. */
+ if (shader->code.writes_depth) {
+ shader->fg_depth_src = R300_FG_DEPTH_SRC_SHADER;
+ shader->us_out_w = R300_W_FMT_W24 | R300_W_SRC_US;
+ } else {
+ shader->fg_depth_src = R300_FG_DEPTH_SRC_SCAN;
+ shader->us_out_w = R300_W_FMT_W0 | R300_W_SRC_US;
+ }
+
/* And, finally... */
rc_destroy(&compiler.Base);
}
boolean r300_pick_fragment_shader(struct r300_context* r300)
{
- struct r300_fragment_shader* fs = r300->fs;
- struct r300_fragment_program_external_state state;
+ 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);
- /* BTW shadow samplers will be known after the first translation,
- * therefore we set ~0, which means it should look at all sampler
- * states. This choice doesn't have any impact on the correctness. */
- get_compare_state(r300, &fs->shader->compare_state, ~0);
+ memcpy(&fs->shader->compare_state, &state,
+ sizeof(struct r300_fragment_program_external_state));
r300_translate_fragment_shader(r300, fs->shader, fs->state.tokens);
- fs->shadow_samplers = fs->shader->shadow_samplers;
return TRUE;
- } else if (fs->shadow_samplers) {
- get_compare_state(r300, &state, fs->shadow_samplers);
-
+ } 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) {