fixed textures overlapping
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
------------ Tyra's v2.0 roadmap to publish on GitHub ------------
|
||||
|
||||
--- H4570
|
||||
- [Renderer] Fix sync problems with textures
|
||||
- [Renderer] Fix color issue in clipper
|
||||
- [Loaders] DFF loader as static Mesh loader
|
||||
- [Game] Update intellisense from docker
|
||||
- [Texture] Test cache hits with large amount of textures (dolphin sample?)
|
||||
- [Demo] Create cool demo which will show all features of Tyra (I will take this one)
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "renderer/renderer_settings.hpp"
|
||||
#include "./renderer_core_gs_vram.hpp"
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
@@ -22,23 +23,16 @@ class RendererCoreGS {
|
||||
prim_t prim;
|
||||
lod_t lod;
|
||||
zbuffer_t zBuffer;
|
||||
RendererCoreGSVRam vram;
|
||||
|
||||
void init(RendererSettings* settings);
|
||||
|
||||
void flipBuffers();
|
||||
|
||||
float getVRamFreeSpaceInMB() const {
|
||||
return 4.0F - spaceOccupiedByFrameBuffers - spaceOccupiedByZBuffer -
|
||||
vramMargin;
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr static float gsCenter = 4096.0F;
|
||||
constexpr static float screenCenter = gsCenter / 2.0F;
|
||||
constexpr static float vramMargin =
|
||||
0.003F; // We don't have perfectly 4MB of VRAM
|
||||
|
||||
float spaceOccupiedByFrameBuffers, spaceOccupiedByZBuffer;
|
||||
RendererSettings* settings;
|
||||
framebuffer_t frameBuffers[2];
|
||||
packet2_t* flipPacket;
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "renderer/renderer_settings.hpp"
|
||||
#include "renderer/core/texture/models/texture.hpp"
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
class RendererCoreGSVRam {
|
||||
public:
|
||||
RendererCoreGSVRam();
|
||||
~RendererCoreGSVRam();
|
||||
|
||||
const float& getFreeSpaceInMB();
|
||||
|
||||
float getSizeInMB(const Texture& texture);
|
||||
float getSizeInMB(const TextureData& texData);
|
||||
float getSizeInMB(int width, const int& height, const int& psm,
|
||||
const int& alignment);
|
||||
|
||||
int allocate(const TextureData& texData);
|
||||
int allocateBuffer(const int& width, const int& height, const int& psm);
|
||||
|
||||
/** Free texture, FIFO order */
|
||||
void free(const int& address);
|
||||
|
||||
private:
|
||||
int allocate(const int& width, const int& height, const int& psm,
|
||||
const int& alignment);
|
||||
|
||||
int getSize(int width, const int& height, const int& psm,
|
||||
const int& alignment);
|
||||
|
||||
static constexpr float ptr2MB = 262144.0F;
|
||||
bool touched;
|
||||
int pointer;
|
||||
float cachedFreeSpace;
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <draw_buffers.h>
|
||||
#include <vector>
|
||||
#include "renderer/core/texture/models/texture.hpp"
|
||||
#include "./renderer_texture_cm_analysis.hpp"
|
||||
#include "../renderer_core_texture_buffers.hpp"
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
class RendererTextureCacheManager {
|
||||
public:
|
||||
RendererTextureCacheManager();
|
||||
~RendererTextureCacheManager();
|
||||
|
||||
void onFrameChange();
|
||||
|
||||
void addRequestedTexture(Texture* texture);
|
||||
|
||||
u32 getTextureIdToDealloc(
|
||||
const std::vector<RendererCoreTextureBuffers>& currentAllocs);
|
||||
|
||||
private:
|
||||
RendererTextureCMAnalysis statistics;
|
||||
|
||||
void tryAddIdThatNotExistInAnalysis(
|
||||
std::vector<u32>* result,
|
||||
const std::vector<RendererCoreTextureBuffers>& currentAllocs,
|
||||
const std::vector<u32>& analysis);
|
||||
|
||||
void addIdThatExistInAnalysisButIsOnTheBottom(
|
||||
std::vector<u32>* result,
|
||||
const std::vector<RendererCoreTextureBuffers>& currentAllocs,
|
||||
const std::vector<u32>& analysis);
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include "debug/debug.hpp"
|
||||
#include <tamtypes.h>
|
||||
#include <vector>
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
struct RendererTextureCMAnalysisWeight {
|
||||
u32 id;
|
||||
u16 weight;
|
||||
};
|
||||
|
||||
struct RendererTextureCMAnalysisOccurence {
|
||||
u32 id;
|
||||
u8 occurence;
|
||||
};
|
||||
|
||||
class RendererTextureCMAnalysis {
|
||||
public:
|
||||
RendererTextureCMAnalysis();
|
||||
~RendererTextureCMAnalysis();
|
||||
|
||||
void changeFrame();
|
||||
|
||||
void addNewRequest(const u32& id);
|
||||
|
||||
/**
|
||||
* @brief Returns top list (from most used to least used) of textures to be
|
||||
* deallocated.
|
||||
*
|
||||
* @param count Number of textures to be returned.
|
||||
*/
|
||||
std::vector<u32> getTopTextureIdsForNextChanges(const u8& count);
|
||||
|
||||
bool isReady();
|
||||
|
||||
bool isProbablyNotCorrect();
|
||||
|
||||
private:
|
||||
std::vector<u32>*current, *last;
|
||||
std::vector<u32> buffers[2];
|
||||
u32 currentIndex;
|
||||
|
||||
void flipBuffers();
|
||||
|
||||
std::vector<u32> getNextTextureIds(const u8& count);
|
||||
|
||||
std::vector<RendererTextureCMAnalysisOccurence> getOccurencesForTextureIds(
|
||||
const std::vector<u32>& textureIds);
|
||||
|
||||
std::vector<u32> getTextureIdsUnique(const std::vector<u32>& textureIds);
|
||||
|
||||
std::vector<RendererTextureCMAnalysisWeight> getWeights(
|
||||
const std::vector<u32>& uniqueTexIds,
|
||||
const std::vector<RendererTextureCMAnalysisOccurence>& occurencies);
|
||||
|
||||
std::vector<u32> weightsToResult(
|
||||
std::vector<RendererTextureCMAnalysisWeight>* weights);
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
@@ -47,7 +47,7 @@ class Texture {
|
||||
|
||||
const TextureData& getCoreData() const { return *core; }
|
||||
|
||||
TextureData* getClutData() { return clut; }
|
||||
const TextureData* getClutData() const { return clut; }
|
||||
|
||||
/**
|
||||
* Get texture name.
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "./texture_repository.hpp"
|
||||
#include "./renderer_core_texture_sender.hpp"
|
||||
#include "renderer/core/paths/path3/path3.hpp"
|
||||
#include "./cache_manager/renderer_texture_cache_manager.hpp"
|
||||
#include "./renderer_core_texture_buffers.hpp"
|
||||
|
||||
namespace Tyra {
|
||||
@@ -33,14 +32,10 @@ class RendererCoreTexture {
|
||||
/** Called by renderer during initialization */
|
||||
void init(RendererCoreGS* gs, Path3* path3);
|
||||
|
||||
/** Called by renderer during beginFrame() */
|
||||
void onFrameChange();
|
||||
|
||||
/** Called by renderer during rendering */
|
||||
void updateClutBuffer(texbuffer_t* clutBuffer);
|
||||
|
||||
private:
|
||||
RendererTextureCacheManager cacheManager;
|
||||
std::vector<RendererCoreTextureBuffers> currentAllocations;
|
||||
|
||||
void initClut();
|
||||
@@ -48,6 +43,7 @@ class RendererCoreTexture {
|
||||
void unregisterAllocation(const u32& textureId);
|
||||
RendererCoreTextureBuffers getAllocatedBuffersByTextureId(const u32& id);
|
||||
|
||||
RendererCoreGS* gs;
|
||||
RendererCoreTextureSender sender;
|
||||
Path3* path3;
|
||||
};
|
||||
|
||||
@@ -31,19 +31,14 @@ class RendererCoreTextureSender {
|
||||
|
||||
void deallocate(const RendererCoreTextureBuffers& texBuffers);
|
||||
|
||||
float getFreeVRamInMB();
|
||||
|
||||
float getSizeInMB(texbuffer_t* texBuffer);
|
||||
|
||||
private:
|
||||
float allocatedVRamMemForTextures;
|
||||
RendererCoreGS* gs;
|
||||
Path3* path3;
|
||||
TextureBpp getBppByPsm(const u32& psm);
|
||||
texbuffer_t* allocateTextureCore(Texture* t_texture);
|
||||
texbuffer_t* allocateTextureClut(Texture* t_texture);
|
||||
|
||||
u8 isTextureVRAMAllocated, isVSyncEnabled;
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
namespace Tyra {
|
||||
|
||||
DynamicMesh::DynamicMesh(const MeshBuilderData& data) : Mesh(data) {
|
||||
TYRA_ASSERT(framesCount > 1, "Frames count must be greater than 1");
|
||||
|
||||
framesCount = data.framesCount;
|
||||
|
||||
TYRA_ASSERT(framesCount > 1, "Frames count must be greater than 1");
|
||||
|
||||
frames = new MeshFrame*[framesCount];
|
||||
for (u32 i = 0; i < framesCount; i++) {
|
||||
frames[i] = new MeshFrame(data, i);
|
||||
|
||||
@@ -25,8 +25,6 @@ namespace Tyra {
|
||||
|
||||
RendererCoreGS::RendererCoreGS() {
|
||||
context = 0;
|
||||
spaceOccupiedByFrameBuffers = 0;
|
||||
spaceOccupiedByZBuffer = 0;
|
||||
currentField = 0;
|
||||
}
|
||||
RendererCoreGS::~RendererCoreGS() {
|
||||
@@ -56,28 +54,25 @@ void RendererCoreGS::allocateBuffers() {
|
||||
frameBuffers[0].width = static_cast<unsigned int>(settings->getWidth());
|
||||
frameBuffers[0].height = static_cast<unsigned int>(settings->getHeight());
|
||||
frameBuffers[0].mask = 0;
|
||||
const u16 fpsm = 32;
|
||||
frameBuffers[0].psm = GS_PSM_32;
|
||||
frameBuffers[0].address =
|
||||
graph_vram_allocate(frameBuffers[0].width, frameBuffers[0].height,
|
||||
frameBuffers[0].psm, GRAPH_ALIGN_PAGE);
|
||||
vram.allocateBuffer(frameBuffers[0].width, frameBuffers[0].height,
|
||||
frameBuffers[0].psm);
|
||||
|
||||
frameBuffers[1].width = frameBuffers[0].width;
|
||||
frameBuffers[1].height = frameBuffers[0].height;
|
||||
frameBuffers[1].mask = frameBuffers[0].mask;
|
||||
frameBuffers[1].psm = frameBuffers[0].psm;
|
||||
frameBuffers[1].address =
|
||||
graph_vram_allocate(frameBuffers[1].width, frameBuffers[1].height,
|
||||
frameBuffers[1].psm, GRAPH_ALIGN_PAGE);
|
||||
vram.allocateBuffer(frameBuffers[1].width, frameBuffers[1].height,
|
||||
frameBuffers[1].psm);
|
||||
|
||||
zBuffer.enable = DRAW_ENABLE;
|
||||
zBuffer.mask = 0;
|
||||
zBuffer.method = ZTEST_METHOD_GREATER_EQUAL;
|
||||
const u16 zpsm = 32;
|
||||
zBuffer.zsm = GS_ZBUF_32;
|
||||
zBuffer.address =
|
||||
graph_vram_allocate(frameBuffers[0].width, frameBuffers[0].height,
|
||||
zBuffer.zsm, GRAPH_ALIGN_PAGE);
|
||||
zBuffer.address = vram.allocateBuffer(frameBuffers[0].width, frameBuffers[0].height,
|
||||
zBuffer.zsm);
|
||||
|
||||
graph_initialize(frameBuffers[1].address, frameBuffers[1].width,
|
||||
frameBuffers[1].height, frameBuffers[1].psm, 0, 0);
|
||||
@@ -93,17 +88,6 @@ void RendererCoreGS::allocateBuffers() {
|
||||
// frameBuffers[1].psm, 0, 0);
|
||||
// graph_enable_output();
|
||||
|
||||
spaceOccupiedByZBuffer =
|
||||
((frameBuffers[0].width / 100.0F) * (frameBuffers[0].height / 100.0F) *
|
||||
(zpsm / 100.0F)) /
|
||||
8.0F;
|
||||
|
||||
spaceOccupiedByFrameBuffers =
|
||||
((frameBuffers[0].width / 100.0F) * (frameBuffers[0].height / 100.0F) *
|
||||
(fpsm / 100.0F)) /
|
||||
8.0F;
|
||||
spaceOccupiedByFrameBuffers *= 2;
|
||||
|
||||
TYRA_LOG("Framebuffers, zBuffer set and allocated!");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include <dma.h>
|
||||
#include <graph.h>
|
||||
#include <gs_psm.h>
|
||||
#include "renderer/core/gs/renderer_core_gs_vram.hpp"
|
||||
|
||||
#define GS_VRAM_TEXTURE_ALIGNMENT GRAPH_ALIGN_BLOCK
|
||||
#define GS_VRAM_BUFFER_ALIGNMENT GRAPH_ALIGN_PAGE
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
RendererCoreGSVRam::RendererCoreGSVRam() {
|
||||
touched = false;
|
||||
pointer = 0;
|
||||
cachedFreeSpace = getFreeSpaceInMB();
|
||||
}
|
||||
|
||||
RendererCoreGSVRam::~RendererCoreGSVRam() {}
|
||||
|
||||
const float& RendererCoreGSVRam::getFreeSpaceInMB() {
|
||||
if (touched) {
|
||||
cachedFreeSpace = (GRAPH_VRAM_MAX_WORDS - pointer) / ptr2MB;
|
||||
touched = false;
|
||||
}
|
||||
|
||||
return cachedFreeSpace;
|
||||
}
|
||||
|
||||
float RendererCoreGSVRam::getSizeInMB(const Texture& texture) {
|
||||
float result = getSizeInMB(texture.getCoreData());
|
||||
|
||||
if (texture.getClutData() != nullptr) {
|
||||
result += getSizeInMB(*texture.getClutData());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float RendererCoreGSVRam::getSizeInMB(const TextureData& texData) {
|
||||
return getSizeInMB(texData.width, texData.height, texData.psm,
|
||||
GS_VRAM_TEXTURE_ALIGNMENT);
|
||||
}
|
||||
|
||||
float RendererCoreGSVRam::getSizeInMB(int width, const int& height,
|
||||
const int& psm, const int& alignment) {
|
||||
return getSize(width, height, psm, alignment) / ptr2MB;
|
||||
}
|
||||
|
||||
int RendererCoreGSVRam::allocate(const TextureData& texData) {
|
||||
return allocate(texData.width, texData.height, texData.psm,
|
||||
GS_VRAM_TEXTURE_ALIGNMENT);
|
||||
}
|
||||
|
||||
int RendererCoreGSVRam::allocateBuffer(const int& width, const int& height,
|
||||
const int& psm) {
|
||||
return allocate(width, height, psm, GS_VRAM_BUFFER_ALIGNMENT);
|
||||
}
|
||||
|
||||
int RendererCoreGSVRam::allocate(const int& width, const int& height,
|
||||
const int& psm, const int& alignment) {
|
||||
auto size = getSize(width, height, psm, alignment);
|
||||
|
||||
pointer += size;
|
||||
|
||||
// If the pointer overflows the vram size
|
||||
if (pointer > GRAPH_VRAM_MAX_WORDS) {
|
||||
pointer -= size;
|
||||
return -1;
|
||||
}
|
||||
|
||||
touched = true;
|
||||
|
||||
return pointer - size;
|
||||
}
|
||||
|
||||
void RendererCoreGSVRam::free(const int& address) {
|
||||
pointer = address;
|
||||
touched = true;
|
||||
}
|
||||
|
||||
int RendererCoreGSVRam::getSize(int width, const int& height, const int& psm,
|
||||
const int& alignment) {
|
||||
int size = 0;
|
||||
|
||||
// First correct the buffer width to be a multiple of 64 or 128
|
||||
// If the width is less than or equal to 16, then it's a palette
|
||||
if (width > 16) {
|
||||
switch (psm) {
|
||||
case GS_PSM_8:
|
||||
case GS_PSM_4:
|
||||
case GS_PSM_8H:
|
||||
case GS_PSM_4HL:
|
||||
case GS_PSM_4HH:
|
||||
width = -128 & (width + 127);
|
||||
break;
|
||||
default:
|
||||
width = -64 & (width + 63);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Texture storage size is in pixels/word
|
||||
switch (psm) {
|
||||
case GS_PSM_4:
|
||||
size = width * (height >> 3);
|
||||
break;
|
||||
case GS_PSM_8:
|
||||
size = width * (height >> 2);
|
||||
break;
|
||||
case GS_PSM_24:
|
||||
case GS_PSM_32:
|
||||
case GS_PSM_8H:
|
||||
case GS_PSM_4HL:
|
||||
case GS_PSM_4HH:
|
||||
case GS_PSMZ_24:
|
||||
case GS_PSMZ_32:
|
||||
size = width * height;
|
||||
break;
|
||||
case GS_PSM_16:
|
||||
case GS_PSM_16S:
|
||||
case GS_PSMZ_16:
|
||||
case GS_PSMZ_16S:
|
||||
size = width * (height >> 1);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (alignment == GS_VRAM_TEXTURE_ALIGNMENT) {
|
||||
// TODO: Without this hack, textures are overlapping ourselves
|
||||
size += 1024 * 2;
|
||||
}
|
||||
|
||||
// The buffer size is dependent on alignment
|
||||
size = -alignment & (size + (alignment - 1));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
} // namespace Tyra
|
||||
@@ -29,7 +29,6 @@ void RendererCore::setClearScreenColor(const Color& color) { bgColor = color; }
|
||||
|
||||
void RendererCore::beginFrame(const CameraInfo3D& cameraInfo) {
|
||||
renderer3D.update(cameraInfo);
|
||||
texture.onFrameChange();
|
||||
Threading::switchThread();
|
||||
path3.clearScreen(&gs.zBuffer, bgColor);
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "renderer/core/texture/cache_manager/renderer_texture_cache_manager.hpp"
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
RendererTextureCacheManager::RendererTextureCacheManager() {}
|
||||
RendererTextureCacheManager::~RendererTextureCacheManager() {}
|
||||
|
||||
void RendererTextureCacheManager::onFrameChange() { statistics.changeFrame(); }
|
||||
|
||||
void RendererTextureCacheManager::addRequestedTexture(Texture* texture) {
|
||||
statistics.addNewRequest(texture->getId());
|
||||
}
|
||||
|
||||
u32 RendererTextureCacheManager::getTextureIdToDealloc(
|
||||
const std::vector<RendererCoreTextureBuffers>& currentAllocs) {
|
||||
if (!statistics.isReady() || statistics.isProbablyNotCorrect()) {
|
||||
return currentAllocs.size() > 0 ? currentAllocs.at(0).id : 0;
|
||||
}
|
||||
|
||||
u8 tuner = currentAllocs.size() > 254 ? 254 : currentAllocs.size();
|
||||
if (tuner >= 6) {
|
||||
tuner /= 3;
|
||||
} else if (tuner >= 4) {
|
||||
tuner /= 2;
|
||||
} else {
|
||||
tuner = 1;
|
||||
}
|
||||
|
||||
std::vector<u32> temp;
|
||||
|
||||
auto probableTextureIds = statistics.getTopTextureIdsForNextChanges(tuner);
|
||||
|
||||
tryAddIdThatNotExistInAnalysis(&temp, currentAllocs, probableTextureIds);
|
||||
|
||||
if (temp.size() == 0) {
|
||||
addIdThatExistInAnalysisButIsOnTheBottom(&temp, currentAllocs,
|
||||
probableTextureIds);
|
||||
}
|
||||
|
||||
return temp.at(0);
|
||||
}
|
||||
|
||||
void RendererTextureCacheManager::tryAddIdThatNotExistInAnalysis(
|
||||
std::vector<u32>* result,
|
||||
const std::vector<RendererCoreTextureBuffers>& currentAllocs,
|
||||
const std::vector<u32>& analysis) {
|
||||
for (u32 i = 0; i < currentAllocs.size(); i++) {
|
||||
if (std::find(analysis.begin(), analysis.end(), currentAllocs.at(i).id) ==
|
||||
analysis.end()) {
|
||||
result->push_back(currentAllocs.at(i).id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RendererTextureCacheManager::addIdThatExistInAnalysisButIsOnTheBottom(
|
||||
std::vector<u32>* result,
|
||||
const std::vector<RendererCoreTextureBuffers>& currentAllocs,
|
||||
const std::vector<u32>& analysis) {
|
||||
u32 lastId = analysis.at(analysis.size() - 1);
|
||||
result->push_back(lastId);
|
||||
}
|
||||
|
||||
} // namespace Tyra
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
# ______ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||
# Licenced under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "renderer/core/texture/cache_manager/renderer_texture_cm_analysis.hpp"
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
RendererTextureCMAnalysis::RendererTextureCMAnalysis() {
|
||||
last = &buffers[0];
|
||||
current = &buffers[1];
|
||||
currentIndex = 0;
|
||||
}
|
||||
RendererTextureCMAnalysis::~RendererTextureCMAnalysis() {}
|
||||
|
||||
void RendererTextureCMAnalysis::changeFrame() {
|
||||
flipBuffers();
|
||||
current->clear();
|
||||
currentIndex = 0;
|
||||
}
|
||||
|
||||
void RendererTextureCMAnalysis::addNewRequest(const u32& id) {
|
||||
current->push_back(id);
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
std::vector<u32> RendererTextureCMAnalysis::getTopTextureIdsForNextChanges(
|
||||
const u8& count) {
|
||||
TYRA_ASSERT(!isProbablyNotCorrect(),
|
||||
"Analysis not available, because its probably not correct - "
|
||||
"internal error");
|
||||
|
||||
auto nextTextureIds = getNextTextureIds(count);
|
||||
auto occurences = getOccurencesForTextureIds(nextTextureIds);
|
||||
auto uniqueTextureIds = getTextureIdsUnique(nextTextureIds);
|
||||
auto weights = getWeights(uniqueTextureIds, occurences);
|
||||
auto result = weightsToResult(&weights);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<u32> RendererTextureCMAnalysis::getNextTextureIds(const u8& count) {
|
||||
std::vector<u32> result;
|
||||
|
||||
for (u32 i = 0; i < count; i++) {
|
||||
u32 index = i + currentIndex;
|
||||
u32 offset = index >= last->size() ? index - last->size() : index;
|
||||
result.push_back(last->at(offset));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<RendererTextureCMAnalysisOccurence>
|
||||
RendererTextureCMAnalysis::getOccurencesForTextureIds(
|
||||
const std::vector<u32>& textureIds) {
|
||||
std::vector<RendererTextureCMAnalysisOccurence> result;
|
||||
|
||||
for (u8 i = 0; i < textureIds.size(); i++) {
|
||||
// If not exist, add with 1 occurence
|
||||
if (std::find_if(result.begin(), result.end(),
|
||||
[textureIds,
|
||||
i](const RendererTextureCMAnalysisOccurence& occurence) {
|
||||
return occurence.id == textureIds[i];
|
||||
}) == result.end()) {
|
||||
result.push_back({textureIds[i], 1});
|
||||
} else {
|
||||
// If exist, increase occurence
|
||||
auto occurence = std::find_if(
|
||||
result.begin(), result.end(),
|
||||
[textureIds, i](const RendererTextureCMAnalysisOccurence& occurence) {
|
||||
return occurence.id == textureIds[i];
|
||||
});
|
||||
occurence->occurence++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<u32> RendererTextureCMAnalysis::getTextureIdsUnique(
|
||||
const std::vector<u32>& textureIds) {
|
||||
std::vector<u32> result;
|
||||
|
||||
for (u8 i = 0; i < textureIds.size(); i++) {
|
||||
if (std::find(result.begin(), result.end(), textureIds[i]) ==
|
||||
result.end()) {
|
||||
result.push_back(textureIds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<RendererTextureCMAnalysisWeight>
|
||||
RendererTextureCMAnalysis::getWeights(
|
||||
const std::vector<u32>& uniqueTexIds,
|
||||
const std::vector<RendererTextureCMAnalysisOccurence>& occurencies) {
|
||||
std::vector<RendererTextureCMAnalysisWeight> result;
|
||||
|
||||
for (u8 i = 0; i < uniqueTexIds.size(); i++) {
|
||||
u16 weight = uniqueTexIds.size() - i;
|
||||
|
||||
for (u8 j = 0; j < occurencies.size(); j++) {
|
||||
if (occurencies[j].id == uniqueTexIds[i]) {
|
||||
weight *= occurencies[j].occurence;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result.push_back({uniqueTexIds[i], weight});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<u32> RendererTextureCMAnalysis::weightsToResult(
|
||||
std::vector<RendererTextureCMAnalysisWeight>* weights) {
|
||||
std::sort(weights->begin(), weights->end(),
|
||||
[](const auto& a, const auto& b) { return a.weight > b.weight; });
|
||||
|
||||
std::vector<u32> result;
|
||||
for (u8 i = 0; i < weights->size(); i++) {
|
||||
result.push_back(weights->at(i).id);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool RendererTextureCMAnalysis::isReady() { return last->size() != 0; }
|
||||
|
||||
bool RendererTextureCMAnalysis::isProbablyNotCorrect() {
|
||||
return currentIndex > last->size();
|
||||
}
|
||||
|
||||
void RendererTextureCMAnalysis::flipBuffers() {
|
||||
if (current == &buffers[0]) {
|
||||
current = &buffers[1];
|
||||
last = &buffers[0];
|
||||
} else {
|
||||
current = &buffers[0];
|
||||
last = &buffers[1];
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Tyra
|
||||
@@ -16,9 +16,8 @@ RendererCoreTexture::RendererCoreTexture() {}
|
||||
|
||||
RendererCoreTexture::~RendererCoreTexture() {}
|
||||
|
||||
void RendererCoreTexture::onFrameChange() { cacheManager.onFrameChange(); }
|
||||
|
||||
void RendererCoreTexture::init(RendererCoreGS* t_gs, Path3* t_path3) {
|
||||
gs = t_gs;
|
||||
sender.init(t_path3, t_gs);
|
||||
path3 = t_path3;
|
||||
initClut();
|
||||
@@ -39,29 +38,16 @@ void RendererCoreTexture::updateClutBuffer(texbuffer_t* clutBuffer) {
|
||||
RendererCoreTextureBuffers RendererCoreTexture::useTexture(Texture* t_tex) {
|
||||
TYRA_ASSERT(t_tex != nullptr, "Provided nullptr texture!");
|
||||
|
||||
// cacheManager.addRequestedTexture(t_tex);
|
||||
|
||||
auto allocated = getAllocatedBuffersByTextureId(t_tex->getId());
|
||||
if (allocated.id != 0) return allocated;
|
||||
|
||||
// TODO: FIXME!
|
||||
if (currentAllocations.size()) {
|
||||
// if (t_tex->getSizeInMB() > sender.getFreeVRamInMB()) {
|
||||
if (gs->vram.getSizeInMB(*t_tex) >= gs->vram.getFreeSpaceInMB()) {
|
||||
for (int i = currentAllocations.size() - 1; i >= 0; i--) {
|
||||
sender.deallocate(currentAllocations[i]);
|
||||
}
|
||||
currentAllocations.clear();
|
||||
}
|
||||
|
||||
// while (t_tex->getSizeInMB() > sender.getFreeVRamInMB()) {
|
||||
// auto idToDealloc =
|
||||
// cacheManager.getTextureIdToDealloc(currentAllocations);
|
||||
// auto buffToDealloc = getAllocatedBuffersByTextureId(idToDealloc);
|
||||
// TYRA_LOG("Deallocate(", buffToDealloc.id, ")");
|
||||
// sender.deallocate(buffToDealloc);
|
||||
// unregisterAllocation(idToDealloc);
|
||||
// }
|
||||
|
||||
auto newTexBuffer = sender.allocate(t_tex);
|
||||
path3->sendTexture(t_tex, newTexBuffer);
|
||||
registerAllocation(newTexBuffer);
|
||||
|
||||
@@ -13,10 +13,7 @@
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
RendererCoreTextureSender::RendererCoreTextureSender() {
|
||||
isTextureVRAMAllocated = false;
|
||||
allocatedVRamMemForTextures = 0;
|
||||
}
|
||||
RendererCoreTextureSender::RendererCoreTextureSender() {}
|
||||
RendererCoreTextureSender::~RendererCoreTextureSender() {}
|
||||
|
||||
void RendererCoreTextureSender::init(Path3* t_path3, RendererCoreGS* t_gs) {
|
||||
@@ -47,36 +44,28 @@ float RendererCoreTextureSender::getSizeInMB(texbuffer_t* texBuffer) {
|
||||
void RendererCoreTextureSender::deallocate(
|
||||
const RendererCoreTextureBuffers& texBuffers) {
|
||||
if (texBuffers.clut != nullptr && texBuffers.clut->width > 0) {
|
||||
graph_vram_free(texBuffers.clut->address);
|
||||
gs->vram.free(texBuffers.clut->address);
|
||||
delete texBuffers.clut;
|
||||
}
|
||||
|
||||
graph_vram_free(texBuffers.core->address);
|
||||
|
||||
float deallocateSize = getSizeInMB(texBuffers.core);
|
||||
gs->vram.free(texBuffers.core->address);
|
||||
|
||||
delete texBuffers.core;
|
||||
|
||||
allocatedVRamMemForTextures -= deallocateSize;
|
||||
}
|
||||
|
||||
texbuffer_t* RendererCoreTextureSender::allocateTextureCore(
|
||||
Texture* t_texture) {
|
||||
auto* result = new texbuffer_t;
|
||||
const auto& core = t_texture->getCoreData();
|
||||
|
||||
result->width = t_texture->getWidth();
|
||||
result->psm = t_texture->getCoreData().psm;
|
||||
result->info.components = t_texture->getCoreData().components;
|
||||
result->psm = core.psm;
|
||||
result->info.components = core.components;
|
||||
|
||||
TYRA_ASSERT(t_texture->getSizeInMB() <= getFreeVRamInMB(),
|
||||
"Not enough VRAM memory for texture!");
|
||||
|
||||
auto address =
|
||||
graph_vram_allocate(t_texture->getWidth(), t_texture->getHeight(),
|
||||
result->psm, GRAPH_ALIGN_BLOCK);
|
||||
auto address = gs->vram.allocate(core);
|
||||
TYRA_ASSERT(address > 0, "Texture buffer allocation error, no memory!");
|
||||
result->address = address;
|
||||
|
||||
allocatedVRamMemForTextures += t_texture->getSizeInMB();
|
||||
result->info.width = draw_log2(t_texture->getWidth());
|
||||
result->info.height = draw_log2(t_texture->getHeight());
|
||||
result->info.function = TEXTURE_FUNCTION_MODULATE;
|
||||
@@ -92,8 +81,7 @@ texbuffer_t* RendererCoreTextureSender::allocateTextureClut(
|
||||
result->psm = clut->psm;
|
||||
result->info.components = clut->components;
|
||||
|
||||
auto address = graph_vram_allocate(clut->width, clut->height, result->psm,
|
||||
GRAPH_ALIGN_BLOCK);
|
||||
auto address = gs->vram.allocate(*clut);
|
||||
TYRA_ASSERT(address > 0, "Texture clut buffer allocation error, no memory!");
|
||||
result->address = address;
|
||||
|
||||
@@ -103,10 +91,6 @@ texbuffer_t* RendererCoreTextureSender::allocateTextureClut(
|
||||
return result;
|
||||
}
|
||||
|
||||
float RendererCoreTextureSender::getFreeVRamInMB() {
|
||||
return gs->getVRamFreeSpaceInMB() - allocatedVRamMemForTextures;
|
||||
}
|
||||
|
||||
TextureBpp RendererCoreTextureSender::getBppByPsm(const u32& psm) {
|
||||
if (psm == GS_PSM_32) {
|
||||
return bpp32;
|
||||
|
||||
Reference in New Issue
Block a user