mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 20:38:06 +02:00
r300: move shadow lowering to NIR
This means we now do fragment shader-variants at the NIR level and we therefore need to run nir_to_rc translation later during the shader variant creation. This is a temporary instruction count as well as registers count regression, due to NIR putting everything to x instead of w, this is fixed in the next commit which also shows some nice shader-db stats improvements in total. Signed-off-by: Pavel Ondračka <pavel.ondracka@gmail.com> Reviewed-by: Filip Gawin <None> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33066>
This commit is contained in:
parent
ea41ecd130
commit
296da387c0
6 changed files with 78 additions and 26 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue