Add internal code for temporary buffers.

This commit is contained in:
Alex Szpakowski
2022-05-30 21:46:55 -03:00
parent a533982cb4
commit fb450b1df4
4 changed files with 134 additions and 36 deletions
+105 -1
View File
@@ -235,6 +235,8 @@ Graphics::~Graphics()
for (int i = 0; i < (int) SHADERSTAGE_MAX_ENUM; i++)
cachedShaderStages[i].clear();
clearTemporaryResources();
Shader::deinitialize();
}
@@ -887,6 +889,10 @@ void Graphics::setRenderTargets(const RenderTargets &rts)
realRTs.depthStencil.texture = getTemporaryTexture(dsformat, pixelw, pixelh, reqmsaa);
realRTs.depthStencil.slice = 0;
// TODO: fix this to call release at the right time.
// This only works here because nothing else calls getTemporaryTexture.
releaseTemporaryTexture(realRTs.depthStencil.texture);
setRenderTargetsInternal(realRTs, pixelw, pixelh, hasSRGBtexture);
}
else
@@ -989,12 +995,15 @@ Texture *Graphics::getTemporaryTexture(PixelFormat format, int w, int h, int sam
for (TemporaryTexture &temp : temporaryTextures)
{
if (temp.framesSinceUse < 0)
continue;
Texture *c = temp.texture;
if (c->getPixelFormat() == format && c->getPixelWidth() == w
&& c->getPixelHeight() == h && c->getRequestedMSAA() == samples)
{
texture = c;
temp.framesSinceUse = 0;
temp.framesSinceUse = -1;
break;
}
}
@@ -1016,6 +1025,101 @@ Texture *Graphics::getTemporaryTexture(PixelFormat format, int w, int h, int sam
return texture;
}
void Graphics::releaseTemporaryTexture(Texture *texture)
{
for (TemporaryTexture &temp : temporaryTextures)
{
if (temp.texture == texture)
{
temp.framesSinceUse = 0;
break;
}
}
}
Buffer *Graphics::getTemporaryBuffer(size_t size, DataFormat format, uint32 usageflags, BufferDataUsage datausage)
{
Buffer *buffer = nullptr;
for (TemporaryBuffer &temp : temporaryBuffers)
{
if (temp.framesSinceUse < 0)
continue;
Buffer *b = temp.buffer;
if (temp.size == size && b->getDataMember(0).decl.format == format
&& b->getUsageFlags() == usageflags && b->getDataUsage() == datausage)
{
buffer = b;
temp.framesSinceUse = -1;
break;
}
}
if (buffer == nullptr)
{
Buffer::Settings settings(usageflags, datausage);
buffer = newBuffer(settings, format, nullptr, size, 0);
temporaryBuffers.emplace_back(buffer, size);
}
return buffer;
}
void Graphics::releaseTemporaryBuffer(Buffer *buffer)
{
for (TemporaryBuffer &temp : temporaryBuffers)
{
if (temp.buffer == buffer)
{
temp.framesSinceUse = 0;
break;
}
}
}
void Graphics::updateTemporaryResources()
{
for (int i = (int) temporaryTextures.size() - 1; i >= 0; i--)
{
auto &t = temporaryTextures[i];
if (t.framesSinceUse >= MAX_TEMPORARY_RESOURCE_UNUSED_FRAMES)
{
t.texture->release();
t = temporaryTextures.back();
temporaryTextures.pop_back();
}
else if (t.framesSinceUse >= 0)
t.framesSinceUse++;
}
for (int i = (int) temporaryBuffers.size() - 1; i >= 0; i--)
{
auto &t = temporaryBuffers[i];
if (t.framesSinceUse >= MAX_TEMPORARY_RESOURCE_UNUSED_FRAMES)
{
t.buffer->release();
t = temporaryBuffers.back();
temporaryBuffers.pop_back();
}
else if (t.framesSinceUse >= 0)
t.framesSinceUse++;
}
}
void Graphics::clearTemporaryResources()
{
for (auto temp :temporaryBuffers)
temp.buffer->release();
for (auto temp : temporaryTextures)
temp.texture->release();
temporaryBuffers.clear();
temporaryTextures.clear();
}
void Graphics::intersectScissor(const Rect &rect)
{
Rect currect = states.back().scissorRect;
+24 -3
View File
@@ -856,6 +856,12 @@ public:
static void flushBatchedDrawsGlobal();
Texture *getTemporaryTexture(PixelFormat format, int w, int h, int samples);
void releaseTemporaryTexture(Texture *texture);
Buffer *getTemporaryBuffer(size_t size, DataFormat format, uint32 usageflags, BufferDataUsage datausage);
void releaseTemporaryBuffer(Buffer *buffer);
void cleanupCachedShaderStage(ShaderStageType type, const std::string &cachekey);
template <typename T>
@@ -954,6 +960,19 @@ protected:
}
};
struct TemporaryBuffer
{
Buffer *buffer;
size_t size;
int framesSinceUse;
TemporaryBuffer(Buffer *buf, size_t size)
: buffer(buf)
, size(size)
, framesSinceUse(-1)
{}
};
struct TemporaryTexture
{
Texture *texture;
@@ -961,7 +980,7 @@ protected:
TemporaryTexture(Texture *tex)
: texture(tex)
, framesSinceUse(0)
, framesSinceUse(-1)
{}
};
@@ -980,7 +999,8 @@ protected:
void createQuadIndexBuffer();
void createFanIndexBuffer();
Texture *getTemporaryTexture(PixelFormat format, int w, int h, int samples);
void updateTemporaryResources();
void clearTemporaryResources();
void restoreState(const DisplayState &s);
void restoreStateChecked(const DisplayState &s);
@@ -1014,6 +1034,7 @@ protected:
std::vector<DisplayState> states;
std::vector<StackType> stackTypeStack;
std::vector<TemporaryBuffer> temporaryBuffers;
std::vector<TemporaryTexture> temporaryTextures;
int renderTargetSwitchCount;
@@ -1028,7 +1049,7 @@ protected:
Deprecations deprecations;
static const size_t MAX_USER_STACK_DEPTH = 128;
static const int MAX_TEMPORARY_TEXTURE_UNUSED_FRAMES = 16;
static const int MAX_TEMPORARY_RESOURCE_UNUSED_FRAMES = 16;
private:
+2 -16
View File
@@ -501,10 +501,7 @@ void Graphics::unSetMode()
submitCommandBuffer(SUBMIT_DONE);
for (auto temp : temporaryTextures)
temp.texture->release();
temporaryTextures.clear();
clearTemporaryResources();
created = false;
metalLayer = nil;
@@ -1620,18 +1617,7 @@ void Graphics::present(void *screenshotCallbackData)
renderTargetSwitchCount = 0;
drawCallsBatched = 0;
// This assumes temporary canvases will only be used within a render pass.
for (int i = (int) temporaryTextures.size() - 1; i >= 0; i--)
{
if (temporaryTextures[i].framesSinceUse >= MAX_TEMPORARY_TEXTURE_UNUSED_FRAMES)
{
temporaryTextures[i].texture->release();
temporaryTextures[i] = temporaryTextures.back();
temporaryTextures.pop_back();
}
else
temporaryTextures[i].framesSinceUse++;
}
updateTemporaryResources();
}}
int Graphics::getRequestedBackbufferMSAA() const
+3 -16
View File
@@ -462,14 +462,12 @@ void Graphics::unSetMode()
// mode change.
Volatile::unloadAll();
clearTemporaryResources();
for (const auto &pair : framebufferObjects)
gl.deleteFramebuffer(pair.second);
for (auto temp : temporaryTextures)
temp.texture->release();
framebufferObjects.clear();
temporaryTextures.clear();
if (mainVAO != 0)
{
@@ -1335,18 +1333,7 @@ void Graphics::present(void *screenshotCallbackData)
renderTargetSwitchCount = 0;
drawCallsBatched = 0;
// This assumes temporary textures will only be used within a render pass.
for (int i = (int) temporaryTextures.size() - 1; i >= 0; i--)
{
if (temporaryTextures[i].framesSinceUse >= MAX_TEMPORARY_TEXTURE_UNUSED_FRAMES)
{
temporaryTextures[i].texture->release();
temporaryTextures[i] = temporaryTextures.back();
temporaryTextures.pop_back();
}
else
temporaryTextures[i].framesSinceUse++;
}
updateTemporaryResources();
}
int Graphics::getRequestedBackbufferMSAA() const