[D3D12] DXBC: Source map comment output
This commit is contained in:
parent
95ed3ea158
commit
6a8a080703
|
@ -34,6 +34,9 @@ DEFINE_bool(dxbc_switch, true,
|
||||||
"driver - on AMD, it's recommended to have this set to true, as "
|
"driver - on AMD, it's recommended to have this set to true, as "
|
||||||
"Halo 3 appears to crash when if is used for flow control "
|
"Halo 3 appears to crash when if is used for flow control "
|
||||||
"(possibly the shader compiler tries to flatten them).");
|
"(possibly the shader compiler tries to flatten them).");
|
||||||
|
DEFINE_bool(dxbc_source_map, false,
|
||||||
|
"Disassemble Xenos instructions as comments in the resulting DXBC "
|
||||||
|
"for debugging.");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
@ -5638,6 +5641,42 @@ std::vector<uint8_t> DxbcShaderTranslator::CompleteTranslation() {
|
||||||
return shader_object_bytes;
|
return shader_object_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DxbcShaderTranslator::EmitInstructionDisassembly() {
|
||||||
|
if (!FLAGS_dxbc_source_map) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* source = instruction_disassembly_buffer_.GetString();
|
||||||
|
uint32_t length = uint32_t(instruction_disassembly_buffer_.length());
|
||||||
|
// Trim leading spaces and trailing new line.
|
||||||
|
while (length != 0 && source[0] == ' ') {
|
||||||
|
++source;
|
||||||
|
--length;
|
||||||
|
}
|
||||||
|
while (length != 0 && source[length - 1] == '\n') {
|
||||||
|
--length;
|
||||||
|
}
|
||||||
|
if (length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t length_dwords =
|
||||||
|
(length + 1 + (sizeof(uint32_t) - 1)) / sizeof(uint32_t);
|
||||||
|
shader_code_.push_back(
|
||||||
|
ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_CUSTOMDATA) |
|
||||||
|
ENCODE_D3D10_SB_CUSTOMDATA_CLASS(D3D10_SB_CUSTOMDATA_COMMENT));
|
||||||
|
shader_code_.push_back(2 + length_dwords);
|
||||||
|
size_t offset_dwords = shader_code_.size();
|
||||||
|
shader_code_.resize(offset_dwords + length_dwords);
|
||||||
|
char* target = reinterpret_cast<char*>(&shader_code_[offset_dwords]);
|
||||||
|
std::memcpy(target, source, length);
|
||||||
|
target[length] = '\0';
|
||||||
|
// Don't leave uninitialized data, and make sure multiple invocations of the
|
||||||
|
// translator for the same Xenos shader give the same DXBC.
|
||||||
|
std::memset(target + length + 1, 0xAB,
|
||||||
|
length_dwords * sizeof(uint32_t) - length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
void DxbcShaderTranslator::LoadDxbcSourceOperand(
|
void DxbcShaderTranslator::LoadDxbcSourceOperand(
|
||||||
const InstructionOperand& operand, DxbcSourceOperand& dxbc_operand) {
|
const InstructionOperand& operand, DxbcSourceOperand& dxbc_operand) {
|
||||||
// Initialize the values to their defaults.
|
// Initialize the values to their defaults.
|
||||||
|
@ -6523,34 +6562,48 @@ void DxbcShaderTranslator::StoreResult(const InstructionResult& result,
|
||||||
|
|
||||||
void DxbcShaderTranslator::UpdateExecConditionals(
|
void DxbcShaderTranslator::UpdateExecConditionals(
|
||||||
ParsedExecInstruction::Type type, uint32_t bool_constant_index,
|
ParsedExecInstruction::Type type, uint32_t bool_constant_index,
|
||||||
bool condition) {
|
bool condition, bool emit_disassembly) {
|
||||||
// Check if we can merge the new exec with the previous one, or the jump with
|
// Check if we can merge the new exec with the previous one, or the jump with
|
||||||
// the previous exec. The instruction-level predicate check is also merged in
|
// the previous exec. The instruction-level predicate check is also merged in
|
||||||
// this case.
|
// this case.
|
||||||
|
bool merge = false;
|
||||||
if (type == ParsedExecInstruction::Type::kConditional) {
|
if (type == ParsedExecInstruction::Type::kConditional) {
|
||||||
// Can merge conditional with conditional, as long as the bool constant and
|
// Can merge conditional with conditional, as long as the bool constant and
|
||||||
// the expected values are the same.
|
// the expected values are the same.
|
||||||
if (cf_exec_bool_constant_ == bool_constant_index &&
|
if (cf_exec_bool_constant_ == bool_constant_index &&
|
||||||
cf_exec_bool_constant_condition_ == condition) {
|
cf_exec_bool_constant_condition_ == condition) {
|
||||||
return;
|
merge = true;
|
||||||
}
|
}
|
||||||
} else if (type == ParsedExecInstruction::Type::kPredicated) {
|
} else if (type == ParsedExecInstruction::Type::kPredicated) {
|
||||||
// Can merge predicated with predicated if the conditions are the same and
|
// Can merge predicated with predicated if the conditions are the same and
|
||||||
// the previous exec hasn't modified the predicate register.
|
// the previous exec hasn't modified the predicate register.
|
||||||
if (!cf_exec_predicate_written_ && cf_exec_predicated_ &&
|
if (!cf_exec_predicate_written_ && cf_exec_predicated_ &&
|
||||||
cf_exec_predicate_condition_ == condition) {
|
cf_exec_predicate_condition_ == condition) {
|
||||||
return;
|
merge = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Can merge unconditional with unconditional.
|
// Can merge unconditional with unconditional.
|
||||||
if (cf_exec_bool_constant_ == kCfExecBoolConstantNone &&
|
if (cf_exec_bool_constant_ == kCfExecBoolConstantNone &&
|
||||||
!cf_exec_predicated_) {
|
!cf_exec_predicated_) {
|
||||||
return;
|
merge = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (merge) {
|
||||||
|
// Emit the disassembly for the exec/jump merged with the previous one.
|
||||||
|
if (emit_disassembly) {
|
||||||
|
EmitInstructionDisassembly();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CloseExecConditionals();
|
CloseExecConditionals();
|
||||||
|
|
||||||
|
// Emit the disassembly for the new exec/jump.
|
||||||
|
if (emit_disassembly) {
|
||||||
|
EmitInstructionDisassembly();
|
||||||
|
}
|
||||||
|
|
||||||
D3D10_SB_INSTRUCTION_TEST_BOOLEAN test =
|
D3D10_SB_INSTRUCTION_TEST_BOOLEAN test =
|
||||||
condition ? D3D10_SB_INSTRUCTION_TEST_NONZERO
|
condition ? D3D10_SB_INSTRUCTION_TEST_NONZERO
|
||||||
: D3D10_SB_INSTRUCTION_TEST_ZERO;
|
: D3D10_SB_INSTRUCTION_TEST_ZERO;
|
||||||
|
@ -6625,15 +6678,25 @@ void DxbcShaderTranslator::CloseExecConditionals() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DxbcShaderTranslator::UpdateInstructionPredication(bool predicated,
|
void DxbcShaderTranslator::UpdateInstructionPredication(bool predicated,
|
||||||
bool condition) {
|
bool condition,
|
||||||
|
bool emit_disassembly) {
|
||||||
if (predicated) {
|
if (predicated) {
|
||||||
if (cf_instruction_predicate_if_open_) {
|
if (cf_instruction_predicate_if_open_) {
|
||||||
if (cf_instruction_predicate_condition_ == condition) {
|
if (cf_instruction_predicate_condition_ == condition) {
|
||||||
// Already in the needed instruction-level `if`.
|
// Already in the needed instruction-level `if`.
|
||||||
|
if (emit_disassembly) {
|
||||||
|
EmitInstructionDisassembly();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CloseInstructionPredication();
|
CloseInstructionPredication();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emit the disassembly before opening (or not opening) the new conditional.
|
||||||
|
if (emit_disassembly) {
|
||||||
|
EmitInstructionDisassembly();
|
||||||
|
}
|
||||||
|
|
||||||
// If the instruction predicate condition is the same as the exec predicate
|
// If the instruction predicate condition is the same as the exec predicate
|
||||||
// condition, no need to open a check. However, if there was a `setp` prior
|
// condition, no need to open a check. However, if there was a `setp` prior
|
||||||
// to this instruction, the predicate value now may be different than it was
|
// to this instruction, the predicate value now may be different than it was
|
||||||
|
@ -6659,6 +6722,9 @@ void DxbcShaderTranslator::UpdateInstructionPredication(bool predicated,
|
||||||
cf_instruction_predicate_condition_ = condition;
|
cf_instruction_predicate_condition_ = condition;
|
||||||
} else {
|
} else {
|
||||||
CloseInstructionPredication();
|
CloseInstructionPredication();
|
||||||
|
if (emit_disassembly) {
|
||||||
|
EmitInstructionDisassembly();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7016,8 +7082,13 @@ void DxbcShaderTranslator::ProcessLabel(uint32_t cf_index) {
|
||||||
|
|
||||||
void DxbcShaderTranslator::ProcessExecInstructionBegin(
|
void DxbcShaderTranslator::ProcessExecInstructionBegin(
|
||||||
const ParsedExecInstruction& instr) {
|
const ParsedExecInstruction& instr) {
|
||||||
UpdateExecConditionals(instr.type, instr.bool_constant_index,
|
if (FLAGS_dxbc_source_map) {
|
||||||
instr.condition);
|
instruction_disassembly_buffer_.Reset();
|
||||||
|
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||||
|
// Will be emitted by UpdateExecConditionals.
|
||||||
|
}
|
||||||
|
UpdateExecConditionals(instr.type, instr.bool_constant_index, instr.condition,
|
||||||
|
true);
|
||||||
// TODO(Triang3l): Find out what PredicateClean=false in exec actually means
|
// TODO(Triang3l): Find out what PredicateClean=false in exec actually means
|
||||||
// (execs containing setp have PredicateClean=false, it possibly means that
|
// (execs containing setp have PredicateClean=false, it possibly means that
|
||||||
// the predicate is dirty after the exec).
|
// the predicate is dirty after the exec).
|
||||||
|
@ -7062,6 +7133,12 @@ void DxbcShaderTranslator::ProcessLoopStartInstruction(
|
||||||
// Loop control is outside execs - actually close the last exec.
|
// Loop control is outside execs - actually close the last exec.
|
||||||
CloseExecConditionals();
|
CloseExecConditionals();
|
||||||
|
|
||||||
|
if (FLAGS_dxbc_source_map) {
|
||||||
|
instruction_disassembly_buffer_.Reset();
|
||||||
|
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||||
|
EmitInstructionDisassembly();
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t loop_count_and_aL = PushSystemTemp();
|
uint32_t loop_count_and_aL = PushSystemTemp();
|
||||||
|
|
||||||
// Count (as uint) in bits 0:7 of the loop constant, aL in 8:15.
|
// Count (as uint) in bits 0:7 of the loop constant, aL in 8:15.
|
||||||
|
@ -7168,6 +7245,12 @@ void DxbcShaderTranslator::ProcessLoopEndInstruction(
|
||||||
// Loop control is outside execs - actually close the last exec.
|
// Loop control is outside execs - actually close the last exec.
|
||||||
CloseExecConditionals();
|
CloseExecConditionals();
|
||||||
|
|
||||||
|
if (FLAGS_dxbc_source_map) {
|
||||||
|
instruction_disassembly_buffer_.Reset();
|
||||||
|
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||||
|
EmitInstructionDisassembly();
|
||||||
|
}
|
||||||
|
|
||||||
// Subtract 1 from the loop counter.
|
// Subtract 1 from the loop counter.
|
||||||
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) |
|
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IADD) |
|
||||||
ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7));
|
ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(7));
|
||||||
|
@ -7320,6 +7403,12 @@ void DxbcShaderTranslator::ProcessLoopEndInstruction(
|
||||||
|
|
||||||
void DxbcShaderTranslator::ProcessJumpInstruction(
|
void DxbcShaderTranslator::ProcessJumpInstruction(
|
||||||
const ParsedJumpInstruction& instr) {
|
const ParsedJumpInstruction& instr) {
|
||||||
|
if (FLAGS_dxbc_source_map) {
|
||||||
|
instruction_disassembly_buffer_.Reset();
|
||||||
|
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||||
|
// Will be emitted by UpdateExecConditionals.
|
||||||
|
}
|
||||||
|
|
||||||
// Treat like exec, merge with execs if possible, since it's an if too.
|
// Treat like exec, merge with execs if possible, since it's an if too.
|
||||||
ParsedExecInstruction::Type type;
|
ParsedExecInstruction::Type type;
|
||||||
if (instr.type == ParsedJumpInstruction::Type::kConditional) {
|
if (instr.type == ParsedJumpInstruction::Type::kConditional) {
|
||||||
|
@ -7329,7 +7418,8 @@ void DxbcShaderTranslator::ProcessJumpInstruction(
|
||||||
} else {
|
} else {
|
||||||
type = ParsedExecInstruction::Type::kUnconditional;
|
type = ParsedExecInstruction::Type::kUnconditional;
|
||||||
}
|
}
|
||||||
UpdateExecConditionals(type, instr.bool_constant_index, instr.condition);
|
UpdateExecConditionals(type, instr.bool_constant_index, instr.condition,
|
||||||
|
true);
|
||||||
|
|
||||||
// UpdateExecConditionals may not necessarily close the instruction-level
|
// UpdateExecConditionals may not necessarily close the instruction-level
|
||||||
// predicate check (it's not necessary if the execs are merged), but here the
|
// predicate check (it's not necessary if the execs are merged), but here the
|
||||||
|
@ -7388,7 +7478,13 @@ void DxbcShaderTranslator::ProcessVertexFetchInstruction(
|
||||||
}
|
}
|
||||||
uint32_t result_write_mask = (1 << result_component_count) - 1;
|
uint32_t result_write_mask = (1 << result_component_count) - 1;
|
||||||
|
|
||||||
UpdateInstructionPredication(instr.is_predicated, instr.predicate_condition);
|
if (FLAGS_dxbc_source_map) {
|
||||||
|
instruction_disassembly_buffer_.Reset();
|
||||||
|
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||||
|
// Will be emitted by UpdateInstructionPredication.
|
||||||
|
}
|
||||||
|
UpdateInstructionPredication(instr.is_predicated, instr.predicate_condition,
|
||||||
|
true);
|
||||||
|
|
||||||
// Convert the index to an integer.
|
// Convert the index to an integer.
|
||||||
DxbcSourceOperand index_operand;
|
DxbcSourceOperand index_operand;
|
||||||
|
@ -8138,6 +8234,12 @@ void DxbcShaderTranslator::ArrayCoordToCubeDirection(uint32_t reg) {
|
||||||
|
|
||||||
void DxbcShaderTranslator::ProcessTextureFetchInstruction(
|
void DxbcShaderTranslator::ProcessTextureFetchInstruction(
|
||||||
const ParsedTextureFetchInstruction& instr) {
|
const ParsedTextureFetchInstruction& instr) {
|
||||||
|
if (FLAGS_dxbc_source_map) {
|
||||||
|
instruction_disassembly_buffer_.Reset();
|
||||||
|
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||||
|
// Will be emitted later explicitly or by UpdateInstructionPredication.
|
||||||
|
}
|
||||||
|
|
||||||
// Predication should not affect derivative calculation:
|
// Predication should not affect derivative calculation:
|
||||||
// https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx9-graphics-reference-asm-ps-registers-output-color
|
// https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx9-graphics-reference-asm-ps-registers-output-color
|
||||||
// Do the part involving derivative calculation unconditionally, and re-enter
|
// Do the part involving derivative calculation unconditionally, and re-enter
|
||||||
|
@ -8154,6 +8256,9 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
|
||||||
}
|
}
|
||||||
uint32_t exec_p0_temp = UINT32_MAX;
|
uint32_t exec_p0_temp = UINT32_MAX;
|
||||||
if (suppress_predication) {
|
if (suppress_predication) {
|
||||||
|
// Emit the disassembly before all this to indicate the reason of going
|
||||||
|
// unconditional.
|
||||||
|
EmitInstructionDisassembly();
|
||||||
// Close instruction-level predication.
|
// Close instruction-level predication.
|
||||||
CloseInstructionPredication();
|
CloseInstructionPredication();
|
||||||
// Temporarily close exec-level predication - will reopen at the end, so not
|
// Temporarily close exec-level predication - will reopen at the end, so not
|
||||||
|
@ -8198,8 +8303,8 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
|
||||||
++stat_.instruction_count;
|
++stat_.instruction_count;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
UpdateInstructionPredication(instr.is_predicated,
|
UpdateInstructionPredication(instr.is_predicated, instr.predicate_condition,
|
||||||
instr.predicate_condition);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool store_result = false;
|
bool store_result = false;
|
||||||
|
@ -9479,8 +9584,8 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update instruction-level predication to the one needed by this tfetch.
|
// Update instruction-level predication to the one needed by this tfetch.
|
||||||
UpdateInstructionPredication(instr.is_predicated,
|
UpdateInstructionPredication(instr.is_predicated, instr.predicate_condition,
|
||||||
instr.predicate_condition);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (store_result) {
|
if (store_result) {
|
||||||
|
@ -9490,7 +9595,13 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
|
||||||
|
|
||||||
void DxbcShaderTranslator::ProcessVectorAluInstruction(
|
void DxbcShaderTranslator::ProcessVectorAluInstruction(
|
||||||
const ParsedAluInstruction& instr) {
|
const ParsedAluInstruction& instr) {
|
||||||
UpdateInstructionPredication(instr.is_predicated, instr.predicate_condition);
|
if (FLAGS_dxbc_source_map) {
|
||||||
|
instruction_disassembly_buffer_.Reset();
|
||||||
|
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||||
|
// Will be emitted by UpdateInstructionPredication.
|
||||||
|
}
|
||||||
|
UpdateInstructionPredication(instr.is_predicated, instr.predicate_condition,
|
||||||
|
true);
|
||||||
// Whether the instruction has changed the predicate and it needs to be
|
// Whether the instruction has changed the predicate and it needs to be
|
||||||
// checked again later.
|
// checked again later.
|
||||||
bool predicate_written = false;
|
bool predicate_written = false;
|
||||||
|
@ -10721,7 +10832,13 @@ void DxbcShaderTranslator::ProcessVectorAluInstruction(
|
||||||
|
|
||||||
void DxbcShaderTranslator::ProcessScalarAluInstruction(
|
void DxbcShaderTranslator::ProcessScalarAluInstruction(
|
||||||
const ParsedAluInstruction& instr) {
|
const ParsedAluInstruction& instr) {
|
||||||
UpdateInstructionPredication(instr.is_predicated, instr.predicate_condition);
|
if (FLAGS_dxbc_source_map) {
|
||||||
|
instruction_disassembly_buffer_.Reset();
|
||||||
|
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||||
|
// Will be emitted by UpdateInstructionPredication.
|
||||||
|
}
|
||||||
|
UpdateInstructionPredication(instr.is_predicated, instr.predicate_condition,
|
||||||
|
true);
|
||||||
// Whether the instruction has changed the predicate and it needs to be
|
// Whether the instruction has changed the predicate and it needs to be
|
||||||
// checked again later.
|
// checked again later.
|
||||||
bool predicate_written = false;
|
bool predicate_written = false;
|
||||||
|
@ -11830,6 +11947,8 @@ uint32_t DxbcShaderTranslator::AppendString(std::vector<uint32_t>& dest,
|
||||||
size_t dest_position = dest.size();
|
size_t dest_position = dest.size();
|
||||||
dest.resize(dest_position + size_aligned / sizeof(uint32_t));
|
dest.resize(dest_position + size_aligned / sizeof(uint32_t));
|
||||||
std::memcpy(&dest[dest_position], source, size);
|
std::memcpy(&dest[dest_position], source, size);
|
||||||
|
// Don't leave uninitialized data, and make sure multiple invocations of the
|
||||||
|
// translator for the same Xenos shader give the same DXBC.
|
||||||
std::memset(reinterpret_cast<uint8_t*>(&dest[dest_position]) + size, 0xAB,
|
std::memset(reinterpret_cast<uint8_t*>(&dest[dest_position]) + size, 0xAB,
|
||||||
size_aligned - size);
|
size_aligned - size);
|
||||||
return uint32_t(size_aligned);
|
return uint32_t(size_aligned);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
|
#include "xenia/base/string_buffer.h"
|
||||||
#include "xenia/gpu/shader_translator.h"
|
#include "xenia/gpu/shader_translator.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
@ -790,6 +791,10 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
void CompletePixelShader();
|
void CompletePixelShader();
|
||||||
void CompleteShaderCode();
|
void CompleteShaderCode();
|
||||||
|
|
||||||
|
// Writes the original instruction disassembly in the output DXBC if enabled,
|
||||||
|
// as shader messages, from instruction_disassembly_buffer_.
|
||||||
|
void EmitInstructionDisassembly();
|
||||||
|
|
||||||
// Abstract 4-component vector source operand.
|
// Abstract 4-component vector source operand.
|
||||||
struct DxbcSourceOperand {
|
struct DxbcSourceOperand {
|
||||||
enum class Type {
|
enum class Type {
|
||||||
|
@ -871,14 +876,21 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
// of exec and in jumps), closing the previous conditionals if needed.
|
// of exec and in jumps), closing the previous conditionals if needed.
|
||||||
// However, if the condition is not different, the instruction-level predicate
|
// However, if the condition is not different, the instruction-level predicate
|
||||||
// `if` also won't be closed - this must be checked separately if needed (for
|
// `if` also won't be closed - this must be checked separately if needed (for
|
||||||
// example, in jumps).
|
// example, in jumps). If emit_disassembly is true, this function emits the
|
||||||
|
// last disassembly written to instruction_disassembly_buffer_ after closing
|
||||||
|
// the previous conditional and before opening a new one.
|
||||||
void UpdateExecConditionals(ParsedExecInstruction::Type type,
|
void UpdateExecConditionals(ParsedExecInstruction::Type type,
|
||||||
uint32_t bool_constant_index, bool condition);
|
uint32_t bool_constant_index, bool condition,
|
||||||
|
bool emit_disassembly);
|
||||||
// Closes `if`s opened by exec and instructions within them (but not by
|
// Closes `if`s opened by exec and instructions within them (but not by
|
||||||
// labels) and updates the state accordingly.
|
// labels) and updates the state accordingly.
|
||||||
void CloseExecConditionals();
|
void CloseExecConditionals();
|
||||||
// Opens or reopens the predicate check conditional for the instruction.
|
// Opens or reopens the predicate check conditional for the instruction. If
|
||||||
void UpdateInstructionPredication(bool predicated, bool condition);
|
// emit_disassembly is true, this function emits the last disassembly written
|
||||||
|
// to instruction_disassembly_buffer_ after closing the previous predicate
|
||||||
|
// conditional and before opening a new one.
|
||||||
|
void UpdateInstructionPredication(bool predicated, bool condition,
|
||||||
|
bool emit_disassembly);
|
||||||
// Closes the instruction-level predicate `if` if it's open, useful if a flow
|
// Closes the instruction-level predicate `if` if it's open, useful if a flow
|
||||||
// control instruction needs to do some code which needs to respect the exec's
|
// control instruction needs to do some code which needs to respect the exec's
|
||||||
// conditional, but can't itself be predicated.
|
// conditional, but can't itself be predicated.
|
||||||
|
@ -924,6 +936,9 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
// generated in the end of translation.
|
// generated in the end of translation.
|
||||||
std::vector<uint32_t> shader_object_;
|
std::vector<uint32_t> shader_object_;
|
||||||
|
|
||||||
|
// Buffer for instruction disassembly comments.
|
||||||
|
StringBuffer instruction_disassembly_buffer_;
|
||||||
|
|
||||||
// Whether the output merger should be emulated in pixel shaders.
|
// Whether the output merger should be emulated in pixel shaders.
|
||||||
bool edram_rov_used_;
|
bool edram_rov_used_;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue