#include "st_format.h"
#include "st_glsl_types.h"
#include "st_nir.h"
+#include "st_shader_cache.h"
#include <algorithm>
uint16_t swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
int negate:4; /**< NEGATE_XYZW mask from mesa */
unsigned abs:1;
- enum glsl_base_type type:4; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
+ enum glsl_base_type type:5; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
unsigned has_index2:1;
gl_register_file file:5; /**< PROGRAM_* from Mesa */
/*
int16_t index2D;
gl_register_file file:5; /**< PROGRAM_* from Mesa */
unsigned writemask:4; /**< Bitfield of WRITEMASK_[XYZW] */
- enum glsl_base_type type:4; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
+ enum glsl_base_type type:5; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
unsigned has_index2:1;
unsigned array_id:10;
unsigned sampler_base:5;
unsigned sampler_array_size:6; /**< 1-based size of sampler array, 1 if not array */
unsigned tex_target:4; /**< One of TEXTURE_*_INDEX */
- glsl_base_type tex_type:4;
+ glsl_base_type tex_type:5;
unsigned tex_shadow:1;
unsigned image_format:9;
unsigned tex_offset_num_offset:3;
ralloc_vasprintf_append(&prog->data->InfoLog, fmt, args);
va_end(args);
- prog->data->LinkStatus = GL_FALSE;
+ prog->data->LinkStatus = linking_failure;
}
static int
if (is_resource_instruction(op))
type = src1.type;
+ else if (src0.type == GLSL_TYPE_INT64 || src1.type == GLSL_TYPE_INT64)
+ type = GLSL_TYPE_INT64;
+ else if (src0.type == GLSL_TYPE_UINT64 || src1.type == GLSL_TYPE_UINT64)
+ type = GLSL_TYPE_UINT64;
else if (src0.type == GLSL_TYPE_DOUBLE || src1.type == GLSL_TYPE_DOUBLE)
type = GLSL_TYPE_DOUBLE;
else if (src0.type == GLSL_TYPE_FLOAT || src1.type == GLSL_TYPE_FLOAT)
else if (native_integers)
type = src0.type == GLSL_TYPE_BOOL ? GLSL_TYPE_INT : src0.type;
+#define case7(c, f, i, u, d, i64, ui64) \
+ case TGSI_OPCODE_##c: \
+ if (type == GLSL_TYPE_UINT64) \
+ op = TGSI_OPCODE_##ui64; \
+ else if (type == GLSL_TYPE_INT64) \
+ op = TGSI_OPCODE_##i64; \
+ else if (type == GLSL_TYPE_DOUBLE) \
+ op = TGSI_OPCODE_##d; \
+ else if (type == GLSL_TYPE_INT) \
+ op = TGSI_OPCODE_##i; \
+ else if (type == GLSL_TYPE_UINT) \
+ op = TGSI_OPCODE_##u; \
+ else \
+ op = TGSI_OPCODE_##f; \
+ break;
#define case5(c, f, i, u, d) \
case TGSI_OPCODE_##c: \
if (type == GLSL_TYPE_DOUBLE) \
break;
#define case3(f, i, u) case4(f, f, i, u)
-#define case4d(f, i, u, d) case5(f, f, i, u, d)
+#define case6d(f, i, u, d, i64, u64) case7(f, f, i, u, d, i64, u64)
#define case3fid(f, i, d) case5(f, f, i, i, d)
+#define case3fid64(f, i, d, i64) case7(f, f, i, i, d, i64, i64)
#define case2fi(f, i) case4(f, f, i, i)
#define case2iu(i, u) case4(i, LAST, i, u)
-#define casecomp(c, f, i, u, d) \
+#define case2iu64(i, i64) case7(i, LAST, i, i, LAST, i64, i64)
+#define case4iu64(i, u, i64, u64) case7(i, LAST, i, u, LAST, i64, u64)
+
+#define casecomp(c, f, i, u, d, i64, ui64) \
case TGSI_OPCODE_##c: \
- if (type == GLSL_TYPE_DOUBLE) \
+ if (type == GLSL_TYPE_INT64) \
+ op = TGSI_OPCODE_##i64; \
+ else if (type == GLSL_TYPE_UINT64) \
+ op = TGSI_OPCODE_##ui64; \
+ else if (type == GLSL_TYPE_DOUBLE) \
op = TGSI_OPCODE_##d; \
else if (type == GLSL_TYPE_INT || type == GLSL_TYPE_SUBROUTINE) \
op = TGSI_OPCODE_##i; \
break;
switch(op) {
- case3fid(ADD, UADD, DADD);
- case3fid(MUL, UMUL, DMUL);
+ case3fid64(ADD, UADD, DADD, U64ADD);
+ case3fid64(MUL, UMUL, DMUL, U64MUL);
case3fid(MAD, UMAD, DMAD);
case3fid(FMA, UMAD, DFMA);
- case3(DIV, IDIV, UDIV);
- case4d(MAX, IMAX, UMAX, DMAX);
- case4d(MIN, IMIN, UMIN, DMIN);
- case2iu(MOD, UMOD);
+ case6d(DIV, IDIV, UDIV, DDIV, I64DIV, U64DIV);
+ case6d(MAX, IMAX, UMAX, DMAX, I64MAX, U64MAX);
+ case6d(MIN, IMIN, UMIN, DMIN, I64MIN, U64MIN);
+ case4iu64(MOD, UMOD, I64MOD, U64MOD);
- casecomp(SEQ, FSEQ, USEQ, USEQ, DSEQ);
- casecomp(SNE, FSNE, USNE, USNE, DSNE);
- casecomp(SGE, FSGE, ISGE, USGE, DSGE);
- casecomp(SLT, FSLT, ISLT, USLT, DSLT);
+ casecomp(SEQ, FSEQ, USEQ, USEQ, DSEQ, U64SEQ, U64SEQ);
+ casecomp(SNE, FSNE, USNE, USNE, DSNE, U64SNE, U64SNE);
+ casecomp(SGE, FSGE, ISGE, USGE, DSGE, I64SGE, U64SGE);
+ casecomp(SLT, FSLT, ISLT, USLT, DSLT, I64SLT, U64SLT);
- case2iu(ISHR, USHR);
+ case2iu64(SHL, U64SHL);
+ case4iu64(ISHR, USHR, I64SHR, U64SHR);
- case3fid(SSG, ISSG, DSSG);
+ case3fid64(SSG, ISSG, DSSG, I64SSG);
case2iu(IBFE, UBFE);
case2iu(IMSB, UMSB);
int index = 0;
immediate_storage *entry;
- int size32 = size * (datatype == GL_DOUBLE ? 2 : 1);
+ int size32 = size * ((datatype == GL_DOUBLE ||
+ datatype == GL_INT64_ARB ||
+ datatype == GL_UNSIGNED_INT64_ARB)? 2 : 1);
int i;
/* Search immediate storage to see if we already have an identical
}
break;
case ir_unop_neg:
- if (result_dst.type == GLSL_TYPE_INT || result_dst.type == GLSL_TYPE_UINT)
+ if (result_dst.type == GLSL_TYPE_INT64 || result_dst.type == GLSL_TYPE_UINT64)
+ emit_asm(ir, TGSI_OPCODE_I64NEG, result_dst, op[0]);
+ else if (result_dst.type == GLSL_TYPE_INT || result_dst.type == GLSL_TYPE_UINT)
emit_asm(ir, TGSI_OPCODE_INEG, result_dst, op[0]);
else if (result_dst.type == GLSL_TYPE_DOUBLE)
emit_asm(ir, TGSI_OPCODE_DNEG, result_dst, op[0]);
emit_asm(ir, TGSI_OPCODE_MOV, result_dst, op[0].get_abs());
else if (result_dst.type == GLSL_TYPE_DOUBLE)
emit_asm(ir, TGSI_OPCODE_DABS, result_dst, op[0]);
+ else if (result_dst.type == GLSL_TYPE_INT64 || result_dst.type == GLSL_TYPE_UINT64)
+ emit_asm(ir, TGSI_OPCODE_I64ABS, result_dst, op[0]);
else
emit_asm(ir, TGSI_OPCODE_IABS, result_dst, op[0]);
break;
emit_asm(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]);
break;
case ir_binop_div:
- if (result_dst.type == GLSL_TYPE_FLOAT || result_dst.type == GLSL_TYPE_DOUBLE)
- assert(!"not reached: should be handled by ir_div_to_mul_rcp");
- else
- emit_asm(ir, TGSI_OPCODE_DIV, result_dst, op[0], op[1]);
+ emit_asm(ir, TGSI_OPCODE_DIV, result_dst, op[0], op[1]);
break;
case ir_binop_mod:
if (result_dst.type == GLSL_TYPE_FLOAT)
/* fallthrough to next case otherwise */
case ir_unop_i2u:
case ir_unop_u2i:
+ case ir_unop_i642u64:
+ case ir_unop_u642i64:
/* Converting between signed and unsigned integers is a no-op. */
result_src = op[0];
result_src.type = result_dst.type;
else
emit_asm(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0));
break;
+ case ir_unop_bitcast_u642d:
+ case ir_unop_bitcast_i642d:
+ result_src = op[0];
+ result_src.type = GLSL_TYPE_DOUBLE;
+ break;
+ case ir_unop_bitcast_d2i64:
+ result_src = op[0];
+ result_src.type = GLSL_TYPE_INT64;
+ break;
+ case ir_unop_bitcast_d2u64:
+ result_src = op[0];
+ result_src.type = GLSL_TYPE_UINT64;
+ break;
case ir_unop_trunc:
emit_asm(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]);
break;
break;
case ir_unop_unpack_double_2x32:
case ir_unop_pack_double_2x32:
+ case ir_unop_unpack_int_2x32:
+ case ir_unop_pack_int_2x32:
+ case ir_unop_unpack_uint_2x32:
+ case ir_unop_pack_uint_2x32:
emit_asm(ir, TGSI_OPCODE_MOV, result_dst, op[0]);
break;
case ir_unop_vote_eq:
emit_asm(ir, TGSI_OPCODE_VOTE_EQ, result_dst, op[0]);
break;
-
+ case ir_unop_u2i64:
+ case ir_unop_u2u64:
+ case ir_unop_b2i64: {
+ st_src_reg temp = get_temp(glsl_type::uvec4_type);
+ st_dst_reg temp_dst = st_dst_reg(temp);
+ unsigned orig_swz = op[0].swizzle;
+ /*
+ * To convert unsigned to 64-bit:
+ * zero Y channel, copy X channel.
+ */
+ temp_dst.writemask = WRITEMASK_Y;
+ if (vector_elements > 1)
+ temp_dst.writemask |= WRITEMASK_W;
+ emit_asm(ir, TGSI_OPCODE_MOV, temp_dst, st_src_reg_for_int(0));
+ temp_dst.writemask = WRITEMASK_X;
+ if (vector_elements > 1)
+ temp_dst.writemask |= WRITEMASK_Z;
+ op[0].swizzle = MAKE_SWIZZLE4(GET_SWZ(orig_swz, 0), GET_SWZ(orig_swz, 0),
+ GET_SWZ(orig_swz, 1), GET_SWZ(orig_swz, 1));
+ if (ir->operation == ir_unop_u2i64 || ir->operation == ir_unop_u2u64)
+ emit_asm(ir, TGSI_OPCODE_MOV, temp_dst, op[0]);
+ else
+ emit_asm(ir, TGSI_OPCODE_AND, temp_dst, op[0], st_src_reg_for_int(1));
+ result_src = temp;
+ result_src.type = GLSL_TYPE_UINT64;
+ if (vector_elements > 2) {
+ /* Subtle: We rely on the fact that get_temp here returns the next
+ * TGSI temporary register directly after the temp register used for
+ * the first two components, so that the result gets picked up
+ * automatically.
+ */
+ st_src_reg temp = get_temp(glsl_type::uvec4_type);
+ st_dst_reg temp_dst = st_dst_reg(temp);
+ temp_dst.writemask = WRITEMASK_Y;
+ if (vector_elements > 3)
+ temp_dst.writemask |= WRITEMASK_W;
+ emit_asm(ir, TGSI_OPCODE_MOV, temp_dst, st_src_reg_for_int(0));
+
+ temp_dst.writemask = WRITEMASK_X;
+ if (vector_elements > 3)
+ temp_dst.writemask |= WRITEMASK_Z;
+ op[0].swizzle = MAKE_SWIZZLE4(GET_SWZ(orig_swz, 2), GET_SWZ(orig_swz, 2),
+ GET_SWZ(orig_swz, 3), GET_SWZ(orig_swz, 3));
+ if (ir->operation == ir_unop_u2i64 || ir->operation == ir_unop_u2u64)
+ emit_asm(ir, TGSI_OPCODE_MOV, temp_dst, op[0]);
+ else
+ emit_asm(ir, TGSI_OPCODE_AND, temp_dst, op[0], st_src_reg_for_int(1));
+ }
+ break;
+ }
+ case ir_unop_i642i:
+ case ir_unop_u642i:
+ case ir_unop_u642u:
+ case ir_unop_i642u: {
+ st_src_reg temp = get_temp(glsl_type::uvec4_type);
+ st_dst_reg temp_dst = st_dst_reg(temp);
+ unsigned orig_swz = op[0].swizzle;
+ unsigned orig_idx = op[0].index;
+ int el;
+ temp_dst.writemask = WRITEMASK_X;
+
+ for (el = 0; el < vector_elements; el++) {
+ unsigned swz = GET_SWZ(orig_swz, el);
+ if (swz & 1)
+ op[0].swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z);
+ else
+ op[0].swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
+ if (swz > 2)
+ op[0].index = orig_idx + 1;
+ op[0].type = GLSL_TYPE_UINT;
+ temp_dst.writemask = WRITEMASK_X << el;
+ emit_asm(ir, TGSI_OPCODE_MOV, temp_dst, op[0]);
+ }
+ result_src = temp;
+ if (ir->operation == ir_unop_u642u || ir->operation == ir_unop_i642u)
+ result_src.type = GLSL_TYPE_UINT;
+ else
+ result_src.type = GLSL_TYPE_INT;
+ break;
+ }
+ case ir_unop_i642b:
+ emit_asm(ir, TGSI_OPCODE_U64SNE, result_dst, op[0], st_src_reg_for_int(0));
+ break;
+ case ir_unop_i642f:
+ emit_asm(ir, TGSI_OPCODE_I642F, result_dst, op[0]);
+ break;
+ case ir_unop_u642f:
+ emit_asm(ir, TGSI_OPCODE_U642F, result_dst, op[0]);
+ break;
+ case ir_unop_i642d:
+ emit_asm(ir, TGSI_OPCODE_I642D, result_dst, op[0]);
+ break;
+ case ir_unop_u642d:
+ emit_asm(ir, TGSI_OPCODE_U642D, result_dst, op[0]);
+ break;
+ case ir_unop_i2i64:
+ emit_asm(ir, TGSI_OPCODE_I2I64, result_dst, op[0]);
+ break;
+ case ir_unop_f2i64:
+ emit_asm(ir, TGSI_OPCODE_F2I64, result_dst, op[0]);
+ break;
+ case ir_unop_d2i64:
+ emit_asm(ir, TGSI_OPCODE_D2I64, result_dst, op[0]);
+ break;
+ case ir_unop_i2u64:
+ emit_asm(ir, TGSI_OPCODE_I2I64, result_dst, op[0]);
+ break;
+ case ir_unop_f2u64:
+ emit_asm(ir, TGSI_OPCODE_F2U64, result_dst, op[0]);
+ break;
+ case ir_unop_d2u64:
+ emit_asm(ir, TGSI_OPCODE_D2U64, result_dst, op[0]);
+ break;
+ /* these might be needed */
case ir_unop_pack_snorm_2x16:
case ir_unop_pack_unorm_2x16:
case ir_unop_pack_snorm_4x8:
else
decl->size = type_size(var->type);
- entry = new(mem_ctx) variable_storage(var,
- PROGRAM_OUTPUT,
- decl->mesa_index,
- decl->array_id);
+ if (var->data.fb_fetch_output) {
+ st_dst_reg dst = st_dst_reg(get_temp(var->type));
+ st_src_reg src = st_src_reg(PROGRAM_OUTPUT, decl->mesa_index,
+ var->type, component, decl->array_id);
+ emit_asm(NULL, TGSI_OPCODE_FBFETCH, dst, src);
+ entry = new(mem_ctx) variable_storage(var, dst.file, dst.index,
+ dst.array_id);
+ } else {
+ entry = new(mem_ctx) variable_storage(var,
+ PROGRAM_OUTPUT,
+ decl->mesa_index,
+ decl->array_id);
+ }
entry->component = component;
this->variables.push_tail(entry);
memcpy(&values[i * 2], &ir->value.d[i], sizeof(double));
}
break;
+ case GLSL_TYPE_INT64:
+ gl_type = GL_INT64_ARB;
+ for (i = 0; i < ir->type->vector_elements; i++) {
+ memcpy(&values[i * 2], &ir->value.d[i], sizeof(int64_t));
+ }
+ break;
+ case GLSL_TYPE_UINT64:
+ gl_type = GL_UNSIGNED_INT64_ARB;
+ for (i = 0; i < ir->type->vector_elements; i++) {
+ memcpy(&values[i * 2], &ir->value.d[i], sizeof(uint64_t));
+ }
+ break;
case GLSL_TYPE_UINT:
gl_type = native_integers ? GL_UNSIGNED_INT : GL_FLOAT;
for (i = 0; i < ir->type->vector_elements; i++) {
inst->resource = buffer;
if (access)
inst->buffer_access = access->value.u[0];
+
+ if (inst == this->instructions.get_head_raw())
+ break;
inst = (glsl_to_tgsi_instruction *)inst->get_prev();
- if (inst->op == TGSI_OPCODE_UADD)
+
+ if (inst->op == TGSI_OPCODE_UADD) {
+ if (inst == this->instructions.get_head_raw())
+ break;
inst = (glsl_to_tgsi_instruction *)inst->get_prev();
- } while (inst && inst->op == op && inst->resource.file == PROGRAM_UNDEFINED);
+ }
+ } while (inst->op == op && inst->resource.file == PROGRAM_UNDEFINED);
}
void
return ureg_DECL_immediate(ureg, &values[0].f, size);
case GL_DOUBLE:
return ureg_DECL_immediate_f64(ureg, (double *)&values[0].f, size);
+ case GL_INT64_ARB:
+ return ureg_DECL_immediate_int64(ureg, (int64_t *)&values[0].f, size);
+ case GL_UNSIGNED_INT64_ARB:
+ return ureg_DECL_immediate_uint64(ureg, (uint64_t *)&values[0].f, size);
case GL_INT:
return ureg_DECL_immediate_int(ureg, &values[0].i, size);
case GL_UNSIGNED_INT:
}
if (procType == PIPE_SHADER_FRAGMENT) {
- if (program->shader->info.EarlyFragmentTests)
+ if (program->shader->Program->info.fs.early_fragment_tests)
ureg_property(ureg, TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL, 1);
if (proginfo->info.inputs_read & VARYING_BIT_POS) {
if (program->use_shared_memory)
t->shared_memory = ureg_DECL_memory(ureg, TGSI_MEMORY_TYPE_SHARED);
- for (i = 0; i < program->shader->NumImages; i++) {
+ for (i = 0; i < program->shader->Program->info.num_images; i++) {
if (program->images_used & (1 << i)) {
t->images[i] = ureg_DECL_image(ureg, i,
program->image_targets[i],
return prog;
}
-static void
-set_affected_state_flags(uint64_t *states,
- struct gl_program *prog,
- struct gl_linked_shader *shader,
- uint64_t new_constants,
- uint64_t new_sampler_views,
- uint64_t new_samplers,
- uint64_t new_images,
- uint64_t new_ubos,
- uint64_t new_ssbos,
- uint64_t new_atomics)
-{
- if (prog->Parameters->NumParameters)
- *states |= new_constants;
-
- if (prog->info.num_textures)
- *states |= new_sampler_views | new_samplers;
-
- if (shader->NumImages)
- *states |= new_images;
-
- if (prog->info.num_ubos)
- *states |= new_ubos;
-
- if (prog->info.num_ssbos)
- *states |= new_ssbos;
-
- if (prog->info.num_abos)
- *states |= new_atomics;
-}
-
-static struct gl_program *
-get_mesa_program(struct gl_context *ctx,
- struct gl_shader_program *shader_program,
- struct gl_linked_shader *shader)
-{
- struct pipe_screen *pscreen = ctx->st->pipe->screen;
- enum pipe_shader_type ptarget = st_shader_stage_to_ptarget(shader->Stage);
- enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir)
- pscreen->get_shader_param(pscreen, ptarget, PIPE_SHADER_CAP_PREFERRED_IR);
- struct gl_program *prog = NULL;
-
- if (preferred_ir == PIPE_SHADER_IR_NIR) {
- /* TODO only for GLSL VS/FS for now: */
- switch (shader->Stage) {
- case MESA_SHADER_VERTEX:
- case MESA_SHADER_FRAGMENT:
- prog = st_nir_get_mesa_program(ctx, shader_program, shader);
- default:
- break;
- }
- } else {
- prog = get_mesa_program_tgsi(ctx, shader_program, shader);
- }
-
- if (prog) {
- uint64_t *states;
-
- /* This determines which states will be updated when the shader is
- * bound.
- */
- switch (shader->Stage) {
- case MESA_SHADER_VERTEX:
- states = &((struct st_vertex_program*)prog)->affected_states;
-
- *states = ST_NEW_VS_STATE |
- ST_NEW_RASTERIZER |
- ST_NEW_VERTEX_ARRAYS;
-
- set_affected_state_flags(states, prog, shader,
- ST_NEW_VS_CONSTANTS,
- ST_NEW_VS_SAMPLER_VIEWS,
- ST_NEW_RENDER_SAMPLERS,
- ST_NEW_VS_IMAGES,
- ST_NEW_VS_UBOS,
- ST_NEW_VS_SSBOS,
- ST_NEW_VS_ATOMICS);
- break;
-
- case MESA_SHADER_TESS_CTRL:
- states = &((struct st_tessctrl_program*)prog)->affected_states;
-
- *states = ST_NEW_TCS_STATE;
-
- set_affected_state_flags(states, prog, shader,
- ST_NEW_TCS_CONSTANTS,
- ST_NEW_TCS_SAMPLER_VIEWS,
- ST_NEW_RENDER_SAMPLERS,
- ST_NEW_TCS_IMAGES,
- ST_NEW_TCS_UBOS,
- ST_NEW_TCS_SSBOS,
- ST_NEW_TCS_ATOMICS);
- break;
-
- case MESA_SHADER_TESS_EVAL:
- states = &((struct st_tesseval_program*)prog)->affected_states;
-
- *states = ST_NEW_TES_STATE |
- ST_NEW_RASTERIZER;
-
- set_affected_state_flags(states, prog, shader,
- ST_NEW_TES_CONSTANTS,
- ST_NEW_TES_SAMPLER_VIEWS,
- ST_NEW_RENDER_SAMPLERS,
- ST_NEW_TES_IMAGES,
- ST_NEW_TES_UBOS,
- ST_NEW_TES_SSBOS,
- ST_NEW_TES_ATOMICS);
- break;
-
- case MESA_SHADER_GEOMETRY:
- states = &((struct st_geometry_program*)prog)->affected_states;
-
- *states = ST_NEW_GS_STATE |
- ST_NEW_RASTERIZER;
-
- set_affected_state_flags(states, prog, shader,
- ST_NEW_GS_CONSTANTS,
- ST_NEW_GS_SAMPLER_VIEWS,
- ST_NEW_RENDER_SAMPLERS,
- ST_NEW_GS_IMAGES,
- ST_NEW_GS_UBOS,
- ST_NEW_GS_SSBOS,
- ST_NEW_GS_ATOMICS);
- break;
-
- case MESA_SHADER_FRAGMENT:
- states = &((struct st_fragment_program*)prog)->affected_states;
-
- /* gl_FragCoord and glDrawPixels always use constants. */
- *states = ST_NEW_FS_STATE |
- ST_NEW_SAMPLE_SHADING |
- ST_NEW_FS_CONSTANTS;
-
- set_affected_state_flags(states, prog, shader,
- ST_NEW_FS_CONSTANTS,
- ST_NEW_FS_SAMPLER_VIEWS,
- ST_NEW_RENDER_SAMPLERS,
- ST_NEW_FS_IMAGES,
- ST_NEW_FS_UBOS,
- ST_NEW_FS_SSBOS,
- ST_NEW_FS_ATOMICS);
- break;
-
- case MESA_SHADER_COMPUTE:
- states = &((struct st_compute_program*)prog)->affected_states;
-
- *states = ST_NEW_CS_STATE;
-
- set_affected_state_flags(states, prog, shader,
- ST_NEW_CS_CONSTANTS,
- ST_NEW_CS_SAMPLER_VIEWS,
- ST_NEW_CS_SAMPLERS,
- ST_NEW_CS_IMAGES,
- ST_NEW_CS_UBOS,
- ST_NEW_CS_SSBOS,
- ST_NEW_CS_ATOMICS);
- break;
-
- default:
- unreachable("unhandled shader stage");
- }
- }
-
- return prog;
-}
-
/* See if there are unsupported control flow statements. */
class ir_control_flow_info_visitor : public ir_hierarchical_visitor {
private:
GLboolean
st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
{
+ /* Return early if we are loading the shader from on-disk cache */
+ if (st_load_tgsi_from_disk_cache(ctx, prog)) {
+ return GL_TRUE;
+ }
+
struct pipe_screen *pscreen = ctx->st->pipe->screen;
assert(prog->data->LinkStatus);
if (prog->_LinkedShaders[i] == NULL)
continue;
- exec_list *ir = prog->_LinkedShaders[i]->ir;
- gl_shader_stage stage = prog->_LinkedShaders[i]->Stage;
+ struct gl_linked_shader *shader = prog->_LinkedShaders[i];
+ exec_list *ir = shader->ir;
+ gl_shader_stage stage = shader->Stage;
const struct gl_shader_compiler_options *options =
&ctx->Const.ShaderCompilerOptions[stage];
enum pipe_shader_type ptarget = st_shader_stage_to_ptarget(stage);
*/
if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput ||
options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) {
- lower_variable_index_to_cond_assign(prog->_LinkedShaders[i]->Stage, ir,
+ lower_variable_index_to_cond_assign(stage, ir,
options->EmitNoIndirectInput,
options->EmitNoIndirectOutput,
options->EmitNoIndirectTemp,
options->EmitNoIndirectUniform);
}
+ if (!pscreen->get_param(pscreen, PIPE_CAP_INT64_DIVMOD))
+ lower_64bit_integer_instructions(ir, DIV64 | MOD64);
+
if (ctx->Extensions.ARB_shading_language_packing) {
unsigned lower_inst = LOWER_PACK_SNORM_2x16 |
LOWER_UNPACK_SNORM_2x16 |
if (!pscreen->get_param(pscreen, PIPE_CAP_TEXTURE_GATHER_OFFSETS))
lower_offset_arrays(ir);
do_mat_op_to_vec(ir);
+
+ if (stage == MESA_SHADER_FRAGMENT)
+ lower_blend_equation_advanced(shader);
+
lower_instructions(ir,
MOD_TO_FLOOR |
- DIV_TO_MUL_RCP |
+ FDIV_TO_MUL_RCP |
EXP_TO_EXP2 |
LOG_TO_LOG2 |
LDEXP_TO_ARITH |
build_program_resource_list(ctx, prog);
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
- struct gl_program *linked_prog;
-
- if (prog->_LinkedShaders[i] == NULL)
+ struct gl_linked_shader *shader = prog->_LinkedShaders[i];
+ if (shader == NULL)
continue;
- linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
+ enum pipe_shader_type ptarget =
+ st_shader_stage_to_ptarget(shader->Stage);
+ enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir)
+ pscreen->get_shader_param(pscreen, ptarget,
+ PIPE_SHADER_CAP_PREFERRED_IR);
+
+ struct gl_program *linked_prog = NULL;
+ if (preferred_ir == PIPE_SHADER_IR_NIR) {
+ /* TODO only for GLSL VS/FS for now: */
+ switch (shader->Stage) {
+ case MESA_SHADER_VERTEX:
+ case MESA_SHADER_FRAGMENT:
+ linked_prog = st_nir_get_mesa_program(ctx, prog, shader);
+ default:
+ break;
+ }
+ } else {
+ linked_prog = get_mesa_program_tgsi(ctx, prog, shader);
+ }
if (linked_prog) {
+ st_set_prog_affected_state_flags(linked_prog);
if (!ctx->Driver.ProgramStringNotify(ctx,
_mesa_shader_stage_to_program(i),
linked_prog)) {
- _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program,
- NULL);
+ _mesa_reference_program(ctx, &shader->Program, NULL);
return GL_FALSE;
}
}
const GLuint outputMapping[],
struct pipe_stream_output_info *so)
{
+ if (!glsl_to_tgsi->shader_program->last_vert_prog)
+ return;
+
struct gl_transform_feedback_info *info =
- glsl_to_tgsi->shader_program->xfb_program->sh.LinkedTransformFeedback;
+ glsl_to_tgsi->shader_program->last_vert_prog->sh.LinkedTransformFeedback;
st_translate_stream_output_info2(info, outputMapping, so);
}