#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_bitmask.h"
+#include "GL/gl.h"
+#include "compiler/shader_info.h"
union tgsi_any_token {
struct tgsi_header header;
return ureg->nr_outputs;
}
+static void
+ureg_setup_clipdist_info(struct ureg_program *ureg,
+ const struct shader_info *info)
+{
+ if (info->clip_distance_array_size)
+ ureg_property(ureg, TGSI_PROPERTY_NUM_CLIPDIST_ENABLED,
+ info->clip_distance_array_size);
+ if (info->cull_distance_array_size)
+ ureg_property(ureg, TGSI_PROPERTY_NUM_CULLDIST_ENABLED,
+ info->cull_distance_array_size);
+}
+
+static void
+ureg_setup_tess_ctrl_shader(struct ureg_program *ureg,
+ const struct shader_info *info)
+{
+ ureg_property(ureg, TGSI_PROPERTY_TCS_VERTICES_OUT,
+ info->tess.tcs_vertices_out);
+}
+
+static void
+ureg_setup_tess_eval_shader(struct ureg_program *ureg,
+ const struct shader_info *info)
+{
+ if (info->tess.primitive_mode == GL_ISOLINES)
+ ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, GL_LINES);
+ else
+ ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE,
+ info->tess.primitive_mode);
+
+ STATIC_ASSERT((TESS_SPACING_EQUAL + 1) % 3 == PIPE_TESS_SPACING_EQUAL);
+ STATIC_ASSERT((TESS_SPACING_FRACTIONAL_ODD + 1) % 3 ==
+ PIPE_TESS_SPACING_FRACTIONAL_ODD);
+ STATIC_ASSERT((TESS_SPACING_FRACTIONAL_EVEN + 1) % 3 ==
+ PIPE_TESS_SPACING_FRACTIONAL_EVEN);
+
+ ureg_property(ureg, TGSI_PROPERTY_TES_SPACING,
+ (info->tess.spacing + 1) % 3);
+
+ ureg_property(ureg, TGSI_PROPERTY_TES_VERTEX_ORDER_CW,
+ !info->tess.ccw);
+ ureg_property(ureg, TGSI_PROPERTY_TES_POINT_MODE,
+ info->tess.point_mode);
+}
+
+static void
+ureg_setup_geometry_shader(struct ureg_program *ureg,
+ const struct shader_info *info)
+{
+ ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM,
+ info->gs.input_primitive);
+ ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM,
+ info->gs.output_primitive);
+ ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES,
+ info->gs.vertices_out);
+ ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS,
+ info->gs.invocations);
+}
+
+static void
+ureg_setup_fragment_shader(struct ureg_program *ureg,
+ const struct shader_info *info)
+{
+ if (info->fs.early_fragment_tests || info->fs.post_depth_coverage) {
+ ureg_property(ureg, TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL, 1);
+
+ if (info->fs.post_depth_coverage)
+ ureg_property(ureg, TGSI_PROPERTY_FS_POST_DEPTH_COVERAGE, 1);
+ }
+
+ if (info->fs.depth_layout != FRAG_DEPTH_LAYOUT_NONE) {
+ switch (info->fs.depth_layout) {
+ case FRAG_DEPTH_LAYOUT_ANY:
+ ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,
+ TGSI_FS_DEPTH_LAYOUT_ANY);
+ break;
+ case FRAG_DEPTH_LAYOUT_GREATER:
+ ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,
+ TGSI_FS_DEPTH_LAYOUT_GREATER);
+ break;
+ case FRAG_DEPTH_LAYOUT_LESS:
+ ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,
+ TGSI_FS_DEPTH_LAYOUT_LESS);
+ break;
+ case FRAG_DEPTH_LAYOUT_UNCHANGED:
+ ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,
+ TGSI_FS_DEPTH_LAYOUT_UNCHANGED);
+ break;
+ default:
+ assert(0);
+ }
+ }
+}
+
+static void
+ureg_setup_compute_shader(struct ureg_program *ureg,
+ const struct shader_info *info)
+{
+ ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH,
+ info->cs.local_size[0]);
+ ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT,
+ info->cs.local_size[1]);
+ ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH,
+ info->cs.local_size[2]);
+
+ if (info->cs.shared_size)
+ ureg_DECL_memory(ureg, TGSI_MEMORY_TYPE_SHARED);
+}
+
+void
+ureg_setup_shader_info(struct ureg_program *ureg,
+ const struct shader_info *info)
+{
+ if (info->layer_viewport_relative)
+ ureg_property(ureg, TGSI_PROPERTY_LAYER_VIEWPORT_RELATIVE, 1);
+
+ switch (info->stage) {
+ case MESA_SHADER_VERTEX:
+ ureg_setup_clipdist_info(ureg, info);
+ break;
+ case MESA_SHADER_TESS_CTRL:
+ ureg_setup_tess_ctrl_shader(ureg, info);
+ break;
+ case MESA_SHADER_TESS_EVAL:
+ ureg_setup_tess_eval_shader(ureg, info);
+ ureg_setup_clipdist_info(ureg, info);
+ ureg_set_next_shader_processor(ureg, pipe_shader_type_from_mesa(info->next_stage));
+ break;
+ case MESA_SHADER_GEOMETRY:
+ ureg_setup_geometry_shader(ureg, info);
+ ureg_setup_clipdist_info(ureg, info);
+ break;
+ case MESA_SHADER_FRAGMENT:
+ ureg_setup_fragment_shader(ureg, info);
+ break;
+ case MESA_SHADER_COMPUTE:
+ ureg_setup_compute_shader(ureg, info);
+ break;
+ default:
+ break;
+ }
+}
+
void ureg_destroy( struct ureg_program *ureg )
{
struct pipe_screen;
struct ureg_program;
struct pipe_stream_output_info;
+struct shader_info;
/* Almost a tgsi_src_register, but we need to pull in the Absolute
* flag from the _ext token. Indirect flag always implies ADDR[0].
return dst.File == TGSI_FILE_NULL;
}
+void
+ureg_setup_shader_info(struct ureg_program *ureg,
+ const struct shader_info *info);
#ifdef __cplusplus
}
t->inputs[t->inputMapping[VARYING_SLOT_FACE]] = ureg_src(face_temp);
}
-static void
-emit_compute_block_size(const struct gl_program *prog,
- struct ureg_program *ureg) {
- ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH,
- prog->info.cs.local_size[0]);
- ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT,
- prog->info.cs.local_size[1]);
- ureg_property(ureg, TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH,
- prog->info.cs.local_size[2]);
-}
-
struct sort_inout_decls {
bool operator()(const struct inout_decl &a, const struct inout_decl &b) const {
return mapping[a.mesa_index] < mapping[b.mesa_index];
}
if (procType == PIPE_SHADER_FRAGMENT) {
- if (program->shader->Program->info.fs.early_fragment_tests ||
- program->shader->Program->info.fs.post_depth_coverage) {
- ureg_property(ureg, TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL, 1);
-
- if (program->shader->Program->info.fs.post_depth_coverage)
- ureg_property(ureg, TGSI_PROPERTY_FS_POST_DEPTH_COVERAGE, 1);
- }
-
if (proginfo->info.inputs_read & VARYING_BIT_POS) {
/* Must do this after setting up t->inputs. */
emit_wpos(st_context(ctx), t, proginfo, ureg,
}
}
- if (procType == PIPE_SHADER_COMPUTE) {
- emit_compute_block_size(proginfo, ureg);
- }
-
- if (program->shader->Program->info.layer_viewport_relative)
- ureg_property(ureg, TGSI_PROPERTY_LAYER_VIEWPORT_RELATIVE, 1);
-
/* Declare address register.
*/
if (program->num_address_regs > 0) {
if (ureg == NULL)
return false;
- if (stp->Base.info.clip_distance_array_size)
- ureg_property(ureg, TGSI_PROPERTY_NUM_CLIPDIST_ENABLED,
- stp->Base.info.clip_distance_array_size);
- if (stp->Base.info.cull_distance_array_size)
- ureg_property(ureg, TGSI_PROPERTY_NUM_CULLDIST_ENABLED,
- stp->Base.info.cull_distance_array_size);
+ ureg_setup_shader_info(ureg, &stp->Base.info);
if (ST_DEBUG & DEBUG_MESA) {
_mesa_print_program(&stp->Base);
if (ureg == NULL)
return false;
+ ureg_setup_shader_info(ureg, &stfp->Base.info);
+
if (ST_DEBUG & DEBUG_MESA) {
_mesa_print_program(&stfp->Base);
_mesa_print_program_parameters(st->ctx, &stfp->Base);
if (write_all == GL_TRUE)
ureg_property(ureg, TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS, 1);
- if (stfp->Base.info.fs.depth_layout != FRAG_DEPTH_LAYOUT_NONE) {
- switch (stfp->Base.info.fs.depth_layout) {
- case FRAG_DEPTH_LAYOUT_ANY:
- ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,
- TGSI_FS_DEPTH_LAYOUT_ANY);
- break;
- case FRAG_DEPTH_LAYOUT_GREATER:
- ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,
- TGSI_FS_DEPTH_LAYOUT_GREATER);
- break;
- case FRAG_DEPTH_LAYOUT_LESS:
- ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,
- TGSI_FS_DEPTH_LAYOUT_LESS);
- break;
- case FRAG_DEPTH_LAYOUT_UNCHANGED:
- ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,
- TGSI_FS_DEPTH_LAYOUT_UNCHANGED);
- break;
- default:
- assert(0);
- }
- }
-
if (stfp->glsl_to_tgsi) {
st_translate_program(st->ctx,
PIPE_SHADER_FRAGMENT,
if (ureg == NULL)
return false;
- switch (stage) {
- case PIPE_SHADER_TESS_CTRL:
- ureg_property(ureg, TGSI_PROPERTY_TCS_VERTICES_OUT,
- stp->Base.info.tess.tcs_vertices_out);
- break;
-
- case PIPE_SHADER_TESS_EVAL:
- if (stp->Base.info.tess.primitive_mode == GL_ISOLINES)
- ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, GL_LINES);
- else
- ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE,
- stp->Base.info.tess.primitive_mode);
-
- STATIC_ASSERT((TESS_SPACING_EQUAL + 1) % 3 == PIPE_TESS_SPACING_EQUAL);
- STATIC_ASSERT((TESS_SPACING_FRACTIONAL_ODD + 1) % 3 ==
- PIPE_TESS_SPACING_FRACTIONAL_ODD);
- STATIC_ASSERT((TESS_SPACING_FRACTIONAL_EVEN + 1) % 3 ==
- PIPE_TESS_SPACING_FRACTIONAL_EVEN);
-
- ureg_property(ureg, TGSI_PROPERTY_TES_SPACING,
- (stp->Base.info.tess.spacing + 1) % 3);
-
- ureg_property(ureg, TGSI_PROPERTY_TES_VERTEX_ORDER_CW,
- !stp->Base.info.tess.ccw);
- ureg_property(ureg, TGSI_PROPERTY_TES_POINT_MODE,
- stp->Base.info.tess.point_mode);
- break;
-
- case PIPE_SHADER_GEOMETRY:
- ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM,
- stp->Base.info.gs.input_primitive);
- ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM,
- stp->Base.info.gs.output_primitive);
- ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES,
- stp->Base.info.gs.vertices_out);
- ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS,
- stp->Base.info.gs.invocations);
- break;
-
- default:
- break;
- }
+ ureg_setup_shader_info(ureg, &stp->Base.info);
ubyte inputSlotToAttr[VARYING_SLOT_TESS_MAX];
ubyte inputMapping[VARYING_SLOT_TESS_MAX];
memset(outputMapping, 0, sizeof(outputMapping));
memset(&stp->state, 0, sizeof(stp->state));
- if (prog->info.clip_distance_array_size)
- ureg_property(ureg, TGSI_PROPERTY_NUM_CLIPDIST_ENABLED,
- prog->info.clip_distance_array_size);
- if (prog->info.cull_distance_array_size)
- ureg_property(ureg, TGSI_PROPERTY_NUM_CULLDIST_ENABLED,
- prog->info.cull_distance_array_size);
-
/*
* Convert Mesa program inputs to TGSI input register semantics.
*/