Merge remote-tracking branch 'origin/master' into polybackend
This commit is contained in:
commit
bb47230f79
126 changed files with 2186 additions and 1293 deletions
|
|
@ -35,13 +35,61 @@
|
|||
|
||||
EXTERN_CVAR(Float, transsouls)
|
||||
|
||||
IMPLEMENT_CLASS(DShape2DTransform, false, false)
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DShape2DTransform, Clear)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||
self->transform.Identity();
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DShape2DTransform, Rotate)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||
PARAM_FLOAT(angle);
|
||||
self->transform = DMatrix3x3::Rotate2D(DEG2RAD(angle)) * self->transform;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DShape2DTransform, Scale)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
self->transform = DMatrix3x3::Scale2D(DVector2(x, y)) * self->transform;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DShape2DTransform, Translate)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2DTransform);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
self->transform = DMatrix3x3::Translate2D(DVector2(x, y)) * self->transform;
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPLEMENT_CLASS(DShape2D, false, false)
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DShape2D, SetTransform)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2D);
|
||||
PARAM_OBJECT(transform, DShape2DTransform);
|
||||
self->transform = transform->transform;
|
||||
self->dirty = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DShape2D, Clear)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DShape2D);
|
||||
PARAM_INT(which);
|
||||
if ( which&C_Verts ) self->mVertices.Clear();
|
||||
if ( which&C_Verts )
|
||||
{
|
||||
self->mVertices.Clear();
|
||||
self->dirty = true;
|
||||
}
|
||||
if ( which&C_Coords ) self->mCoords.Clear();
|
||||
if ( which&C_Indices ) self->mIndices.Clear();
|
||||
return 0;
|
||||
|
|
@ -53,6 +101,7 @@ DEFINE_ACTION_FUNCTION(DShape2D, PushVertex)
|
|||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
self->mVertices.Push(DVector2(x,y));
|
||||
self->dirty = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -380,13 +429,22 @@ void F2DDrawer::AddShape( FTexture *img, DShape2D *shape, DrawParms &parms )
|
|||
if (!img->isHardwareCanvas() && parms.remap != nullptr && !parms.remap->Inactive)
|
||||
dg.mTranslation = parms.remap;
|
||||
|
||||
if (shape->dirty) {
|
||||
if (shape->mVertices.Size() != shape->mTransformedVertices.Size())
|
||||
shape->mTransformedVertices.Resize(shape->mVertices.Size());
|
||||
for (int i = 0; i < dg.mVertCount; i++) {
|
||||
shape->mTransformedVertices[i] = (shape->transform * DVector3(shape->mVertices[i], 1.0)).XY();
|
||||
}
|
||||
shape->dirty = false;
|
||||
}
|
||||
|
||||
double minx = 16383, miny = 16383, maxx = -16384, maxy = -16384;
|
||||
for ( int i=0; i<dg.mVertCount; i++ )
|
||||
{
|
||||
if ( shape->mVertices[i].X < minx ) minx = shape->mVertices[i].X;
|
||||
if ( shape->mVertices[i].Y < miny ) miny = shape->mVertices[i].Y;
|
||||
if ( shape->mVertices[i].X > maxx ) maxx = shape->mVertices[i].X;
|
||||
if ( shape->mVertices[i].Y > maxy ) maxy = shape->mVertices[i].Y;
|
||||
if ( shape->mTransformedVertices[i].X < minx ) minx = shape->mTransformedVertices[i].X;
|
||||
if ( shape->mTransformedVertices[i].Y < miny ) miny = shape->mTransformedVertices[i].Y;
|
||||
if ( shape->mTransformedVertices[i].X > maxx ) maxx = shape->mTransformedVertices[i].X;
|
||||
if ( shape->mTransformedVertices[i].Y > maxy ) maxy = shape->mTransformedVertices[i].Y;
|
||||
}
|
||||
if (minx < (double)parms.lclip || miny < (double)parms.uclip || maxx >(double)parms.rclip || maxy >(double)parms.dclip)
|
||||
{
|
||||
|
|
@ -402,7 +460,7 @@ void F2DDrawer::AddShape( FTexture *img, DShape2D *shape, DrawParms &parms )
|
|||
dg.mVertIndex = (int)mVertices.Reserve(dg.mVertCount);
|
||||
TwoDVertex *ptr = &mVertices[dg.mVertIndex];
|
||||
for ( int i=0; i<dg.mVertCount; i++ )
|
||||
ptr[i].Set(shape->mVertices[i].X, shape->mVertices[i].Y, 0, shape->mCoords[i].X, shape->mCoords[i].Y, vertexcolor);
|
||||
ptr[i].Set(shape->mTransformedVertices[i].X, shape->mTransformedVertices[i].Y, 0, shape->mCoords[i].X, shape->mCoords[i].Y, vertexcolor);
|
||||
dg.mIndexIndex = mIndices.Size();
|
||||
dg.mIndexCount += shape->mIndices.Size();
|
||||
for ( int i=0; i<int(shape->mIndices.Size()); i+=3 )
|
||||
|
|
@ -485,10 +543,10 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
|||
mVertices[poly.mVertIndex+i].Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale, color0);
|
||||
}
|
||||
poly.mIndexIndex = mIndices.Size();
|
||||
poly.mIndexCount += (npoints - 2) * 3;
|
||||
|
||||
if (indices == nullptr || indexcount == 0)
|
||||
{
|
||||
poly.mIndexCount += (npoints - 2) * 3;
|
||||
for (int i = 2; i < npoints; ++i)
|
||||
{
|
||||
AddIndices(poly.mVertIndex, 3, 0, i - 1, i);
|
||||
|
|
@ -496,10 +554,11 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
|||
}
|
||||
else
|
||||
{
|
||||
poly.mIndexCount += (int)indexcount;
|
||||
int addr = mIndices.Reserve(indexcount);
|
||||
for (size_t i = 0; i < indexcount; i++)
|
||||
{
|
||||
mIndices[addr + i] = addr + indices[i];
|
||||
mIndices[addr + i] = poly.mVertIndex + indices[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,18 @@
|
|||
|
||||
struct DrawParms;
|
||||
|
||||
class DShape2DTransform : public DObject
|
||||
{
|
||||
|
||||
DECLARE_CLASS(DShape2DTransform, DObject)
|
||||
public:
|
||||
DShape2DTransform()
|
||||
{
|
||||
transform.Identity();
|
||||
}
|
||||
DMatrix3x3 transform;
|
||||
};
|
||||
|
||||
// intermediate struct for shape drawing
|
||||
|
||||
enum EClearWhich
|
||||
|
|
@ -23,9 +35,21 @@ class DShape2D : public DObject
|
|||
|
||||
DECLARE_CLASS(DShape2D,DObject)
|
||||
public:
|
||||
DShape2D()
|
||||
{
|
||||
transform.Identity();
|
||||
}
|
||||
|
||||
TArray<int> mIndices;
|
||||
TArray<DVector2> mVertices;
|
||||
TArray<DVector2> mCoords;
|
||||
|
||||
DMatrix3x3 transform;
|
||||
|
||||
// dirty stores whether we need to re-apply the transformation
|
||||
// otherwise it uses the cached values
|
||||
bool dirty = true;
|
||||
TArray<DVector2> mTransformedVertices;
|
||||
};
|
||||
|
||||
class F2DDrawer
|
||||
|
|
|
|||
|
|
@ -235,7 +235,8 @@ void FGLRenderer::DrawPresentTexture(const IntRect &box, bool applyGamma)
|
|||
}
|
||||
mPresentShader->Uniforms->Scale = { screen->mScreenViewport.width / (float)mBuffers->GetWidth(), screen->mScreenViewport.height / (float)mBuffers->GetHeight() };
|
||||
mPresentShader->Uniforms->Offset = { 0.0f, 0.0f };
|
||||
mPresentShader->Uniforms.Set();
|
||||
mPresentShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresentShader->Uniforms.GetBuffer())->BindBase();
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
#include "gl/renderer/gl_postprocessstate.h"
|
||||
#include "gl/shaders/gl_shaderprogram.h"
|
||||
#include "gl/system/gl_buffers.h"
|
||||
#include <random>
|
||||
|
||||
CVAR(Int, gl_multisample, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
|
||||
|
|
@ -955,7 +956,7 @@ void GLPPRenderState::Draw()
|
|||
if (!shader->Uniforms)
|
||||
shader->Uniforms.reset(screen->CreateDataBuffer(POSTPROCESS_BINDINGPOINT, false, false));
|
||||
shader->Uniforms->SetData(Uniforms.Data.Size(), Uniforms.Data.Data());
|
||||
shader->Uniforms->BindBase();
|
||||
static_cast<GLDataBuffer*>(shader->Uniforms.get())->BindBase();
|
||||
}
|
||||
|
||||
// Set shader
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
#include "r_videoscale.h"
|
||||
#include "r_data/models/models.h"
|
||||
#include "gl/renderer/gl_postprocessstate.h"
|
||||
#include "gl/system/gl_buffers.h"
|
||||
|
||||
EXTERN_CVAR(Int, screenblocks)
|
||||
EXTERN_CVAR(Bool, cl_capfps)
|
||||
|
|
@ -191,12 +192,17 @@ void FGLRenderer::UpdateShadowMap()
|
|||
|
||||
FGLPostProcessState savedState;
|
||||
|
||||
static_cast<GLDataBuffer*>(screen->mShadowMap.mLightList)->BindBase();
|
||||
static_cast<GLDataBuffer*>(screen->mShadowMap.mNodesBuffer)->BindBase();
|
||||
static_cast<GLDataBuffer*>(screen->mShadowMap.mLinesBuffer)->BindBase();
|
||||
|
||||
mBuffers->BindShadowMapFB();
|
||||
|
||||
mShadowMapShader->Bind();
|
||||
mShadowMapShader->Uniforms->ShadowmapQuality = gl_shadowmap_quality;
|
||||
mShadowMapShader->Uniforms->NodesCount = screen->mShadowMap.NodesCount();
|
||||
mShadowMapShader->Uniforms.Set();
|
||||
mShadowMapShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mShadowMapShader->Uniforms.GetBuffer())->BindBase();
|
||||
|
||||
glViewport(0, 0, gl_shadowmap_quality, 1024);
|
||||
RenderScreenQuad();
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class FGLRenderBuffers;
|
|||
class FGL2DDrawer;
|
||||
class FHardwareTexture;
|
||||
class SWSceneDrawer;
|
||||
class GLViewpointBuffer;
|
||||
class HWViewpointBuffer;
|
||||
struct FRenderViewpoint;
|
||||
|
||||
namespace OpenGLRenderer
|
||||
|
|
|
|||
|
|
@ -189,9 +189,21 @@ bool FGLRenderState::ApplyShader()
|
|||
matrixToGL(identityMatrix, activeShader->normalmodelmatrix_index);
|
||||
}
|
||||
|
||||
auto index = screen->mLights->BindUBO(mLightIndex);
|
||||
activeShader->muLightIndex.Set(index);
|
||||
int index = mLightIndex;
|
||||
// Mess alert for crappy AncientGL!
|
||||
if (!screen->mLights->GetBufferType() && index >= 0)
|
||||
{
|
||||
size_t start, size;
|
||||
index = screen->mLights->GetBinding(index, &start, &size);
|
||||
|
||||
if (start != mLastMappedLightIndex)
|
||||
{
|
||||
mLastMappedLightIndex = start;
|
||||
static_cast<GLDataBuffer*>(screen->mLights->GetBuffer())->BindRange(nullptr, start, size);
|
||||
}
|
||||
}
|
||||
|
||||
activeShader->muLightIndex.Set(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ class FGLRenderState : public FRenderState
|
|||
int lastClamp = 0;
|
||||
int lastTranslation = 0;
|
||||
int maxBoundMaterial = -1;
|
||||
size_t mLastMappedLightIndex = SIZE_MAX;
|
||||
|
||||
IVertexBuffer *mCurrentVertexBuffer;
|
||||
int mCurrentVertexOffsets[2]; // one per binding point
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include "hwrenderer/scene/hw_portal.h"
|
||||
#include "hwrenderer/utility/hw_vrmodes.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/system/gl_buffers.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "gl/renderer/gl_postprocessstate.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/shaders/gl_shaderprogram.h"
|
||||
#include "gl/system/gl_buffers.h"
|
||||
#include "menu/menu.h"
|
||||
|
||||
EXTERN_CVAR(Int, vr_mode)
|
||||
|
|
@ -174,7 +175,8 @@ void FGLRenderer::prepareInterleavedPresent(FPresentShaderBase& shader)
|
|||
screen->mScreenViewport.height / (float)mBuffers->GetHeight()
|
||||
};
|
||||
shader.Uniforms->Offset = { 0.0f, 0.0f };
|
||||
shader.Uniforms.Set();
|
||||
shader.Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(shader.Uniforms.GetBuffer())->BindBase();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -198,7 +200,8 @@ void FGLRenderer::PresentColumnInterleaved()
|
|||
int windowHOffset = 0;
|
||||
|
||||
mPresent3dColumnShader->Uniforms->WindowPositionParity = windowHOffset;
|
||||
mPresent3dColumnShader->Uniforms.Set();
|
||||
mPresent3dColumnShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresent3dColumnShader->Uniforms.GetBuffer())->BindBase();
|
||||
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
|
@ -225,7 +228,8 @@ void FGLRenderer::PresentRowInterleaved()
|
|||
+ screen->mOutputLetterbox.height + 1 // +1 because of origin at bottom
|
||||
) % 2;
|
||||
|
||||
mPresent3dRowShader->Uniforms.Set();
|
||||
mPresent3dRowShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresent3dRowShader->Uniforms.GetBuffer())->BindBase();
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
|
|
@ -256,7 +260,8 @@ void FGLRenderer::PresentCheckerInterleaved()
|
|||
+ screen->mOutputLetterbox.height + 1 // +1 because of origin at bottom
|
||||
) % 2; // because we want the top pixel offset, but gl_FragCoord.y is the bottom pixel offset
|
||||
|
||||
mPresent3dCheckerShader->Uniforms.Set();
|
||||
mPresent3dCheckerShader->Uniforms.SetData();
|
||||
static_cast<GLDataBuffer*>(mPresent3dCheckerShader->Uniforms.GetBuffer())->BindBase();
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -210,10 +210,9 @@ void GLVertexBuffer::Bind(int *offsets)
|
|||
}
|
||||
}
|
||||
|
||||
void GLDataBuffer::BindRange(size_t start, size_t length)
|
||||
void GLDataBuffer::BindRange(FRenderState *state, size_t start, size_t length)
|
||||
{
|
||||
if (mUseType == GL_UNIFORM_BUFFER) // SSBO's cannot be rebound.
|
||||
glBindBufferRange(mUseType, mBindingPoint, mBufferId, start, length);
|
||||
glBindBufferRange(mUseType, mBindingPoint, mBufferId, start, length);
|
||||
}
|
||||
|
||||
void GLDataBuffer::BindBase()
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ class GLDataBuffer : public IDataBuffer, public GLBuffer
|
|||
int mBindingPoint;
|
||||
public:
|
||||
GLDataBuffer(int bindingpoint, bool is_ssbo) : GLBuffer(is_ssbo? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER), mBindingPoint(bindingpoint) {}
|
||||
void BindRange(size_t start, size_t length) override;
|
||||
void BindBase() override;
|
||||
void BindRange(FRenderState* state, size_t start, size_t length);
|
||||
void BindBase();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -126,7 +126,7 @@ void OpenGLFrameBuffer::InitializeState()
|
|||
glslversion = gl.glslversion;
|
||||
uniformblockalignment = gl.uniformblockalignment;
|
||||
maxuniformblock = gl.maxuniformblock;
|
||||
gl_vendorstring = gl.vendorstring;
|
||||
vendorstring = gl.vendorstring;
|
||||
|
||||
if (first)
|
||||
{
|
||||
|
|
@ -154,12 +154,14 @@ void OpenGLFrameBuffer::InitializeState()
|
|||
|
||||
mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight());
|
||||
mSkyData = new FSkyVertexBuffer;
|
||||
mViewpoints = new GLViewpointBuffer;
|
||||
mViewpoints = new HWViewpointBuffer;
|
||||
mLights = new FLightBuffer();
|
||||
|
||||
GLRenderer = new FGLRenderer(this);
|
||||
GLRenderer->Initialize(GetWidth(), GetHeight());
|
||||
|
||||
static_cast<GLDataBuffer*>(mLights->GetBuffer())->BindBase();
|
||||
|
||||
mDebug = std::make_shared<FGLDebug>();
|
||||
mDebug->Update();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ void gl_LoadExtensions()
|
|||
|
||||
// Mesa implements shader storage only for fragment shaders.
|
||||
// Just disable the feature there. The light buffer may just use a uniform buffer without any adverse effects.
|
||||
int v;
|
||||
int v = 0;
|
||||
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v);
|
||||
if (v == 0)
|
||||
gl.flags &= ~RFL_SHADER_STORAGE_BUFFER;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
class FRenderState;
|
||||
|
||||
// The low level code needs to know which attributes exist.
|
||||
// OpenGL needs to change the state of all of them per buffer binding.
|
||||
// VAOs are mostly useless for this because they lump buffer and binding state together which the model code does not want.
|
||||
|
|
@ -76,7 +78,6 @@ class IDataBuffer : virtual public IBuffer
|
|||
{
|
||||
// Can be either uniform or shader storage buffer, depending on its needs.
|
||||
public:
|
||||
virtual void BindRange(size_t start, size_t length) = 0;
|
||||
virtual void BindBase() = 0;
|
||||
virtual void BindRange(FRenderState *state, size_t start, size_t length) = 0;
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
static const int INITIAL_BUFFER_SIZE = 100; // 100 viewpoints per frame should nearly always be enough
|
||||
|
||||
GLViewpointBuffer::GLViewpointBuffer()
|
||||
HWViewpointBuffer::HWViewpointBuffer()
|
||||
{
|
||||
mBufferSize = INITIAL_BUFFER_SIZE;
|
||||
mBlockAlign = ((sizeof(HWViewpointUniforms) / screen->uniformblockalignment) + 1) * screen->uniformblockalignment;
|
||||
|
|
@ -45,13 +45,13 @@ GLViewpointBuffer::GLViewpointBuffer()
|
|||
mClipPlaneInfo.Push(0);
|
||||
}
|
||||
|
||||
GLViewpointBuffer::~GLViewpointBuffer()
|
||||
HWViewpointBuffer::~HWViewpointBuffer()
|
||||
{
|
||||
delete mBuffer;
|
||||
}
|
||||
|
||||
|
||||
void GLViewpointBuffer::CheckSize()
|
||||
void HWViewpointBuffer::CheckSize()
|
||||
{
|
||||
if (mUploadIndex >= mBufferSize)
|
||||
{
|
||||
|
|
@ -62,18 +62,18 @@ void GLViewpointBuffer::CheckSize()
|
|||
}
|
||||
}
|
||||
|
||||
int GLViewpointBuffer::Bind(FRenderState &di, unsigned int index)
|
||||
int HWViewpointBuffer::Bind(FRenderState &di, unsigned int index)
|
||||
{
|
||||
if (index != mLastMappedIndex)
|
||||
{
|
||||
mLastMappedIndex = index;
|
||||
mBuffer->BindRange(index * mBlockAlign, mBlockAlign);
|
||||
mBuffer->BindRange(&di, index * mBlockAlign, mBlockAlign);
|
||||
di.EnableClipDistance(0, mClipPlaneInfo[index]);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void GLViewpointBuffer::Set2D(FRenderState &di, int width, int height)
|
||||
void HWViewpointBuffer::Set2D(FRenderState &di, int width, int height)
|
||||
{
|
||||
if (width != m2DWidth || height != m2DHeight)
|
||||
{
|
||||
|
|
@ -91,7 +91,7 @@ void GLViewpointBuffer::Set2D(FRenderState &di, int width, int height)
|
|||
Bind(di, 0);
|
||||
}
|
||||
|
||||
int GLViewpointBuffer::SetViewpoint(FRenderState &di, HWViewpointUniforms *vp)
|
||||
int HWViewpointBuffer::SetViewpoint(FRenderState &di, HWViewpointUniforms *vp)
|
||||
{
|
||||
CheckSize();
|
||||
mBuffer->Map();
|
||||
|
|
@ -102,7 +102,7 @@ int GLViewpointBuffer::SetViewpoint(FRenderState &di, HWViewpointUniforms *vp)
|
|||
return Bind(di, mUploadIndex++);
|
||||
}
|
||||
|
||||
void GLViewpointBuffer::Clear()
|
||||
void HWViewpointBuffer::Clear()
|
||||
{
|
||||
// Index 0 is reserved for the 2D projection.
|
||||
mUploadIndex = 1;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
struct HWViewpointUniforms;
|
||||
class FRenderState;
|
||||
|
||||
class GLViewpointBuffer
|
||||
class HWViewpointBuffer
|
||||
{
|
||||
IDataBuffer *mBuffer;
|
||||
|
||||
|
|
@ -24,8 +24,8 @@ class GLViewpointBuffer
|
|||
|
||||
public:
|
||||
|
||||
GLViewpointBuffer();
|
||||
~GLViewpointBuffer();
|
||||
HWViewpointBuffer();
|
||||
~HWViewpointBuffer();
|
||||
void Clear();
|
||||
int Bind(FRenderState &di, unsigned int index);
|
||||
void Set2D(FRenderState &di, int width, int height);
|
||||
|
|
|
|||
|
|
@ -126,14 +126,16 @@ public:
|
|||
mBuffer = screen->CreateDataBuffer(bindingpoint, false, false);
|
||||
}
|
||||
|
||||
void Set(bool bind = true)
|
||||
void SetData()
|
||||
{
|
||||
if (mBuffer != nullptr)
|
||||
mBuffer->SetData(sizeof(T), &Values);
|
||||
}
|
||||
|
||||
// Let's hope this can be done better when things have moved further ahead.
|
||||
// This really is not the best place to add something that depends on API behavior.
|
||||
if (bind) mBuffer->BindBase();
|
||||
IDataBuffer* GetBuffer() const
|
||||
{
|
||||
// OpenGL needs to mess around with this in ways that should not be part of the interface.
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
T *operator->() { return &Values; }
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ FLightBuffer::FLightBuffer()
|
|||
// Hack alert: On Intel's GL driver SSBO's perform quite worse than UBOs.
|
||||
// We only want to disable using SSBOs for lights but not disable the feature entirely.
|
||||
// Note that using an uniform buffer here will limit the number of lights per surface so it isn't done for NVidia and AMD.
|
||||
if (screen->IsVulkan() || ((screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && !strstr(screen->gl_vendorstring, "Intel")))
|
||||
if (screen->IsVulkan() || ((screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && !strstr(screen->vendorstring, "Intel")))
|
||||
{
|
||||
mBufferType = true;
|
||||
mBlockAlign = 0;
|
||||
|
|
@ -74,7 +74,6 @@ FLightBuffer::~FLightBuffer()
|
|||
void FLightBuffer::Clear()
|
||||
{
|
||||
mIndex = 0;
|
||||
mLastMappedIndex = UINT_MAX;
|
||||
}
|
||||
|
||||
int FLightBuffer::UploadLights(FDynLightData &data)
|
||||
|
|
@ -127,16 +126,13 @@ int FLightBuffer::UploadLights(FDynLightData &data)
|
|||
}
|
||||
}
|
||||
|
||||
int FLightBuffer::DoBindUBO(unsigned int index)
|
||||
int FLightBuffer::GetBinding(unsigned int index, size_t* pOffset, size_t* pSize)
|
||||
{
|
||||
// this function will only get called if a uniform buffer is used. For a shader storage buffer we only need to bind the buffer once at the start.
|
||||
unsigned int offset = (index / mBlockAlign) * mBlockAlign;
|
||||
|
||||
if (offset != mLastMappedIndex)
|
||||
{
|
||||
mLastMappedIndex = offset;
|
||||
mBuffer->BindRange(offset * ELEMENT_SIZE, mBlockSize * ELEMENT_SIZE);
|
||||
}
|
||||
*pOffset = offset * ELEMENT_SIZE;
|
||||
*pSize = mBlockSize * ELEMENT_SIZE;
|
||||
return (index - offset);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ class FLightBuffer
|
|||
|
||||
bool mBufferType;
|
||||
std::atomic<unsigned int> mIndex;
|
||||
unsigned int mLastMappedIndex;
|
||||
unsigned int mBlockAlign;
|
||||
unsigned int mBlockSize;
|
||||
unsigned int mBufferSize;
|
||||
|
|
@ -34,32 +33,12 @@ public:
|
|||
void Unmap() { mBuffer->Unmap(); }
|
||||
unsigned int GetBlockSize() const { return mBlockSize; }
|
||||
bool GetBufferType() const { return mBufferType; }
|
||||
int GetBinding(unsigned int index, size_t* pOffset, size_t* pSize);
|
||||
|
||||
int DoBindUBO(unsigned int index);
|
||||
|
||||
int ShaderIndex(unsigned int index) const
|
||||
{
|
||||
if (mBlockAlign == 0) return index;
|
||||
// This must match the math in BindUBO.
|
||||
unsigned int offset = (index / mBlockAlign) * mBlockAlign;
|
||||
return int(index-offset);
|
||||
}
|
||||
|
||||
// Only relevant for OpenGL, so this does not need access to the render state.
|
||||
int BindUBO(int index)
|
||||
// OpenGL needs the buffer to mess around with the binding.
|
||||
IDataBuffer* GetBuffer() const
|
||||
{
|
||||
if (!mBufferType && index > -1)
|
||||
{
|
||||
index = DoBindUBO(index);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
// The parameter is a reminder for Vulkan.
|
||||
void BindBase()
|
||||
{
|
||||
mBuffer->BindBase();
|
||||
mLastMappedIndex = UINT_MAX;
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -176,9 +176,6 @@ bool IShadowMap::PerformUpdate()
|
|||
UpdateCycles.Clock();
|
||||
UploadAABBTree();
|
||||
UploadLights();
|
||||
mLightList->BindBase();
|
||||
mNodesBuffer->BindBase();
|
||||
mLinesBuffer->BindBase();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ protected:
|
|||
IShadowMap &operator=(IShadowMap &) = delete;
|
||||
|
||||
// OpenGL storage buffer with the list of lights in the shadow map texture
|
||||
// These buffers need to be accessed by the OpenGL backend directly so that they can be bound.
|
||||
public:
|
||||
IDataBuffer *mLightList = nullptr;
|
||||
|
||||
// OpenGL storage buffers for the AABB tree
|
||||
|
|
|
|||
|
|
@ -468,7 +468,6 @@ void HWDrawInfo::RenderScene(FRenderState &state)
|
|||
|
||||
state.SetDepthMask(true);
|
||||
|
||||
screen->mLights->BindBase();
|
||||
state.EnableFog(true);
|
||||
state.SetRenderStyle(STYLE_Source);
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#include "templates.h"
|
||||
#include "r_utility.h"
|
||||
#include "r_renderer.h"
|
||||
#include "atterm.h"
|
||||
#include <atomic>
|
||||
|
||||
FDynamicColormap NormalLight;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ void VkPostprocess::SetActiveRenderTarget()
|
|||
imageTransition.addImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false);
|
||||
imageTransition.execute(fb->GetDrawCommands());
|
||||
|
||||
fb->GetRenderState()->SetRenderTarget(buffers->PipelineImage[mCurrentPipelineImage].View.get(), nullptr, buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
|
||||
fb->GetRenderState()->SetRenderTarget(&buffers->PipelineImage[mCurrentPipelineImage], nullptr, buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT);
|
||||
}
|
||||
|
||||
void VkPostprocess::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D)
|
||||
|
|
@ -402,6 +402,18 @@ VkPPTexture::VkPPTexture(PPTexture *texture)
|
|||
}
|
||||
}
|
||||
|
||||
VkPPTexture::~VkPPTexture()
|
||||
{
|
||||
if (auto fb = GetVulkanFrameBuffer())
|
||||
{
|
||||
if (TexImage.Image) fb->FrameDeleteList.Images.push_back(std::move(TexImage.Image));
|
||||
if (TexImage.View) fb->FrameDeleteList.ImageViews.push_back(std::move(TexImage.View));
|
||||
if (TexImage.DepthOnlyView) fb->FrameDeleteList.ImageViews.push_back(std::move(TexImage.DepthOnlyView));
|
||||
if (TexImage.PPFramebuffer) fb->FrameDeleteList.Framebuffers.push_back(std::move(TexImage.PPFramebuffer));
|
||||
if (Staging) fb->FrameDeleteList.Buffers.push_back(std::move(Staging));
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VkPPShader::VkPPShader(PPShader *shader)
|
||||
|
|
@ -585,6 +597,7 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co
|
|||
VkTextureImage *tex = GetTexture(output.Type, output.Texture);
|
||||
|
||||
VkImageView view;
|
||||
std::unique_ptr<VulkanFramebuffer> *framebufferptr = nullptr;
|
||||
int w, h;
|
||||
if (tex)
|
||||
{
|
||||
|
|
@ -597,15 +610,17 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co
|
|||
view = tex->View->view;
|
||||
w = tex->Image->width;
|
||||
h = tex->Image->height;
|
||||
framebufferptr = &tex->PPFramebuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
view = fb->swapChain->swapChainImageViews[fb->presentImageIndex];
|
||||
framebufferptr = &fb->swapChain->framebuffers[fb->presentImageIndex];
|
||||
w = fb->swapChain->actualExtent.width;
|
||||
h = fb->swapChain->actualExtent.height;
|
||||
}
|
||||
|
||||
auto &framebuffer = passSetup->Framebuffers[view];
|
||||
auto &framebuffer = *framebufferptr;
|
||||
if (!framebuffer)
|
||||
{
|
||||
FramebufferBuilder builder;
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ class VkPPTexture : public PPTextureBackend
|
|||
{
|
||||
public:
|
||||
VkPPTexture(PPTexture *texture);
|
||||
~VkPPTexture();
|
||||
|
||||
VkTextureImage TexImage;
|
||||
std::unique_ptr<VulkanBuffer> Staging;
|
||||
|
|
@ -103,7 +104,6 @@ public:
|
|||
std::unique_ptr<VulkanPipelineLayout> PipelineLayout;
|
||||
std::unique_ptr<VulkanRenderPass> RenderPass;
|
||||
std::unique_ptr<VulkanPipeline> Pipeline;
|
||||
std::map<VkImageView, std::unique_ptr<VulkanFramebuffer>> Framebuffers;
|
||||
|
||||
private:
|
||||
void CreateDescriptorLayout(const VkPPRenderPassKey &key);
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ public:
|
|||
VkRenderPassKey PassKey;
|
||||
std::unique_ptr<VulkanRenderPass> RenderPasses[8];
|
||||
std::map<VkPipelineKey, std::unique_ptr<VulkanPipeline>> Pipelines;
|
||||
std::map<VkImageView, std::unique_ptr<VulkanFramebuffer>> Framebuffer;
|
||||
|
||||
private:
|
||||
std::unique_ptr<VulkanRenderPass> CreateRenderPass(int clearTargets);
|
||||
|
|
|
|||
|
|
@ -528,11 +528,11 @@ void VkRenderState::EnableDrawBuffers(int count)
|
|||
}
|
||||
}
|
||||
|
||||
void VkRenderState::SetRenderTarget(VulkanImageView *view, VulkanImageView *depthStencilView, int width, int height, VkFormat format, VkSampleCountFlagBits samples)
|
||||
void VkRenderState::SetRenderTarget(VkTextureImage *image, VulkanImageView *depthStencilView, int width, int height, VkFormat format, VkSampleCountFlagBits samples)
|
||||
{
|
||||
EndRenderPass();
|
||||
|
||||
mRenderTarget.View = view;
|
||||
mRenderTarget.Image = image;
|
||||
mRenderTarget.DepthStencil = depthStencilView;
|
||||
mRenderTarget.Width = width;
|
||||
mRenderTarget.Height = height;
|
||||
|
|
@ -552,14 +552,14 @@ void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer)
|
|||
|
||||
mPassSetup = fb->GetRenderPassManager()->GetRenderPass(key);
|
||||
|
||||
auto &framebuffer = mPassSetup->Framebuffer[mRenderTarget.View->view];
|
||||
auto &framebuffer = mRenderTarget.Image->RSFramebuffers[key];
|
||||
if (!framebuffer)
|
||||
{
|
||||
auto buffers = fb->GetBuffers();
|
||||
FramebufferBuilder builder;
|
||||
builder.setRenderPass(mPassSetup->GetRenderPass(0));
|
||||
builder.setSize(mRenderTarget.Width, mRenderTarget.Height);
|
||||
builder.addAttachment(mRenderTarget.View);
|
||||
builder.addAttachment(mRenderTarget.Image->View.get());
|
||||
if (key.DrawBuffers > 1)
|
||||
builder.addAttachment(buffers->SceneFog.View.get());
|
||||
if (key.DrawBuffers > 2)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "hwrenderer/textures/hw_material.h"
|
||||
|
||||
class VkRenderPassSetup;
|
||||
class VkTextureImage;
|
||||
|
||||
class VkRenderState : public FRenderState
|
||||
{
|
||||
|
|
@ -43,7 +44,7 @@ public:
|
|||
void EnableDrawBuffers(int count) override;
|
||||
|
||||
void BeginFrame();
|
||||
void SetRenderTarget(VulkanImageView *view, VulkanImageView *depthStencilView, int width, int height, VkFormat Format, VkSampleCountFlagBits samples);
|
||||
void SetRenderTarget(VkTextureImage *image, VulkanImageView *depthStencilView, int width, int height, VkFormat Format, VkSampleCountFlagBits samples);
|
||||
void Bind(int bindingpoint, uint32_t offset);
|
||||
void EndRenderPass();
|
||||
void EndFrame();
|
||||
|
|
@ -112,7 +113,7 @@ protected:
|
|||
|
||||
struct RenderTarget
|
||||
{
|
||||
VulkanImageView *View = nullptr;
|
||||
VkTextureImage *Image = nullptr;
|
||||
VulkanImageView *DepthStencil = nullptr;
|
||||
int Width = 0;
|
||||
int Height = 0;
|
||||
|
|
|
|||
|
|
@ -204,12 +204,9 @@ void VKVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t s
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VKDataBuffer::BindRange(size_t start, size_t length)
|
||||
|
||||
void VKDataBuffer::BindRange(FRenderState* state, size_t start, size_t length)
|
||||
{
|
||||
GetVulkanFrameBuffer()->GetRenderState()->Bind(bindingpoint, (uint32_t)start);
|
||||
static_cast<VkRenderState*>(state)->Bind(bindingpoint, (uint32_t)start);
|
||||
}
|
||||
|
||||
void VKDataBuffer::BindBase()
|
||||
{
|
||||
GetVulkanFrameBuffer()->GetRenderState()->Bind(bindingpoint, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,8 +68,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void BindRange(size_t start, size_t length) override;
|
||||
void BindBase() override;
|
||||
void BindRange(FRenderState *state, size_t start, size_t length) override;
|
||||
|
||||
int bindingpoint;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -128,7 +128,14 @@ void VulkanFrameBuffer::InitializeState()
|
|||
first = false;
|
||||
}
|
||||
|
||||
gl_vendorstring = "Vulkan";
|
||||
switch (device->PhysicalDevice.Properties.vendorID)
|
||||
{
|
||||
case 0x1002: vendorstring = "AMD"; break;
|
||||
case 0x10DE: vendorstring = "NVIDIA"; break;
|
||||
case 0x8086: vendorstring = "Intel"; break;
|
||||
default: vendorstring = "Unknown"; break;
|
||||
}
|
||||
|
||||
hwcaps = RFL_SHADER_STORAGE_BUFFER | RFL_BUFFER_STORAGE;
|
||||
glslversion = 4.50f;
|
||||
uniformblockalignment = (unsigned int)device->PhysicalDevice.Properties.limits.minUniformBufferOffsetAlignment;
|
||||
|
|
@ -145,7 +152,7 @@ void VulkanFrameBuffer::InitializeState()
|
|||
|
||||
mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight());
|
||||
mSkyData = new FSkyVertexBuffer;
|
||||
mViewpoints = new GLViewpointBuffer;
|
||||
mViewpoints = new HWViewpointBuffer;
|
||||
mLights = new FLightBuffer();
|
||||
|
||||
CreateFanToTrisIndexBuffer();
|
||||
|
|
@ -199,6 +206,7 @@ void VulkanFrameBuffer::DeleteFrameObjects()
|
|||
{
|
||||
FrameDeleteList.Images.clear();
|
||||
FrameDeleteList.ImageViews.clear();
|
||||
FrameDeleteList.Framebuffers.clear();
|
||||
FrameDeleteList.Buffers.clear();
|
||||
FrameDeleteList.Descriptors.clear();
|
||||
FrameDeleteList.DescriptorPools.clear();
|
||||
|
|
@ -444,7 +452,7 @@ sector_t *VulkanFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor *
|
|||
|
||||
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
|
||||
{
|
||||
mRenderState->SetRenderTarget(GetBuffers()->SceneColor.View.get(), GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
mRenderState->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
bool useSSAO = (gl_ssao != 0);
|
||||
GetRenderState()->SetPassType(useSSAO ? GBUFFER_PASS : NORMAL_PASS);
|
||||
GetRenderState()->EnableDrawBuffers(GetRenderState()->GetPassDrawBufferCount());
|
||||
|
|
@ -514,7 +522,7 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint
|
|||
barrier0.addImage(image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
|
||||
barrier0.execute(GetDrawCommands());
|
||||
|
||||
mRenderState->SetRenderTarget(image->View.get(), depthStencil->View.get(), image->Image->width, image->Image->height, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT);
|
||||
mRenderState->SetRenderTarget(image, depthStencil->View.get(), image->Image->width, image->Image->height, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT);
|
||||
|
||||
IntRect bounds;
|
||||
bounds.left = bounds.top = 0;
|
||||
|
|
@ -530,7 +538,7 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint
|
|||
barrier1.addImage(image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
barrier1.execute(GetDrawCommands());
|
||||
|
||||
mRenderState->SetRenderTarget(GetBuffers()->SceneColor.View.get(), GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
mRenderState->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
|
||||
|
||||
tex->SetUpdated(true);
|
||||
}
|
||||
|
|
@ -709,11 +717,12 @@ void VulkanFrameBuffer::UpdatePalette()
|
|||
|
||||
FTexture *VulkanFrameBuffer::WipeStartScreen()
|
||||
{
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
||||
SetViewportRects(nullptr);
|
||||
|
||||
auto tex = new FWrapperTexture(mScreenViewport.width, mScreenViewport.height, 1);
|
||||
auto systex = static_cast<VkHardwareTexture*>(tex->GetSystemTexture());
|
||||
|
||||
systex->CreateWipeTexture(viewport.width, viewport.height, "WipeStartScreen");
|
||||
systex->CreateWipeTexture(mScreenViewport.width, mScreenViewport.height, "WipeStartScreen");
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
|
@ -724,11 +733,10 @@ FTexture *VulkanFrameBuffer::WipeEndScreen()
|
|||
Draw2D();
|
||||
Clear2D();
|
||||
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
||||
auto tex = new FWrapperTexture(mScreenViewport.width, mScreenViewport.height, 1);
|
||||
auto systex = static_cast<VkHardwareTexture*>(tex->GetSystemTexture());
|
||||
|
||||
systex->CreateWipeTexture(viewport.width, viewport.height, "WipeEndScreen");
|
||||
systex->CreateWipeTexture(mScreenViewport.width, mScreenViewport.height, "WipeEndScreen");
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public:
|
|||
public:
|
||||
std::vector<std::unique_ptr<VulkanImage>> Images;
|
||||
std::vector<std::unique_ptr<VulkanImageView>> ImageViews;
|
||||
std::vector<std::unique_ptr<VulkanFramebuffer>> Framebuffers;
|
||||
std::vector<std::unique_ptr<VulkanBuffer>> Buffers;
|
||||
std::vector<std::unique_ptr<VulkanDescriptorSet>> Descriptors;
|
||||
std::vector<std::unique_ptr<VulkanDescriptorPool>> DescriptorPools;
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ bool VulkanSwapChain::CreateSwapChain(VkSwapchainKHR oldSwapChain)
|
|||
|
||||
void VulkanSwapChain::CreateViews()
|
||||
{
|
||||
framebuffers.resize(swapChainImages.size());
|
||||
swapChainImageViews.reserve(swapChainImages.size());
|
||||
for (size_t i = 0; i < swapChainImages.size(); i++)
|
||||
{
|
||||
|
|
@ -335,6 +336,7 @@ void VulkanSwapChain::GetImages()
|
|||
|
||||
void VulkanSwapChain::ReleaseViews()
|
||||
{
|
||||
framebuffers.clear();
|
||||
for (auto &view : swapChainImageViews)
|
||||
{
|
||||
vkDestroyImageView(device->device, view, nullptr);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
class VulkanSemaphore;
|
||||
class VulkanFence;
|
||||
class VulkanFramebuffer;
|
||||
|
||||
class VulkanSwapChain
|
||||
{
|
||||
|
|
@ -22,6 +23,7 @@ public:
|
|||
|
||||
std::vector<VkImage> swapChainImages;
|
||||
std::vector<VkImageView> swapChainImageViews;
|
||||
std::vector<std::unique_ptr<VulkanFramebuffer>> framebuffers;
|
||||
|
||||
VkExtent2D actualExtent;
|
||||
|
||||
|
|
|
|||
|
|
@ -72,8 +72,10 @@ void VkHardwareTexture::Reset()
|
|||
auto &deleteList = fb->FrameDeleteList;
|
||||
if (mImage.Image) deleteList.Images.push_back(std::move(mImage.Image));
|
||||
if (mImage.View) deleteList.ImageViews.push_back(std::move(mImage.View));
|
||||
for (auto &it : mImage.RSFramebuffers) deleteList.Framebuffers.push_back(std::move(it.second));
|
||||
if (mDepthStencil.Image) deleteList.Images.push_back(std::move(mDepthStencil.Image));
|
||||
if (mDepthStencil.View) deleteList.ImageViews.push_back(std::move(mDepthStencil.View));
|
||||
for (auto &it : mDepthStencil.RSFramebuffers) deleteList.Framebuffers.push_back(std::move(it.second));
|
||||
mImage.reset();
|
||||
mDepthStencil.reset();
|
||||
}
|
||||
|
|
@ -374,5 +376,33 @@ void VkHardwareTexture::CreateWipeTexture(int w, int h, const char *name)
|
|||
mImage.View = viewbuilder.create(fb->device);
|
||||
mImage.View->SetDebugName(name);
|
||||
|
||||
fb->GetPostprocess()->BlitCurrentToImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
if (fb->GetBuffers()->GetWidth() > 0 && fb->GetBuffers()->GetHeight() > 0)
|
||||
{
|
||||
fb->GetPostprocess()->BlitCurrentToImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// hwrenderer asked image data from a frame buffer that was never written into. Let's give it that..
|
||||
// (ideally the hwrenderer wouldn't do this, but the calling code is too complex for me to fix)
|
||||
|
||||
VkImageTransition transition0;
|
||||
transition0.addImage(&mImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
|
||||
transition0.execute(fb->GetTransferCommands());
|
||||
|
||||
VkImageSubresourceRange range = {};
|
||||
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
range.layerCount = 1;
|
||||
range.levelCount = 1;
|
||||
|
||||
VkClearColorValue value = {};
|
||||
value.float32[0] = 0.0f;
|
||||
value.float32[1] = 0.0f;
|
||||
value.float32[2] = 0.0f;
|
||||
value.float32[3] = 1.0f;
|
||||
fb->GetTransferCommands()->clearColorImage(mImage.Image->image, mImage.Layout, &value, 1, &range);
|
||||
|
||||
VkImageTransition transition1;
|
||||
transition1.addImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
|
||||
transition1.execute(fb->GetTransferCommands());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "vulkan/system/vk_objects.h"
|
||||
#include "vulkan/system/vk_builders.h"
|
||||
#include "vulkan/renderer/vk_renderpass.h"
|
||||
|
||||
class VkTextureImage
|
||||
{
|
||||
|
|
@ -23,6 +24,8 @@ public:
|
|||
std::unique_ptr<VulkanImageView> DepthOnlyView;
|
||||
VkImageLayout Layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
VkImageAspectFlags AspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
std::unique_ptr<VulkanFramebuffer> PPFramebuffer;
|
||||
std::map<VkRenderPassKey, std::unique_ptr<VulkanFramebuffer>> RSFramebuffers;
|
||||
};
|
||||
|
||||
class VkImageTransition
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue