Skip to content
8 changes: 4 additions & 4 deletions ps2xRuntime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -377,12 +377,12 @@ endfunction()

add_library(ps2_runtime STATIC
src/lib/game_overrides.cpp
src/lib/ps2_gif_arbiter.cpp
src/lib/gs/ps2_gif_arbiter.cpp
src/lib/ps2_audio.cpp
src/lib/ps2_audio_vag.cpp
src/lib/ps2_gs_gpu.cpp
src/lib/ps2_gs_memory.cpp
src/lib/ps2_gs_rasterizer.cpp
src/lib/gs/ps2_gs_memory.cpp
src/lib/gs/gs_frontend.cpp
src/lib/gs/gs_cpu_backend.cpp
src/lib/ps2_iop_host.cpp
src/lib/ps2_memory.cpp
src/lib/ps2_pad.cpp
Expand Down
4 changes: 2 additions & 2 deletions ps2xRuntime/include/ps2_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@

#include "ps2_log.h"
#include "runtime/ps2_address.h"
#include "runtime/ps2_gif_arbiter.h"
#include "runtime/gs/ps2_gif_arbiter.h"
#include "runtime/ps2_memory.h"
#include "runtime/ps2_gs_gpu.h"
#include "runtime/gs/gs_frontend.h"
#include "runtime/ps2_vu1.h"
#include "runtime/ps2_audio.h"
#include "runtime/ps2_pad.h"
Expand Down
33 changes: 33 additions & 0 deletions ps2xRuntime/include/runtime/gs/gs_backend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include "runtime/gs/gs_types.h"

#include <cstdint>
#include <vector>

class GSRasterBackend
{
public:
virtual ~GSRasterBackend() = default;

virtual void Initialize(uint8_t *vram, uint32_t vramSize) = 0;
virtual void Reset() = 0;

virtual void Submit(const GSPrimitiveBatch &batch) = 0;

virtual void BeginTransfer(const GSTransferCommand &command) = 0;
virtual void UploadImage(const uint8_t *data, uint32_t sizeBytes) = 0;

virtual void Flush() = 0;
virtual void TextureFlush() = 0;
virtual void Sync(GSSyncReason reason) = 0;
virtual PresentationFrame Present(const GSPresentationRequest &request) = 0;

virtual bool ClearFramebuffer(const GSContext &context, uint32_t rgba) = 0;
virtual uint32_t ConsumeLocalToHostBytes(uint8_t *dst, uint32_t maxBytes) = 0;

virtual uint32_t ReadVram(uint32_t psm, uint32_t base, uint32_t bw, uint32_t x, uint32_t y) const = 0;
virtual void WriteVram(uint32_t psm, uint32_t base, uint32_t bw, uint32_t x, uint32_t y, uint32_t value) = 0;
virtual void SnapshotVram(std::vector<uint8_t> &out) const = 0;
virtual GSTransferSnapshot GetTransferSnapshot() const = 0;
};
75 changes: 75 additions & 0 deletions ps2xRuntime/include/runtime/gs/gs_cpu_backend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#pragma once

#include "runtime/gs/gs_backend.h"

#include <array>
#include <functional>
#include <mutex>
#include <vector>

class GSCpuBackend final : public GSRasterBackend
{
public:
GSCpuBackend();

void Initialize(uint8_t *vram, uint32_t vramSize) override;
void Reset() override;

void Submit(const GSPrimitiveBatch &batch) override;
void BeginTransfer(const GSTransferCommand &command) override;
void UploadImage(const uint8_t *data, uint32_t sizeBytes) override;

void Flush() override;
void TextureFlush() override;
void Sync(GSSyncReason reason) override;
PresentationFrame Present(const GSPresentationRequest &request) override;

bool ClearFramebuffer(const GSContext &context, uint32_t rgba) override;
uint32_t ConsumeLocalToHostBytes(uint8_t *dst, uint32_t maxBytes) override;

uint32_t ReadVram(uint32_t psm, uint32_t base, uint32_t bw, uint32_t x, uint32_t y) const override;
void WriteVram(uint32_t psm, uint32_t base, uint32_t bw, uint32_t x, uint32_t y, uint32_t value) override;
void SnapshotVram(std::vector<uint8_t> &out) const override;
GSTransferSnapshot GetTransferSnapshot() const override;

private:
void ResetUnlocked();
uint32_t ReadVramUnlocked(uint32_t psm, uint32_t base, uint32_t bw, uint32_t x, uint32_t y) const;
void WriteVramUnlocked(uint32_t psm, uint32_t base, uint32_t bw, uint32_t x, uint32_t y, uint32_t value);

void DrawPrimitive(const GSPrimitiveBatch &batch);
void DrawSprite(const GSPrimitiveBatch &batch);
void DrawTriangle(const GSPrimitiveBatch &batch);
void DrawLine(const GSPrimitiveBatch &batch);
void WritePixel(const GSDrawState &state, int x, int y, int z, uint8_t r, uint8_t g, uint8_t b, uint8_t a, uint8_t fog);
uint32_t SampleTexture(const GSDrawState &state, float s, float t, float q, uint16_t u, uint16_t v);
uint32_t LookupCLUT(const GSDrawState &state, uint8_t index, uint32_t cbp, uint8_t cpsm, uint8_t csm, uint8_t csa, uint8_t sourcePsm);

void PerformLocalToLocalTransfer();
void PerformLocalToHostTransfer();
PresentationFrame PresentFromLocalMemory(const GSPresentationRequest &request);
bool CopyFrameToHostRgba(const GSFrameReg &frame,
uint32_t width,
uint32_t height,
std::vector<uint8_t> &outPixels,
bool preserveAlpha,
bool useLocalMemoryLayout,
bool frameBaseIsPages,
uint32_t sourceOriginX,
uint32_t sourceOriginY) const;

using WriteVramFunc = std::function<void(uint8_t *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)>;
using ReadVramFunc = std::function<uint32_t(uint8_t *, uint32_t, uint32_t, uint32_t, uint32_t)>;

static constexpr size_t kPsmHandlerCount = 1u << 6u;
mutable std::mutex m_mutex;
uint8_t *m_vram = nullptr;
uint32_t m_vramSize = 0;
std::array<ReadVramFunc, kPsmHandlerCount> m_readVramFuncs{};
std::array<WriteVramFunc, kPsmHandlerCount> m_writeVramFuncs{};

GSTransferCommand m_transfer{};
GSTransferSnapshot m_transferState{};
std::vector<uint8_t> m_localToHostBuffer;
size_t m_localToHostReadPos = 0;
};
Loading