Skip to content

Commit

Permalink
finish dynamic resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
malytomas committed Nov 10, 2024
1 parent 298648b commit 69781d0
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 74 deletions.
9 changes: 3 additions & 6 deletions sources/include/cage-engine/provisionalGraphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,32 @@ namespace cage
{
public:
Holder<UniformBuffer> resolve(); // requires opengl context
bool ready() const;
};

class CAGE_ENGINE_API ProvisionalFrameBuffer : private Immovable
{
public:
Holder<FrameBuffer> resolve(); // requires opengl context
bool ready() const;
};

class CAGE_ENGINE_API ProvisionalTexture : private Immovable
{
public:
Holder<Texture> resolve(); // requires opengl context
bool ready() const;
};

class CAGE_ENGINE_API ProvisionalGraphics : private Immovable
{
public:
// section: thread-safe, does not require opengl context

Holder<ProvisionalUniformBuffer> uniformBuffer(const String &name);
Holder<ProvisionalUniformBuffer> uniformBuffer(const String &name, std::function<void(UniformBuffer *)> &&init = {});

Holder<ProvisionalFrameBuffer> frameBufferDraw(const String &name);
Holder<ProvisionalFrameBuffer> frameBufferRead(const String &name);

Holder<ProvisionalTexture> texture(const String &name, std::function<void(Texture *)> &&init);
Holder<ProvisionalTexture> texture(const String &name, uint32 target, std::function<void(Texture *)> &&init);
Holder<ProvisionalTexture> texture(const String &name, std::function<void(Texture *)> &&init = {});
Holder<ProvisionalTexture> texture(const String &name, uint32 target, std::function<void(Texture *)> &&init = {});

// section: thread-safe, requires opengl context

Expand Down
2 changes: 1 addition & 1 deletion sources/include/cage-simple/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ namespace cage
VoicesMixer *engineMasterMixer();
VoicesMixer *engineEffectsMixer();
VoicesMixer *engineGuiMixer();
ProvisionalGraphics *engineProvisonalGraphics();
ProvisionalGraphics *engineProvisionalGraphics();
uint64 engineControlTime();

struct EngineDynamicResolution
Expand Down
54 changes: 21 additions & 33 deletions sources/libengine/graphics/provisionalGraphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ namespace cage
{
public:
const String name;
std::function<void(UniformBuffer *)> init;
Holder<UniformBuffer> result;
ProvisionalGraphicsImpl *impl = nullptr;
uint32 type = m; // 1 = init copied
bool used = true;

ProvisionalUniformBufferImpl(const String &name) : name(name) {}
Expand Down Expand Up @@ -64,25 +66,21 @@ namespace cage
{
Holder<T> v = systemMemory().createHolder<T>(name);
data.insert(v.share());
return std::move(v);
return v;
}
return it->share();
}

void reset()
{
ScopeLock lock(mutex);
auto it = data.begin();
while (it != data.end())
{
if ((*it)->used)
std::erase_if(data,
[](auto &it)
{
(*it)->used = false;
it++;
}
else
it = data.erase(it);
}
const bool res = it->used;
it->used = false;
return !res;
});
}

void purge()
Expand Down Expand Up @@ -119,9 +117,14 @@ namespace cage
Container<ProvisionalFrameBufferHandleImpl> frameBuffers;
Container<ProvisionalTextureHandleImpl> textures;

Holder<ProvisionalUniformBuffer> uniformBuffer(const String &name)
Holder<ProvisionalUniformBuffer> uniformBuffer(const String &name, std::function<void(UniformBuffer *)> &&init)
{
auto ub = uniformBuffers.acquire(name);
if (ub->type == m)
{
ub->type = 1;
ub->init = std::move(init);
}
return std::move(ub).cast<ProvisionalUniformBuffer>();
}

Expand Down Expand Up @@ -169,16 +172,12 @@ namespace cage
{
impl->result = newUniformBuffer();
impl->result->setDebugName(impl->name);
if (impl->init)
impl->init(+impl->result);
}
return impl->result.share();
}

bool ProvisionalUniformBuffer::ready() const
{
const ProvisionalUniformBufferImpl *impl = (const ProvisionalUniformBufferImpl *)this;
return !!impl->result;
}

Holder<FrameBuffer> ProvisionalFrameBuffer::resolve()
{
ProvisionalFrameBufferHandleImpl *impl = (ProvisionalFrameBufferHandleImpl *)this;
Expand All @@ -199,12 +198,6 @@ namespace cage
return impl->result.share();
}

bool ProvisionalFrameBuffer::ready() const
{
const ProvisionalFrameBufferHandleImpl *impl = (const ProvisionalFrameBufferHandleImpl *)this;
return !!impl->result;
}

Holder<Texture> ProvisionalTexture::resolve()
{
ProvisionalTextureHandleImpl *impl = (ProvisionalTextureHandleImpl *)this;
Expand All @@ -213,21 +206,16 @@ namespace cage
{
impl->result = newTexture(impl->target);
impl->result->setDebugName(impl->name);
impl->init(+impl->result);
if (impl->init)
impl->init(+impl->result);
}
return impl->result.share();
}

bool ProvisionalTexture::ready() const
{
const ProvisionalTextureHandleImpl *impl = (const ProvisionalTextureHandleImpl *)this;
return !!impl->result;
}

Holder<ProvisionalUniformBuffer> ProvisionalGraphics::uniformBuffer(const String &name)
Holder<ProvisionalUniformBuffer> ProvisionalGraphics::uniformBuffer(const String &name, std::function<void(UniformBuffer *)> &&init)
{
ProvisionalGraphicsImpl *impl = (ProvisionalGraphicsImpl *)this;
return impl->uniformBuffer(name);
return impl->uniformBuffer(name, std::move(init));
}

Holder<ProvisionalFrameBuffer> ProvisionalGraphics::frameBufferDraw(const String &name)
Expand Down
27 changes: 15 additions & 12 deletions sources/libengine/graphics/renderPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@ namespace cage
TextureHandle colorTexture = provisionalGraphics->texture(Stringizer() + "colorTarget_" + data.name + "_" + data.resolution,
[resolution = data.resolution](Texture *t)
{
t->initialize(resolution, 1, GL_RGBA16F);
t->initialize(resolution, 1, GL_RGBA16F); // RGB16F (without alpha) is not required to work in frame buffer
t->filters(GL_LINEAR, GL_LINEAR, 0);
t->wraps(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
});
Expand Down Expand Up @@ -1047,17 +1047,13 @@ namespace cage
const auto graphicsDebugScope = renderQueue->namedScope("effects");

TextureHandle texSource = colorTexture;
TextureHandle texTarget = [&]()
{
TextureHandle t = provisionalGraphics->texture(Stringizer() + "intermediateTarget_" + data.resolution,
[resolution = data.resolution](Texture *t)
{
t->initialize(resolution, 1, GL_RGBA16F);
t->filters(GL_LINEAR, GL_LINEAR, 0);
t->wraps(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
});
return t;
}();
TextureHandle texTarget = provisionalGraphics->texture(Stringizer() + "intermediateTarget_" + data.resolution,
[resolution = data.resolution](Texture *t)
{
t->initialize(resolution, 1, GL_RGBA16F); // RGB16F (without alpha) is not required to work in frame buffer
t->filters(GL_LINEAR, GL_LINEAR, 0);
t->wraps(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
});

// depth of field
if (any(data.effects.effects & ScreenSpaceEffectsFlags::DepthOfField))
Expand All @@ -1073,6 +1069,10 @@ namespace cage
std::swap(texSource, texTarget);
}

renderQueue->resetFrameBuffer();
renderQueue->resetAllState();
renderQueue->resetAllTextures();

// eye adaptation
if (any(data.effects.effects & ScreenSpaceEffectsFlags::EyeAdaptation))
{
Expand Down Expand Up @@ -1138,11 +1138,13 @@ namespace cage
// blit to destination
if (texSource != colorTexture)
{
const auto graphicsDebugScope = renderQueue->namedScope("effects blit");
renderQueue->viewport(Vec2i(), data.resolution);
renderQueue->bind(texSource, 0);
renderQueue->bind(shaderBlitPixels);
renderQueue->bind(renderTarget);
renderQueue->colorTexture(renderTarget, 0, colorTexture);
renderQueue->depthTexture(renderTarget, {});
renderQueue->activeAttachments(renderTarget, 1);
renderQueue->checkFrameBuffer(renderTarget);
renderQueue->draw(modelSquare);
Expand All @@ -1155,6 +1157,7 @@ namespace cage
const auto graphicsDebugScope = renderQueue->namedScope("final blit");
renderQueue->resetAllState();
renderQueue->viewport(Vec2i(), data.resolution);
renderQueue->bind(data.target, 0); // ensure the texture is properly initialized
renderQueue->bind(colorTexture, 0);
renderQueue->bind(shaderBlitPixels);
renderQueue->bind(renderTarget);
Expand Down
13 changes: 4 additions & 9 deletions sources/libengine/graphics/screenSpaceEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <cage-engine/screenSpaceEffects.h>
#include <cage-engine/shaderProgram.h>
#include <cage-engine/texture.h>
#include <cage-engine/uniformBuffer.h>

namespace cage
{
Expand Down Expand Up @@ -82,13 +83,7 @@ namespace cage
FrameBufferHandle fb = config.provisionals->frameBufferDraw("graphicsEffects");
q->bind(fb);

UniformBufferHandle ssaoPoints = config.provisionals->uniformBuffer("ssaoPoints");
{ // potentially dangerous hack
ProvisionalUniformBuffer *pub = (ProvisionalUniformBuffer *)ssaoPoints.pointer();
CAGE_ASSERT(pub);
if (!pub->ready())
q->writeWhole(ssaoPoints, privat::pointsForSsaoShader(), GL_STATIC_DRAW);
}
UniformBufferHandle ssaoPoints = config.provisionals->uniformBuffer("ssaoPoints", [](UniformBuffer *ub) { ub->writeWhole(privat::pointsForSsaoShader(), GL_STATIC_DRAW); });
q->bind(ssaoPoints, 3);

struct Shader
Expand Down Expand Up @@ -229,7 +224,7 @@ namespace cage
q->bindImage(config.inColor, 0, true, false);
TextureHandle texHist = provTex(config.provisionals, Stringizer() + "luminanceHistogram", Vec2i(256, 1), 1, GL_R32UI);
q->bindImage(texHist, 1, true, true);
TextureHandle texAccum = provTex(config.provisionals, Stringizer() + "luminanceAccumulation" + config.cameraId, Vec2i(1), 1, GL_R32F);
TextureHandle texAccum = provTex(config.provisionals, Stringizer() + "luminanceAccumulation_" + config.cameraId, Vec2i(1), 1, GL_R32F);
q->bindImage(texAccum, 2, true, true);

// collection
Expand Down Expand Up @@ -312,7 +307,7 @@ namespace cage
q->colorTexture(fb, 0, config.outColor);
q->checkFrameBuffer(fb);
q->bind(config.inColor, 0);
TextureHandle texAccum = provTex(config.provisionals, Stringizer() + "luminanceAccumulation" + config.cameraId, Vec2i(1), 1, GL_R32F);
TextureHandle texAccum = provTex(config.provisionals, Stringizer() + "luminanceAccumulation_" + config.cameraId, Vec2i(1), 1, GL_R32F);
q->bind(texAccum, 1);
Holder<ShaderProgram> shader = config.assets->get<AssetSchemeIndexShaderProgram, MultiShaderProgram>(HashString("cage/shader/effects/luminanceApply.glsl"))->get(0);
q->bind(shader);
Expand Down
2 changes: 1 addition & 1 deletion sources/libsimple/gameloop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,7 @@ namespace cage
return +engineData->guiBus;
}

ProvisionalGraphics *engineProvisonalGraphics()
ProvisionalGraphics *engineProvisionalGraphics()
{
return +engineData->provisionalGraphics;
}
Expand Down
18 changes: 9 additions & 9 deletions sources/libsimple/graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ namespace cage
TextureHandle initializeTarget(const String &prefix, Vec2i resolution)
{
const String name = Stringizer() + prefix + "_" + resolution;
TextureHandle tex = engineProvisonalGraphics()->texture(name,
TextureHandle tex = engineProvisionalGraphics()->texture(name,
[resolution](Texture *tex)
{
tex->initialize(resolution, 1, GL_RGB8);
Expand Down Expand Up @@ -174,15 +174,15 @@ namespace cage

void initialize() // opengl thread
{
renderQueue = newRenderQueue("engine", engineProvisonalGraphics());
renderQueue = newRenderQueue("engine", engineProvisionalGraphics());
onDemand = newAssetsOnDemand(engineAssets());
}

void finalize() // opengl thread
{
onDemand->clear(); // make sure to release all assets, but keep the structure to allow remaining calls to enginePurgeAssetsOnDemandCache
renderQueue.clear();
engineProvisonalGraphics()->purge();
engineProvisionalGraphics()->purge();
}

void emit(uint64 emitTime) // control thread
Expand Down Expand Up @@ -266,7 +266,7 @@ namespace cage
else
{
CAGE_ASSERT(!windowTarget);
windowTarget = initializeTarget(data.name, data.resolution);
windowTarget = initializeTarget(Stringizer() + "windowTarget_" + data.name, data.resolution);
data.target = windowTarget;
}
data.finalProduct = !cam.target;
Expand Down Expand Up @@ -307,13 +307,13 @@ namespace cage
if (dynamicResolution != 1)
data.effects.effects &= ~ScreenSpaceEffectsFlags::AntiAliasing;
data.effects.gamma = Real(confRenderGamma);
data.name = Stringizer() + "vr_camera_" + index;
data.name = Stringizer() + "vrCamera_" + index;
data.resolution = applyDynamicResolution(it.resolution);
data.transform = transformByVrOrigin(cfg.scene, it.transform, cfg.interpolationFactor);
data.projection = it.projection;
data.lodSelection.screenSize = perspectiveScreenSize(it.verticalFov, data.resolution[1]);
data.lodSelection.center = it.primary ? vrFrame->pose().position : it.transform.position;
data.target = initializeTarget(data.name, data.resolution);
data.target = initializeTarget(Stringizer() + "vrTarget_" + data.name, data.resolution);
data.finalProduct = true;
vrTargets.push_back(data.target);
cameras.push_back(std::move(data));
Expand Down Expand Up @@ -370,7 +370,7 @@ namespace cage
Holder<Model> modelSquare = engineAssets()->get<AssetSchemeIndexModel, Model>(HashString("cage/model/square.obj"));
CAGE_ASSERT(modelSquare);
modelSquare->bind();
Holder<FrameBuffer> renderTarget = engineProvisonalGraphics()->frameBufferDraw("vr_blit")->resolve();
Holder<FrameBuffer> renderTarget = engineProvisionalGraphics()->frameBufferDraw("vr_blit")->resolve();
renderTarget->bind();
frame->acquireTextures();
CAGE_ASSERT(frame->cameras.size() == targets.size());
Expand Down Expand Up @@ -419,7 +419,7 @@ namespace cage
const Vec2i windowResolution = engineWindow()->resolution();
RenderPipelineConfig cfg;
cfg.assets = engineAssets();
cfg.provisionalGraphics = engineProvisonalGraphics();
cfg.provisionalGraphics = engineProvisionalGraphics();
cfg.scene = +eb.scene;
cfg.onDemand = +onDemand;
const uint64 period = controlThread().updatePeriod();
Expand Down Expand Up @@ -457,7 +457,7 @@ namespace cage
void dispatch() // opengl thread
{
renderQueue->dispatch();
engineProvisonalGraphics()->reset();
engineProvisionalGraphics()->reset();

{ // check gl errors (even in release, but do not halt the game)
try
Expand Down
6 changes: 3 additions & 3 deletions sources/libsimple/guiInWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace cage
{
GuiManagerCreateConfig cfg;
cfg.assetManager = engineAssets();
cfg.provisionalGraphics = +engineProvisonalGraphics();
cfg.provisionalGraphics = +engineProvisionalGraphics();
cfg.tooltipsEnabled = config.tooltipsEnabled;
guiMan = newGuiManager(cfg);
guiMan->outputResolution(config.resolution);
Expand Down Expand Up @@ -152,7 +152,7 @@ namespace cage
}

// retrieve this every frame so that it is not removed
auto fb = engineProvisonalGraphics()->frameBufferDraw(Stringizer() + "gui-in-world-framebuffer-" + (uintPtr)this);
auto fb = engineProvisionalGraphics()->frameBufferDraw(Stringizer() + "gui-in-world-framebuffer-" + (uintPtr)this);

Holder<RenderQueue> qq;
{
Expand All @@ -162,7 +162,7 @@ namespace cage
if (!qq)
return;

Holder<RenderQueue> q = newRenderQueue("gui in world", engineProvisonalGraphics());
Holder<RenderQueue> q = newRenderQueue("gui in world", engineProvisionalGraphics());
{
auto name = q->namedScope("gui in world");
q->bind(fb);
Expand Down

0 comments on commit 69781d0

Please sign in to comment.