#include "compiler/nir/nir.h"
#include "compiler/nir/nir_control_flow.h"
#include "compiler/nir/nir_builder.h"
-#include "compiler/glsl/gl_nir.h"
-#include "compiler/glsl/list.h"
#include "compiler/shader_enums.h"
#include "tgsi_to_nir.h"
/* How many TGSI_FILE_IMMEDIATE vec4s have been parsed so far. */
unsigned next_imm;
- bool cap_scalar;
bool cap_face_is_sysval;
bool cap_position_is_sysval;
bool cap_point_is_sysval;
case TGSI_SEMANTIC_PSIZE:
return VARYING_SLOT_PSIZ;
case TGSI_SEMANTIC_GENERIC:
+ assert(index < 32);
return VARYING_SLOT_VAR0 + index;
case TGSI_SEMANTIC_FACE:
return VARYING_SLOT_FACE;
case TGSI_SEMANTIC_CLIPVERTEX:
return VARYING_SLOT_CLIP_VERTEX;
case TGSI_SEMANTIC_TEXCOORD:
+ assert(index < 8);
return VARYING_SLOT_TEX0 + index;
case TGSI_SEMANTIC_PCOORD:
return VARYING_SLOT_PNTC;
case TGSI_INTERPOLATE_PERSPECTIVE:
return INTERP_MODE_SMOOTH;
case TGSI_INTERPOLATE_COLOR:
- return INTERP_MODE_SMOOTH;
+ return INTERP_MODE_NONE;
default:
unreachable("bad TGSI interpolation mode");
}
} else {
var->data.location =
tgsi_varying_semantic_to_slot(semantic_name, semantic_index);
+ if (var->data.location == VARYING_SLOT_FOGC ||
+ var->data.location == VARYING_SLOT_PSIZ) {
+ var->type = glsl_float_type();
+ }
}
if (is_array) {
unreachable("bad system value");
}
+ if (load->num_components == 2)
+ load = nir_swizzle(b, load, SWIZ(X, Y, Y, Y), 4);
+ else if (load->num_components == 3)
+ load = nir_swizzle(b, load, SWIZ(X, Y, Z, Z), 4);
+
src = nir_src_for_ssa(load);
b->shader->info.system_values_read |=
- (1 << nir_system_value_from_intrinsic(op));
+ (1ull << nir_system_value_from_intrinsic(op));
break;
}
static void
ttn_kill_if(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
{
+ /* flt must be exact, because NaN shouldn't discard. (apps rely on this) */
+ b->exact = true;
nir_ssa_def *cmp = nir_bany(b, nir_flt(b, src[0], nir_imm_float(b, 0.0)));
+ b->exact = false;
+
nir_intrinsic_instr *discard =
nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard_if);
discard->src[0] = nir_src_for_ssa(cmp);
enum glsl_sampler_dim dim,
bool is_shadow,
bool is_array,
- enum glsl_base_type base_type)
+ enum glsl_base_type base_type,
+ nir_texop op)
{
nir_variable *var = c->samplers[binding];
if (!var) {
var->data.binding = binding;
var->data.explicit_binding = true;
c->samplers[binding] = var;
+
+ /* Record textures used */
+ unsigned mask = 1 << binding;
+ c->build.shader->info.textures_used |= mask;
+ if (op == nir_texop_txf ||
+ op == nir_texop_txf_ms ||
+ op == nir_texop_txf_ms_mcs)
+ c->build.shader->info.textures_used_by_txf |= mask;
}
return var;
var = nir_variable_create(c->build.shader, nir_var_uniform, type, "image");
var->data.binding = binding;
var->data.explicit_binding = true;
- var->data.image.access = access;
+ var->data.access = access;
var->data.image.format = format;
c->images[binding] = var;
}
get_sampler_var(c, sview, instr->sampler_dim,
instr->is_shadow,
instr->is_array,
- base_type_for_alu_type(instr->dest_type));
+ base_type_for_alu_type(instr->dest_type),
+ op);
nir_deref_instr *deref = nir_build_deref_var(b, var);
get_sampler_var(c, tex_index, txs->sampler_dim,
txs->is_shadow,
txs->is_array,
- base_type_for_alu_type(txs->dest_type));
+ base_type_for_alu_type(txs->dest_type),
+ nir_texop_txs);
nir_deref_instr *deref = nir_build_deref_var(b, var);
get_image_format(struct tgsi_full_instruction *tgsi_inst)
{
switch (tgsi_inst->Memory.Format) {
+ case PIPE_FORMAT_NONE:
+ return GL_NONE;
+
case PIPE_FORMAT_R8_UNORM:
return GL_R8;
case PIPE_FORMAT_R8G8_UNORM:
nir_deref_instr *image_deref = nir_build_deref_var(b, image);
const struct glsl_type *type = image_deref->type;
- nir_intrinsic_set_access(instr, image_deref->var->data.image.access);
+ nir_intrinsic_set_access(instr, image_deref->var->data.access);
instr->src[0] = nir_src_for_ssa(&image_deref->dest.ssa);
instr->src[1] = nir_src_for_ssa(src[addr_src_index]);
if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_LOAD) {
- nir_ssa_dest_init(&instr->instr, &instr->dest,
- util_last_bit(tgsi_inst->Dst[0].Register.WriteMask),
+ nir_ssa_dest_init(&instr->instr, &instr->dest, instr->num_components,
32, NULL);
nir_builder_instr_insert(b, &instr->instr);
ttn_move_dest(b, dest, &instr->dest.ssa);
store_value = nir_channel(b, store_value, 2);
else if (var->data.location == FRAG_RESULT_STENCIL)
store_value = nir_channel(b, store_value, 1);
+ } else {
+ /* FOGC and PSIZ are scalar values */
+ if (var->data.location == VARYING_SLOT_FOGC ||
+ var->data.location == VARYING_SLOT_PSIZ) {
+ store_value = nir_channel(b, store_value, 0);
+ }
}
nir_store_deref(b, nir_build_deref_var(b, var), store_value,
ttn_read_pipe_caps(struct ttn_compile *c,
struct pipe_screen *screen)
{
- c->cap_scalar = screen->get_shader_param(screen, c->scan->processor, PIPE_SHADER_CAP_SCALAR_ISA);
c->cap_packed_uniforms = screen->get_param(screen, PIPE_CAP_PACKED_UNIFORMS);
c->cap_samplers_as_deref = screen->get_param(screen, PIPE_CAP_NIR_SAMPLERS_AS_DEREF);
c->cap_face_is_sysval = screen->get_param(screen, PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL);
s->num_inputs = scan.file_max[TGSI_FILE_INPUT] + 1;
s->num_uniforms = scan.const_file_max[0] + 1;
s->num_outputs = scan.file_max[TGSI_FILE_OUTPUT] + 1;
+ s->info.num_ssbos = util_last_bit(scan.shader_buffers_declared);
+ s->info.num_ubos = util_last_bit(scan.const_buffers_declared >> 1);
+ s->info.num_images = util_last_bit(scan.images_declared);
+ s->info.num_textures = util_last_bit(scan.samplers_declared);
for (unsigned i = 0; i < TGSI_PROPERTY_COUNT; i++) {
unsigned value = scan.properties[i];
case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
break; /* handled in ttn_emit_declaration */
case TGSI_PROPERTY_FS_COORD_ORIGIN:
- s->info.fs.origin_upper_left = value == TGSI_FS_COORD_ORIGIN_UPPER_LEFT;
+ if (s->info.stage == MESA_SHADER_FRAGMENT)
+ s->info.fs.origin_upper_left = value == TGSI_FS_COORD_ORIGIN_UPPER_LEFT;
break;
case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
- s->info.fs.pixel_center_integer = value == TGSI_FS_COORD_PIXEL_CENTER_INTEGER;
+ if (s->info.stage == MESA_SHADER_FRAGMENT)
+ s->info.fs.pixel_center_integer = value == TGSI_FS_COORD_PIXEL_CENTER_INTEGER;
break;
case TGSI_PROPERTY_FS_DEPTH_LAYOUT:
- s->info.fs.depth_layout = ttn_get_depth_layout(value);
+ if (s->info.stage == MESA_SHADER_FRAGMENT)
+ s->info.fs.depth_layout = ttn_get_depth_layout(value);
break;
case TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION:
- s->info.vs.window_space_position = value;
+ if (s->info.stage == MESA_SHADER_VERTEX)
+ s->info.vs.window_space_position = value;
break;
case TGSI_PROPERTY_NEXT_SHADER:
s->info.next_stage = tgsi_processor_to_shader_stage(value);
break;
case TGSI_PROPERTY_VS_BLIT_SGPRS_AMD:
- s->info.vs.blit_sgprs_amd = value;
+ if (s->info.stage == MESA_SHADER_VERTEX)
+ s->info.vs.blit_sgprs_amd = value;
break;
case TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH:
- s->info.cs.local_size[0] = value;
+ if (s->info.stage == MESA_SHADER_COMPUTE)
+ s->info.cs.local_size[0] = value;
break;
case TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT:
- s->info.cs.local_size[1] = value;
+ if (s->info.stage == MESA_SHADER_COMPUTE)
+ s->info.cs.local_size[1] = value;
break;
case TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH:
- s->info.cs.local_size[2] = value;
+ if (s->info.stage == MESA_SHADER_COMPUTE)
+ s->info.cs.local_size[2] = value;
break;
case TGSI_PROPERTY_CS_USER_DATA_COMPONENTS_AMD:
- s->info.cs.user_data_components_amd = value;
+ if (s->info.stage == MESA_SHADER_COMPUTE)
+ s->info.cs.user_data_components_amd = value;
break;
default:
if (value) {
}
static void
-ttn_optimize_nir(nir_shader *nir, bool scalar)
+ttn_optimize_nir(nir_shader *nir)
{
bool progress;
do {
NIR_PASS_V(nir, nir_lower_vars_to_ssa);
- if (scalar) {
- NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL);
+ if (nir->options->lower_to_scalar) {
+ NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL, NULL);
NIR_PASS_V(nir, nir_lower_phis_to_scalar);
}
* so we have to do it here too.
*/
static void
-ttn_finalize_nir(struct ttn_compile *c)
+ttn_finalize_nir(struct ttn_compile *c, struct pipe_screen *screen)
{
struct nir_shader *nir = c->build.shader;
if (c->cap_packed_uniforms)
NIR_PASS_V(nir, nir_lower_uniforms_to_ubo, 16);
- if (c->cap_samplers_as_deref)
- NIR_PASS_V(nir, gl_nir_lower_samplers_as_deref, NULL);
- else
- NIR_PASS_V(nir, gl_nir_lower_samplers, NULL);
+ if (!c->cap_samplers_as_deref)
+ NIR_PASS_V(nir, nir_lower_samplers);
+
+ if (screen->finalize_nir) {
+ screen->finalize_nir(screen, nir, true);
+ } else {
+ ttn_optimize_nir(nir);
+ nir_shader_gather_info(nir, c->build.impl);
+ }
- ttn_optimize_nir(nir, c->cap_scalar);
- nir_shader_gather_info(nir, c->build.impl);
nir_validate_shader(nir, "TTN: after all optimizations");
}
c = ttn_compile_init(tgsi_tokens, NULL, screen);
s = c->build.shader;
- ttn_finalize_nir(c);
+ ttn_finalize_nir(c, screen);
ralloc_free(c);
return s;