mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-22 10:04:39 +00:00
spirv_emit_context: Use atomic for fault buffer
This commit is contained in:
parent
34ce2723f8
commit
a5e8aa960d
@ -1103,30 +1103,30 @@ Id EmitContext::DefineUfloatM5ToFloat32(u32 mantissa_bits, const std::string_vie
|
|||||||
}
|
}
|
||||||
|
|
||||||
Id EmitContext::DefineGetBdaPointer() {
|
Id EmitContext::DefineGetBdaPointer() {
|
||||||
const auto caching_pagebits{
|
const Id caching_pagebits{
|
||||||
Constant(U64, static_cast<u64>(VideoCore::BufferCache::CACHING_PAGEBITS))};
|
Constant(U64, static_cast<u64>(VideoCore::BufferCache::CACHING_PAGEBITS))};
|
||||||
const auto caching_pagemask{Constant(U64, VideoCore::BufferCache::CACHING_PAGESIZE - 1)};
|
const Id caching_pagemask{Constant(U64, VideoCore::BufferCache::CACHING_PAGESIZE - 1)};
|
||||||
|
|
||||||
const auto func_type{TypeFunction(U64, U64)};
|
const Id func_type{TypeFunction(U64, U64)};
|
||||||
const auto func{OpFunction(U64, spv::FunctionControlMask::MaskNone, func_type)};
|
const Id func{OpFunction(U64, spv::FunctionControlMask::MaskNone, func_type)};
|
||||||
const auto address{OpFunctionParameter(U64)};
|
const Id address{OpFunctionParameter(U64)};
|
||||||
Name(func, "get_bda_pointer");
|
Name(func, "get_bda_pointer");
|
||||||
AddLabel();
|
AddLabel();
|
||||||
|
|
||||||
const auto fault_label{OpLabel()};
|
const Id fault_label{OpLabel()};
|
||||||
const auto available_label{OpLabel()};
|
const Id available_label{OpLabel()};
|
||||||
const auto merge_label{OpLabel()};
|
const Id merge_label{OpLabel()};
|
||||||
|
|
||||||
// Get page BDA
|
// Get page BDA
|
||||||
const auto page{OpShiftRightLogical(U64, address, caching_pagebits)};
|
|
||||||
const auto page32{OpUConvert(U32[1], page)};
|
|
||||||
const auto& bda_buffer{buffers[bda_pagetable_index]};
|
const auto& bda_buffer{buffers[bda_pagetable_index]};
|
||||||
const auto [bda_buffer_id, bda_pointer_type] = bda_buffer.Alias(PointerType::U64);
|
const auto [bda_buffer_id, bda_pointer_type] = bda_buffer.Alias(PointerType::U64);
|
||||||
const auto bda_ptr{OpAccessChain(bda_pointer_type, bda_buffer_id, u32_zero_value, page32)};
|
const Id page{OpShiftRightLogical(U64, address, caching_pagebits)};
|
||||||
const auto bda{OpLoad(U64, bda_ptr)};
|
const Id page32{OpUConvert(U32[1], page)};
|
||||||
|
const Id bda_ptr{OpAccessChain(bda_pointer_type, bda_buffer_id, u32_zero_value, page32)};
|
||||||
|
const Id bda{OpLoad(U64, bda_ptr)};
|
||||||
|
|
||||||
// Check if page is GPU cached
|
// Check if page is GPU cached
|
||||||
const auto is_fault{OpIEqual(U1[1], bda, u64_zero_value)};
|
const Id is_fault{OpIEqual(U1[1], bda, u64_zero_value)};
|
||||||
OpSelectionMerge(merge_label, spv::SelectionControlMask::MaskNone);
|
OpSelectionMerge(merge_label, spv::SelectionControlMask::MaskNone);
|
||||||
OpBranchConditional(is_fault, fault_label, available_label);
|
OpBranchConditional(is_fault, fault_label, available_label);
|
||||||
|
|
||||||
@ -1134,28 +1134,26 @@ Id EmitContext::DefineGetBdaPointer() {
|
|||||||
AddLabel(fault_label);
|
AddLabel(fault_label);
|
||||||
const auto& fault_buffer{buffers[fault_buffer_index]};
|
const auto& fault_buffer{buffers[fault_buffer_index]};
|
||||||
const auto [fault_buffer_id, fault_pointer_type] = fault_buffer.Alias(PointerType::U32);
|
const auto [fault_buffer_id, fault_pointer_type] = fault_buffer.Alias(PointerType::U32);
|
||||||
const auto page_div32{OpShiftRightLogical(U32[1], page32, ConstU32(5U))};
|
const Id page_div32{OpShiftRightLogical(U32[1], page32, ConstU32(5U))};
|
||||||
const auto page_mod32{OpBitwiseAnd(U32[1], page32, ConstU32(31U))};
|
const Id page_mod32{OpBitwiseAnd(U32[1], page32, ConstU32(31U))};
|
||||||
const auto page_mask{OpShiftLeftLogical(U32[1], u32_one_value, page_mod32)};
|
const Id page_mask{OpShiftLeftLogical(U32[1], u32_one_value, page_mod32)};
|
||||||
const auto fault_ptr{
|
const Id fault_ptr{
|
||||||
OpAccessChain(fault_pointer_type, fault_buffer_id, u32_zero_value, page_div32)};
|
OpAccessChain(fault_pointer_type, fault_buffer_id, u32_zero_value, page_div32)};
|
||||||
const auto fault_value{OpLoad(U32[1], fault_ptr)};
|
OpAtomicOr(U32[1], fault_ptr, ConstU32(u32(spv::Scope::Device)), u32_zero_value, page_mask);
|
||||||
const auto fault_value_masked{OpBitwiseOr(U32[1], fault_value, page_mask)};
|
|
||||||
OpStore(fault_ptr, fault_value_masked);
|
|
||||||
|
|
||||||
// Return null pointer
|
// Return null pointer
|
||||||
const auto fallback_result{u64_zero_value};
|
const Id fallback_result{u64_zero_value};
|
||||||
OpBranch(merge_label);
|
OpBranch(merge_label);
|
||||||
|
|
||||||
// Value is available, compute address
|
// Value is available, compute address
|
||||||
AddLabel(available_label);
|
AddLabel(available_label);
|
||||||
const auto offset_in_bda{OpBitwiseAnd(U64, address, caching_pagemask)};
|
const Id offset_in_bda{OpBitwiseAnd(U64, address, caching_pagemask)};
|
||||||
const auto addr{OpIAdd(U64, bda, offset_in_bda)};
|
const Id addr{OpIAdd(U64, bda, offset_in_bda)};
|
||||||
OpBranch(merge_label);
|
OpBranch(merge_label);
|
||||||
|
|
||||||
// Merge
|
// Merge
|
||||||
AddLabel(merge_label);
|
AddLabel(merge_label);
|
||||||
const auto result{OpPhi(U64, addr, available_label, fallback_result, fault_label)};
|
const Id result{OpPhi(U64, addr, available_label, fallback_result, fault_label)};
|
||||||
OpReturnValue(result);
|
OpReturnValue(result);
|
||||||
OpFunctionEnd();
|
OpFunctionEnd();
|
||||||
return func;
|
return func;
|
||||||
|
Loading…
Reference in New Issue
Block a user