3rdParty: rebase rt64 on latest master

This commit is contained in:
Rosalie Wanders
2024-07-08 16:18:12 +02:00
parent 2ac0594179
commit 9899df462b
36 changed files with 178 additions and 63 deletions
+8 -1
View File
@@ -72,7 +72,8 @@
#define G_EX_PUSHGEOMETRYMODE_V1 0x000029
#define G_EX_POPGEOMETRYMODE_V1 0x00002A
#define G_EX_SETDITHERNOISESTRENGTH_V1 0x00002B
#define G_EX_MAX 0x00002C
#define G_EX_SETRDRAMEXTENDED_V1 0x00002C
#define G_EX_MAX 0x00002D
#define G_EX_ORIGIN_NONE 0x800
#define G_EX_ORIGIN_LEFT 0x0
@@ -508,4 +509,10 @@ typedef union {
PARAM((value) * 1024, 16, 0) \
)
#define gEXSetRDRAMExtended(cmd, isExtended) \
G_EX_COMMAND1(cmd, \
PARAM(RT64_EXTENDED_OPCODE, 8, 24) | PARAM(G_EX_SETRDRAMEXTENDED_V1, 24, 0), \
PARAM(isExtended, 1, 0) \
)
#endif // RT64_EXTENDED_GBI
+1
View File
@@ -60,6 +60,7 @@ namespace RT64 {
// that are available without root privileges are lower priority. Instead you can set the thread's "nice" value, which ranges
// from -20 to 19 (lower being higher priority). However, by strict POSIX spec "nice" is meant to be per-process instead of
// per-thread. Therefore to avoid issues in case Linux is modified to match the spec in the future, this function does nothing.
(void)priority;
# else
static_assert(false, "Unimplemented");
# endif
+6 -4
View File
@@ -2966,12 +2966,9 @@ namespace RT64 {
// Pick this adapter and device if it has better feature support than the current one.
bool preferOverNothing = (adapter == nullptr) || (d3d == nullptr);
bool preferShaderModel = (dataShaderModel.HighestShaderModel > shaderModel);
bool preferRtSupport = rtSupportOption && !capabilities.raytracing;
bool preferRtStateUpdateSupport = rtStateUpdateSupportOption && !capabilities.raytracingStateUpdate;
bool preferVideoMemory = adapterDesc.DedicatedVideoMemory > dedicatedVideoMemory;
bool preferUserChoice = false;//wcsstr(adapterDesc.Description, L"AMD") != nullptr;
bool preferOption = preferOverNothing || preferShaderModel || preferRtSupport || preferRtStateUpdateSupport || preferVideoMemory || preferUserChoice;
bool preferOption = preferOverNothing || preferVideoMemory || preferUserChoice;
if (preferOption) {
if (d3d != nullptr) {
d3d->Release();
@@ -2987,6 +2984,7 @@ namespace RT64 {
capabilities.raytracing = rtSupportOption;
capabilities.raytracingStateUpdate = rtStateUpdateSupportOption;
capabilities.sampleLocations = samplePositionsOption;
description.name = win32::Utf16ToUtf8(adapterDesc.Description);
dedicatedVideoMemory = adapterDesc.DedicatedVideoMemory;
if (preferUserChoice) {
@@ -3290,6 +3288,10 @@ namespace RT64 {
return capabilities;
}
const RenderDeviceDescription &D3D12Device::getDescription() const {
return description;
}
RenderSampleCounts D3D12Device::getSampleCountsSupported(RenderFormat format) const {
HRESULT res;
RenderSampleCounts countsSupported = RenderSampleCount::COUNT_0;
+3 -1
View File
@@ -27,7 +27,7 @@ namespace RT64 {
struct D3D12Texture;
struct D3D12DescriptorHeapAllocator {
enum {
enum : uint32_t {
INVALID_OFFSET = 0xFFFFFFFFU
};
@@ -382,6 +382,7 @@ namespace RT64 {
std::unique_ptr<D3D12DescriptorHeapAllocator> colorTargetHeapAllocator;
std::unique_ptr<D3D12DescriptorHeapAllocator> depthTargetHeapAllocator;
RenderDeviceCapabilities capabilities;
RenderDeviceDescription description;
D3D12Device(D3D12Interface *renderInterface);
~D3D12Device() override;
@@ -404,6 +405,7 @@ namespace RT64 {
void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild, bool preferFastTrace) override;
void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) override;
const RenderDeviceCapabilities &getCapabilities() const override;
const RenderDeviceDescription &getDescription() const override;
RenderSampleCounts getSampleCountsSupported(RenderFormat format) const override;
void release();
bool isValid() const;
+5 -4
View File
@@ -5,6 +5,7 @@
#include "rt64_gbi.h"
#include <cassert>
#include <cinttypes>
#include "rt64_gbi_extended.h"
#include "rt64_gbi_f3d.h"
@@ -171,7 +172,7 @@ namespace RT64 {
// If we used an unknown value in the database, print the hash.
if (gbiSegment.hashValue == GBI_UNKNOWN_HASH_NUMB) {
fprintf(stdout, "HASH: 0x%016llXULL SIZE: 0x%X\n", rdramHash, rdramHashed);
fprintf(stdout, "HASH: 0x%016" PRIX64 "ULL SIZE: 0x%X\n", rdramHash, rdramHashed);
}
};
@@ -290,8 +291,8 @@ namespace RT64 {
const uint8_t *twoPointResult = std::search(searchResult, searchResultEnd, twoPointPattern, twoPointPattern + std::size(twoPointPattern) - 1);
if ((f3dexResult != searchResultEnd) && (twoPointResult != searchResultEnd)) {
const uint32_t lastOverlay = *reinterpret_cast<const uint32_t *>(&RDRAM[dataAddress + 0x410]);
const uint16_t lastOverlaySize = *reinterpret_cast<const uint16_t *>(&RDRAM[dataAddress + 0x414 ^ 2]);
const uint16_t estimatedDataSize = *reinterpret_cast<const uint16_t *>(&RDRAM[dataAddress + 0x380 ^ 2]);
const uint16_t lastOverlaySize = *reinterpret_cast<const uint16_t *>(&RDRAM[(dataAddress + 0x414) ^ 2]);
const uint16_t estimatedDataSize = *reinterpret_cast<const uint16_t *>(&RDRAM[(dataAddress + 0x380) ^ 2]);
const uint32_t textSize = lastOverlay + lastOverlaySize + 1;
fprintf(stderr, "Detected text size is 0x%X\n", textSize);
fprintf(stderr, "Estimated data size is 0x%X\n", estimatedDataSize);
@@ -300,7 +301,7 @@ namespace RT64 {
const uint8_t *s2dexResult = std::search(searchResult, searchResultEnd, s2dexPattern, s2dexPattern + std::size(s2dexPattern) - 1);
if ((s2dexResult != searchResultEnd) && (twoPointResult != searchResultEnd)) {
const uint32_t lastOverlay = *reinterpret_cast<const uint32_t *>(&RDRAM[dataAddress + 0x31C]);
const uint16_t lastOverlaySize = *reinterpret_cast<const uint16_t *>(&RDRAM[dataAddress + 0x320 ^ 2]);
const uint16_t lastOverlaySize = *reinterpret_cast<const uint16_t *>(&RDRAM[(dataAddress + 0x320) ^ 2]);
const uint32_t textSize = lastOverlay + lastOverlaySize + 1;
fprintf(stderr, "Detected text size is 0x%X\n", textSize);
}
+8 -2
View File
@@ -286,6 +286,11 @@ namespace RT64 {
state->setDitherNoiseStrength(noiseStrength / 1024.0f);
}
void setRDRAMExtendedV1(State *state, DisplayList **dl) {
const uint8_t extended = (*dl)->p1(0, 1);
state->setExtendedRDRAM(extended);
}
void noOpHook(State *state, DisplayList **dl) {
uint32_t magicNumber = (*dl)->p0(0, 24);
if (magicNumber == RT64_HOOK_MAGIC_NUMBER) {
@@ -293,7 +298,7 @@ namespace RT64 {
uint32_t hookOp = (*dl)->p1(28, 4);
switch (hookOp) {
case RT64_HOOK_OP_GETVERSION: {
const uint32_t rdramAddress = state->rsp->fromSegmented(hookValue);
const uint32_t rdramAddress = state->rsp->fromSegmentedMasked(hookValue);
uint32_t *returnRDRAM = reinterpret_cast<uint32_t *>(state->fromRDRAM(rdramAddress));
*returnRDRAM = G_EX_VERSION;
break;
@@ -317,7 +322,7 @@ namespace RT64 {
state->pushReturnAddress(*dl);
}
const uint32_t rdramAddress = state->rsp->fromSegmented(hookValue);
const uint32_t rdramAddress = state->rsp->fromSegmentedMasked(hookValue);
*dl = reinterpret_cast<DisplayList *>(state->fromRDRAM(rdramAddress)) - 1;
break;
}
@@ -386,6 +391,7 @@ namespace RT64 {
Map[G_EX_PUSHGEOMETRYMODE_V1] = &pushGeometryModeV1;
Map[G_EX_POPGEOMETRYMODE_V1] = &popGeometryModeV1;
Map[G_EX_SETDITHERNOISESTRENGTH_V1] = &setDitherNoiseStrengthV1;
Map[G_EX_SETRDRAMEXTENDED_V1] = &setRDRAMExtendedV1;
MapInitialized = true;
}
}
+2 -2
View File
@@ -78,7 +78,7 @@ namespace RT64 {
state->pushReturnAddress(*dl);
}
const uint32_t rdramAddress = state->rsp->fromSegmented((*dl)->w1);
const uint32_t rdramAddress = state->rsp->fromSegmentedMasked((*dl)->w1);
*dl = reinterpret_cast<DisplayList *>(state->fromRDRAM(rdramAddress)) - 1;
}
@@ -121,7 +121,7 @@ namespace RT64 {
// TODO
break;
case G_MW_SEGMENT:
state->rsp->setSegment((*dl)->p0(10, 4), (*dl)->w1 & 0x00FFFFFF);
state->rsp->setSegment((*dl)->p0(10, 4), (*dl)->w1);
break;
case G_MW_FOG:
state->rsp->setFog((int16_t)((*dl)->p1(16, 16)), (int16_t)((*dl)->p1(0, 16)));
+1 -1
View File
@@ -77,7 +77,7 @@ namespace RT64 {
state->rsp->setClipRatio((*dl)->w1);
break;
case G_MW_SEGMENT:
state->rsp->setSegment((*dl)->p0(2, 4), (*dl)->w1 & 0x00FFFFFF);
state->rsp->setSegment((*dl)->p0(2, 4), (*dl)->w1);
break;
case G_MW_FOG:
state->rsp->setFog((int16_t)((*dl)->p1(16, 16)), (int16_t)((*dl)->p1(0, 16)));
+3 -3
View File
@@ -133,7 +133,7 @@ namespace RT64 {
RDP *rdp = state->rdp.get();
RSP *rsp = state->rsp.get();
const uint32_t rdramAddress = state->rsp->fromSegmented((*dl)->w1);
const uint32_t rdramAddress = state->rsp->fromSegmentedMasked((*dl)->w1);
// TODO load this into the S2D struct buffer for a more accurate implementation in case there's ever command state bleed.
const uObjBg *bgObject = reinterpret_cast<const uObjBg *>(state->fromRDRAM(rdramAddress));
const uObjBg_t &bg = bgObject->bg;
@@ -398,7 +398,7 @@ namespace RT64 {
RDP *rdp = state->rdp.get();
RSP* rsp = state->rsp.get();
const uint32_t rdramAddress = state->rsp->fromSegmented((*dl)->w1);
const uint32_t rdramAddress = state->rsp->fromSegmentedMasked((*dl)->w1);
// TODO load this into the S2D struct buffer for a more accurate implementation in case there's ever command state bleed.
const uObjBg *bgObject = reinterpret_cast<const uObjBg *>(state->fromRDRAM(rdramAddress));
const uObjBg_t &bg = bgObject->bg;
@@ -451,7 +451,7 @@ namespace RT64 {
void readS2DStruct(State *state, uint32_t ptr, uint32_t loadSize) {
// Convert the segmented obj pointer
uint32_t rdramAddress = state->rsp->fromSegmented(ptr);
uint32_t rdramAddress = state->rsp->fromSegmentedMasked(ptr);
// Mask the address as the RSP DMA hardware would
rdramAddress &= RSP_DMA_MASK;
// Truncate the load size as the ucode does
+3 -3
View File
@@ -261,7 +261,7 @@ namespace RT64 {
uint32_t totalSyncCount = 0;
for (uint32_t f = 0; f < workload.fbPairCount; f++) {
auto &fbPair = workload.fbPairs[f];
if (renderer.framebufferIndex == f) {
if ((uint32_t)renderer.framebufferIndex == f) {
renderer.framebufferAddress = renderer.framebufferDepth ? fbPair.depthImage.address : fbPair.colorImage.address;
}
@@ -896,7 +896,7 @@ namespace RT64 {
ImGui::PushID(l);
if (openCall) {
bool open = (openLoadIndex == (callDesc.loadIndex + l));
bool open = ((uint32_t)openLoadIndex == (callDesc.loadIndex + l));
ImGui::SetNextItemOpen(open);
if (open) {
ImGui::SetScrollHereY(0.0f);
@@ -984,7 +984,7 @@ namespace RT64 {
const DrawCallTile &callTile = drawData.callTiles[callDesc.tileIndex + t];
const LoadTile &loadTile = callTile.loadTile;
if (openCall) {
bool open = (openTileIndex == (callDesc.tileIndex + t));
bool open = ((uint32_t)openTileIndex == (callDesc.tileIndex + t));
ImGui::SetNextItemOpen(open);
if (open) {
ImGui::SetScrollHereY(0.0f);
+2 -1
View File
@@ -181,11 +181,12 @@ namespace RT64 {
# if defined(_WIN32) && !defined(RT64_BUILD_PLUGIN)
ImGui_ImplWin32_NewFrame();
# else
# elif defined(RT64_BUILD_PLUGIN)
// ????????
// if mupen64plus == true, dont assert....
ImGuiIO &io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)window_width, (float)window_height);
# else
//assert(false && "Unimplemented.");
# endif
+23
View File
@@ -175,6 +175,29 @@ namespace RT64 {
return SetupResult::GraphicsDeviceNotFound;
}
// Driver workarounds.
//
// Wireframe artifacts have been reported when using a high-precision color format on RDNA3 GPUs in D3D12. The workaround is to switch to Vulkan if this is the case.
bool isRDNA3 = device->getDescription().name.find("AMD Radeon RX 7") != std::string::npos;
bool useHDRinD3D12 = (userConfig.graphicsAPI == UserConfiguration::GraphicsAPI::D3D12) && (userConfig.internalColorFormat == UserConfiguration::InternalColorFormat::Automatic) && device->getCapabilities().preferHDR;
if (isRDNA3 && useHDRinD3D12) {
device.reset();
renderInterface.reset();
renderInterface = CreateVulkanInterface();
if (renderInterface == nullptr) {
fprintf(stderr, "Unable to initialize graphics API.\n");
return SetupResult::GraphicsAPINotFound;
}
createdGraphicsAPI = UserConfiguration::GraphicsAPI::Vulkan;
device = renderInterface->createDevice();
if (device == nullptr) {
fprintf(stderr, "Unable to find compatible graphics device.\n");
return SetupResult::GraphicsDeviceNotFound;
}
}
// Call the init hook if one was attached.
RenderHookInit *initHook = GetRenderHookInit();
if (initHook != nullptr) {
+9 -2
View File
@@ -285,13 +285,18 @@ namespace RT64 {
RRMode activeModeID = 0;
for (int i = 0; i < screenResources->ncrtc; ++i) {
XRRCrtcInfo *crtcInfo = XRRGetCrtcInfo(windowHandle.display, screenResources, screenResources->crtcs[i]);
if ((crtcInfo != nullptr) && (crtcInfo->mode != 0L)) {
activeModeID = crtcInfo->mode;
if (crtcInfo != nullptr) {
if (crtcInfo->mode != 0L) {
activeModeID = crtcInfo->mode;
}
XRRFreeCrtcInfo(crtcInfo);
}
}
if (activeModeID == 0L) {
fprintf(stderr, "Unable to find active mode through XRRGetScreenResources and XRRGetCrtcInfo.\n");
XRRFreeScreenResources(screenResources);
return;
}
@@ -302,6 +307,8 @@ namespace RT64 {
break;
}
}
XRRFreeScreenResources(screenResources);
# endif
}
+1 -1
View File
@@ -109,7 +109,7 @@ namespace RT64 {
hlslpp::float3 sunCol = { 0.8f, 0.7f, 0.6f };
float biggestIntensity = 0;
int biggestDirLight = -1;
for (int i = 0; i < directionalLights.size(); i++) {
for (size_t i = 0; i < directionalLights.size(); i++) {
if (directionalLights[i].intensityTotal > biggestIntensity) {
biggestDirLight = i;
biggestIntensity = directionalLights[i].intensityTotal;
+5 -5
View File
@@ -92,7 +92,7 @@ namespace RT64 {
presentThread = new std::thread(&PresentQueue::threadLoop, this);
}
void PresentQueue::threadPresent(const Present &present) {
void PresentQueue::threadPresent(const Present &present, bool &swapChainValid) {
FramebufferManager &fbManager = ext.sharedResources->framebufferManager;
RenderTargetManager &targetManager = ext.sharedResources->renderTargetManager;
const bool usingMSAA = (targetManager.multisampling.sampleCount > 1);
@@ -264,7 +264,6 @@ namespace RT64 {
}
}
bool swapChainValid = true;
for (int32_t i = 0; i < framesToPresent; i++) {
uint32_t frameCountersNextPresented = 0;
if ((framesToPresent > 1) && (usingMSAA || (i > 0))) {
@@ -432,6 +431,7 @@ namespace RT64 {
bool skipPresent = false;
uint32_t displayTimingRate = UINT32_MAX;
const bool displayTiming = ext.device->getCapabilities().displayTiming;
bool swapChainValid = false;
while (presentThreadRunning) {
{
std::unique_lock<std::mutex> cursorLock(cursorMutex);
@@ -448,13 +448,13 @@ namespace RT64 {
if (processCursor >= 0) {
std::unique_lock<std::mutex> threadLock(threadMutex);
const bool needsResize = ext.swapChain->needsResize();
const bool needsResize = ext.swapChain->needsResize() || !swapChainValid;
if (needsResize) {
ext.presentGraphicsWorker->commandList->begin();
ext.presentGraphicsWorker->commandList->end();
ext.presentGraphicsWorker->execute();
ext.presentGraphicsWorker->wait();
ext.swapChain->resize();
swapChainValid = ext.swapChain->resize();
swapChainFramebuffers.clear();
ext.sharedResources->setSwapChainSize(ext.swapChain->getWidth(), ext.swapChain->getHeight());
}
@@ -490,7 +490,7 @@ namespace RT64 {
notifyPresentId(present);
}
else {
threadPresent(present);
threadPresent(present, swapChainValid);
}
if (!present.fbOperations.empty()) {
+1 -1
View File
@@ -63,7 +63,7 @@ namespace RT64 {
void waitForIdle();
void waitForPresentId(uint64_t waitId);
void setup(const External &ext);
void threadPresent(const Present &present);
void threadPresent(const Present &present, bool &swapChainValid);
void skipInterpolation();
void notifyPresentId(const Present &present);
void threadAdvanceBarrier();
+10 -3
View File
@@ -222,10 +222,17 @@ namespace RT64 {
}
};
uint32_t RDP::maskAddress(uint32_t address) {
if (state->extended.extendRDRAM && ((address & 0xF0000000) == 0x80000000)) {
return address - 0x80000000;
}
return address & RDP_ADDRESS_MASK;
}
void RDP::setColorImage(uint8_t fmt, uint8_t siz, uint16_t width, uint32_t address) {
// Make sure the new color image is actually different. Some games will set the color image
// multiple times despite setting the exact same parameters.
const uint32_t newAddress = address & RDP_ADDRESS_MASK;
const uint32_t newAddress = maskAddress(address);
if ((colorImage.fmt != fmt) ||
(colorImage.siz != siz) ||
(colorImage.width != width) ||
@@ -244,7 +251,7 @@ namespace RT64 {
}
void RDP::setDepthImage(uint32_t address) {
const uint32_t newAddress = address & RDP_ADDRESS_MASK;
const uint32_t newAddress = maskAddress(address);
if (depthImage.address != newAddress) {
depthImage.address = newAddress;
depthImage.changed = true;
@@ -259,7 +266,7 @@ namespace RT64 {
texture.fmt = fmt;
texture.siz = siz;
texture.width = width;
texture.address = address & RDP_ADDRESS_MASK;
texture.address = maskAddress(address);
state->updateDrawStatusAttribute(DrawAttribute::Texture);
# ifdef LOG_TEXTURE_IMAGE_METHODS
+1
View File
@@ -142,6 +142,7 @@ namespace RT64 {
void checkFramebufferOverlap(uint32_t tmemStart, uint32_t tmemWords, uint32_t tmemMask, uint32_t addressStart, uint32_t addressEnd, uint32_t tileWidth, uint32_t tileHeight, bool RGBA32, bool makeTileCopy);
void checkImageOverlap(uint32_t addressStart, uint32_t addressEnd);
int32_t movedFromOrigin(int32_t x, uint16_t ori);
uint32_t maskAddress(uint32_t address);
void setColorImage(uint8_t fmt, uint8_t siz, uint16_t width, uint32_t address);
void setDepthImage(uint32_t address);
void setTextureImage(uint8_t fmt, uint8_t siz, uint16_t width, uint32_t address);
+34 -16
View File
@@ -90,17 +90,35 @@ namespace RT64 {
clearExtended();
}
// Masks addresses as the RSP DMA hardware would.
uint32_t RSP::maskPhysicalAddress(uint32_t address) {
if (state->extended.extendRDRAM && ((address & 0xF0000000) == 0x80000000)) {
return address - 0x80000000;
}
return address & 0x00FFFFF8;
}
// Performs a lookup in the segment table to convert the given address.
uint32_t RSP::fromSegmented(uint32_t segAddress) {
if (state->extended.extendRDRAM && ((segAddress & 0xF0000000) == 0x80000000)) {
return segAddress;
}
return segments[((segAddress) >> 24) & 0x0F] + ((segAddress) & 0x00FFFFFF);
}
// Converts the given segmented address and then applies the RSP DMA physical address mask.
// Used in cases where the RSP performs a DMA with a segmented address as the input.
uint32_t RSP::fromSegmentedMasked(uint32_t segAddress) {
return maskPhysicalAddress(fromSegmented(segAddress));
}
void RSP::setSegment(uint32_t seg, uint32_t address) {
assert(seg < RSP_MAX_SEGMENTS);
segments[seg] = address;
}
void RSP::matrix(uint32_t address, uint8_t params) {
const uint32_t rdramAddress = fromSegmented(address);
const uint32_t rdramAddress = fromSegmentedMasked(address);
const FixedMatrix *fixedMatrix = reinterpret_cast<FixedMatrix *>(state->fromRDRAM(rdramAddress));
const hlslpp::float4x4 floatMatrix = fixedMatrix->toMatrix4x4();
@@ -258,7 +276,7 @@ namespace RT64 {
RT64_LOG_PRINTF("RSP::forceMatrix(0x%08X)", address);
# endif
const uint32_t rdramAddress = fromSegmented(address);
const uint32_t rdramAddress = fromSegmentedMasked(address);
const FixedMatrix *fixedMatrix = reinterpret_cast<FixedMatrix *>(state->fromRDRAM(rdramAddress));
modelViewProjMatrix = fixedMatrix->toMatrix4x4();
modelViewProjInserted = true;
@@ -288,25 +306,25 @@ namespace RT64 {
modelViewProjChanged = changed;
}
void RSP::setVertex(uint32_t address, uint8_t vtxCount, uint8_t dstIndex) {
void RSP::setVertex(uint32_t address, uint8_t vtxCount, uint32_t dstIndex) {
if ((dstIndex >= RSP_MAX_VERTICES) || ((dstIndex + vtxCount) > RSP_MAX_VERTICES)) {
assert(false && "Vertex indices are not valid. DL is possibly corrupted.");
return;
}
const uint32_t rdramAddress = fromSegmented(address);
const uint32_t rdramAddress = fromSegmentedMasked(address);
const Vertex *dlVerts = reinterpret_cast<const Vertex *>(state->fromRDRAM(rdramAddress));
memcpy(&vertices[dstIndex], dlVerts, sizeof(Vertex) * vtxCount);
setVertexCommon<true>(dstIndex, dstIndex + vtxCount);
}
void RSP::setVertexPD(uint32_t address, uint8_t vtxCount, uint8_t dstIndex) {
void RSP::setVertexPD(uint32_t address, uint8_t vtxCount, uint32_t dstIndex) {
if ((dstIndex >= RSP_MAX_VERTICES) || ((dstIndex + vtxCount) > RSP_MAX_VERTICES)) {
assert(false && "Vertex indices are not valid. DL is possibly corrupted.");
return;
}
const uint32_t rdramAddress = fromSegmented(address);
const uint32_t rdramAddress = fromSegmentedMasked(address);
const VertexPD *dlVerts = reinterpret_cast<const VertexPD *>(state->fromRDRAM(rdramAddress));
for (uint32_t i = 0; i < vtxCount; i++) {
Vertex &dst = vertices[dstIndex + i];
@@ -326,7 +344,7 @@ namespace RT64 {
setVertexCommon<true>(dstIndex, dstIndex + vtxCount);
}
void RSP::setVertexEXV1(uint32_t address, uint8_t vtxCount, uint8_t dstIndex) {
void RSP::setVertexEXV1(uint32_t address, uint8_t vtxCount, uint32_t dstIndex) {
if ((dstIndex >= RSP_MAX_VERTICES) || ((dstIndex + vtxCount) > RSP_MAX_VERTICES)) {
assert(false && "Vertex indices are not valid. DL is possibly corrupted.");
return;
@@ -334,7 +352,7 @@ namespace RT64 {
const int workloadCursor = state->ext.workloadQueue->writeCursor;
Workload &workload = state->ext.workloadQueue->workloads[workloadCursor];
const uint32_t rdramAddress = fromSegmented(address);
const uint32_t rdramAddress = fromSegmentedMasked(address);
const VertexEXV1 *dlVerts = reinterpret_cast<const VertexEXV1 *>(state->fromRDRAM(rdramAddress));
auto &velShorts = workload.drawData.velShorts;
for (uint32_t i = 0; i < vtxCount; i++) {
@@ -349,7 +367,7 @@ namespace RT64 {
}
void RSP::setVertexColorPD(uint32_t address) {
vertexColorPDAddress = fromSegmented(address);
vertexColorPDAddress = fromSegmentedMasked(address);
}
Projection::Type RSP::getCurrentProjectionType() const {
@@ -720,7 +738,7 @@ namespace RT64 {
const float screenZ = workload.drawData.posScreen[globalIndex][2] * DepthRange;
const float zValueFloat = zValue / 65536.0f;
if (forceBranch || (screenZ < zValueFloat)) {
const uint32_t rdramAddress = fromSegmented(branchDl);
const uint32_t rdramAddress = fromSegmentedMasked(branchDl);
*dl = reinterpret_cast<DisplayList *>(state->fromRDRAM(rdramAddress)) - 1;
}
}
@@ -732,7 +750,7 @@ namespace RT64 {
const uint32_t globalIndex = indices[vtxIndex];
const float posW = workload.drawData.posTransformed[globalIndex][3];
if (forceBranch || (posW < static_cast<float>(wValue))) {
const uint32_t rdramAddress = fromSegmented(branchDl);
const uint32_t rdramAddress = fromSegmentedMasked(branchDl);
*dl = reinterpret_cast<DisplayList *>(state->fromRDRAM(rdramAddress)) - 1;
}
}
@@ -778,7 +796,7 @@ namespace RT64 {
}
void RSP::setViewport(uint32_t address, uint16_t ori, int16_t offx, int16_t offy) {
const uint32_t rdramAddress = fromSegmented(address);
const uint32_t rdramAddress = fromSegmentedMasked(address);
const Vp_t *vp = reinterpret_cast<const Vp_t *>(state->fromRDRAM(rdramAddress));
interop::RSPViewport &viewport = viewportStack[viewportStackSize - 1];
viewport.scale.x = float(vp->vscale[1]) / 4.0f;
@@ -807,7 +825,7 @@ namespace RT64 {
void RSP::setLight(uint8_t index, uint32_t address) {
assert((index >= 0) && (index <= RSP_MAX_LIGHTS));
const uint32_t rdramAddress = fromSegmented(address);
const uint32_t rdramAddress = fromSegmentedMasked(address);
const uint8_t *data = reinterpret_cast<const uint8_t *>(state->fromRDRAM(rdramAddress));
memcpy(&lights[index], data, sizeof(Light));
lightsChanged = true;
@@ -836,7 +854,7 @@ namespace RT64 {
void RSP::setLookAt(uint8_t index, uint32_t address) {
assert(index < 2);
const uint32_t rdramAddress = fromSegmented(address);
const uint32_t rdramAddress = fromSegmentedMasked(address);
const DirLight *dirLight = reinterpret_cast<const DirLight *>(state->fromRDRAM(rdramAddress));
auto &dstLookAt = (index == 1) ? lookAt.y : lookAt.x;
if ((dirLight->dirx != 0) || (dirLight->diry != 0) || (dirLight->dirz != 0)) {
@@ -1077,7 +1095,7 @@ namespace RT64 {
};
if (idIsAddress && editGroup) {
const uint32_t rdramAddress = fromSegmented(id);
const uint32_t rdramAddress = fromSegmentedMasked(id);
const int workloadCursor = state->ext.workloadQueue->writeCursor;
Workload &workload = state->ext.workloadQueue->workloads[workloadCursor];
@@ -1099,7 +1117,7 @@ namespace RT64 {
int &stackSize = proj ? extended.viewProjMatrixIdStackSize : extended.modelMatrixIdStackSize;
bool &stackChanged = proj ? extended.viewProjMatrixIdStackChanged : extended.modelMatrixIdStackChanged;
if (push) {
if (stackSize < stack.size()) {
if ((size_t)stackSize < stack.size()) {
stackSize++;
}
else {
+6 -3
View File
@@ -221,7 +221,9 @@ namespace RT64 {
void reset();
Projection::Type getCurrentProjectionType() const;
void addCurrentProjection(Projection::Type type);
uint32_t maskPhysicalAddress(uint32_t address);
uint32_t fromSegmented(uint32_t segAddress);
uint32_t fromSegmentedMasked(uint32_t segAddress);
void setSegment(uint32_t seg, uint32_t address);
void matrix(uint32_t address, uint8_t params);
void popMatrix(uint32_t count);
@@ -232,9 +234,9 @@ namespace RT64 {
void computeModelViewProj();
void specialComputeModelViewProj();
void setModelViewProjChanged(bool changed);
void setVertex(uint32_t address, uint8_t vtxCount, uint8_t dstIndex);
void setVertexPD(uint32_t address, uint8_t vtxCount, uint8_t dstIndex);
void setVertexEXV1(uint32_t address, uint8_t vtxCount, uint8_t dstIndex);
void setVertex(uint32_t address, uint8_t vtxCount, uint32_t dstIndex);
void setVertexPD(uint32_t address, uint8_t vtxCount, uint32_t dstIndex);
void setVertexEXV1(uint32_t address, uint8_t vtxCount, uint32_t dstIndex);
void setVertexColorPD(uint32_t address);
template<bool addEmptyVelocity>
void setVertexCommon(uint8_t dstIndex, uint8_t dstMax);
@@ -276,6 +278,7 @@ namespace RT64 {
void matrixId(uint32_t id, bool push, bool proj, bool decompose, uint8_t pos, uint8_t rot, uint8_t scale, uint8_t skew, uint8_t persp, uint8_t vert, uint8_t tile, uint8_t order, uint8_t editable, bool idIsAddress, bool editGroup);
void popMatrixId(uint8_t count, bool proj);
void forceBranch(bool force);
void extendRDRAM(bool isExtended);
void clearExtended();
void setGBI(GBI *gbi);
};
+9
View File
@@ -2199,6 +2199,11 @@ namespace RT64 {
# endif
ImGui::NewLine();
ImGui::Text("Offline Shaders: %zu", ext.rasterShaderCache->offlineList.entries.size());
ImGui::Text("Specialized Shaders: %u", ext.rasterShaderCache->shaderCount());
ImGui::NewLine();
bool ubershadersOnly = ext.workloadQueue->ubershadersOnly;
ImGui::Checkbox("Ubershaders Only", &ubershadersOnly);
ext.workloadQueue->ubershadersOnly = ubershadersOnly;
@@ -2364,6 +2369,10 @@ namespace RT64 {
void State::setDitherNoiseStrength(float noiseStrength) {
extended.ditherNoiseStrength = noiseStrength;
}
void State::setExtendedRDRAM(bool isExtended) {
extended.extendRDRAM = isExtended;
}
uint8_t *State::fromRDRAM(uint32_t rdramAddress) const {
return &RDRAM[rdramAddress];
+2
View File
@@ -125,6 +125,7 @@ namespace RT64 {
uint8_t renderToRAM = UINT8_MAX;
bool vertexTestZActive = false;
float ditherNoiseStrength = 1.0f;
bool extendRDRAM = false;
};
Extended extended;
@@ -157,6 +158,7 @@ namespace RT64 {
void setRefreshRate(uint16_t refreshRate);
void setRenderToRAM(uint8_t renderToRAM);
void setDitherNoiseStrength(float noiseStrength);
void setExtendedRDRAM(bool isExtended);
uint8_t *fromRDRAM(uint32_t rdramAddress) const;
void dumpRDRAM(const std::string &path);
void enableExtendedGBI(uint8_t opCode);
+2 -2
View File
@@ -735,7 +735,7 @@ namespace RT64 {
}
// Do the resolve if using MSAA while target override is active and we're on the correct framebuffer pair index.
if (usingMSAA && (overrideTarget != nullptr) && (overrideTargetFbPairIndex == f)) {
if (usingMSAA && (overrideTarget != nullptr) && ((uint32_t)overrideTargetFbPairIndex == f)) {
overrideTarget->resize(ext.workloadGraphicsWorker, colorTarget->width, colorTarget->height);
overrideTarget->resolveFromTarget(ext.workloadGraphicsWorker, colorTarget);
}
@@ -831,7 +831,7 @@ namespace RT64 {
threadConfigurationUpdate(workloadConfig);
// FIXME: This is a very hacky way to find out if we need to advance the frame if the workload was paused for the first time.
if (!workload.paused || (!gameFrames[curFrameIndex].workloads.empty() && (gameFrames[curFrameIndex].workloads[0] != processCursor))) {
if (!workload.paused || (!gameFrames[curFrameIndex].workloads.empty() && (gameFrames[curFrameIndex].workloads[0] != (uint32_t)processCursor))) {
prevFrameIndex = curFrameIndex;
curFrameIndex = (curFrameIndex + 1) % gameFrames.size();
}
+2 -1
View File
@@ -34,6 +34,7 @@ namespace RT64 {
struct PresetBase {
bool enabled = true;
virtual ~PresetBase() = default;
virtual bool readJson(const json &jsonObj);
virtual bool writeJson(json &jsonObj) const;
};
@@ -60,7 +61,7 @@ namespace RT64 {
}
void writeJson(json &jroot) {
for (const auto it : presetMap) {
for (const auto& it : presetMap) {
json jpreset;
jpreset["name"] = it.first;
it.second.writeJson(jpreset);
+1 -1
View File
@@ -79,7 +79,7 @@ namespace RT64 {
return false;
}
for (const auto it : lightMap) {
for (const auto& it : lightMap) {
json jlight;
jlight["name"] = it.first;
jlight["description"] = it.second.description;
+2 -2
View File
@@ -172,10 +172,10 @@ namespace RT64 {
ImGui::SameLine();
if (checkboxValue) {
ImGui::Text(name);
ImGui::Text("%s", name);
}
else {
ImGui::TextDisabled(name);
ImGui::TextDisabled("%s", name);
}
return checkboxValue;
@@ -1200,7 +1200,7 @@ namespace RT64 {
bool depthState = false;
worker->commandList->setFramebuffer(targetDrawCall.fbStorage->colorDepthWrite.get());
for (const auto pair : targetDrawCall.sceneIndices) {
for (const auto& pair : targetDrawCall.sceneIndices) {
# if RT_ENABLED
if (pair.second) {
const auto &rtScene = targetDrawCall.rtScenes[pair.first];
@@ -1241,7 +1241,7 @@ namespace RT64 {
submitDepthAccess(worker, targetDrawCall.fbStorage, true, depthState);
submitRaytracingScene(worker, targetDrawCall.fbStorage->colorTarget, rtScene);
}
else
else
# endif
{
const RasterScene &rasterScene = targetDrawCall.rasterScenes[pair.first];
@@ -1598,6 +1598,9 @@ namespace RT64 {
triangles.viewport = rawViewportWide;
break;
}
case Projection::Type::None: {
break;
}
}
triangles.scissor = convertFixedRect(call.callDesc.scissorRect, p.resolutionScale, p.fbWidth, invRatioScale, extOriginPercentage, int32_t(horizontalMisalignment), call.callDesc.scissorLeftOrigin, call.callDesc.scissorRightOrigin);
+1 -1
View File
@@ -271,7 +271,7 @@ namespace RT64 {
writeShader = &shaderLibrary->fbWriteColor;
}
assert((fmt != G_IM_FMT_DEPTH) || (siz == G_IM_SIZ_16b) && "Depth format is not allowed outside of 16-bits.");
assert(((fmt != G_IM_FMT_DEPTH) || (siz == G_IM_SIZ_16b)) && "Depth format is not allowed outside of 16-bits.");
// We need at least one read buffer in the history to use to write the output to.
if (readBufferHistory.empty()) {
@@ -367,4 +367,9 @@ namespace RT64 {
descQueueChanged.notify_all();
}
uint32_t RasterShaderCache::shaderCount() {
std::unique_lock<std::mutex> lock(GPUShadersMutex);
return GPUShaders.size();
}
};
@@ -86,5 +86,6 @@ namespace RT64 {
bool stopOfflineDumper();
bool loadOfflineList(std::istream &stream);
void resetOfflineList();
uint32_t shaderCount();
};
};
+1 -1
View File
@@ -197,7 +197,7 @@ namespace RT64 {
else {
const uint8_t *srcData = reinterpret_cast<const uint8_t *>(bytes);
size_t offset = 0;
while ((offset + rowPitch) <= byteCount) {
while ((offset + rowPitch) <= (size_t)byteCount) {
memcpy(dstData, srcData, rowPitch);
srcData += rowPitch;
offset += rowPitch;
+1
View File
@@ -208,6 +208,7 @@ namespace RT64 {
virtual void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild = true, bool preferFastTrace = false) = 0;
virtual void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) = 0;
virtual const RenderDeviceCapabilities &getCapabilities() const = 0;
virtual const RenderDeviceDescription &getDescription() const = 0;
virtual RenderSampleCounts getSampleCountsSupported(RenderFormat format) const = 0;
};
@@ -1529,6 +1529,11 @@ namespace RT64 {
RenderShaderBindingGroupsInfo groups;
};
struct RenderDeviceDescription {
std::string name = "Unknown";
uint32_t driverVersion = 0;
};
struct RenderDeviceCapabilities {
// Raytracing.
bool raytracing = false;
+1
View File
@@ -55,6 +55,7 @@ int main(int argc, const char** argv) {
// Write the C file with the array
{
std::ofstream output_c_file{output_c_path};
output_c_file << "extern const char " << array_name << "[" << contents.size() << "];\n";
output_c_file << "const char " << array_name << "[" << contents.size() << "] = {";
for (char x : contents) {
+6
View File
@@ -3406,6 +3406,8 @@ namespace RT64 {
bool preferOption = preferDeviceTypeScore;
if (preferOption) {
physicalDevice = physicalDevices[i];
description.name = std::string(deviceProperties.deviceName);
description.driverVersion = deviceProperties.driverVersion;
currentDeviceTypeScore = deviceTypeScore;
}
}
@@ -3944,6 +3946,10 @@ namespace RT64 {
const RenderDeviceCapabilities &VulkanDevice::getCapabilities() const {
return capabilities;
}
const RenderDeviceDescription &VulkanDevice::getDescription() const {
return description;
}
RenderSampleCounts VulkanDevice::getSampleCountsSupported(RenderFormat format) const {
const bool isDepthFormat = (format == RenderFormat::D16_UNORM) || (format == RenderFormat::D32_FLOAT);
+2
View File
@@ -363,6 +363,7 @@ namespace RT64 {
uint32_t queueFamilyIndices[3] = {};
std::vector<VulkanQueueFamily> queueFamilies;
RenderDeviceCapabilities capabilities;
RenderDeviceDescription description;
VkPhysicalDeviceRayTracingPipelinePropertiesKHR rtPipelineProperties = {};
VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationProperties = {};
bool loadStoreOpNoneSupported = false;
@@ -388,6 +389,7 @@ namespace RT64 {
void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild, bool preferFastTrace) override;
void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) override;
const RenderDeviceCapabilities &getCapabilities() const override;
const RenderDeviceDescription &getDescription() const override;
RenderSampleCounts getSampleCountsSupported(RenderFormat format) const override;
void release();
bool isValid() const;