Merge remote-tracking branch 'upstream/master' into canary-old-update
This commit is contained in:
commit
535696e6bd
|
@ -20,6 +20,7 @@
|
|||
#include "xenia/gpu/d3d12/d3d12_command_processor.h"
|
||||
#include "xenia/gpu/d3d12/d3d12_graphics_system.h"
|
||||
#include "xenia/gpu/d3d12/d3d12_shader.h"
|
||||
#include "xenia/gpu/gpu_flags.h"
|
||||
#include "xenia/gpu/xenos.h"
|
||||
#include "xenia/ui/d3d12/d3d12_util.h"
|
||||
|
||||
|
@ -1476,10 +1477,23 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
|||
}
|
||||
const auto& vfetch_constant = regs.Get<xenos::xe_gpu_vertex_fetch_t>(
|
||||
XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + vfetch_index * 2);
|
||||
if (vfetch_constant.type != 3) {
|
||||
XELOGW("Vertex fetch type is not 3 (fetch constant %u is %.8X %.8X)!",
|
||||
vfetch_index, vfetch_constant.dword_0, vfetch_constant.dword_1);
|
||||
return false;
|
||||
switch (vfetch_constant.type) {
|
||||
case xenos::FetchConstantType::kVertex:
|
||||
break;
|
||||
case xenos::FetchConstantType::kInvalidVertex:
|
||||
if (cvars::gpu_allow_invalid_fetch_constants) {
|
||||
break;
|
||||
}
|
||||
XELOGW(
|
||||
"Vertex fetch constant %u (%.8X %.8X) has \"invalid\" type! This "
|
||||
"is incorrect behavior, but you can try bypassing this by "
|
||||
"launching Xenia with --gpu_allow_invalid_fetch_constants=true.",
|
||||
vfetch_index, vfetch_constant.dword_0, vfetch_constant.dword_1);
|
||||
return false;
|
||||
default:
|
||||
XELOGW("Vertex fetch constant %u (%.8X %.8X) is completely invalid!",
|
||||
vfetch_index, vfetch_constant.dword_0, vfetch_constant.dword_1);
|
||||
return false;
|
||||
}
|
||||
if (!shared_memory_->RequestRange(vfetch_constant.address << 2,
|
||||
vfetch_constant.size << 2)) {
|
||||
|
|
|
@ -72,7 +72,8 @@ PipelineCache::PipelineCache(D3D12CommandProcessor* command_processor,
|
|||
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider();
|
||||
|
||||
shader_translator_ = std::make_unique<DxbcShaderTranslator>(
|
||||
provider->GetAdapterVendorID(), edram_rov_used_);
|
||||
provider->GetAdapterVendorID(), edram_rov_used_,
|
||||
provider->GetGraphicsAnalysis() != nullptr);
|
||||
|
||||
if (edram_rov_used_) {
|
||||
depth_only_pixel_shader_ =
|
||||
|
|
|
@ -1087,7 +1087,7 @@ bool RenderTargetCache::Resolve(SharedMemory* shared_memory,
|
|||
// HACK: Vertices to use are always in vf0.
|
||||
const auto& fetch = regs.Get<xenos::xe_gpu_vertex_fetch_t>(
|
||||
XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0);
|
||||
assert_true(fetch.type == 3);
|
||||
assert_true(fetch.type == xenos::FetchConstantType::kVertex);
|
||||
assert_true(fetch.endian == Endian::k8in32);
|
||||
assert_true(fetch.size == 6);
|
||||
trace_writer_->WriteMemoryRead(fetch.address << 2, fetch.size << 2);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "xenia/base/math.h"
|
||||
#include "xenia/base/profiling.h"
|
||||
#include "xenia/gpu/d3d12/d3d12_command_processor.h"
|
||||
#include "xenia/gpu/gpu_flags.h"
|
||||
#include "xenia/gpu/texture_info.h"
|
||||
#include "xenia/gpu/texture_util.h"
|
||||
#include "xenia/ui/d3d12/d3d12_util.h"
|
||||
|
@ -2094,13 +2095,28 @@ void TextureCache::BindingInfoFromFetchConstant(
|
|||
*has_signed_out = false;
|
||||
}
|
||||
|
||||
if (fetch.type != 2) {
|
||||
XELOGW(
|
||||
"Texture fetch type is not 2 - ignoring (fetch constant is %.8X %.8X "
|
||||
"%.8X %.8X %.8X %.8X)!",
|
||||
fetch.dword_0, fetch.dword_1, fetch.dword_2, fetch.dword_3,
|
||||
fetch.dword_4, fetch.dword_5);
|
||||
return;
|
||||
switch (fetch.type) {
|
||||
case xenos::FetchConstantType::kTexture:
|
||||
break;
|
||||
case xenos::FetchConstantType::kInvalidTexture:
|
||||
if (cvars::gpu_allow_invalid_fetch_constants) {
|
||||
break;
|
||||
}
|
||||
XELOGW(
|
||||
"Texture fetch constant (%.8X %.8X %.8X %.8X %.8X %.8X) has "
|
||||
"\"invalid\" type! This is incorrect behavior, but you can try "
|
||||
"bypassing this by launching Xenia with "
|
||||
"--gpu_allow_invalid_fetch_constants=true.",
|
||||
fetch.dword_0, fetch.dword_1, fetch.dword_2, fetch.dword_3,
|
||||
fetch.dword_4, fetch.dword_5);
|
||||
return;
|
||||
default:
|
||||
XELOGW(
|
||||
"Texture fetch constant (%.8X %.8X %.8X %.8X %.8X %.8X) is "
|
||||
"completely invalid!",
|
||||
fetch.dword_0, fetch.dword_1, fetch.dword_2, fetch.dword_3,
|
||||
fetch.dword_4, fetch.dword_5);
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the dimensions, get the size and clamp the maximum mip level.
|
||||
|
|
|
@ -81,8 +81,10 @@ constexpr uint32_t DxbcShaderTranslator::kCbufferIndexUnallocated;
|
|||
constexpr uint32_t DxbcShaderTranslator::kCfExecBoolConstantNone;
|
||||
|
||||
DxbcShaderTranslator::DxbcShaderTranslator(uint32_t vendor_id,
|
||||
bool edram_rov_used)
|
||||
bool edram_rov_used,
|
||||
bool force_emit_source_map)
|
||||
: vendor_id_(vendor_id), edram_rov_used_(edram_rov_used) {
|
||||
emit_source_map_ = force_emit_source_map || cvars::dxbc_source_map;
|
||||
// Don't allocate again and again for the first shader.
|
||||
shader_code_.reserve(8192);
|
||||
shader_object_.reserve(16384);
|
||||
|
@ -1963,7 +1965,7 @@ std::vector<uint8_t> DxbcShaderTranslator::CompleteTranslation() {
|
|||
}
|
||||
|
||||
void DxbcShaderTranslator::EmitInstructionDisassembly() {
|
||||
if (!cvars::dxbc_source_map) {
|
||||
if (!emit_source_map_) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2955,7 +2957,7 @@ void DxbcShaderTranslator::ProcessLabel(uint32_t cf_index) {
|
|||
|
||||
void DxbcShaderTranslator::ProcessExecInstructionBegin(
|
||||
const ParsedExecInstruction& instr) {
|
||||
if (cvars::dxbc_source_map) {
|
||||
if (emit_source_map_) {
|
||||
instruction_disassembly_buffer_.Reset();
|
||||
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||
// Will be emitted by UpdateExecConditionals.
|
||||
|
@ -3006,7 +3008,7 @@ void DxbcShaderTranslator::ProcessLoopStartInstruction(
|
|||
// Loop control is outside execs - actually close the last exec.
|
||||
CloseExecConditionals();
|
||||
|
||||
if (cvars::dxbc_source_map) {
|
||||
if (emit_source_map_) {
|
||||
instruction_disassembly_buffer_.Reset();
|
||||
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||
EmitInstructionDisassembly();
|
||||
|
@ -3118,7 +3120,7 @@ void DxbcShaderTranslator::ProcessLoopEndInstruction(
|
|||
// Loop control is outside execs - actually close the last exec.
|
||||
CloseExecConditionals();
|
||||
|
||||
if (cvars::dxbc_source_map) {
|
||||
if (emit_source_map_) {
|
||||
instruction_disassembly_buffer_.Reset();
|
||||
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||
EmitInstructionDisassembly();
|
||||
|
@ -3276,7 +3278,7 @@ void DxbcShaderTranslator::ProcessLoopEndInstruction(
|
|||
|
||||
void DxbcShaderTranslator::ProcessJumpInstruction(
|
||||
const ParsedJumpInstruction& instr) {
|
||||
if (cvars::dxbc_source_map) {
|
||||
if (emit_source_map_) {
|
||||
instruction_disassembly_buffer_.Reset();
|
||||
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||
// Will be emitted by UpdateExecConditionals.
|
||||
|
@ -3305,7 +3307,7 @@ void DxbcShaderTranslator::ProcessJumpInstruction(
|
|||
|
||||
void DxbcShaderTranslator::ProcessAllocInstruction(
|
||||
const ParsedAllocInstruction& instr) {
|
||||
if (cvars::dxbc_source_map) {
|
||||
if (emit_source_map_) {
|
||||
instruction_disassembly_buffer_.Reset();
|
||||
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||
EmitInstructionDisassembly();
|
||||
|
|
|
@ -55,7 +55,8 @@ namespace gpu {
|
|||
// 0 for NaN.
|
||||
class DxbcShaderTranslator : public ShaderTranslator {
|
||||
public:
|
||||
DxbcShaderTranslator(uint32_t vendor_id, bool edram_rov_used);
|
||||
DxbcShaderTranslator(uint32_t vendor_id, bool edram_rov_used,
|
||||
bool force_emit_source_map = false);
|
||||
~DxbcShaderTranslator() override;
|
||||
|
||||
// Constant buffer bindings in space 0.
|
||||
|
@ -1874,6 +1875,10 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
|||
// Buffer for instruction disassembly comments.
|
||||
StringBuffer instruction_disassembly_buffer_;
|
||||
|
||||
// Whether to write comments with the original Xenos instructions to the
|
||||
// output.
|
||||
bool emit_source_map_;
|
||||
|
||||
// Vendor ID of the GPU manufacturer, for toggling unsupported features.
|
||||
uint32_t vendor_id_;
|
||||
|
||||
|
|
|
@ -2425,7 +2425,7 @@ void DxbcShaderTranslator::ProcessAluInstruction(
|
|||
return;
|
||||
}
|
||||
|
||||
if (cvars::dxbc_source_map) {
|
||||
if (emit_source_map_) {
|
||||
instruction_disassembly_buffer_.Reset();
|
||||
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||
// Will be emitted by UpdateInstructionPredication.
|
||||
|
|
|
@ -322,7 +322,7 @@ void DxbcShaderTranslator::ProcessVertexFetchInstruction(
|
|||
}
|
||||
uint32_t result_write_mask = (1 << result_component_count) - 1;
|
||||
|
||||
if (cvars::dxbc_source_map) {
|
||||
if (emit_source_map_) {
|
||||
instruction_disassembly_buffer_.Reset();
|
||||
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||
// Will be emitted by UpdateInstructionPredication.
|
||||
|
@ -1162,7 +1162,7 @@ void DxbcShaderTranslator::ArrayCoordToCubeDirection(uint32_t reg) {
|
|||
|
||||
void DxbcShaderTranslator::ProcessTextureFetchInstruction(
|
||||
const ParsedTextureFetchInstruction& instr) {
|
||||
if (cvars::dxbc_source_map) {
|
||||
if (emit_source_map_) {
|
||||
instruction_disassembly_buffer_.Reset();
|
||||
instr.Disassemble(&instruction_disassembly_buffer_);
|
||||
// Will be emitted later explicitly or by UpdateInstructionPredication.
|
||||
|
|
|
@ -17,3 +17,11 @@ DEFINE_string(dump_shaders, "",
|
|||
"Path to write GPU shaders to as they are compiled.", "GPU");
|
||||
|
||||
DEFINE_bool(vsync, true, "Enable VSYNC.", "GPU");
|
||||
|
||||
DEFINE_bool(
|
||||
gpu_allow_invalid_fetch_constants, false,
|
||||
"Allow texture and vertex fetch constants with invalid type - generally "
|
||||
"unsafe because the constant may contain completely invalid values, but "
|
||||
"may be used to bypass fetch constant type errors in certain games until "
|
||||
"the real reason why they're invalid is found.",
|
||||
"GPU");
|
||||
|
|
|
@ -18,4 +18,6 @@ DECLARE_string(dump_shaders);
|
|||
|
||||
DECLARE_bool(vsync);
|
||||
|
||||
DECLARE_bool(gpu_allow_invalid_fetch_constants);
|
||||
|
||||
#endif // XENIA_GPU_GPU_FLAGS_H_
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "xenia/base/string.h"
|
||||
#include "xenia/base/threading.h"
|
||||
#include "xenia/gpu/command_processor.h"
|
||||
#include "xenia/gpu/gpu_flags.h"
|
||||
#include "xenia/gpu/graphics_system.h"
|
||||
#include "xenia/gpu/packet_disassembler.h"
|
||||
#include "xenia/gpu/register_file.h"
|
||||
|
@ -664,7 +665,9 @@ void TraceViewer::DrawTextureInfo(
|
|||
texture_binding.fetch_constant * 6;
|
||||
auto group = reinterpret_cast<const xe_gpu_fetch_group_t*>(®s.values[r]);
|
||||
auto& fetch = group->texture_fetch;
|
||||
if (fetch.type != 0x2) {
|
||||
if (fetch.type != xenos::FetchConstantType::kTexture &&
|
||||
(!cvars::gpu_allow_invalid_fetch_constants ||
|
||||
fetch.type != xenos::FetchConstantType::kInvalidTexture)) {
|
||||
DrawFailedTextureInfo(texture_binding, "Invalid fetch type");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -639,9 +639,24 @@ VkDescriptorSet BufferCache::PrepareVertexSet(
|
|||
break;
|
||||
}
|
||||
|
||||
if (fetch->type != 0x3) {
|
||||
// TODO(DrChat): Some games use type 0x0 (with no data).
|
||||
return nullptr;
|
||||
// TODO(DrChat): Some games use type kInvalidTexture (with no data).
|
||||
switch (fetch->type) {
|
||||
case xenos::FetchConstantType::kVertex:
|
||||
break;
|
||||
case xenos::FetchConstantType::kInvalidVertex:
|
||||
if (cvars::gpu_allow_invalid_fetch_constants) {
|
||||
break;
|
||||
}
|
||||
XELOGW(
|
||||
"Vertex fetch constant %u (%.8X %.8X) has \"invalid\" type! This "
|
||||
"is incorrect behavior, but you can try bypassing this by "
|
||||
"launching Xenia with --gpu_allow_invalid_fetch_constants=true.",
|
||||
vertex_binding.fetch_constant, fetch->dword_0, fetch->dword_1);
|
||||
return nullptr;
|
||||
default:
|
||||
XELOGW("Vertex fetch constant %u (%.8X %.8X) is completely invalid!",
|
||||
vertex_binding.fetch_constant, fetch->dword_0, fetch->dword_1);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO(benvanik): compute based on indices or vertex count.
|
||||
|
|
|
@ -1501,9 +1501,28 @@ bool TextureCache::SetupTextureBinding(VkCommandBuffer command_buffer,
|
|||
|
||||
// Disabled?
|
||||
// TODO(benvanik): reset sampler.
|
||||
if (fetch.type != 0x2) {
|
||||
XELOGGPU("Fetch type is not 2!");
|
||||
return false;
|
||||
switch (fetch.type) {
|
||||
case xenos::FetchConstantType::kTexture:
|
||||
break;
|
||||
case xenos::FetchConstantType::kInvalidTexture:
|
||||
if (cvars::gpu_allow_invalid_fetch_constants) {
|
||||
break;
|
||||
}
|
||||
XELOGW(
|
||||
"Texture fetch constant %u (%.8X %.8X %.8X %.8X %.8X %.8X) has "
|
||||
"\"invalid\" type! This is incorrect behavior, but you can try "
|
||||
"bypassing this by launching Xenia with "
|
||||
"--gpu_allow_invalid_fetch_constants=true.",
|
||||
binding.fetch_constant, fetch.dword_0, fetch.dword_1, fetch.dword_2,
|
||||
fetch.dword_3, fetch.dword_4, fetch.dword_5);
|
||||
return false;
|
||||
default:
|
||||
XELOGW(
|
||||
"Texture fetch constant %u (%.8X %.8X %.8X %.8X %.8X %.8X) is "
|
||||
"completely invalid!",
|
||||
binding.fetch_constant, fetch.dword_0, fetch.dword_1, fetch.dword_2,
|
||||
fetch.dword_3, fetch.dword_4, fetch.dword_5);
|
||||
return false;
|
||||
}
|
||||
|
||||
TextureInfo texture_info;
|
||||
|
|
|
@ -966,7 +966,7 @@ bool VulkanCommandProcessor::IssueCopy() {
|
|||
fetch = &group->vertex_fetch_2;
|
||||
break;
|
||||
}
|
||||
assert_true(fetch->type == 3);
|
||||
assert_true(fetch->type == xenos::FetchConstantType::kVertex);
|
||||
assert_true(fetch->endian == Endian::k8in32);
|
||||
assert_true(fetch->size == 6);
|
||||
const uint8_t* vertex_addr = memory_->TranslatePhysical(fetch->address << 2);
|
||||
|
|
|
@ -605,11 +605,19 @@ inline uint32_t GpuToCpu(uint32_t p) { return p; }
|
|||
|
||||
inline uint32_t CpuToGpu(uint32_t p) { return p & 0x1FFFFFFF; }
|
||||
|
||||
// SQ_TEX_VTX_INVALID/VALID_TEXTURE/BUFFER
|
||||
enum class FetchConstantType : uint32_t {
|
||||
kInvalidTexture,
|
||||
kInvalidVertex,
|
||||
kTexture,
|
||||
kVertex,
|
||||
};
|
||||
|
||||
// XE_GPU_REG_SHADER_CONSTANT_FETCH_*
|
||||
XEPACKEDUNION(xe_gpu_vertex_fetch_t, {
|
||||
XEPACKEDSTRUCTANONYMOUS({
|
||||
uint32_t type : 2; // +0
|
||||
uint32_t address : 30; // +2 address in dwords
|
||||
FetchConstantType type : 2; // +0
|
||||
uint32_t address : 30; // +2 address in dwords
|
||||
|
||||
Endian endian : 2; // +0
|
||||
uint32_t size : 24; // +2 size in words
|
||||
|
@ -624,7 +632,7 @@ XEPACKEDUNION(xe_gpu_vertex_fetch_t, {
|
|||
// XE_GPU_REG_SHADER_CONSTANT_FETCH_*
|
||||
XEPACKEDUNION(xe_gpu_texture_fetch_t, {
|
||||
XEPACKEDSTRUCTANONYMOUS({
|
||||
uint32_t type : 2; // +0 dword_0
|
||||
FetchConstantType type : 2; // +0 dword_0
|
||||
TextureSign sign_x : 2; // +2
|
||||
TextureSign sign_y : 2; // +4
|
||||
TextureSign sign_z : 2; // +6
|
||||
|
|
Loading…
Reference in New Issue