mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-26 20:15:03 +00:00
video_core: Add a few missed things
This commit is contained in:
parent
71dda8c776
commit
c86a00638f
@ -104,7 +104,7 @@ int PS4_SYSV_ABI sceUserServiceGetDiscPlayerFlag() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceUserServiceGetEvent(OrbisUserServiceEvent* event) {
|
s32 PS4_SYSV_ABI sceUserServiceGetEvent(OrbisUserServiceEvent* event) {
|
||||||
LOG_INFO(Lib_UserService, "(DUMMY) called");
|
LOG_TRACE(Lib_UserService, "(DUMMY) called");
|
||||||
// fake a loggin event
|
// fake a loggin event
|
||||||
static bool logged_in = false;
|
static bool logged_in = false;
|
||||||
|
|
||||||
|
@ -83,6 +83,9 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M
|
|||||||
MemoryMapFlags flags, VMAType type, std::string_view name,
|
MemoryMapFlags flags, VMAType type, std::string_view name,
|
||||||
bool is_exec, PAddr phys_addr, u64 alignment) {
|
bool is_exec, PAddr phys_addr, u64 alignment) {
|
||||||
std::scoped_lock lk{mutex};
|
std::scoped_lock lk{mutex};
|
||||||
|
if (total_flexible_usage + size > 448_MB) {
|
||||||
|
return SCE_KERNEL_ERROR_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
// When virtual addr is zero, force it to virtual_base. The guest cannot pass Fixed
|
// When virtual addr is zero, force it to virtual_base. The guest cannot pass Fixed
|
||||||
// flag so we will take the branch that searches for free (or reserved) mappings.
|
// flag so we will take the branch that searches for free (or reserved) mappings.
|
||||||
@ -100,6 +103,9 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M
|
|||||||
new_vma.phys_base = phys_addr;
|
new_vma.phys_base = phys_addr;
|
||||||
MapVulkanMemory(mapped_addr, size);
|
MapVulkanMemory(mapped_addr, size);
|
||||||
}
|
}
|
||||||
|
if (type == VMAType::Flexible) {
|
||||||
|
total_flexible_usage += size;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fixed mapping means the virtual address must exactly match the provided one.
|
// Fixed mapping means the virtual address must exactly match the provided one.
|
||||||
@ -139,6 +145,9 @@ void MemoryManager::UnmapMemory(VAddr virtual_addr, size_t size) {
|
|||||||
if (type == VMAType::Direct) {
|
if (type == VMAType::Direct) {
|
||||||
UnmapVulkanMemory(virtual_addr, size);
|
UnmapVulkanMemory(virtual_addr, size);
|
||||||
}
|
}
|
||||||
|
if (type == VMAType::Flexible) {
|
||||||
|
total_flexible_usage -= size;
|
||||||
|
}
|
||||||
|
|
||||||
// Mark region as free and attempt to coalesce it with neighbours.
|
// Mark region as free and attempt to coalesce it with neighbours.
|
||||||
auto& vma = it->second;
|
auto& vma = it->second;
|
||||||
|
@ -182,6 +182,7 @@ private:
|
|||||||
DMemMap dmem_map;
|
DMemMap dmem_map;
|
||||||
VMAMap vma_map;
|
VMAMap vma_map;
|
||||||
std::recursive_mutex mutex;
|
std::recursive_mutex mutex;
|
||||||
|
size_t total_flexible_usage{};
|
||||||
|
|
||||||
struct MappedMemory {
|
struct MappedMemory {
|
||||||
vk::UniqueBuffer buffer;
|
vk::UniqueBuffer buffer;
|
||||||
|
@ -160,7 +160,7 @@ void Translator::S_OR_B64(bool negate, const GcnInst& inst) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::S_AND_B64(const GcnInst& inst) {
|
void Translator::S_AND_B64(bool negate, const GcnInst& inst) {
|
||||||
const auto get_src = [&](const InstOperand& operand) {
|
const auto get_src = [&](const InstOperand& operand) {
|
||||||
switch (operand.field) {
|
switch (operand.field) {
|
||||||
case OperandField::VccLo:
|
case OperandField::VccLo:
|
||||||
@ -175,7 +175,10 @@ void Translator::S_AND_B64(const GcnInst& inst) {
|
|||||||
};
|
};
|
||||||
const IR::U1 src0{get_src(inst.src[0])};
|
const IR::U1 src0{get_src(inst.src[0])};
|
||||||
const IR::U1 src1{get_src(inst.src[1])};
|
const IR::U1 src1{get_src(inst.src[1])};
|
||||||
const IR::U1 result = ir.LogicalAnd(src0, src1);
|
IR::U1 result = ir.LogicalAnd(src0, src1);
|
||||||
|
if (negate) {
|
||||||
|
result = ir.LogicalNot(result);
|
||||||
|
}
|
||||||
ir.SetScc(result);
|
ir.SetScc(result);
|
||||||
switch (inst.dst[0].field) {
|
switch (inst.dst[0].field) {
|
||||||
case OperandField::VccLo:
|
case OperandField::VccLo:
|
||||||
|
@ -366,6 +366,9 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
|||||||
case Opcode::V_CMP_NLE_F32:
|
case Opcode::V_CMP_NLE_F32:
|
||||||
translator.V_CMP_F32(ConditionOp::GT, false, inst);
|
translator.V_CMP_F32(ConditionOp::GT, false, inst);
|
||||||
break;
|
break;
|
||||||
|
case Opcode::V_CMP_NLT_F32:
|
||||||
|
translator.V_CMP_F32(ConditionOp::GE, false, inst);
|
||||||
|
break;
|
||||||
case Opcode::S_CMP_LG_U32:
|
case Opcode::S_CMP_LG_U32:
|
||||||
translator.S_CMP(ConditionOp::LG, false, inst);
|
translator.S_CMP(ConditionOp::LG, false, inst);
|
||||||
break;
|
break;
|
||||||
@ -554,7 +557,10 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
|||||||
translator.S_OR_B64(true, inst);
|
translator.S_OR_B64(true, inst);
|
||||||
break;
|
break;
|
||||||
case Opcode::S_AND_B64:
|
case Opcode::S_AND_B64:
|
||||||
translator.S_AND_B64(inst);
|
translator.S_AND_B64(false, inst);
|
||||||
|
break;
|
||||||
|
case Opcode::S_NAND_B64:
|
||||||
|
translator.S_AND_B64(true, inst);
|
||||||
break;
|
break;
|
||||||
case Opcode::V_LSHRREV_B32:
|
case Opcode::V_LSHRREV_B32:
|
||||||
translator.V_LSHRREV_B32(inst);
|
translator.V_LSHRREV_B32(inst);
|
||||||
|
@ -41,7 +41,7 @@ public:
|
|||||||
void S_AND_SAVEEXEC_B64(const GcnInst& inst);
|
void S_AND_SAVEEXEC_B64(const GcnInst& inst);
|
||||||
void S_MOV_B64(const GcnInst& inst);
|
void S_MOV_B64(const GcnInst& inst);
|
||||||
void S_OR_B64(bool negate, const GcnInst& inst);
|
void S_OR_B64(bool negate, const GcnInst& inst);
|
||||||
void S_AND_B64(const GcnInst& inst);
|
void S_AND_B64(bool negate, const GcnInst& inst);
|
||||||
void S_ADD_I32(const GcnInst& inst);
|
void S_ADD_I32(const GcnInst& inst);
|
||||||
void S_AND_B32(const GcnInst& inst);
|
void S_AND_B32(const GcnInst& inst);
|
||||||
void S_LSHR_B32(const GcnInst& inst);
|
void S_LSHR_B32(const GcnInst& inst);
|
||||||
|
@ -15,7 +15,7 @@ void Translator::V_SAD(const GcnInst& inst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_MAC_F32(const GcnInst& inst) {
|
void Translator::V_MAC_F32(const GcnInst& inst) {
|
||||||
SetDst(inst.dst[0], ir.FPFma(GetSrc(inst.src[0]), GetSrc(inst.src[1]), GetSrc(inst.dst[0])));
|
SetDst(inst.dst[0], ir.FPFma(GetSrc(inst.src[0], true), GetSrc(inst.src[1], true), GetSrc(inst.dst[0], true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_CVT_PKRTZ_F16_F32(const GcnInst& inst) {
|
void Translator::V_CVT_PKRTZ_F16_F32(const GcnInst& inst) {
|
||||||
@ -127,13 +127,13 @@ void Translator::V_FLOOR_F32(const GcnInst& inst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_SUB_F32(const GcnInst& inst) {
|
void Translator::V_SUB_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0])};
|
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
||||||
const IR::F32 src1{GetSrc(inst.src[1])};
|
const IR::F32 src1{GetSrc(inst.src[1], true)};
|
||||||
SetDst(inst.dst[0], ir.FPSub(src0, src1));
|
SetDst(inst.dst[0], ir.FPSub(src0, src1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::V_RCP_F32(const GcnInst& inst) {
|
void Translator::V_RCP_F32(const GcnInst& inst) {
|
||||||
const IR::F32 src0{GetSrc(inst.src[0])};
|
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
||||||
SetDst(inst.dst[0], ir.FPRecip(src0));
|
SetDst(inst.dst[0], ir.FPRecip(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,9 +479,9 @@ struct Liverpool {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Scissor {
|
struct Scissor {
|
||||||
union {
|
struct {
|
||||||
BitField<0, 16, s32> top_left_x;
|
s16 top_left_x;
|
||||||
BitField<16, 16, s32> top_left_y;
|
s16 top_left_y;
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
BitField<0, 15, u32> bottom_right_x;
|
BitField<0, 15, u32> bottom_right_x;
|
||||||
|
@ -36,7 +36,8 @@ ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler
|
|||||||
for (const auto& image : info.images) {
|
for (const auto& image : info.images) {
|
||||||
bindings.push_back({
|
bindings.push_back({
|
||||||
.binding = binding++,
|
.binding = binding++,
|
||||||
.descriptorType = vk::DescriptorType::eSampledImage,
|
.descriptorType = image.is_storage ? vk::DescriptorType::eStorageImage
|
||||||
|
: vk::DescriptorType::eSampledImage,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.stageFlags = vk::ShaderStageFlagBits::eCompute,
|
.stageFlags = vk::ShaderStageFlagBits::eCompute,
|
||||||
});
|
});
|
||||||
|
@ -289,7 +289,8 @@ void GraphicsPipeline::BuildDescSetLayout() {
|
|||||||
for (const auto& image : stage.images) {
|
for (const auto& image : stage.images) {
|
||||||
bindings.push_back({
|
bindings.push_back({
|
||||||
.binding = binding++,
|
.binding = binding++,
|
||||||
.descriptorType = vk::DescriptorType::eSampledImage,
|
.descriptorType = image.is_storage ? vk::DescriptorType::eStorageImage
|
||||||
|
: vk::DescriptorType::eSampledImage,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.stageFlags = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment,
|
.stageFlags = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment,
|
||||||
});
|
});
|
||||||
@ -316,8 +317,8 @@ void GraphicsPipeline::BindResources(Core::MemoryManager* memory, StreamBuffer&
|
|||||||
BindVertexBuffers(staging);
|
BindVertexBuffers(staging);
|
||||||
|
|
||||||
// Bind resource buffers and textures.
|
// Bind resource buffers and textures.
|
||||||
boost::container::static_vector<vk::DescriptorBufferInfo, 4> buffer_infos;
|
boost::container::static_vector<vk::DescriptorBufferInfo, 16> buffer_infos;
|
||||||
boost::container::static_vector<vk::DescriptorImageInfo, 8> image_infos;
|
boost::container::static_vector<vk::DescriptorImageInfo, 16> image_infos;
|
||||||
boost::container::small_vector<vk::WriteDescriptorSet, 16> set_writes;
|
boost::container::small_vector<vk::WriteDescriptorSet, 16> set_writes;
|
||||||
u32 binding{};
|
u32 binding{};
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "shader_recompiler/backend/spirv/emit_spirv.h"
|
#include "shader_recompiler/backend/spirv/emit_spirv.h"
|
||||||
#include "shader_recompiler/recompiler.h"
|
#include "shader_recompiler/recompiler.h"
|
||||||
#include "shader_recompiler/runtime_info.h"
|
#include "shader_recompiler/runtime_info.h"
|
||||||
|
#include "shader_recompiler/exception.h"
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||||
@ -88,6 +89,8 @@ void PipelineCache::RefreshGraphicsKey() {
|
|||||||
auto& key = graphics_key;
|
auto& key = graphics_key;
|
||||||
|
|
||||||
key.depth = regs.depth_control;
|
key.depth = regs.depth_control;
|
||||||
|
key.depth.depth_write_enable.Assign(regs.depth_control.depth_write_enable.Value() &&
|
||||||
|
!regs.depth_render_control.depth_clear_enable);
|
||||||
key.depth_bounds_min = regs.depth_bounds_min;
|
key.depth_bounds_min = regs.depth_bounds_min;
|
||||||
key.depth_bounds_max = regs.depth_bounds_max;
|
key.depth_bounds_max = regs.depth_bounds_max;
|
||||||
key.depth_bias_enable = regs.polygon_control.enable_polygon_offset_back ||
|
key.depth_bias_enable = regs.polygon_control.enable_polygon_offset_back ||
|
||||||
@ -180,6 +183,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
|
|||||||
inst_pool.ReleaseContents();
|
inst_pool.ReleaseContents();
|
||||||
|
|
||||||
// Recompile shader to IR.
|
// Recompile shader to IR.
|
||||||
|
LOG_INFO(Render_Vulkan, "Compiling {} shader {:#X}", stage, hash);
|
||||||
const Shader::Info info = MakeShaderInfo(stage, pgm->user_data, regs);
|
const Shader::Info info = MakeShaderInfo(stage, pgm->user_data, regs);
|
||||||
programs[i] = Shader::TranslateProgram(inst_pool, block_pool, code, std::move(info));
|
programs[i] = Shader::TranslateProgram(inst_pool, block_pool, code, std::move(info));
|
||||||
|
|
||||||
|
@ -46,18 +46,20 @@ vk::ComponentSwizzle ConvertComponentSwizzle(u32 dst_sel) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image) noexcept {
|
ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, bool is_storage) noexcept : is_storage{is_storage} {
|
||||||
type = ConvertImageViewType(image.type);
|
type = ConvertImageViewType(image.type);
|
||||||
format = Vulkan::LiverpoolToVK::SurfaceFormat(image.GetDataFmt(), image.GetNumberFmt());
|
format = Vulkan::LiverpoolToVK::SurfaceFormat(image.GetDataFmt(), image.GetNumberFmt());
|
||||||
range.base.level = 0;
|
range.base.level = 0;
|
||||||
range.base.layer = 0;
|
range.base.layer = 0;
|
||||||
range.extent.levels = image.NumLevels();
|
range.extent.levels = image.NumLevels();
|
||||||
range.extent.layers = image.NumLayers();
|
range.extent.layers = image.NumLayers();
|
||||||
|
if (!is_storage) {
|
||||||
mapping.r = ConvertComponentSwizzle(image.dst_sel_x);
|
mapping.r = ConvertComponentSwizzle(image.dst_sel_x);
|
||||||
mapping.g = ConvertComponentSwizzle(image.dst_sel_y);
|
mapping.g = ConvertComponentSwizzle(image.dst_sel_y);
|
||||||
mapping.b = ConvertComponentSwizzle(image.dst_sel_z);
|
mapping.b = ConvertComponentSwizzle(image.dst_sel_z);
|
||||||
mapping.a = ConvertComponentSwizzle(image.dst_sel_w);
|
mapping.a = ConvertComponentSwizzle(image.dst_sel_w);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info_, Image& image,
|
ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info_, Image& image,
|
||||||
std::optional<vk::ImageUsageFlags> usage_override /*= {}*/)
|
std::optional<vk::ImageUsageFlags> usage_override /*= {}*/)
|
||||||
@ -74,7 +76,7 @@ ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info
|
|||||||
}
|
}
|
||||||
|
|
||||||
const vk::ImageViewCreateInfo image_view_ci = {
|
const vk::ImageViewCreateInfo image_view_ci = {
|
||||||
.pNext = usage_override.has_value() ? &usage_ci : nullptr,
|
.pNext = nullptr,
|
||||||
.image = image.image,
|
.image = image.image,
|
||||||
.viewType = info.type,
|
.viewType = info.type,
|
||||||
.format = format,
|
.format = format,
|
||||||
|
@ -18,12 +18,13 @@ namespace VideoCore {
|
|||||||
|
|
||||||
struct ImageViewInfo {
|
struct ImageViewInfo {
|
||||||
explicit ImageViewInfo() = default;
|
explicit ImageViewInfo() = default;
|
||||||
explicit ImageViewInfo(const AmdGpu::Image& image) noexcept;
|
explicit ImageViewInfo(const AmdGpu::Image& image, bool is_storage) noexcept;
|
||||||
|
|
||||||
vk::ImageViewType type = vk::ImageViewType::e2D;
|
vk::ImageViewType type = vk::ImageViewType::e2D;
|
||||||
vk::Format format = vk::Format::eR8G8B8A8Unorm;
|
vk::Format format = vk::Format::eR8G8B8A8Unorm;
|
||||||
SubresourceRange range;
|
SubresourceRange range;
|
||||||
vk::ComponentMapping mapping{};
|
vk::ComponentMapping mapping{};
|
||||||
|
bool is_storage;
|
||||||
|
|
||||||
auto operator<=>(const ImageViewInfo&) const = default;
|
auto operator<=>(const ImageViewInfo&) const = default;
|
||||||
};
|
};
|
||||||
|
@ -169,14 +169,14 @@ ImageView& TextureCache::FindImageView(const AmdGpu::Image& desc, bool is_storag
|
|||||||
image.Transit(vk::ImageLayout::eShaderReadOnlyOptimal, vk::AccessFlagBits::eShaderRead);
|
image.Transit(vk::ImageLayout::eShaderReadOnlyOptimal, vk::AccessFlagBits::eShaderRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ImageViewInfo view_info{desc};
|
const ImageViewInfo view_info{desc, is_storage};
|
||||||
return RegisterImageView(image, view_info);
|
return RegisterImageView(image, view_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageView& TextureCache::RenderTarget(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
ImageView& TextureCache::RenderTarget(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
||||||
const AmdGpu::Liverpool::CbDbExtent& hint) {
|
const AmdGpu::Liverpool::CbDbExtent& hint) {
|
||||||
const ImageInfo info{buffer, hint};
|
const ImageInfo info{buffer, hint};
|
||||||
auto& image = FindImage(info, buffer.Address());
|
auto& image = FindImage(info, buffer.Address(), false);
|
||||||
image.flags &= ~ImageFlagBits::CpuModified;
|
image.flags &= ~ImageFlagBits::CpuModified;
|
||||||
|
|
||||||
image.Transit(vk::ImageLayout::eColorAttachmentOptimal,
|
image.Transit(vk::ImageLayout::eColorAttachmentOptimal,
|
||||||
|
Loading…
Reference in New Issue
Block a user