- merged gzdoom-gles2 and fixed some issues with pipeline size validation.

This commit is contained in:
Christoph Oelckers 2021-08-03 18:46:45 +02:00
commit 441cd0796f
116 changed files with 12502 additions and 80 deletions

View file

@ -5,6 +5,8 @@
class FRenderState;
#define HW_MAX_PIPELINE_BUFFERS 8
// 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.
@ -54,10 +56,15 @@ public:
virtual void *Lock(unsigned int size) = 0;
virtual void Unlock() = 0;
virtual void Resize(size_t newsize) = 0;
virtual void Upload(size_t start, size_t size) {} // For unmappable buffers
virtual void Map() {} // Only needed by old OpenGL but this needs to be in the interface.
virtual void Unmap() {}
void *Memory() { return map; }
size_t Size() { return buffersize; }
virtual void GPUDropSync() {}
virtual void GPUWaitSync() {}
};
class IVertexBuffer : virtual public IBuffer

View file

@ -45,7 +45,8 @@
//
//==========================================================================
FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
FFlatVertexBuffer::FFlatVertexBuffer(int width, int height, int pipelineNbr):
mPipelineNbr(pipelineNbr)
{
vbo_shadowdata.Resize(NUM_RESERVED);
@ -78,19 +79,27 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
vbo_shadowdata[18].Set(32767.0f, -32767.0f, 32767.0f, 0, 0);
vbo_shadowdata[19].Set(32767.0f, -32767.0f, -32767.0f, 0, 0);
mVertexBuffer = screen->CreateVertexBuffer();
mIndexBuffer = screen->CreateIndexBuffer();
int data[4] = {};
mIndexBuffer->SetData(4, data); // On Vulkan this may not be empty, so set some dummy defaults to avoid crashes.
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
mVertexBuffer->SetData(bytesize, nullptr, false);
static const FVertexBufferAttribute format[] = {
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FFlatVertex, x) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) }
};
mVertexBuffer->SetFormat(1, 2, sizeof(FFlatVertex), format);
for (int n = 0; n < mPipelineNbr; n++)
{
mVertexBufferPipeline[n] = screen->CreateVertexBuffer();
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
mVertexBufferPipeline[n]->SetData(bytesize, nullptr, false);
static const FVertexBufferAttribute format[] = {
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FFlatVertex, x) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) }
};
mVertexBufferPipeline[n]->SetFormat(1, 2, sizeof(FFlatVertex), format);
}
mVertexBuffer = mVertexBufferPipeline[mPipelinePos];
mIndex = mCurIndex = NUM_RESERVED;
mNumReserved = NUM_RESERVED;
@ -105,8 +114,12 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
FFlatVertexBuffer::~FFlatVertexBuffer()
{
for (int n = 0; n < mPipelineNbr; n++)
{
delete mVertexBufferPipeline[n];
}
delete mIndexBuffer;
delete mVertexBuffer;
mIndexBuffer = nullptr;
mVertexBuffer = nullptr;
}
@ -153,8 +166,17 @@ std::pair<FFlatVertex *, unsigned int> FFlatVertexBuffer::AllocVertices(unsigned
void FFlatVertexBuffer::Copy(int start, int count)
{
Map();
memcpy(GetBuffer(start), &vbo_shadowdata[0], count * sizeof(FFlatVertex));
Unmap();
IVertexBuffer* old = mVertexBuffer;
for (int n = 0; n < mPipelineNbr; n++)
{
mVertexBuffer = mVertexBufferPipeline[n];
Map();
memcpy(GetBuffer(start), &vbo_shadowdata[0], count * sizeof(FFlatVertex));
Unmap();
mVertexBuffer->Upload(start * sizeof(FFlatVertex), count * sizeof(FFlatVertex));
}
mVertexBuffer = old;
}

View file

@ -45,13 +45,20 @@ public:
TArray<FFlatVertex> vbo_shadowdata;
TArray<uint32_t> ibo_data;
IVertexBuffer *mVertexBuffer;
int mPipelineNbr;
int mPipelinePos = 0;
IVertexBuffer* mVertexBuffer;
IVertexBuffer *mVertexBufferPipeline[HW_MAX_PIPELINE_BUFFERS];
IIndexBuffer *mIndexBuffer;
unsigned int mIndex;
std::atomic<unsigned int> mCurIndex;
unsigned int mNumReserved;
unsigned int mMapStart;
static const unsigned int BUFFER_SIZE = 2000000;
static const unsigned int BUFFER_SIZE_TO_USE = BUFFER_SIZE-500;
@ -68,7 +75,7 @@ public:
NUM_RESERVED = 20
};
FFlatVertexBuffer(int width, int height);
FFlatVertexBuffer(int width, int height, int pipelineNbr = 1);
~FFlatVertexBuffer();
void OutputResized(int width, int height);
@ -97,16 +104,40 @@ public:
mCurIndex = mIndex;
}
void NextPipelineBuffer()
{
mPipelinePos++;
mPipelinePos %= mPipelineNbr;
mVertexBuffer = mVertexBufferPipeline[mPipelinePos];
}
void Map()
{
mMapStart = mCurIndex;
mVertexBuffer->Map();
}
void Unmap()
{
mVertexBuffer->Unmap();
mVertexBuffer->Upload(mMapStart * sizeof(FFlatVertex), (mCurIndex - mMapStart) * sizeof(FFlatVertex));
}
void DropSync()
{
mVertexBuffer->GPUDropSync();
}
void WaitSync()
{
mVertexBuffer->GPUWaitSync();
}
int GetPipelinePos()
{
return mPipelinePos;
}
};
#endif

View file

@ -33,7 +33,8 @@ static const int ELEMENTS_PER_LIGHT = 4; // each light needs 4 vec4's.
static const int ELEMENT_SIZE = (4*sizeof(float));
FLightBuffer::FLightBuffer()
FLightBuffer::FLightBuffer(int pipelineNbr):
mPipelineNbr(pipelineNbr)
{
int maxNumberOfLights = 80000;
@ -43,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->IsPoly() || ((screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && !strstr(screen->vendorstring, "Intel")))
if (screen->IsVulkan() || screen->IsPoly() || ((screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && screen->mPipelineType == 0 && !strstr(screen->vendorstring, "Intel")))
{
mBufferType = true;
mBlockAlign = 0;
@ -56,11 +57,15 @@ FLightBuffer::FLightBuffer()
mBlockSize = screen->maxuniformblock / ELEMENT_SIZE;
mBlockAlign = screen->uniformblockalignment / ELEMENT_SIZE;
mMaxUploadSize = (mBlockSize - mBlockAlign);
mByteSize += screen->maxuniformblock; // to avoid mapping beyond the end of the buffer.
//mByteSize += screen->maxuniformblock; // to avoid mapping beyond the end of the buffer. REMOVED this...This can try to allocate 100's of MB..
}
mBuffer = screen->CreateDataBuffer(LIGHTBUF_BINDINGPOINT, mBufferType, false);
mBuffer->SetData(mByteSize, nullptr, false);
for (int n = 0; n < mPipelineNbr; n++)
{
mBufferPipeline[n] = screen->CreateDataBuffer(LIGHTBUF_BINDINGPOINT, mBufferType, false);
mBufferPipeline[n]->SetData(mByteSize, nullptr, false);
}
Clear();
}
@ -73,6 +78,11 @@ FLightBuffer::~FLightBuffer()
void FLightBuffer::Clear()
{
mIndex = 0;
mPipelinePos++;
mPipelinePos %= mPipelineNbr;
mBuffer = mBufferPipeline[mPipelinePos];
}
int FLightBuffer::UploadLights(FDynLightData &data)

View file

@ -12,6 +12,9 @@ class FRenderState;
class FLightBuffer
{
IDataBuffer *mBuffer;
IDataBuffer* mBufferPipeline[HW_MAX_PIPELINE_BUFFERS];
int mPipelineNbr;
int mPipelinePos = 0;
bool mBufferType;
std::atomic<unsigned int> mIndex;
@ -25,7 +28,7 @@ class FLightBuffer
public:
FLightBuffer();
FLightBuffer(int pipelineNbr = 1);
~FLightBuffer();
void Clear();
int UploadLights(FDynLightData &data);

View file

@ -226,6 +226,10 @@ protected:
float mAlphaThreshold;
float mClipSplit[2];
int mColorMapSpecial;
float mColorMapFlash;
StreamData mStreamData = {};
PalEntry mFogColor;
@ -278,6 +282,9 @@ public:
mBias.Reset();
mPassType = NORMAL_PASS;
mColorMapSpecial = 0;
mColorMapFlash = 1;
mVertexBuffer = nullptr;
mVertexOffsets[0] = mVertexOffsets[1] = 0;
mIndexBuffer = nullptr;
@ -676,6 +683,12 @@ public:
return mPassType;
}
void SetSpecialColormap(int cm, float flash)
{
mColorMapSpecial = cm;
mColorMapFlash = flash;
}
// API-dependent render interface
// Draw commands

View file

@ -98,7 +98,7 @@ bool IShadowMap::PerformUpdate()
LightsProcessed = 0;
LightsShadowmapped = 0;
if (gl_light_shadowmap && (screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && CollectLights != nullptr)
if (gl_light_shadowmap && (screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && screen->mPipelineType == 0 && CollectLights != nullptr)
{
UpdateCycles.Clock();
UploadAABBTree();

View file

@ -33,13 +33,19 @@
static const int INITIAL_BUFFER_SIZE = 100; // 100 viewpoints per frame should nearly always be enough
HWViewpointBuffer::HWViewpointBuffer()
HWViewpointBuffer::HWViewpointBuffer(int pipelineNbr):
mPipelineNbr(pipelineNbr)
{
mBufferSize = INITIAL_BUFFER_SIZE;
mBlockAlign = ((sizeof(HWViewpointUniforms) / screen->uniformblockalignment) + 1) * screen->uniformblockalignment;
mByteSize = mBufferSize * mBlockAlign;
mBuffer = screen->CreateDataBuffer(VIEWPOINT_BINDINGPOINT, false, true);
mBuffer->SetData(mByteSize, nullptr, false);
for (int n = 0; n < mPipelineNbr; n++)
{
mBufferPipeline[n] = screen->CreateDataBuffer(VIEWPOINT_BINDINGPOINT, false, true);
mBufferPipeline[n]->SetData(mByteSize, nullptr, false);
}
Clear();
mLastMappedIndex = UINT_MAX;
mClipPlaneInfo.Push(0);
@ -57,7 +63,10 @@ void HWViewpointBuffer::CheckSize()
{
mBufferSize *= 2;
mByteSize *= 2;
mBuffer->Resize(mByteSize);
for (int n = 0; n < mPipelineNbr; n++)
{
mBufferPipeline[n]->Resize(mByteSize);
}
m2DHeight = m2DWidth = -1;
}
}
@ -89,9 +98,14 @@ void HWViewpointBuffer::Set2D(FRenderState &di, int width, int height, int pll)
matrices.mProjectionMatrix.ortho(0, (float)width, (float)height, 0, -1.0f, 1.0f);
matrices.CalcDependencies();
mBuffer->Map();
memcpy(mBuffer->Memory(), &matrices, sizeof(matrices));
mBuffer->Unmap();
for (int n = 0; n < mPipelineNbr; n++)
{
mBufferPipeline[n]->Map();
memcpy(mBufferPipeline[n]->Memory(), &matrices, sizeof(matrices));
mBufferPipeline[n]->Unmap();
}
m2DWidth = width;
m2DHeight = height;
mLastMappedIndex = -1;
@ -115,5 +129,10 @@ void HWViewpointBuffer::Clear()
// Index 0 is reserved for the 2D projection.
mUploadIndex = 1;
mClipPlaneInfo.Resize(1);
mPipelinePos++;
mPipelinePos %= mPipelineNbr;
mBuffer = mBufferPipeline[mPipelinePos];
}

View file

@ -8,6 +8,9 @@ class FRenderState;
class HWViewpointBuffer
{
IDataBuffer *mBuffer;
IDataBuffer* mBufferPipeline[HW_MAX_PIPELINE_BUFFERS];
int mPipelineNbr;
int mPipelinePos = 0;
unsigned int mBufferSize;
unsigned int mBlockAlign;
@ -24,7 +27,7 @@ class HWViewpointBuffer
public:
HWViewpointBuffer();
HWViewpointBuffer(int pipelineNbr = 1);
~HWViewpointBuffer();
void Clear();
int Bind(FRenderState &di, unsigned int index);