tgsi/scan: move src operand processing into a separate function
the next commit will need this Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
This commit is contained in:
@@ -102,6 +102,186 @@ computes_derivative(unsigned opcode)
|
||||
}
|
||||
|
||||
|
||||
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,
|
||||
@@ -183,177 +363,9 @@ scan_instruction(struct tgsi_shader_info *info,
|
||||
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 */
|
||||
|
||||
Reference in New Issue
Block a user