memory: Fix tessellation buffer mapping

This commit is contained in:
raphaelthegreat 2024-06-11 17:31:01 +03:00
parent eccd454db2
commit 1666b9d199
13 changed files with 60 additions and 15 deletions

View file

@ -97,4 +97,5 @@ File* HandleTable::getFile(const std::string& host_name) {
}
return nullptr;
}
} // namespace Core::FileSys

View file

@ -36,7 +36,6 @@ int PS4_SYSV_ABI Func_E7EBCE96E92F91F8() {
}
void RegisterlibSceDiscMap(Core::Loader::SymbolsResolver* sym) {
return;
LIB_FUNCTION("fl1eoDnwQ4s", "libSceDiscMap", 1, "libSceDiscMap", 1, 1,
sceDiscMapGetPackageSize);
LIB_FUNCTION("lbQKqsERhtE", "libSceDiscMap", 1, "libSceDiscMap", 1, 1,

View file

@ -650,7 +650,6 @@ int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr) {
}
int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond) {
LOG_INFO(Kernel_Pthread, "called");
cond = static_cast<ScePthreadCond*>(createCond(cond));
if (cond == nullptr) {
@ -659,7 +658,7 @@ int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond) {
int result = pthread_cond_broadcast(&(*cond)->cond);
LOG_INFO(Kernel_Pthread, "name={}, result={}", (*cond)->name, result);
LOG_TRACE(Kernel_Pthread, "called name={}, result={}", (*cond)->name, result);
return (result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL);
}

View file

@ -39,10 +39,26 @@ int PS4_SYSV_ABI internal_memcmp(const void* s1, const void* s2, size_t n) {
return std::memcmp(s1, s2, n);
}
int PS4_SYSV_ABI internal_strncmp(const char* str1, const char* str2, size_t num) {
return std::strncmp(str1, str2, num);
}
int PS4_SYSV_ABI internal_strlen(const char* str) {
return std::strlen(str);
}
float PS4_SYSV_ABI internal_expf(float x) {
return expf(x);
}
void* PS4_SYSV_ABI internal_malloc(size_t size) {
return std::malloc(size);
}
char* PS4_SYSV_ABI internal_strncpy(char* dest, const char* src, std::size_t count) {
return std::strncpy(dest, src, count);
}
void RegisterlibSceLibcInternal(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("NFLs+dRJGNg", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1,
internal_memcpy_s);
@ -55,6 +71,10 @@ void RegisterlibSceLibcInternal(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("DfivPArhucg", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1,
internal_memcmp);
LIB_FUNCTION("8zsu04XNsZ4", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1, internal_expf);
LIB_FUNCTION("aesyjrHVWy4", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1, internal_strncmp);
LIB_FUNCTION("j4ViWNHEgww", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1, internal_strlen);
LIB_FUNCTION("6sJWiWSRuqk", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1, internal_strncpy);
LIB_FUNCTION("gQX+4GDQjpM", "libSceLibcInternal", 1, "libSceLibcInternal", 1, 1, internal_malloc);
};
} // namespace Libraries::LibcInternal
} // namespace Libraries::LibcInternal

View file

@ -119,12 +119,18 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M
// Find the first free area starting with provided virtual address.
if (False(flags & MemoryMapFlags::Fixed)) {
auto it = FindVMA(mapped_addr);
while (it->second.type != VMAType::Free || it->second.size < size) {
it++;
// If the VMA is free and contains the requested mapping we are done.
if (it->second.type == VMAType::Free && it->second.Contains(virtual_addr, size)) {
mapped_addr = alignment > 0 ? Common::AlignUp(base, alignment) : base;
} else {
// Search for the first free VMA that fits our mapping.
while (it->second.type != VMAType::Free || it->second.size < size) {
it++;
}
ASSERT(it != vma_map.end());
const auto& vma = it->second;
mapped_addr = alignment > 0 ? Common::AlignUp(vma.base, alignment) : vma.base;
}
ASSERT(it != vma_map.end());
const VAddr base = it->second.base;
mapped_addr = alignment > 0 ? Common::AlignUp(base, alignment) : base;
}
// Perform the mapping.

View file

@ -88,6 +88,10 @@ struct VirtualMemoryArea {
std::string name = "";
void* fd = nullptr;
bool Contains(VAddr addr, size_t size) const {
return addr >= base && (addr + size) < (base + this->size);
}
bool CanMergeWith(const VirtualMemoryArea& next) const {
if (disallow_merge || next.disallow_merge) {
return false;

View file

@ -121,6 +121,9 @@ IR::U32F32 Translator::GetSrc(const InstOperand& operand, bool force_flt) {
case OperandField::ConstFloatNeg_2_0:
value = ir.Imm32(-2.0f);
break;
case OperandField::ConstFloatNeg_4_0:
value = ir.Imm32(-4.0f);
break;
case OperandField::VccLo:
if (force_flt) {
value = ir.BitCast<IR::F32>(ir.GetVccLo());
@ -301,6 +304,7 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
case Opcode::V_MADAK_F32: // Yes these can share the opcode
translator.V_FMA_F32(inst);
break;
case Opcode::IMAGE_SAMPLE_LZ_O:
case Opcode::IMAGE_SAMPLE_C_LZ:
case Opcode::IMAGE_SAMPLE_LZ:
case Opcode::IMAGE_SAMPLE:

View file

@ -281,7 +281,7 @@ struct Sampler {
};
float LodBias() const noexcept {
return static_cast<float>(lod_bias);
return static_cast<float>(static_cast<int16_t>((lod_bias.Value() ^ 0x2000u) - 0x2000u)) / 256.0f;
}
float MinLod() const noexcept {

View file

@ -347,6 +347,9 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu
if (data_format == AmdGpu::DataFormat::Format8_8 && num_format == AmdGpu::NumberFormat::Unorm) {
return vk::Format::eR8G8Unorm;
}
if (data_format == AmdGpu::DataFormat::FormatBc2 && num_format == AmdGpu::NumberFormat::Unorm) {
return vk::Format::eBc2UnormBlock;
}
UNREACHABLE_MSG("Unknown data_format={} and num_format={}", u32(data_format), u32(num_format));
}
@ -367,6 +370,10 @@ vk::Format DepthFormat(DepthBuffer::ZFormat z_format, DepthBuffer::StencilFormat
stencil_format == DepthBuffer::StencilFormat::Stencil8) {
return vk::Format::eD16UnormS8Uint;
}
if (z_format == DepthBuffer::ZFormat::Invald &&
stencil_format == DepthBuffer::StencilFormat::Invalid) {
return vk::Format::eUndefined;
}
UNREACHABLE();
}

View file

@ -78,7 +78,7 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
.depthClampEnable = false,
.rasterizerDiscardEnable = false,
.polygonMode = LiverpoolToVK::PolygonMode(key.polygon_mode),
.cullMode = LiverpoolToVK::CullMode(key.cull_mode),
.cullMode = vk::CullModeFlagBits::eNone/*LiverpoolToVK::CullMode(key.cull_mode)*/,
.frontFace = key.front_face == Liverpool::FrontFace::Clockwise
? vk::FrontFace::eClockwise
: vk::FrontFace::eCounterClockwise,

View file

@ -79,6 +79,10 @@ public:
return key.write_masks;
}
[[nodiscard]] bool IsDepthEnabled() const {
return key.depth.depth_enable.Value();
}
private:
void BuildDescSetLayout();
void BindVertexBuffers(StreamBuffer& staging) const;

View file

@ -114,9 +114,10 @@ void PipelineCache::RefreshGraphicsKey() {
key.front_face = regs.polygon_control.front_face;
const auto& db = regs.depth_buffer;
key.depth_format = key.depth.depth_enable
? LiverpoolToVK::DepthFormat(db.z_info.format, db.stencil_info.format)
: vk::Format::eUndefined;
if (key.depth.depth_enable) {
key.depth_format = LiverpoolToVK::DepthFormat(db.z_info.format, db.stencil_info.format);
key.depth.depth_enable.Assign(key.depth_format != vk::Format::eUndefined);
}
// `RenderingInfo` is assumed to be initialized with a contiguous array of valid color
// attachments. This might be not a case as HW color buffers can be bound in an arbitrary order.
// We need to do some arrays compaction at this stage

View file

@ -59,7 +59,7 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
.storeOp = vk::AttachmentStoreOp::eStore,
});
}
if (regs.depth_control.depth_enable && regs.depth_buffer.Address() != 0) {
if (pipeline->IsDepthEnabled() && regs.depth_buffer.Address() != 0) {
const bool is_clear = regs.depth_render_control.depth_clear_enable;
const auto& image_view =
texture_cache.DepthTarget(regs.depth_buffer, liverpool->last_db_extent);