mirror of
https://github.com/shadergz/cosmic-station.git
synced 2024-11-27 00:00:21 +00:00
GS
: Made numerous fixes to the TAG/IMAGE Gif decompressor
This commit is contained in:
parent
c186ce0675
commit
f29ccdb34a
1
.idea/inspectionProfiles/Project_Default.xml
generated
1
.idea/inspectionProfiles/Project_Default.xml
generated
@ -1,6 +1,7 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="ClangTidy" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="JniGetFieldID" enabled="true" level="ERROR" enabled_by_default="true" editorAttributes="ERRORS_ATTRIBUTES" />
|
||||
<inspection_tool class="OCUnusedGlobalDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="UnreachableCallsOfFunction" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
|
1
.idea/misc.xml
generated
1
.idea/misc.xml
generated
@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="BuildAttributionWarningsFilter">
|
||||
<option name="noGCSettingWarning" value="true" />
|
||||
|
@ -29,10 +29,10 @@ target_sources(cosmic PRIVATE
|
||||
${COSMIC_DIR}/engine/ee_plus.cpp
|
||||
${COSMIC_DIR}/engine/ee_timers.cpp
|
||||
${COSMIC_DIR}/engine/ee_intc.cpp
|
||||
${COSMIC_DIR}/engine/copctrl/cop_cache.cpp
|
||||
${COSMIC_DIR}/engine/copctrl/cop0.cpp
|
||||
${COSMIC_DIR}/engine/copctrl/cop_misc.cpp
|
||||
${COSMIC_DIR}/engine/copctrl/cop_dma.cpp
|
||||
${COSMIC_DIR}/engine/cop_cache.cpp
|
||||
${COSMIC_DIR}/engine/cop0.cpp
|
||||
${COSMIC_DIR}/engine/cop_misc.cpp
|
||||
${COSMIC_DIR}/engine/cop_dma.cpp
|
||||
${COSMIC_DIR}/engine/cop1_fu.cpp
|
||||
${COSMIC_DIR}/mio/mmu_tlb.cpp
|
||||
${COSMIC_DIR}/mio/tlb_mapper.cpp
|
||||
|
@ -10,7 +10,7 @@ namespace cosmic {
|
||||
namespace vm { class EmuVm; }
|
||||
namespace engine {
|
||||
class FpuCop;
|
||||
namespace copctrl { class CtrlCop; }
|
||||
class CtrlCop;
|
||||
}
|
||||
}
|
||||
namespace cosmic::creeper::ee {
|
||||
@ -188,7 +188,7 @@ namespace cosmic::creeper::ee {
|
||||
static Ref<engine::EeMipsCore> cpu;
|
||||
static Ref<vm::EmuVm> vm;
|
||||
static Ref<engine::FpuCop> fpu;
|
||||
static Ref<engine::copctrl::CtrlCop> c0;
|
||||
static Ref<engine::CtrlCop> c0;
|
||||
|
||||
static EeMapSpecial ivSpecial;
|
||||
static EeRegImm ivRegImm;
|
||||
|
@ -176,5 +176,5 @@ namespace cosmic::creeper::ee {
|
||||
Ref<engine::EeMipsCore> MipsIvInterpreter::cpu;
|
||||
Ref<vm::EmuVm> MipsIvInterpreter::vm;
|
||||
Ref<engine::FpuCop> MipsIvInterpreter::fpu;
|
||||
Ref<engine::copctrl::CtrlCop> MipsIvInterpreter::c0;
|
||||
Ref<engine::CtrlCop> MipsIvInterpreter::c0;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
#include <arm_neon.h>
|
||||
#include <engine/copctrl/cop0.h>
|
||||
#include <engine/cop0.h>
|
||||
|
||||
namespace cosmic::engine::copctrl {
|
||||
namespace cosmic::engine {
|
||||
CtrlCop::CtrlCop(std::shared_ptr<mio::DmaController>& ctrl) :
|
||||
dmac(ctrl) {
|
||||
// Invalidating all cache lines
|
@ -7,7 +7,7 @@
|
||||
namespace cosmic::engine {
|
||||
class EeMipsCore;
|
||||
}
|
||||
namespace cosmic::engine::copctrl {
|
||||
namespace cosmic::engine {
|
||||
static constexpr u8 cop0RegsCount{32};
|
||||
class alignas(16) CopCacheLine {
|
||||
public:
|
@ -1,8 +1,8 @@
|
||||
#include <common/except.h>
|
||||
#include <engine/copctrl/cop0.h>
|
||||
#include <engine/cop0.h>
|
||||
#include <engine/ee_core.h>
|
||||
|
||||
namespace cosmic::engine::copctrl {
|
||||
namespace cosmic::engine {
|
||||
// We don't check for a cache miss here
|
||||
os::vec CtrlCop::readCache(u32 address, CacheMode mode) {
|
||||
u32 tag{getCachePfn(address, mode)};
|
@ -1,7 +1,7 @@
|
||||
#include <engine/copctrl/cop0.h>
|
||||
#include <engine/cop0.h>
|
||||
#include <mio/mem_pipe.h>
|
||||
|
||||
namespace cosmic::engine::copctrl {
|
||||
namespace cosmic::engine {
|
||||
bool CtrlCop::getCondition() {
|
||||
u32 stat{mio::bitBashing<u32>(dmac->performRead(0x1000e10)) & 0x3ff};
|
||||
u32 pcr{mio::bitBashing<u32>(dmac->performRead(0x1000e020)) & 0x3ff};
|
@ -1,6 +1,6 @@
|
||||
#include <engine/copctrl/cop0.h>
|
||||
#include <engine/cop0.h>
|
||||
#include <mio/mmu_tlb.h>
|
||||
namespace cosmic::engine::copctrl {
|
||||
namespace cosmic::engine {
|
||||
// Due to the peculiarities of the implementation, the calling function of configureGlobalTlb
|
||||
// must map and unmap the TLB on its own
|
||||
void CtrlCop::configureGlobalTlb(mio::TlbPageEntry& entry) {
|
@ -1,7 +1,7 @@
|
||||
#include <common/global.h>
|
||||
|
||||
#include <engine/ee_core.h>
|
||||
#include <engine/copctrl/cop0.h>
|
||||
#include <engine/cop0.h>
|
||||
|
||||
#include <creeper/ee/cached_blocks.h>
|
||||
#include <fishron/ee2arm/jitter_arm64_ee.h>
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include <engine/ee_info.h>
|
||||
|
||||
#include <engine/copctrl/cop0.h>
|
||||
#include <engine/cop0.h>
|
||||
#include <engine/cop1_fu.h>
|
||||
#include <engine/ee_timers.h>
|
||||
#include <vu/v01_cop2vu.h>
|
||||
@ -125,7 +125,7 @@ namespace cosmic::engine {
|
||||
bool isABranch{};
|
||||
u32 delaySlot{};
|
||||
ExecutionMode cpuMode{ExecutionMode::CachedInterpreter};
|
||||
copctrl::CtrlCop cop0;
|
||||
CtrlCop cop0;
|
||||
FpuCop cop1;
|
||||
std::unique_ptr<vu::MacroModeCop2> cop2;
|
||||
|
||||
|
@ -15,9 +15,9 @@ namespace cosmic::gs {
|
||||
if (!queueGetSize())
|
||||
return;
|
||||
paths[3].status = Busy;
|
||||
requestDmac(3);
|
||||
requestDmac(Gif);
|
||||
}
|
||||
void GifBridge::requestDmac(u8 path, bool intPath3) {
|
||||
void GifBridge::requestDmac(PathsTr path, bool intPath3) {
|
||||
if (!activatePath || activatePath == path) {
|
||||
activatePath = path;
|
||||
if (activatePath == 3 && (!maskedPath3() ||
|
||||
@ -42,8 +42,32 @@ namespace cosmic::gs {
|
||||
|
||||
queueReset();
|
||||
}
|
||||
bool GifBridge::isPathActivated(u8 path, bool intPath3) {
|
||||
if (path != 3 && intPath3) {
|
||||
void GifBridge::flushDmacFifo() {
|
||||
feedPathWithData(Gif, queueConsume());
|
||||
if (!queueGetSize()) {
|
||||
if (maskedPath3()) {
|
||||
} else {
|
||||
// requestDmac(Gif);
|
||||
}
|
||||
}
|
||||
}
|
||||
void GifBridge::update(u32 cycles) {
|
||||
if (!maskedPath3() &&
|
||||
!queueGetSize()) {
|
||||
requestDmac(Gif);
|
||||
}
|
||||
bool isPathMasked{isPathActivated(Gif) && !maskedPath3()};
|
||||
bool shouldRun{cycles && queueGetSize()};
|
||||
while (isPathMasked && shouldRun) {
|
||||
flushDmacFifo();
|
||||
cycles--;
|
||||
|
||||
isPathMasked = isPathActivated(Gif) && !maskedPath3();
|
||||
shouldRun = cycles && queueGetSize();
|
||||
}
|
||||
}
|
||||
bool GifBridge::isPathActivated(PathsTr path, bool intPath3) {
|
||||
if (path != Gif && intPath3) {
|
||||
}
|
||||
const bool isSelected{activatePath == path};
|
||||
return isSelected &&
|
||||
@ -51,10 +75,12 @@ namespace cosmic::gs {
|
||||
!status.tempStop &&
|
||||
!gs->privileged(GsBusDir);
|
||||
}
|
||||
bool GifBridge::feedPathWithData(u8 path, os::vec data) {
|
||||
bool GifBridge::feedPathWithData(PathsTr whatPath, os::vec data) {
|
||||
std::function<void(os::vec&)> feedDev;
|
||||
switch (path) {
|
||||
case 1:
|
||||
switch (whatPath) {
|
||||
case Vu1:
|
||||
case Vif1:
|
||||
case Gif:
|
||||
feedDev = [&](os::vec& graphics) {
|
||||
transfer2Gif(graphics);
|
||||
};
|
||||
@ -62,8 +88,8 @@ namespace cosmic::gs {
|
||||
}
|
||||
if (feedDev)
|
||||
feedDev(data);
|
||||
return (path == 1) &&
|
||||
paths[path].tag.isCompleted();
|
||||
return (whatPath == 1) &&
|
||||
paths[whatPath].tag.isCompleted();
|
||||
}
|
||||
void GifBridge::transfer2Gif(os::vec packet) {
|
||||
std::array<u64, 2> package{};
|
||||
@ -74,13 +100,14 @@ namespace cosmic::gs {
|
||||
if (!activated->leftRegsData[1]) {
|
||||
primitiveCounts++;
|
||||
decodeGifTag(activated, package.data());
|
||||
// NOTE: The GS Q register is initialized to 1.0f when reading a GIFtag
|
||||
gsQ = 1.0;
|
||||
|
||||
if (activated->leftRegsData[1] != 0) {
|
||||
}
|
||||
} else {
|
||||
switch (activated->dataFormat) {
|
||||
case PackedFmtTag:
|
||||
case TagDataFormat::Packed:
|
||||
// This is an element loop count, like N * M, where N is the count of regs and M is
|
||||
// the number of times the regs data packet needs to be transferred
|
||||
activated->leftRegsData[0]--;
|
||||
@ -91,44 +118,44 @@ namespace cosmic::gs {
|
||||
activated->leftRegsData[1]--;
|
||||
}
|
||||
break;
|
||||
case RegListFmtTag:
|
||||
case TagDataFormat::RegList:
|
||||
break;
|
||||
case Image2FmtTag:
|
||||
case Image3FmtTag:
|
||||
case TagDataFormat::Image2:
|
||||
case TagDataFormat::Image3:
|
||||
for (u8 pack{}; pack < 2; pack++)
|
||||
gs->gsWrite(0x54, package[pack]);
|
||||
activated->leftRegsData[1]--;
|
||||
break;
|
||||
case Unrecognized:
|
||||
case TagDataFormat::Unrecognized:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void GifBridge::decodeGifTag(Ref<GifTag>& unpacked, u64 packet[2]) {
|
||||
unpacked->dataFormat = static_cast<TagDataFormat>(packet[0] >> 58 & 0x3);
|
||||
[[unlikely]] if (unpacked->dataFormat > Image3FmtTag) {
|
||||
if (unpacked->dataFormat > TagDataFormat::Image3) {
|
||||
}
|
||||
|
||||
// The first transfer from Vif to GS is its Gif-Tag; let's decode it now
|
||||
// The first transfer from Vif to GS is its Gif-Tag let's decode it now
|
||||
unpacked->perLoop = packet[0] & 0x7fff;
|
||||
unpacked->isEndOfPacket = packet[0] & 1 << 0xf;
|
||||
unpacked->regs = packet[1];
|
||||
const u16 regs = packet[0] >> 60;
|
||||
|
||||
const u8 regs = packet[0] >> 60;
|
||||
unpacked->regsNum = regs;
|
||||
if (!regs) {
|
||||
unpacked->regsNum = 0x10;
|
||||
}
|
||||
unpacked->leftRegsData[0] = unpacked->regsNum;
|
||||
unpacked->leftRegsData[1] = unpacked->perLoop;
|
||||
}
|
||||
void GifBridge::deactivatePath(u8 path) {
|
||||
void GifBridge::deactivatePath(PathsTr path) {
|
||||
}
|
||||
bool GifBridge::maskedPath3() {
|
||||
bool isMasked{};
|
||||
if (status.path3enbVifMask || status.path3enbGif) {
|
||||
isMasked = (pathsFormat[3] == TagDataFormat::Unrecognized);
|
||||
if (isMasked) {
|
||||
deactivatePath(3);
|
||||
deactivatePath(Gif);
|
||||
}
|
||||
}
|
||||
return isMasked;
|
||||
|
@ -6,10 +6,10 @@ namespace cosmic::gs {
|
||||
class GsEngine;
|
||||
|
||||
enum TagDataFormat {
|
||||
PackedFmtTag,
|
||||
RegListFmtTag,
|
||||
Image2FmtTag,
|
||||
Image3FmtTag,
|
||||
Packed,
|
||||
RegList,
|
||||
Image2,
|
||||
Image3,
|
||||
Unrecognized
|
||||
};
|
||||
|
||||
@ -45,6 +45,11 @@ namespace cosmic::gs {
|
||||
// PATH1: VU1 via XGKICK instruction; Highest priority
|
||||
// PATH2: VIF1 via DIRECT/DIRECTHL; Medium priority
|
||||
// PATH3: GIF DMAC channel (channel 2); Lowest priority
|
||||
enum PathsTr {
|
||||
Vu1,
|
||||
Vif1,
|
||||
Gif = 3
|
||||
};
|
||||
class GifBridge {
|
||||
public:
|
||||
GifBridge() = default;
|
||||
@ -52,18 +57,23 @@ namespace cosmic::gs {
|
||||
|
||||
bool downloadGsData(os::vec& put);
|
||||
void resumeDmacPath();
|
||||
void requestDmac(u8 path, bool intPath3 = false);
|
||||
void deactivatePath(u8 path);
|
||||
bool isPathActivated(u8 path, bool intPath3 = false);
|
||||
bool feedPathWithData(u8 path, os::vec data);
|
||||
void requestDmac(PathsTr path, bool intPath3 = false);
|
||||
void deactivatePath(PathsTr path);
|
||||
bool isPathActivated(PathsTr path, bool intPath3 = false);
|
||||
bool feedPathWithData(PathsTr whatPath, os::vec data);
|
||||
|
||||
void update(u32 cycles);
|
||||
private:
|
||||
void transfer2Gif(os::vec packet);
|
||||
void decodeGifTag(Ref<GifTag>& unpacked, u64 packet[2]);
|
||||
void uploadPackedData(Ref<GifTag>& dsTag, u64 packet[2]);
|
||||
void queueReset();
|
||||
u32 queueGetSize();
|
||||
u64 queueGetSize();
|
||||
os::vec queueConsume();
|
||||
u64 queueFreePos();
|
||||
|
||||
bool maskedPath3();
|
||||
void flushDmacFifo();
|
||||
|
||||
Ref<GsEngine> gs;
|
||||
std::array<GifPath, 4> paths;
|
||||
@ -74,14 +84,18 @@ namespace cosmic::gs {
|
||||
f32 gsQ;
|
||||
u8 pathQueue;
|
||||
|
||||
u32 fifoSize;
|
||||
u64 fifoSize;
|
||||
alignas(16) std::array<os::vec, 16> gifFifo;
|
||||
using QueueIterator = std::array<os::vec, 16>::iterator;
|
||||
static_assert(sizeof(gifFifo) == 256);
|
||||
Ref<os::vec> fifoBack, fifoFront;
|
||||
|
||||
QueueIterator fifoFront;
|
||||
std::array<bool, 16> fifoArr;
|
||||
|
||||
u64 primitiveCounts;
|
||||
[[gnu::always_inline]] u8 colorUnzip(u64 v, u8 a) {
|
||||
return static_cast<u8>((v << a) & 0xff);
|
||||
template <typename T>
|
||||
[[gnu::always_inline]] auto extractPair(u64 v, T a, u64 clean) {
|
||||
return static_cast<T>((v >> a) & clean);
|
||||
}
|
||||
};
|
||||
}
|
@ -15,24 +15,28 @@ namespace cosmic::gs {
|
||||
}
|
||||
|
||||
switch (reg) {
|
||||
case PrimitiveOffset:
|
||||
case RegDesc::Primitive:
|
||||
gs->gsWrite(0x00, packet[0]);
|
||||
break;
|
||||
case RGBAQOffset: {
|
||||
RGBAQReg color;
|
||||
color.r = colorUnzip(packet[0], 0 );
|
||||
color.g = colorUnzip(packet[0], 32);
|
||||
color.b = colorUnzip(packet[1], 0 );
|
||||
color.a = colorUnzip(packet[1], 32);
|
||||
case RegDesc::RGBAQ: {
|
||||
RGBAQReg color{};
|
||||
// NOTES: There was a mistake in the type of bitwise operation
|
||||
// used to extract the values below
|
||||
color.r = extractPair<u8>(packet[0], 0, 0xff);
|
||||
color.g = extractPair<u8>(packet[0], 32, 0xff);
|
||||
|
||||
color.b = extractPair<u8>(packet[1], 0, 0xff);
|
||||
color.a = extractPair<u8>(packet[1], 32, 0xff);
|
||||
// The internal Q register is used here and stays the same
|
||||
color.gsq = gsQ;
|
||||
|
||||
gs->gsWrite(0x01, color.rainbow);
|
||||
}
|
||||
break;
|
||||
case StPosOffset: {
|
||||
case RegDesc::StPos: {
|
||||
u64 neoQ;
|
||||
// Fixing float types, this can be remedied or disabled later...
|
||||
neoQ = packet[1] & 0x7f800000;
|
||||
neoQ = extractPair<u64>(packet[1], 0, 0x7f800000);
|
||||
if ((neoQ & 0x7f800000) == 0x7f800000)
|
||||
neoQ = (neoQ & 0x80000000) | 0x7f7fffff;
|
||||
gs->gsWrite(0x02, packet[0]);
|
||||
@ -40,23 +44,32 @@ namespace cosmic::gs {
|
||||
gsQ = *reinterpret_cast<f32*>(&neoQ);
|
||||
}
|
||||
break;
|
||||
case UvPosOffset:
|
||||
gs->gsWrite(0x03, packet[0]);
|
||||
break;
|
||||
case Xyz2Offset: {
|
||||
CoordinatesXyz c;
|
||||
c.x = packet[0] & 0xffff;
|
||||
c.y = (packet[0] >> 32) & 0xffff;
|
||||
c.z = packet[1] & 0xffffffff;
|
||||
gs->gsWrite(0x05, c.xyz);
|
||||
case RegDesc::UvPos: {
|
||||
std::array<u16, 2> uvsCods{};
|
||||
uvsCods[0] = extractPair<u16>(packet[0], 0, 0x3fff);
|
||||
uvsCods[1] = extractPair<u16>(packet[0], 32, 0x3fff);
|
||||
gs->gsWrite(0x03, *reinterpret_cast<u32 *>(uvsCods.data()));
|
||||
}
|
||||
case NopOffset:
|
||||
break;
|
||||
case FogOffset ... AdOffset: {
|
||||
case RegDesc::Xyz2: {
|
||||
CoordinatesXyz c{
|
||||
.x = extractPair<u16>(packet[0], 0, 0xffff),
|
||||
.y = extractPair<u16>(packet[0], 32, 0xffff),
|
||||
.z = extractPair<u32>(packet[1], 0, 0xffffffff)
|
||||
};
|
||||
auto disableDraw{(packet[1] >> (111 - 64)) & 1};
|
||||
auto address{disableDraw ? 0xd : 0x5};
|
||||
|
||||
gs->gsWrite(static_cast<u32>(address), c.xyz);
|
||||
}
|
||||
case RegDesc::Nop:
|
||||
break;
|
||||
case RegDesc::Fog ... RegDesc::Ad: {
|
||||
u32 addr{static_cast<u32>(packet[1] & 0xff)};
|
||||
if (addr < 0x7f) {
|
||||
gs->gsWrite(addr, packet[0]);
|
||||
if (addr > 0x7f) {
|
||||
|
||||
}
|
||||
gs->gsWrite(addr, packet[0]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <range/v3/algorithm.hpp>
|
||||
#include <gs/gif_bridge.h>
|
||||
|
||||
namespace cosmic::gs {
|
||||
@ -7,22 +8,48 @@ namespace cosmic::gs {
|
||||
memset(&gifFifo[0], 0xff, sizeof(gifFifo));
|
||||
#endif
|
||||
__asm("eor v0.16b, v0.16b, v0.16b");
|
||||
#define STORE_PACKED_16B(addr)\
|
||||
__asm("st1 {v0.16b}, [%0]" :: "r" (addr))
|
||||
|
||||
for (u32 gifData{}; gifData < gifFifo.size(); ) {
|
||||
__asm("st1 {v0.16b}, [%0]" :: "r" (&gifFifo[gifData++]));
|
||||
__asm("st1 {v0.16b}, [%0]" :: "r" (&gifFifo[gifData++]));
|
||||
__asm("st1 {v0.16b}, [%0]" :: "r" (&gifFifo[gifData++]));
|
||||
__asm("st1 {v0.16b}, [%0]" :: "r" (&gifFifo[gifData++]));
|
||||
STORE_PACKED_16B(&gifFifo[gifData++]);
|
||||
STORE_PACKED_16B(&gifFifo[gifData++]);
|
||||
STORE_PACKED_16B(&gifFifo[gifData++]);
|
||||
STORE_PACKED_16B(&gifFifo[gifData++]);
|
||||
}
|
||||
fifoFront = std::ref(gifFifo[0]);
|
||||
fifoBack = std::ref(gifFifo[15]);
|
||||
fifoFront = std::begin(gifFifo);
|
||||
ranges::fill(fifoArr, 0);
|
||||
}
|
||||
u32 GifBridge::queueGetSize() {
|
||||
if (fifoBack && fifoFront) {
|
||||
fifoSize = static_cast<u32>(std::abs(&fifoBack - &fifoFront)) / sizeof(gifFifo[0]);
|
||||
u64 GifBridge::queueFreePos() {
|
||||
u64 writable{};
|
||||
ranges::for_each(fifoArr, [&](const auto pos){
|
||||
if (!pos)
|
||||
writable++;
|
||||
});
|
||||
return writable;
|
||||
}
|
||||
os::vec GifBridge::queueConsume() {
|
||||
if (fifoFront > std::end(gifFifo)) {
|
||||
return {};
|
||||
}
|
||||
auto front{*fifoFront};
|
||||
fifoSize = static_cast<u64>(
|
||||
std::abs(fifoFront - std::begin(gifFifo)));
|
||||
fifoArr[fifoSize] = {};
|
||||
|
||||
fifoFront++;
|
||||
return front;
|
||||
}
|
||||
|
||||
u64 GifBridge::queueGetSize() {
|
||||
if (fifoFront) {
|
||||
fifoSize = static_cast<u64>(
|
||||
std::abs(fifoFront - std::begin(gifFifo)));
|
||||
}
|
||||
// We can pre-load the array values into the L2 cache since we'll be accessing it shortly
|
||||
for (u32 preload{}; preload < gifFifo.size(); preload++)
|
||||
__asm("prfm pldl2keep, [%0]" :: "r" (&gifFifo[preload]));
|
||||
for (u64 preload{}; preload < gifFifo.size(); preload++) {
|
||||
__asm("prfm pldl2keep, [%0]"::"r" (&gifFifo[preload]));
|
||||
}
|
||||
|
||||
return fifoSize;
|
||||
}
|
||||
|
@ -21,16 +21,16 @@ namespace cosmic::gs {
|
||||
GsBusDir
|
||||
};
|
||||
enum RegDesc {
|
||||
PrimitiveOffset,
|
||||
RGBAQOffset,
|
||||
StPosOffset,
|
||||
UvPosOffset,
|
||||
Xyz2Offset,
|
||||
Primitive,
|
||||
RGBAQ,
|
||||
StPos,
|
||||
UvPos,
|
||||
Xyz2,
|
||||
|
||||
FogOffset = 0xa,
|
||||
AdOffset = 0xe,
|
||||
Fog = 0xa,
|
||||
Ad = 0xe,
|
||||
|
||||
NopOffset = 0xf
|
||||
Nop = 0xf
|
||||
};
|
||||
|
||||
union RGBAQReg {
|
||||
|
@ -16,14 +16,14 @@ namespace cosmic::vu {
|
||||
|
||||
gifAddr += 16;
|
||||
quad = *BitCast<os::vec*>(&vecRegion.rw[addr]);
|
||||
if (vu1Gif.value()->feedPathWithData(1, quad)) {
|
||||
if (vu1Gif.value()->feedPathWithData(gs::Vu1, quad)) {
|
||||
if (!path1.stallXgKick) {
|
||||
// Reactivating the previous interrupted transfer
|
||||
path1.stallXgKick = {};
|
||||
gifAddr = gifStallAddr;
|
||||
vu1Gif.value()->requestDmac(1, true);
|
||||
vu1Gif.value()->requestDmac(gs::Vu1, true);
|
||||
} else {
|
||||
vu1Gif.value()->deactivatePath(1);
|
||||
vu1Gif.value()->deactivatePath(gs::Vu1);
|
||||
path1.transferringGif = {};
|
||||
return;
|
||||
}
|
||||
@ -33,9 +33,9 @@ namespace cosmic::vu {
|
||||
void VectorUnit::startXgKick2Gif() {
|
||||
if (!vu1Gif.has_value())
|
||||
return;
|
||||
vu1Gif.value()->requestDmac(1, true);
|
||||
vu1Gif.value()->requestDmac(gs::Vu1, true);
|
||||
while (path1.cycles >= 0x2) {
|
||||
if (!vu1Gif.value()->isPathActivated(1, true)) {
|
||||
if (!vu1Gif.value()->isPathActivated(gs::Vu1, true)) {
|
||||
path1.cycles = 0;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user