From 48a158f18a27508636f3efdc4ccc8de1e99327ed Mon Sep 17 00:00:00 2001 From: raphaelthegreat <47210458+raphaelthegreat@users.noreply.github.com> Date: Tue, 4 Jun 2024 22:03:18 +0300 Subject: [PATCH] kernel: Module loading --- src/core/file_sys/fs.cpp | 1 - src/core/libraries/kernel/libkernel.cpp | 39 +++++++++++++++++-- src/core/linker.cpp | 15 ++++--- src/core/linker.h | 12 ++++-- src/core/loader/symbols_resolver.cpp | 2 +- src/core/loader/symbols_resolver.h | 6 +++ src/core/memory.cpp | 4 +- src/core/module.cpp | 1 + src/core/module.h | 14 ++++++- .../frontend/translate/scalar_alu.cpp | 8 ++++ .../frontend/translate/translate.cpp | 6 +++ .../frontend/translate/translate.h | 2 + .../frontend/translate/vector_alu.cpp | 5 +++ .../frontend/translate/vector_memory.cpp | 2 +- src/video_core/amdgpu/liverpool.cpp | 21 ++++++++++ src/video_core/amdgpu/pm4_cmds.h | 11 ++++++ .../renderer_vulkan/liverpool_to_vk.cpp | 6 +++ .../renderer_vulkan/vk_compute_pipeline.cpp | 16 ++++++-- .../renderer_vulkan/vk_compute_pipeline.h | 3 +- .../renderer_vulkan/vk_rasterizer.cpp | 17 +++----- .../renderer_vulkan/vk_rasterizer.h | 5 +-- 21 files changed, 155 insertions(+), 41 deletions(-) diff --git a/src/core/file_sys/fs.cpp b/src/core/file_sys/fs.cpp index 54e96f7a..dd2de269 100644 --- a/src/core/file_sys/fs.cpp +++ b/src/core/file_sys/fs.cpp @@ -52,7 +52,6 @@ std::string MntPoints::GetHostFile(const std::string& guest_file) { if (find == 0) { std::string npath = guest_file.substr(pair.guest_path.size(), guest_file.size() - 1); std::replace(pair.host_path.begin(), pair.host_path.end(), '\\', '/'); - fmt::print("GetHostFile: {}\n", pair.host_path + npath); return pair.host_path + npath; } } diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index 8e4bf3d1..be92e6dc 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -236,13 +236,42 @@ size_t PS4_SYSV_ABI sceKernelPread(int fd, void *buf, size_t count, uint64_t off return file.ReadRaw(buf, count); } -int PS4_SYSV_ABI Unknown1() { - return 0x81100004; +s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char *moduleFileName, size_t args, const void *argp, + u32 flags, const void *pOpt, int *pRes) { + LOG_INFO(Lib_Kernel, "called filename = {}, args = {}", moduleFileName, args); + + if (flags != 0) { + return 0x80020016; + } + + auto* mnt = Common::Singleton::Instance(); + const auto path = mnt->GetHostFile(moduleFileName); + + // Load PRX module. + auto* linker = Common::Singleton::Instance(); + u32 handle = linker->LoadModule(path); + auto* module = linker->GetModule(handle); + linker->Relocate(module); + + // Retrieve and verify proc param according to libkernel. + const u64* param = module->GetProcParam(); + ASSERT_MSG(!param || param[0] >= 0x18, "Invalid module param size: {}", param[0]); + module->Start(args, argp, 0); + + return handle; +} + +s32 PS4_SYSV_ABI sceKernelDlsym(s32 handle, const char *symbol, void **addrp) { + auto* linker = Common::Singleton::Instance(); + auto* module = linker->GetModule(handle); + *addrp = module->FindByName(symbol); + if (*addrp == nullptr) { + return 0x80020003; + } + return ORBIS_OK; } void LibKernel_Register(Core::Loader::SymbolsResolver* sym) { - LIB_FUNCTION("fJgP+wqifno", "libSceDiscMap", 1, "libSceDiscMap", 1, 1, Unknown1); - // obj LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard); // memory @@ -260,6 +289,8 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("IWIBBdTHit4", "libkernel", 1, "libkernel", 1, 1, sceKernelMapFlexibleMemory); LIB_FUNCTION("rVjRvHJ0X6c", "libkernel", 1, "libkernel", 1, 1, sceKernelVirtualQuery); LIB_FUNCTION("p5EcQeEeJAE", "libkernel", 1, "libkernel", 1, 1, _sceKernelRtldSetApplicationHeapAPI); + LIB_FUNCTION("wzvqT4UqKX8", "libkernel", 1, "libkernel", 1, 1, sceKernelLoadStartModule); + LIB_FUNCTION("LwG8g3niqwA", "libkernel", 1, "libkernel", 1, 1, sceKernelDlsym); // equeue LIB_FUNCTION("D0OdFMjp46I", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateEqueue); diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 287f3b6b..4cc62bbf 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -94,23 +94,22 @@ void Linker::Execute() { } } -Module* Linker::LoadModule(const std::filesystem::path& elf_name) { +s32 Linker::LoadModule(const std::filesystem::path& elf_name) { + std::scoped_lock lk{mutex}; + if (!std::filesystem::exists(elf_name)) { LOG_ERROR(Core_Linker, "Provided file {} does not exist", elf_name.string()); - return nullptr; + return -1; } auto module = std::make_unique(elf_name); if (!module->IsValid()) { LOG_ERROR(Core_Linker, "Provided file {} is not valid ELF file", elf_name.string()); - return nullptr; + return -1; } - if (!module->IsSharedLib()) { - main_proc_param_addr = module->GetProcParam(); - } - - return m_modules.emplace_back(std::move(module)).get(); + m_modules.emplace_back(std::move(module)); + return m_modules.size() - 1; } void Linker::Relocate(Module* module) { diff --git a/src/core/linker.h b/src/core/linker.h index 76d153c6..5d794430 100644 --- a/src/core/linker.h +++ b/src/core/linker.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include "core/module.h" @@ -29,7 +30,11 @@ public: } VAddr GetProcParam() const { - return main_proc_param_addr; + return m_modules[0]->GetProcParam(); + } + + Module* GetModule(s32 index) const { + return m_modules.at(index).get(); } void SetHeapApiFunc(void* func) { @@ -39,7 +44,7 @@ public: void* TlsGetAddr(u64 module_index, u64 offset); void InitTlsForThread(bool is_primary = false); - Module* LoadModule(const std::filesystem::path& elf_name); + s32 LoadModule(const std::filesystem::path& elf_name); void Relocate(Module* module); void Resolve(const std::string& name, Loader::SymbolType type, @@ -49,15 +54,14 @@ public: private: const Module* FindExportedModule(const ModuleInfo& m, const LibraryInfo& l); - void InitTls(); + std::mutex mutex; u32 dtv_generation_counter{1}; size_t static_tls_size{}; size_t max_tls_index{}; HeapApiFunc heap_api_func{}; std::vector> m_modules; Loader::SymbolsResolver m_hle_symbols{}; - VAddr main_proc_param_addr{}; }; } // namespace Core diff --git a/src/core/loader/symbols_resolver.cpp b/src/core/loader/symbols_resolver.cpp index 129f23e4..0b09a020 100644 --- a/src/core/loader/symbols_resolver.cpp +++ b/src/core/loader/symbols_resolver.cpp @@ -11,7 +11,7 @@ namespace Core::Loader { void SymbolsResolver::AddSymbol(const SymbolResolver& s, u64 virtual_addr) { - m_symbols.emplace_back(GenerateName(s), virtual_addr); + m_symbols.emplace_back(GenerateName(s), s.nidName, virtual_addr); } std::string SymbolsResolver::GenerateName(const SymbolResolver& s) { diff --git a/src/core/loader/symbols_resolver.h b/src/core/loader/symbols_resolver.h index afd4bddb..6efbb2c6 100644 --- a/src/core/loader/symbols_resolver.h +++ b/src/core/loader/symbols_resolver.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "common/types.h" namespace Core::Loader { @@ -20,6 +21,7 @@ enum class SymbolType { struct SymbolRecord { std::string name; + std::string nid_name; u64 virtual_address; }; @@ -42,6 +44,10 @@ public: void AddSymbol(const SymbolResolver& s, u64 virtual_addr); const SymbolRecord* FindSymbol(const SymbolResolver& s) const; + std::span GetSymbols() const { + return m_symbols; + } + size_t GetSize() const noexcept { return m_symbols.size(); } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index a0438fa9..b14cc502 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -240,7 +240,7 @@ MemoryManager::VMAHandle MemoryManager::MergeAdjacent(VMAHandle iter) { } void MemoryManager::MapVulkanMemory(VAddr addr, size_t size) { - return; + //return; const vk::Device device = instance->GetDevice(); const auto memory_props = instance->GetPhysicalDevice().getMemoryProperties(); void* host_pointer = reinterpret_cast(addr); @@ -312,7 +312,7 @@ void MemoryManager::MapVulkanMemory(VAddr addr, size_t size) { } void MemoryManager::UnmapVulkanMemory(VAddr addr, size_t size) { - return; + //return; const auto it = mapped_memories.find(addr); ASSERT(it != mapped_memories.end() && it->second.buffer_size == size); mapped_memories.erase(it); diff --git a/src/core/module.cpp b/src/core/module.cpp index cb266a2f..01da8bf6 100644 --- a/src/core/module.cpp +++ b/src/core/module.cpp @@ -349,6 +349,7 @@ void Module::LoadSymbols() { const auto aeronid = AeroLib::FindByNid(ids.at(0).c_str()); const auto nid_name = aeronid ? aeronid->name : "UNK"; + LOG_INFO(Core_Linker, "NidName {}", nid_name); Loader::SymbolResolver sym_r{}; sym_r.name = ids.at(0); diff --git a/src/core/module.h b/src/core/module.h index a09de2d2..2c5230f1 100644 --- a/src/core/module.h +++ b/src/core/module.h @@ -119,8 +119,18 @@ public: return elf.IsSharedLib(); } - VAddr GetProcParam() const noexcept { - return proc_param_virtual_addr; + void* FindByName(std::string_view name) { + const auto symbols = export_sym.GetSymbols(); + const auto it = std::ranges::find(symbols, name, &Loader::SymbolRecord::nid_name); + if (it != symbols.end()) { + return reinterpret_cast(it->virtual_address); + } + return nullptr; + } + + template + const T GetProcParam() const noexcept { + return reinterpret_cast(proc_param_virtual_addr); } std::span GetImportModules() const { diff --git a/src/shader_recompiler/frontend/translate/scalar_alu.cpp b/src/shader_recompiler/frontend/translate/scalar_alu.cpp index eef822b3..bdb6acc7 100644 --- a/src/shader_recompiler/frontend/translate/scalar_alu.cpp +++ b/src/shader_recompiler/frontend/translate/scalar_alu.cpp @@ -247,4 +247,12 @@ void Translator::S_BFE_U32(const GcnInst& inst) { ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); } +void Translator::S_LSHL_B32(const GcnInst& inst) { + const IR::U32 src0{GetSrc(inst.src[0])}; + const IR::U32 src1{GetSrc(inst.src[1])}; + const IR::U32 result = ir.ShiftLeftLogical(src0, ir.BitwiseAnd(src1, ir.Imm32(0x1F))); + SetDst(inst.dst[0], result); + ir.SetScc(ir.INotEqual(result, ir.Imm32(0))); +} + } // namespace Shader::Gcn diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index fa43a9e1..ffd02f64 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -371,6 +371,9 @@ void Translate(IR::Block* block, std::span inst_list, Info& info) case Opcode::S_CMP_EQ_U32: translator.S_CMP(ConditionOp::EQ, false, inst); break; + case Opcode::S_LSHL_B32: + translator.S_LSHL_B32(inst); + break; case Opcode::V_CNDMASK_B32: translator.V_CNDMASK_B32(inst); break; @@ -527,6 +530,9 @@ void Translate(IR::Block* block, std::span inst_list, Info& info) case Opcode::S_BFE_U32: translator.S_BFE_U32(inst); break; + case Opcode::V_RNDNE_F32: + translator.V_RNDNE_F32(inst); + break; case Opcode::S_NOP: case Opcode::S_CBRANCH_EXECZ: case Opcode::S_CBRANCH_SCC0: diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index 8910f9fa..c5f34cc6 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -48,6 +48,7 @@ public: void S_CSELECT_B32(const GcnInst& inst); void S_CSELECT_B64(const GcnInst& inst); void S_BFE_U32(const GcnInst& inst); + void S_LSHL_B32(const GcnInst& inst); // Scalar Memory void S_LOAD_DWORD(int num_dwords, const GcnInst& inst); @@ -102,6 +103,7 @@ public: void V_LSHR_B32(const GcnInst& inst); void V_ASHRREV_I32(const GcnInst& inst); void V_MAD_U32_U24(const GcnInst& inst); + void V_RNDNE_F32(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 10c5c1a1..7484da57 100644 --- a/src/shader_recompiler/frontend/translate/vector_alu.cpp +++ b/src/shader_recompiler/frontend/translate/vector_alu.cpp @@ -367,4 +367,9 @@ void Translator::V_MAD_U32_U24(const GcnInst& inst) { V_MAD_I32_I24(inst); } +void Translator::V_RNDNE_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0], true)}; + SetDst(inst.dst[0], ir.FPRoundEven(src0)); +} + } // namespace Shader::Gcn diff --git a/src/shader_recompiler/frontend/translate/vector_memory.cpp b/src/shader_recompiler/frontend/translate/vector_memory.cpp index 9694b06c..909217d7 100644 --- a/src/shader_recompiler/frontend/translate/vector_memory.cpp +++ b/src/shader_recompiler/frontend/translate/vector_memory.cpp @@ -31,7 +31,7 @@ void Translator::IMAGE_GET_RESINFO(const GcnInst& inst) { void Translator::IMAGE_SAMPLE(const GcnInst& inst) { const auto& mimg = inst.control.mimg; - ASSERT(!mimg.da); + //ASSERT(!mimg.da); IR::VectorReg addr_reg{inst.src[0].code}; IR::VectorReg dest_reg{inst.dst[0].code}; diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index 2d645c9d..eace1e86 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -252,6 +252,16 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span(header); + regs.max_index_size = draw_index_off->max_size; + regs.num_indices = draw_index_off->index_count; + regs.draw_initiator = draw_index_off->draw_initiator; + if (rasterizer) { + rasterizer->Draw(true, draw_index_off->index_offset); + } + break; + } case PM4ItOpcode::DrawIndexAuto: { const auto* draw_index = reinterpret_cast(header); regs.num_indices = draw_index->index_count; @@ -272,6 +282,17 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span(header); + regs.num_instances.num_instances = num_instances->num_instances; + break; + } + case PM4ItOpcode::IndexBase: { + const auto* index_base = reinterpret_cast(header); + regs.index_base_address.base_addr_lo = index_base->addr_lo; + regs.index_base_address.base_addr_hi.Assign(index_base->addr_hi); + break; + } case PM4ItOpcode::EventWrite: { // const auto* event = reinterpret_cast(header); break; diff --git a/src/video_core/amdgpu/pm4_cmds.h b/src/video_core/amdgpu/pm4_cmds.h index c7b1452b..4883834f 100644 --- a/src/video_core/amdgpu/pm4_cmds.h +++ b/src/video_core/amdgpu/pm4_cmds.h @@ -548,4 +548,15 @@ struct PM4CmdDispatchDirect { u32 dispatch_initiator; ///< Dispatch Initiator Register }; +struct PM4CmdDrawNumInstances { + PM4Type3Header header; + u32 num_instances; +}; + +struct PM4CmdDrawIndexBase { + PM4Type3Header header; + u32 addr_lo; + u32 addr_hi; +}; + } // namespace AmdGpu diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index a1362c56..e95ac6da 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -309,6 +309,12 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu if (data_format == AmdGpu::DataFormat::FormatBc3 && num_format == AmdGpu::NumberFormat::Srgb) { return vk::Format::eBc3SrgbBlock; } + if (data_format == AmdGpu::DataFormat::Format16_16_16_16 && num_format == AmdGpu::NumberFormat::Sint) { + return vk::Format::eR16G16B16A16Sint; + } + if (data_format == AmdGpu::DataFormat::FormatBc7 && num_format == AmdGpu::NumberFormat::Srgb) { + return vk::Format::eBc7SrgbBlock; + } UNREACHABLE(); } diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 3227a232..4958b8c0 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -81,8 +81,17 @@ ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler ComputePipeline::~ComputePipeline() = default; -void ComputePipeline::BindResources(Core::MemoryManager* memory, +void ComputePipeline::BindResources(Core::MemoryManager* memory, StreamBuffer& staging, VideoCore::TextureCache& texture_cache) const { + static constexpr u64 MinUniformAlignment = 64; + + const auto map_staging = [&](auto src, size_t size) { + const auto [data, offset, _] = staging.Map(size, MinUniformAlignment); + std::memcpy(data, reinterpret_cast(src), size); + staging.Commit(size); + return offset; + }; + // Bind resource buffers and textures. boost::container::static_vector buffer_infos; boost::container::static_vector image_infos; @@ -94,8 +103,9 @@ void ComputePipeline::BindResources(Core::MemoryManager* memory, const u32 size = vsharp.GetSize(); const VAddr addr = vsharp.base_address.Value(); texture_cache.OnCpuWrite(addr); - const auto [vk_buffer, offset] = memory->GetVulkanBuffer(addr); - buffer_infos.emplace_back(vk_buffer, offset, size); + const u32 offset = map_staging(addr, size); + //const auto [vk_buffer, offset] = memory->GetVulkanBuffer(addr); + buffer_infos.emplace_back(staging.Handle(), offset, size); set_writes.push_back({ .dstSet = VK_NULL_HANDLE, .dstBinding = binding++, diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.h b/src/video_core/renderer_vulkan/vk_compute_pipeline.h index df9743c2..781bd81b 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.h @@ -31,7 +31,8 @@ public: return *pipeline; } - void BindResources(Core::MemoryManager* memory, VideoCore::TextureCache& texture_cache) const; + void BindResources(Core::MemoryManager* memory, StreamBuffer& staging, + VideoCore::TextureCache& texture_cache) const; private: const Instance& instance; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 3b953138..30959c5e 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -32,16 +32,15 @@ Rasterizer::Rasterizer(const Instance& instance_, Scheduler& scheduler_, Rasterizer::~Rasterizer() = default; -void Rasterizer::Draw(bool is_indexed) { +void Rasterizer::Draw(bool is_indexed, u32 index_offset) { const auto cmdbuf = scheduler.CommandBuffer(); const auto& regs = liverpool->regs; - const u32 num_indices = SetupIndexBuffer(is_indexed); + const u32 num_indices = SetupIndexBuffer(is_indexed, index_offset); const GraphicsPipeline* pipeline = pipeline_cache.GetGraphicsPipeline(); pipeline->BindResources(memory, vertex_index_buffer, texture_cache); boost::container::static_vector color_attachments{}; - const std::array color = {0.5f, 0.5f, 0.5f, 1.f}; for (auto col_buf_id = 0u; col_buf_id < Liverpool::NumColorBuffers; ++col_buf_id) { const auto& col_buf = regs.color_buffers[col_buf_id]; if (!col_buf) { @@ -54,12 +53,10 @@ void Rasterizer::Draw(bool is_indexed) { color_attachments.push_back({ .imageView = *image_view.image_view, .imageLayout = vk::ImageLayout::eGeneral, - .loadOp = compute_done ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, + .loadOp = vk::AttachmentLoadOp::eLoad, .storeOp = vk::AttachmentStoreOp::eStore, - .clearValue = vk::ClearValue{color}, }); } - compute_done = false; // TODO: Don't restart renderpass every draw const auto& scissor = regs.screen_scissor; @@ -88,18 +85,16 @@ void Rasterizer::Draw(bool is_indexed) { } void Rasterizer::DispatchDirect() { - compute_done = true; - return; const auto cmdbuf = scheduler.CommandBuffer(); const auto& cs_program = liverpool->regs.cs_program; const ComputePipeline* pipeline = pipeline_cache.GetComputePipeline(); - pipeline->BindResources(memory, texture_cache); + pipeline->BindResources(memory, vertex_index_buffer, texture_cache); cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, pipeline->Handle()); cmdbuf.dispatch(cs_program.dim_x, cs_program.dim_y, cs_program.dim_z); } -u32 Rasterizer::SetupIndexBuffer(bool& is_indexed) { +u32 Rasterizer::SetupIndexBuffer(bool& is_indexed, u32 index_offset) { // Emulate QuadList primitive type with CPU made index buffer. const auto& regs = liverpool->regs; if (liverpool->regs.primitive_type == Liverpool::PrimitiveType::QuadList) { @@ -135,7 +130,7 @@ u32 Rasterizer::SetupIndexBuffer(bool& is_indexed) { // Bind index buffer. const auto cmdbuf = scheduler.CommandBuffer(); - cmdbuf.bindIndexBuffer(vertex_index_buffer.Handle(), offset, index_type); + cmdbuf.bindIndexBuffer(vertex_index_buffer.Handle(), offset + index_offset * index_size, index_type); return regs.num_indices; } diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 8f365f65..2ff4c244 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -29,12 +29,12 @@ public: VideoCore::TextureCache& texture_cache, AmdGpu::Liverpool* liverpool); ~Rasterizer(); - void Draw(bool is_indexed); + void Draw(bool is_indexed, u32 index_offset = 0); void DispatchDirect(); private: - u32 SetupIndexBuffer(bool& is_indexed); + u32 SetupIndexBuffer(bool& is_indexed, u32 index_offset); void MapMemory(VAddr addr, size_t size); void UpdateDynamicState(const GraphicsPipeline& pipeline); @@ -49,7 +49,6 @@ private: Core::MemoryManager* memory; PipelineCache pipeline_cache; StreamBuffer vertex_index_buffer; - bool compute_done{}; }; } // namespace Vulkan