diff --git a/src/gallium/drivers/r300/ci/r300-rv530-nohiz-fails.txt b/src/gallium/drivers/r300/ci/r300-rv530-nohiz-fails.txt index 574642a47a0..a2866170099 100644 --- a/src/gallium/drivers/r300/ci/r300-rv530-nohiz-fails.txt +++ b/src/gallium/drivers/r300/ci/r300-rv530-nohiz-fails.txt @@ -739,7 +739,6 @@ spec@glsl-1.10@execution@interpolation@interpolation-none-other-smooth-vertex,Fa # HW limitation (SM3 256 loop iters) spec@glsl-1.10@execution@loops@glsl-fs-loop-300,Fail spec@glsl-1.10@execution@loops@glsl-vs-loop-300,Fail - spec@glsl-1.10@execution@variable-indexing@vs-output-array-vec2-index-wr-no-unroll,Fail # HW limitation (no support for gl_ClipVertex) diff --git a/src/gallium/drivers/r300/compiler/nir_to_rc.c b/src/gallium/drivers/r300/compiler/nir_to_rc.c index e4c26c4b8fa..7cdc7d93620 100644 --- a/src/gallium/drivers/r300/compiler/nir_to_rc.c +++ b/src/gallium/drivers/r300/compiler/nir_to_rc.c @@ -8,6 +8,10 @@ #include "compiler/nir/nir_deref.h" #include "compiler/nir/nir_legacy.h" #include "compiler/nir/nir_worklist.h" +#include "compiler/radeon_code.h" +#include "compiler/radeon_program_constants.h" +#include "r300_nir.h" +#include "r300_screen.h" #include "pipe/p_screen.h" #include "pipe/p_state.h" #include "tgsi/tgsi_dump.h" @@ -803,8 +807,7 @@ ntr_setup_uniforms(struct ntr_compile *c) const struct glsl_type *stype = glsl_without_array(var->type); enum tgsi_texture_type target = tgsi_texture_type_from_sampler_dim( - glsl_get_sampler_dim(stype), glsl_sampler_type_is_array(stype), - glsl_sampler_type_is_shadow(stype)); + glsl_get_sampler_dim(stype), glsl_sampler_type_is_array(stype), false); enum tgsi_return_type ret_type = tgsi_return_type_from_base_type(glsl_get_sampler_result_type(stype)); for (int i = 0; i < size; i++) { @@ -2240,7 +2243,8 @@ nir_to_rc_lower_txp(nir_shader *s) * TGSI tokens instead. If you need to keep the NIR, then pass us a clone. */ const void * -nir_to_rc(struct nir_shader *s, struct pipe_screen *screen) +nir_to_rc(struct nir_shader *s, struct pipe_screen *screen, + struct r300_fragment_program_external_state state) { struct ntr_compile *c; const void *tgsi_tokens; @@ -2286,8 +2290,27 @@ nir_to_rc(struct nir_shader *s, struct pipe_screen *screen) NIR_PASS_V(s, nir_lower_io, nir_var_shader_in | nir_var_shader_out, type_size, nir_lower_io_use_interpolated_input_intrinsics); - nir_to_rc_lower_txp(s); - NIR_PASS_V(s, nir_to_rc_lower_tex); + if (s->info.stage == MESA_SHADER_FRAGMENT) { + /* Shadow lowering. */ + int num_texture_states = state.sampler_state_count; + if (num_texture_states > 0) { + nir_lower_tex_shadow_swizzle tex_swizzle[PIPE_MAX_SHADER_SAMPLER_VIEWS]; + enum compare_func tex_compare_func[PIPE_MAX_SHADER_SAMPLER_VIEWS]; + + for (unsigned i = 0; i < num_texture_states; i++) { + tex_compare_func[i] = state.unit[i].texture_compare_func; + tex_swizzle[i].swizzle_r = GET_SWZ(state.unit[i].texture_swizzle, 0); + tex_swizzle[i].swizzle_g = GET_SWZ(state.unit[i].texture_swizzle, 1); + tex_swizzle[i].swizzle_b = GET_SWZ(state.unit[i].texture_swizzle, 2); + tex_swizzle[i].swizzle_a = GET_SWZ(state.unit[i].texture_swizzle, 3); + } + NIR_PASS_V(s, nir_lower_tex_shadow, num_texture_states, tex_compare_func, + tex_swizzle, true); + } + + nir_to_rc_lower_txp(s); + NIR_PASS_V(s, nir_to_rc_lower_tex); + } bool progress; do { diff --git a/src/gallium/drivers/r300/compiler/nir_to_rc.h b/src/gallium/drivers/r300/compiler/nir_to_rc.h index 2b82bc3494d..d79e5eb3634 100644 --- a/src/gallium/drivers/r300/compiler/nir_to_rc.h +++ b/src/gallium/drivers/r300/compiler/nir_to_rc.h @@ -11,7 +11,9 @@ struct nir_shader; struct pipe_screen; +struct r300_fragment_program_external_state; -const void *nir_to_rc(struct nir_shader *s, struct pipe_screen *screen); +const void *nir_to_rc(struct nir_shader *s, struct pipe_screen *screen, + struct r300_fragment_program_external_state state); #endif /* NIR_TO_RC_H */ diff --git a/src/gallium/drivers/r300/compiler/radeon_code.h b/src/gallium/drivers/r300/compiler/radeon_code.h index 3d9920b8da4..b5400f8f1ab 100644 --- a/src/gallium/drivers/r300/compiler/radeon_code.h +++ b/src/gallium/drivers/r300/compiler/radeon_code.h @@ -160,6 +160,8 @@ struct r300_fragment_program_external_state { } unit[16]; unsigned alpha_to_one : 1; + + int sampler_state_count; }; struct r300_fragment_program_node { diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index 3933274c238..3c362cf3153 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -22,6 +22,8 @@ #include "r300_tgsi_to_rc.h" #include "compiler/radeon_compiler.h" +#include "compiler/nir_to_rc.h" +#include "nir.h" /* Convert info about FS input semantics to r300_shader_semantics. */ void r300_shader_read_fs_inputs(struct tgsi_shader_info* info, @@ -151,6 +153,7 @@ void r300_fragment_program_get_external_state( unsigned i; state->alpha_to_one = r300->alpha_to_one && r300->msaa_enable; + state->sampler_state_count = texstate->sampler_state_count; for (i = 0; i < texstate->sampler_state_count; i++) { struct r300_sampler_state *s = texstate->sampler_states[i]; @@ -207,7 +210,7 @@ void r300_fragment_program_get_external_state( static void r300_translate_fragment_shader( struct r300_context* r300, struct r300_fragment_shader_code* shader, - const struct tgsi_token *tokens); + struct pipe_shader_state state); static void r300_dummy_fragment_shader( struct r300_context* r300, @@ -229,7 +232,7 @@ static void r300_dummy_fragment_shader( state.tokens = ureg_finalize(ureg); shader->dummy = true; - r300_translate_fragment_shader(r300, shader, state.tokens); + r300_translate_fragment_shader(r300, shader, state); ureg_destroy(ureg); } @@ -416,14 +419,19 @@ static void r300_emit_fs_code_to_buffer( static void r300_translate_fragment_shader( struct r300_context* r300, struct r300_fragment_shader_code* shader, - const struct tgsi_token *tokens) + struct pipe_shader_state state) { struct r300_fragment_program_compiler compiler; struct tgsi_to_rc ttr; int wpos, face; unsigned i; - tgsi_scan_shader(tokens, &shader->info); + if (state.type == PIPE_SHADER_IR_NIR) { + nir_shader *clone = nir_shader_clone(NULL, state.ir.nir); + state.tokens = nir_to_rc(clone, (struct pipe_screen *)r300->screen, shader->compare_state); + } + + tgsi_scan_shader(state.tokens, &shader->info); r300_shader_read_fs_inputs(&shader->info, &shader->inputs); wpos = shader->inputs.wpos; @@ -461,14 +469,18 @@ static void r300_translate_fragment_shader( if (compiler.Base.Debug & RC_DBG_LOG) { DBG(r300, DBG_FP, "r300: Initial fragment program\n"); - tgsi_dump(tokens, 0); + tgsi_dump(state.tokens, 0); } /* Translate TGSI to our internal representation */ ttr.compiler = &compiler.Base; ttr.info = &shader->info; - r300_tgsi_to_rc(&ttr, tokens); + r300_tgsi_to_rc(&ttr, state.tokens); + + if (state.type == PIPE_SHADER_IR_NIR) { + FREE((void*)state.tokens); + } if (ttr.error) { fprintf(stderr, "r300 FP: Cannot translate a shader. " @@ -576,7 +588,7 @@ bool r300_pick_fragment_shader(struct r300_context *r300, fs->first = fs->shader = CALLOC_STRUCT(r300_fragment_shader_code); memcpy(&fs->shader->compare_state, state, sizeof(*state)); - r300_translate_fragment_shader(r300, fs->shader, fs->state.tokens); + r300_translate_fragment_shader(r300, fs->shader, fs->state); return true; } else { @@ -603,7 +615,7 @@ bool r300_pick_fragment_shader(struct r300_context *r300, fs->first = fs->shader = ptr; memcpy(&ptr->compare_state, state, sizeof(*state)); - r300_translate_fragment_shader(r300, ptr, fs->state.tokens); + r300_translate_fragment_shader(r300, ptr, fs->state); return true; } } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index eba1da947e2..d6ba6f9aa7b 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1029,7 +1029,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe, fs->state = *shader; if (fs->state.type == PIPE_SHADER_IR_NIR) { - fs->state.tokens = nir_to_rc(shader->ir.nir, pipe->screen); + //fs->state.tokens = nir_to_rc(shader->ir.nir, pipe->screen); } else { assert(fs->state.type == PIPE_SHADER_IR_TGSI); /* we need to keep a local copy of the tokens */ @@ -1042,14 +1042,23 @@ static void* r300_create_fs_state(struct pipe_context* pipe, struct r300_fragment_program_external_state precompile_state; memset(&precompile_state, 0, sizeof(precompile_state)); - struct tgsi_shader_info info; - tgsi_scan_shader(fs->state.tokens, &info); - for (int i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) { - if (info.sampler_targets[i] == TGSI_TEXTURE_SHADOW1D || - info.sampler_targets[i] == TGSI_TEXTURE_SHADOW2D || - info.sampler_targets[i] == TGSI_TEXTURE_SHADOWRECT) { - precompile_state.unit[i].compare_mode_enabled = true; - precompile_state.unit[i].texture_compare_func = PIPE_FUNC_LESS; + if (fs->state.type == PIPE_SHADER_IR_NIR) { + /* Pick something for the shadow samplers so that we have somewhat reliable shader stats later. */ + nir_foreach_function_impl(impl, shader->ir.nir) { + nir_foreach_block_safe(block, impl) { + nir_foreach_instr_safe(instr, block) { + if (instr->type != nir_instr_type_tex) + continue; + nir_tex_instr *tex = nir_instr_as_tex(instr); + + if (tex->is_shadow) { + precompile_state.unit[tex->sampler_index].compare_mode_enabled = true; + precompile_state.unit[tex->sampler_index].texture_compare_func = PIPE_FUNC_LESS; + } + precompile_state.sampler_state_count = MAX2(tex->sampler_index + 1, + precompile_state.sampler_state_count); + } + } } } r300_pick_fragment_shader(r300, fs, &precompile_state); @@ -1110,7 +1119,11 @@ static void r300_delete_fs_state(struct pipe_context* pipe, void* shader) FREE(tmp->cb_code); FREE(tmp); } - FREE((void*)fs->state.tokens); + if (fs->state.type == PIPE_SHADER_IR_NIR) { + ralloc_free(fs->state.ir.nir); + } else { + FREE((void*)fs->state.tokens); + } FREE(shader); } @@ -1921,7 +1934,8 @@ static void* r300_create_vs_state(struct pipe_context* pipe, vs->state = *shader; if (vs->state.type == PIPE_SHADER_IR_NIR) { - vs->state.tokens = nir_to_rc(shader->ir.nir, pipe->screen); + struct r300_fragment_program_external_state state = {}; + vs->state.tokens = nir_to_rc(shader->ir.nir, pipe->screen, state); } else { assert(vs->state.type == PIPE_SHADER_IR_TGSI); /* we need to keep a local copy of the tokens */