}
+static void
+scan_src_operand(struct tgsi_shader_info *info,
+ const struct tgsi_full_instruction *fullinst,
+ const struct tgsi_full_src_register *src,
+ unsigned src_index,
+ unsigned usage_mask,
+ bool is_interp_instruction,
+ bool *is_mem_inst)
+{
+ int ind = src->Register.Index;
+
+ /* Mark which inputs are effectively used */
+ if (src->Register.File == TGSI_FILE_INPUT) {
+ if (src->Register.Indirect) {
+ for (ind = 0; ind < info->num_inputs; ++ind) {
+ info->input_usage_mask[ind] |= usage_mask;
+ }
+ } else {
+ assert(ind >= 0);
+ assert(ind < PIPE_MAX_SHADER_INPUTS);
+ info->input_usage_mask[ind] |= usage_mask;
+ }
+
+ if (info->processor == PIPE_SHADER_FRAGMENT) {
+ unsigned name, index, input;
+
+ if (src->Register.Indirect && src->Indirect.ArrayID)
+ input = info->input_array_first[src->Indirect.ArrayID];
+ else
+ input = src->Register.Index;
+
+ name = info->input_semantic_name[input];
+ index = info->input_semantic_index[input];
+
+ if (name == TGSI_SEMANTIC_POSITION &&
+ (src->Register.SwizzleX == TGSI_SWIZZLE_Z ||
+ src->Register.SwizzleY == TGSI_SWIZZLE_Z ||
+ src->Register.SwizzleZ == TGSI_SWIZZLE_Z ||
+ src->Register.SwizzleW == TGSI_SWIZZLE_Z))
+ info->reads_z = TRUE;
+
+ if (name == TGSI_SEMANTIC_COLOR) {
+ unsigned mask =
+ (1 << src->Register.SwizzleX) |
+ (1 << src->Register.SwizzleY) |
+ (1 << src->Register.SwizzleZ) |
+ (1 << src->Register.SwizzleW);
+
+ info->colors_read |= mask << (index * 4);
+ }
+
+ /* Process only interpolated varyings. Don't include POSITION.
+ * Don't include integer varyings, because they are not
+ * interpolated. Don't process inputs interpolated by INTERP
+ * opcodes. Those are tracked separately.
+ */
+ if ((!is_interp_instruction || src_index != 0) &&
+ (name == TGSI_SEMANTIC_GENERIC ||
+ name == TGSI_SEMANTIC_TEXCOORD ||
+ name == TGSI_SEMANTIC_COLOR ||
+ name == TGSI_SEMANTIC_BCOLOR ||
+ name == TGSI_SEMANTIC_FOG ||
+ name == TGSI_SEMANTIC_CLIPDIST)) {
+ switch (info->input_interpolate[input]) {
+ case TGSI_INTERPOLATE_COLOR:
+ case TGSI_INTERPOLATE_PERSPECTIVE:
+ switch (info->input_interpolate_loc[input]) {
+ case TGSI_INTERPOLATE_LOC_CENTER:
+ info->uses_persp_center = TRUE;
+ break;
+ case TGSI_INTERPOLATE_LOC_CENTROID:
+ info->uses_persp_centroid = TRUE;
+ break;
+ case TGSI_INTERPOLATE_LOC_SAMPLE:
+ info->uses_persp_sample = TRUE;
+ break;
+ }
+ break;
+ case TGSI_INTERPOLATE_LINEAR:
+ switch (info->input_interpolate_loc[input]) {
+ case TGSI_INTERPOLATE_LOC_CENTER:
+ info->uses_linear_center = TRUE;
+ break;
+ case TGSI_INTERPOLATE_LOC_CENTROID:
+ info->uses_linear_centroid = TRUE;
+ break;
+ case TGSI_INTERPOLATE_LOC_SAMPLE:
+ info->uses_linear_sample = TRUE;
+ break;
+ }
+ break;
+ /* TGSI_INTERPOLATE_CONSTANT doesn't do any interpolation. */
+ }
+ }
+ }
+ }
+
+ /* check for indirect register reads */
+ if (src->Register.Indirect) {
+ info->indirect_files |= (1 << src->Register.File);
+ info->indirect_files_read |= (1 << src->Register.File);
+
+ /* record indirect constant buffer indexing */
+ if (src->Register.File == TGSI_FILE_CONSTANT) {
+ if (src->Register.Dimension) {
+ if (src->Dimension.Indirect)
+ info->const_buffers_indirect = info->const_buffers_declared;
+ else
+ info->const_buffers_indirect |= 1u << src->Dimension.Index;
+ } else {
+ info->const_buffers_indirect |= 1;
+ }
+ }
+ }
+
+ if (src->Register.Dimension && src->Dimension.Indirect)
+ info->dim_indirect_files |= 1u << src->Register.File;
+
+ /* Texture samplers */
+ if (src->Register.File == TGSI_FILE_SAMPLER) {
+ const unsigned index = src->Register.Index;
+
+ assert(fullinst->Instruction.Texture);
+ assert(index < ARRAY_SIZE(info->is_msaa_sampler));
+ assert(index < PIPE_MAX_SAMPLERS);
+
+ if (is_texture_inst(fullinst->Instruction.Opcode)) {
+ const unsigned target = fullinst->Texture.Texture;
+ assert(target < TGSI_TEXTURE_UNKNOWN);
+ /* for texture instructions, check that the texture instruction
+ * target matches the previous sampler view declaration (if there
+ * was one.)
+ */
+ if (info->sampler_targets[index] == TGSI_TEXTURE_UNKNOWN) {
+ /* probably no sampler view declaration */
+ info->sampler_targets[index] = target;
+ } else {
+ /* Make sure the texture instruction's sampler/target info
+ * agrees with the sampler view declaration.
+ */
+ assert(info->sampler_targets[index] == target);
+ }
+ /* MSAA samplers */
+ if (target == TGSI_TEXTURE_2D_MSAA ||
+ target == TGSI_TEXTURE_2D_ARRAY_MSAA) {
+ info->is_msaa_sampler[src->Register.Index] = TRUE;
+ }
+ }
+ }
+
+ if (is_memory_file(src->Register.File) &&
+ !is_mem_query_inst(fullinst->Instruction.Opcode)) {
+ *is_mem_inst = true;
+
+ if (tgsi_get_opcode_info(fullinst->Instruction.Opcode)->is_store) {
+ info->writes_memory = TRUE;
+
+ if (src->Register.File == TGSI_FILE_IMAGE) {
+ if (src->Register.Indirect)
+ info->images_writemask = info->images_declared;
+ else
+ info->images_writemask |= 1 << src->Register.Index;
+ } else if (src->Register.File == TGSI_FILE_BUFFER) {
+ if (src->Register.Indirect)
+ info->shader_buffers_atomic = info->shader_buffers_declared;
+ else
+ info->shader_buffers_atomic |= 1 << src->Register.Index;
+ }
+ } else {
+ if (src->Register.File == TGSI_FILE_BUFFER) {
+ if (src->Register.Indirect)
+ info->shader_buffers_load = info->shader_buffers_declared;
+ else
+ info->shader_buffers_load |= 1 << src->Register.Index;
+ }
+ }
+ }
+}
+
+
static void
scan_instruction(struct tgsi_shader_info *info,
const struct tgsi_full_instruction *fullinst,
info->uses_doubles = TRUE;
for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
- const struct tgsi_full_src_register *src = &fullinst->Src[i];
- int ind = src->Register.Index;
-
- /* Mark which inputs are effectively used */
- if (src->Register.File == TGSI_FILE_INPUT) {
- unsigned usage_mask;
- usage_mask = tgsi_util_get_inst_usage_mask(fullinst, i);
- if (src->Register.Indirect) {
- for (ind = 0; ind < info->num_inputs; ++ind) {
- info->input_usage_mask[ind] |= usage_mask;
- }
- } else {
- assert(ind >= 0);
- assert(ind < PIPE_MAX_SHADER_INPUTS);
- info->input_usage_mask[ind] |= usage_mask;
- }
-
- if (info->processor == PIPE_SHADER_FRAGMENT) {
- unsigned name, index, input;
-
- if (src->Register.Indirect && src->Indirect.ArrayID)
- input = info->input_array_first[src->Indirect.ArrayID];
- else
- input = src->Register.Index;
-
- name = info->input_semantic_name[input];
- index = info->input_semantic_index[input];
-
- if (name == TGSI_SEMANTIC_POSITION &&
- (src->Register.SwizzleX == TGSI_SWIZZLE_Z ||
- src->Register.SwizzleY == TGSI_SWIZZLE_Z ||
- src->Register.SwizzleZ == TGSI_SWIZZLE_Z ||
- src->Register.SwizzleW == TGSI_SWIZZLE_Z))
- info->reads_z = TRUE;
-
- if (name == TGSI_SEMANTIC_COLOR) {
- unsigned mask =
- (1 << src->Register.SwizzleX) |
- (1 << src->Register.SwizzleY) |
- (1 << src->Register.SwizzleZ) |
- (1 << src->Register.SwizzleW);
-
- info->colors_read |= mask << (index * 4);
- }
-
- /* Process only interpolated varyings. Don't include POSITION.
- * Don't include integer varyings, because they are not
- * interpolated. Don't process inputs interpolated by INTERP
- * opcodes. Those are tracked separately.
- */
- if ((!is_interp_instruction || i != 0) &&
- (name == TGSI_SEMANTIC_GENERIC ||
- name == TGSI_SEMANTIC_TEXCOORD ||
- name == TGSI_SEMANTIC_COLOR ||
- name == TGSI_SEMANTIC_BCOLOR ||
- name == TGSI_SEMANTIC_FOG ||
- name == TGSI_SEMANTIC_CLIPDIST)) {
- switch (info->input_interpolate[input]) {
- case TGSI_INTERPOLATE_COLOR:
- case TGSI_INTERPOLATE_PERSPECTIVE:
- switch (info->input_interpolate_loc[input]) {
- case TGSI_INTERPOLATE_LOC_CENTER:
- info->uses_persp_center = TRUE;
- break;
- case TGSI_INTERPOLATE_LOC_CENTROID:
- info->uses_persp_centroid = TRUE;
- break;
- case TGSI_INTERPOLATE_LOC_SAMPLE:
- info->uses_persp_sample = TRUE;
- break;
- }
- break;
- case TGSI_INTERPOLATE_LINEAR:
- switch (info->input_interpolate_loc[input]) {
- case TGSI_INTERPOLATE_LOC_CENTER:
- info->uses_linear_center = TRUE;
- break;
- case TGSI_INTERPOLATE_LOC_CENTROID:
- info->uses_linear_centroid = TRUE;
- break;
- case TGSI_INTERPOLATE_LOC_SAMPLE:
- info->uses_linear_sample = TRUE;
- break;
- }
- break;
- /* TGSI_INTERPOLATE_CONSTANT doesn't do any interpolation. */
- }
- }
- }
- }
-
- /* check for indirect register reads */
- if (src->Register.Indirect) {
- info->indirect_files |= (1 << src->Register.File);
- info->indirect_files_read |= (1 << src->Register.File);
-
- /* record indirect constant buffer indexing */
- if (src->Register.File == TGSI_FILE_CONSTANT) {
- if (src->Register.Dimension) {
- if (src->Dimension.Indirect)
- info->const_buffers_indirect = info->const_buffers_declared;
- else
- info->const_buffers_indirect |= 1u << src->Dimension.Index;
- } else {
- info->const_buffers_indirect |= 1;
- }
- }
- }
-
- if (src->Register.Dimension && src->Dimension.Indirect)
- info->dim_indirect_files |= 1u << src->Register.File;
-
- /* Texture samplers */
- if (src->Register.File == TGSI_FILE_SAMPLER) {
- const unsigned index = src->Register.Index;
-
- assert(fullinst->Instruction.Texture);
- assert(index < ARRAY_SIZE(info->is_msaa_sampler));
- assert(index < PIPE_MAX_SAMPLERS);
-
- if (is_texture_inst(fullinst->Instruction.Opcode)) {
- const unsigned target = fullinst->Texture.Texture;
- assert(target < TGSI_TEXTURE_UNKNOWN);
- /* for texture instructions, check that the texture instruction
- * target matches the previous sampler view declaration (if there
- * was one.)
- */
- if (info->sampler_targets[index] == TGSI_TEXTURE_UNKNOWN) {
- /* probably no sampler view declaration */
- info->sampler_targets[index] = target;
- } else {
- /* Make sure the texture instruction's sampler/target info
- * agrees with the sampler view declaration.
- */
- assert(info->sampler_targets[index] == target);
- }
- /* MSAA samplers */
- if (target == TGSI_TEXTURE_2D_MSAA ||
- target == TGSI_TEXTURE_2D_ARRAY_MSAA) {
- info->is_msaa_sampler[src->Register.Index] = TRUE;
- }
- }
- }
-
- if (is_memory_file(src->Register.File) &&
- !is_mem_query_inst(fullinst->Instruction.Opcode)) {
- is_mem_inst = true;
-
- if (tgsi_get_opcode_info(fullinst->Instruction.Opcode)->is_store) {
- info->writes_memory = TRUE;
-
- if (src->Register.File == TGSI_FILE_IMAGE) {
- if (src->Register.Indirect)
- info->images_writemask = info->images_declared;
- else
- info->images_writemask |= 1 << src->Register.Index;
- } else if (src->Register.File == TGSI_FILE_BUFFER) {
- if (src->Register.Indirect)
- info->shader_buffers_atomic = info->shader_buffers_declared;
- else
- info->shader_buffers_atomic |= 1 << src->Register.Index;
- }
- } else {
- if (src->Register.File == TGSI_FILE_BUFFER) {
- if (src->Register.Indirect)
- info->shader_buffers_load = info->shader_buffers_declared;
- else
- info->shader_buffers_load |= 1 << src->Register.Index;
- }
- }
- }
+ scan_src_operand(info, fullinst, &fullinst->Src[i], i,
+ tgsi_util_get_inst_usage_mask(fullinst, i),
+ is_interp_instruction, &is_mem_inst);
}
/* check for indirect register writes */