diff --git a/src/core/libraries/kernel/thread_management.cpp b/src/core/libraries/kernel/thread_management.cpp index d1187a87..c5db12a7 100644 --- a/src/core/libraries/kernel/thread_management.cpp +++ b/src/core/libraries/kernel/thread_management.cpp @@ -1260,6 +1260,10 @@ int PS4_SYSV_ABI posix_sem_post(sem_t* sem) { return sem_post(sem); } +int PS4_SYSV_ABI posix_sem_getvalue(sem_t* sem, int* sval) { + return sem_getvalue(sem, sval); +} + int PS4_SYSV_ABI scePthreadGetschedparam(ScePthread thread, int* policy, SceKernelSchedParam* param) { return pthread_getschedparam(thread->pth, policy, param); @@ -1379,6 +1383,7 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("pDuPEf3m4fI", "libScePosix", 1, "libkernel", 1, 1, posix_sem_init); LIB_FUNCTION("YCV5dGGBcCo", "libScePosix", 1, "libkernel", 1, 1, posix_sem_wait); LIB_FUNCTION("IKP8typ0QUk", "libScePosix", 1, "libkernel", 1, 1, posix_sem_post); + LIB_FUNCTION("Bq+LRV-N6Hk", "libScePosix", 1, "libkernel", 1, 1, posix_sem_getvalue); // libs RwlockSymbolsRegister(sym); SemaphoreSymbolsRegister(sym); diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index a19ade4b..b95dd06d 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -328,6 +328,7 @@ void Translate(IR::Block* block, std::span inst_list, Info& info) translator.V_FMA_F32(inst); break; case Opcode::IMAGE_SAMPLE_LZ_O: + case Opcode::IMAGE_SAMPLE_O: case Opcode::IMAGE_SAMPLE_C_LZ: case Opcode::IMAGE_SAMPLE_LZ: case Opcode::IMAGE_SAMPLE: @@ -455,6 +456,7 @@ void Translate(IR::Block* block, std::span inst_list, Info& info) translator.BUFFER_LOAD_FORMAT(4, false, inst); break; case Opcode::BUFFER_STORE_FORMAT_X: + case Opcode::BUFFER_STORE_DWORD: translator.BUFFER_STORE_FORMAT(1, false, inst); break; case Opcode::BUFFER_STORE_FORMAT_XYZW: @@ -469,6 +471,9 @@ void Translate(IR::Block* block, std::span inst_list, Info& info) case Opcode::V_MAX_U32: translator.V_MAX_U32(false, inst); break; + case Opcode::V_NOT_B32: + translator.V_NOT_B32(inst); + break; case Opcode::V_RSQ_F32: translator.V_RSQ_F32(inst); break; diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index e52b4fb0..8ae77ec6 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -129,6 +129,7 @@ public: void V_MIN_U32(const GcnInst& inst); void V_CMP_NE_U64(const GcnInst& inst); void V_BFI_B32(const GcnInst& inst); + void V_NOT_B32(const GcnInst& inst); // Vector Memory void BUFFER_LOAD_FORMAT(u32 num_dwords, bool is_typed, const GcnInst& inst); diff --git a/src/shader_recompiler/frontend/translate/vector_alu.cpp b/src/shader_recompiler/frontend/translate/vector_alu.cpp index 5534f14e..1dbb9062 100644 --- a/src/shader_recompiler/frontend/translate/vector_alu.cpp +++ b/src/shader_recompiler/frontend/translate/vector_alu.cpp @@ -46,7 +46,10 @@ void Translator::V_CNDMASK_B32(const GcnInst& inst) { const bool has_flt_source = is_float_const(inst.src[0].field) || is_float_const(inst.src[1].field); const IR::U32F32 src0 = GetSrc(inst.src[0], has_flt_source); - const IR::U32F32 src1 = GetSrc(inst.src[1], has_flt_source); + IR::U32F32 src1 = GetSrc(inst.src[1], has_flt_source); + if (src0.Type() == IR::Type::F32 && src1.Type() == IR::Type::U32) { + src1 = ir.BitCast(src1); + } const IR::Value result = ir.Select(flag, src1, src0); ir.SetVectorReg(dst_reg, IR::U32F32{result}); } @@ -478,4 +481,9 @@ void Translator::V_BFI_B32(const GcnInst& inst) { ir.BitwiseOr(ir.BitwiseAnd(src0, src1), ir.BitwiseAnd(ir.BitwiseNot(src0), src2))); } +void Translator::V_NOT_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.BitwiseNot(src0)); +} + } // namespace Shader::Gcn diff --git a/src/shader_recompiler/ir/ir_emitter.cpp b/src/shader_recompiler/ir/ir_emitter.cpp index d7e1d477..5617950e 100644 --- a/src/shader_recompiler/ir/ir_emitter.cpp +++ b/src/shader_recompiler/ir/ir_emitter.cpp @@ -9,7 +9,7 @@ namespace Shader::IR { namespace { [[noreturn]] void ThrowInvalidType(Type type) { - throw InvalidArgument("Invalid type {}", u32(type)); + UNREACHABLE_MSG("Invalid type {}", u32(type)); } Value MakeLodClampPair(IREmitter& ir, const F32& bias_lod, const F32& lod_clamp) { @@ -251,7 +251,7 @@ U32U64 IREmitter::ReadShared(int bit_size, bool is_signed, const U32& offset) { case 64: return Inst(Opcode::ReadSharedU64, offset); } - throw InvalidArgument("Invalid bit size {}", bit_size);*/ + UNREACHABLE_MSG("Invalid bit size {}", bit_size);*/ } void IREmitter::WriteShared(int bit_size, const Value& value, const U32& offset) { @@ -269,7 +269,7 @@ void IREmitter::WriteShared(int bit_size, const Value& value, const U32& offset) Inst(Opcode::WriteSharedU64, offset, value); break; default: - throw InvalidArgument("Invalid bit size {}", bit_size); + UNREACHABLE_MSG("Invalid bit size {}", bit_size); }*/ } @@ -293,7 +293,7 @@ Value IREmitter::LoadBuffer(int num_dwords, const Value& handle, const Value& ad case 4: return Inst(Opcode::LoadBufferF32x4, Flags{info}, handle, address); default: - throw InvalidArgument("Invalid number of dwords {}", num_dwords); + UNREACHABLE_MSG("Invalid number of dwords {}", num_dwords); } } @@ -314,7 +314,7 @@ void IREmitter::StoreBuffer(int num_dwords, const Value& handle, const Value& ad Inst(Opcode::StoreBufferF32x4, Flags{info}, handle, address, data); break; default: - throw InvalidArgument("Invalid number of dwords {}", num_dwords); + UNREACHABLE_MSG("Invalid number of dwords {}", num_dwords); } } @@ -328,7 +328,7 @@ U32 IREmitter::QuadShuffle(const U32& value, const U32& index) { F32F64 IREmitter::FPAdd(const F32F64& a, const F32F64& b) { if (a.Type() != b.Type()) { - throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); } switch (a.Type()) { case Type::F32: @@ -342,7 +342,7 @@ F32F64 IREmitter::FPAdd(const F32F64& a, const F32F64& b) { F32F64 IREmitter::FPSub(const F32F64& a, const F32F64& b) { if (a.Type() != b.Type()) { - throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); } switch (a.Type()) { case Type::F32: @@ -354,7 +354,7 @@ F32F64 IREmitter::FPSub(const F32F64& a, const F32F64& b) { Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2) { if (e1.Type() != e2.Type()) { - throw InvalidArgument("Mismatching types {} and {}", e1.Type(), e2.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", e1.Type(), e2.Type()); } switch (e1.Type()) { case Type::U32: @@ -372,7 +372,7 @@ Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2) { Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2, const Value& e3) { if (e1.Type() != e2.Type() || e1.Type() != e3.Type()) { - throw InvalidArgument("Mismatching types {}, {}, and {}", e1.Type(), e2.Type(), e3.Type()); + UNREACHABLE_MSG("Mismatching types {}, {}, and {}", e1.Type(), e2.Type(), e3.Type()); } switch (e1.Type()) { case Type::U32: @@ -391,7 +391,7 @@ Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2, const Valu Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2, const Value& e3, const Value& e4) { if (e1.Type() != e2.Type() || e1.Type() != e3.Type() || e1.Type() != e4.Type()) { - throw InvalidArgument("Mismatching types {}, {}, {}, and {}", e1.Type(), e2.Type(), + UNREACHABLE_MSG("Mismatching types {}, {}, {}, and {}", e1.Type(), e2.Type(), e3.Type(), e4.Type()); } switch (e1.Type()) { @@ -411,7 +411,7 @@ Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2, const Valu Value IREmitter::CompositeExtract(const Value& vector, size_t element) { const auto read{[&](Opcode opcode, size_t limit) -> Value { if (element >= limit) { - throw InvalidArgument("Out of bounds element {}", element); + UNREACHABLE_MSG("Out of bounds element {}", element); } return Inst(opcode, vector, Value{static_cast(element)}); }}; @@ -448,7 +448,7 @@ Value IREmitter::CompositeExtract(const Value& vector, size_t element) { Value IREmitter::CompositeInsert(const Value& vector, const Value& object, size_t element) { const auto insert{[&](Opcode opcode, size_t limit) { if (element >= limit) { - throw InvalidArgument("Out of bounds element {}", element); + UNREACHABLE_MSG("Out of bounds element {}", element); } return Inst(opcode, vector, object, Value{static_cast(element)}); }}; @@ -484,7 +484,7 @@ Value IREmitter::CompositeInsert(const Value& vector, const Value& object, size_ Value IREmitter::Select(const U1& condition, const Value& true_value, const Value& false_value) { if (true_value.Type() != false_value.Type()) { - throw InvalidArgument("Mismatching types {} and {}", true_value.Type(), false_value.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", true_value.Type(), false_value.Type()); } switch (true_value.Type()) { case Type::U1: @@ -502,7 +502,7 @@ Value IREmitter::Select(const U1& condition, const Value& true_value, const Valu case Type::F64: return Inst(Opcode::SelectF64, condition, true_value, false_value); default: - throw InvalidArgument("Invalid type {}", true_value.Type()); + UNREACHABLE_MSG("Invalid type {}", true_value.Type()); } } @@ -532,7 +532,7 @@ Value IREmitter::UnpackHalf2x16(const U32& value) { F32F64 IREmitter::FPMul(const F32F64& a, const F32F64& b) { if (a.Type() != b.Type()) { - throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); } switch (a.Type()) { case Type::F32: @@ -546,7 +546,7 @@ F32F64 IREmitter::FPMul(const F32F64& a, const F32F64& b) { F32F64 IREmitter::FPFma(const F32F64& a, const F32F64& b, const F32F64& c) { if (a.Type() != b.Type() || a.Type() != c.Type()) { - throw InvalidArgument("Mismatching types {}, {}, and {}", a.Type(), b.Type(), c.Type()); + UNREACHABLE_MSG("Mismatching types {}, {}, and {}", a.Type(), b.Type(), c.Type()); } switch (a.Type()) { case Type::F32: @@ -646,7 +646,7 @@ F32F64 IREmitter::FPSaturate(const F32F64& value) { F32F64 IREmitter::FPClamp(const F32F64& value, const F32F64& min_value, const F32F64& max_value) { if (value.Type() != min_value.Type() || value.Type() != max_value.Type()) { - throw InvalidArgument("Mismatching types {}, {}, and {}", value.Type(), min_value.Type(), + UNREACHABLE_MSG("Mismatching types {}, {}, and {}", value.Type(), min_value.Type(), max_value.Type()); } switch (value.Type()) { @@ -709,7 +709,7 @@ F32 IREmitter::Fract(const F32& value) { U1 IREmitter::FPEqual(const F32F64& lhs, const F32F64& rhs, bool ordered) { if (lhs.Type() != rhs.Type()) { - throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); } switch (lhs.Type()) { case Type::F32: @@ -723,7 +723,7 @@ U1 IREmitter::FPEqual(const F32F64& lhs, const F32F64& rhs, bool ordered) { U1 IREmitter::FPNotEqual(const F32F64& lhs, const F32F64& rhs, bool ordered) { if (lhs.Type() != rhs.Type()) { - throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); } switch (lhs.Type()) { case Type::F32: @@ -737,7 +737,7 @@ U1 IREmitter::FPNotEqual(const F32F64& lhs, const F32F64& rhs, bool ordered) { U1 IREmitter::FPLessThan(const F32F64& lhs, const F32F64& rhs, bool ordered) { if (lhs.Type() != rhs.Type()) { - throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); } switch (lhs.Type()) { case Type::F32: @@ -751,7 +751,7 @@ U1 IREmitter::FPLessThan(const F32F64& lhs, const F32F64& rhs, bool ordered) { U1 IREmitter::FPGreaterThan(const F32F64& lhs, const F32F64& rhs, bool ordered) { if (lhs.Type() != rhs.Type()) { - throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); } switch (lhs.Type()) { case Type::F32: @@ -767,7 +767,7 @@ U1 IREmitter::FPGreaterThan(const F32F64& lhs, const F32F64& rhs, bool ordered) U1 IREmitter::FPLessThanEqual(const F32F64& lhs, const F32F64& rhs, bool ordered) { if (lhs.Type() != rhs.Type()) { - throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); } switch (lhs.Type()) { case Type::F32: @@ -783,7 +783,7 @@ U1 IREmitter::FPLessThanEqual(const F32F64& lhs, const F32F64& rhs, bool ordered U1 IREmitter::FPGreaterThanEqual(const F32F64& lhs, const F32F64& rhs, bool ordered) { if (lhs.Type() != rhs.Type()) { - throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); } switch (lhs.Type()) { case Type::F32: @@ -812,21 +812,21 @@ U1 IREmitter::FPIsNan(const F32F64& value) { U1 IREmitter::FPOrdered(const F32F64& lhs, const F32F64& rhs) { if (lhs.Type() != rhs.Type()) { - throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); } return LogicalAnd(LogicalNot(FPIsNan(lhs)), LogicalNot(FPIsNan(rhs))); } U1 IREmitter::FPUnordered(const F32F64& lhs, const F32F64& rhs) { if (lhs.Type() != rhs.Type()) { - throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); } return LogicalOr(FPIsNan(lhs), FPIsNan(rhs)); } F32F64 IREmitter::FPMax(const F32F64& lhs, const F32F64& rhs) { if (lhs.Type() != rhs.Type()) { - throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); } switch (lhs.Type()) { case Type::F32: @@ -840,7 +840,7 @@ F32F64 IREmitter::FPMax(const F32F64& lhs, const F32F64& rhs) { F32F64 IREmitter::FPMin(const F32F64& lhs, const F32F64& rhs) { if (lhs.Type() != rhs.Type()) { - throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); } switch (lhs.Type()) { case Type::F32: @@ -854,7 +854,7 @@ F32F64 IREmitter::FPMin(const F32F64& lhs, const F32F64& rhs) { U32U64 IREmitter::IAdd(const U32U64& a, const U32U64& b) { if (a.Type() != b.Type()) { - throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); } switch (a.Type()) { case Type::U32: @@ -868,7 +868,7 @@ U32U64 IREmitter::IAdd(const U32U64& a, const U32U64& b) { U32U64 IREmitter::ISub(const U32U64& a, const U32U64& b) { if (a.Type() != b.Type()) { - throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type()); } switch (a.Type()) { case Type::U32: @@ -1021,7 +1021,7 @@ U1 IREmitter::ILessThan(const U32& lhs, const U32& rhs, bool is_signed) { U1 IREmitter::IEqual(const U32U64& lhs, const U32U64& rhs) { if (lhs.Type() != rhs.Type()) { - throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); + UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type()); } switch (lhs.Type()) { case Type::U32: @@ -1075,7 +1075,7 @@ U32U64 IREmitter::ConvertFToS(size_t bitsize, const F32F64& value) { ThrowInvalidType(value.Type()); } default: - throw InvalidArgument("Invalid destination bitsize {}", bitsize); + UNREACHABLE_MSG("Invalid destination bitsize {}", bitsize); } } @@ -1089,7 +1089,7 @@ U32U64 IREmitter::ConvertFToU(size_t bitsize, const F32F64& value) { ThrowInvalidType(value.Type()); } default: - throw InvalidArgument("Invalid destination bitsize {}", bitsize); + UNREACHABLE_MSG("Invalid destination bitsize {}", bitsize); } } @@ -1112,7 +1112,7 @@ F32F64 IREmitter::ConvertSToF(size_t dest_bitsize, size_t src_bitsize, const Val } break; } - throw InvalidArgument("Invalid bit size combination dst={} src={}", dest_bitsize, src_bitsize); + UNREACHABLE_MSG("Invalid bit size combination dst={} src={}", dest_bitsize, src_bitsize); } F32F64 IREmitter::ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const Value& value) { @@ -1130,7 +1130,7 @@ F32F64 IREmitter::ConvertUToF(size_t dest_bitsize, size_t src_bitsize, const Val } break; } - throw InvalidArgument("Invalid bit size combination dst={} src={}", dest_bitsize, src_bitsize); + UNREACHABLE_MSG("Invalid bit size combination dst={} src={}", dest_bitsize, src_bitsize); } F32F64 IREmitter::ConvertIToF(size_t dest_bitsize, size_t src_bitsize, bool is_signed, diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index acb6ec18..dcdb2638 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -306,8 +306,13 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; inst.SetArg(0, ir.Imm32(image_binding)); + // No need to patch coordinates if we are just querying. + if (inst.GetOpcode() == IR::Opcode::ImageQueryDimensions) { + return; + } + // Now that we know the image type, adjust texture coordinate vector. - const IR::Inst* body = inst.Arg(1).InstRecursive(); + IR::Inst* body = inst.Arg(1).InstRecursive(); const auto [coords, arg] = [&] -> std::pair { switch (image.GetType()) { case AmdGpu::ImageType::Color1D: // x diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index a6d4d708..b0b64570 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -373,6 +373,12 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu num_format == AmdGpu::NumberFormat::Snorm) { return vk::Format::eR16G16Snorm; } + if (data_format == AmdGpu::DataFormat::Format2_10_10_10 && num_format == AmdGpu::NumberFormat::Unorm) { + return vk::Format::eA2R10G10B10UnormPack32; + } + if (data_format == AmdGpu::DataFormat::Format10_11_11 && num_format == AmdGpu::NumberFormat::Float) { + return vk::Format::eB10G11R11UfloatPack32; + } UNREACHABLE_MSG("Unknown data_format={} and num_format={}", u32(data_format), u32(num_format)); } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 71a09ea2..7858758d 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -207,22 +207,26 @@ std::unique_ptr PipelineCache::CreateGraphicsPipeline() { inst_pool.ReleaseContents(); // Recompile shader to IR. - LOG_INFO(Render_Vulkan, "Compiling {} shader {:#x}", stage, hash); - const Shader::Info info = MakeShaderInfo(stage, pgm->user_data, regs); - programs[i] = Shader::TranslateProgram(inst_pool, block_pool, code, std::move(info)); + try { + LOG_INFO(Render_Vulkan, "Compiling {} shader {:#x}", stage, hash); + const Shader::Info info = MakeShaderInfo(stage, pgm->user_data, regs); + programs[i] = Shader::TranslateProgram(inst_pool, block_pool, code, std::move(info)); - // Compile IR to SPIR-V - auto spv_code = Shader::Backend::SPIRV::EmitSPIRV(profile, programs[i], binding); - stages[i] = CompileSPV(spv_code, instance.GetDevice()); - infos[i] = &programs[i].info; + // Compile IR to SPIR-V + auto spv_code = Shader::Backend::SPIRV::EmitSPIRV(profile, programs[i], binding); + stages[i] = CompileSPV(spv_code, instance.GetDevice()); + infos[i] = &programs[i].info; + + if (Config::dumpShaders()) { + DumpShader(spv_code, hash, stage, "spv"); + } + } catch (const Shader::Exception& e) { + UNREACHABLE_MSG("{}", e.what()); + } // Set module name to hash in renderdoc const auto name = fmt::format("{}_{:#x}", stage, hash); Vulkan::SetObjectName(instance.GetDevice(), stages[i], name); - - if (Config::dumpShaders()) { - DumpShader(spv_code, hash, stage, "spv"); - } } return std::make_unique(instance, scheduler, graphics_key, *pipeline_cache, diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index d378bd15..7086b23e 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -91,7 +91,7 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) { // TODO: Don't restart renderpass every draw const auto& scissor = regs.screen_scissor; - const vk::RenderingInfo rendering_info = { + vk::RenderingInfo rendering_info = { .renderArea = { .offset = {scissor.top_left_x, scissor.top_left_y}, @@ -102,6 +102,11 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) { .pColorAttachments = color_attachments.data(), .pDepthAttachment = num_depth_attachments ? &depth_attachment : nullptr, }; + auto& area = rendering_info.renderArea.extent; + if (area.width == 2048) { + area.width = 1920; + area.height = 1080; + } UpdateDynamicState(*pipeline); diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp index b5371f6b..21127c2b 100644 --- a/src/video_core/texture_cache/texture_cache.cpp +++ b/src/video_core/texture_cache/texture_cache.cpp @@ -116,7 +116,8 @@ Image& TextureCache::FindImage(const ImageInfo& info, VAddr cpu_address, bool re std::unique_lock lock{m_page_table}; boost::container::small_vector image_ids; ForEachImageInRegion(cpu_address, info.guest_size_bytes, [&](ImageId image_id, Image& image) { - if (image.cpu_addr == cpu_address && image.info.size.width == info.size.width) { + if (image.cpu_addr == cpu_address && image.info.size.width == info.size.width && + image.info.IsDepthStencil() == info.IsDepthStencil()) { image_ids.push_back(image_id); } });