Manage the light buffer in the backend

This commit is contained in:
Magnus Norddahl 2023-04-30 03:43:38 +02:00 committed by Christoph Oelckers
parent 62a227621a
commit d24ffc021b
23 changed files with 97 additions and 267 deletions

View file

@ -1101,7 +1101,6 @@ set (PCH_SOURCES
common/rendering/hwrenderer/data/hw_modelvertexbuffer.cpp
common/rendering/hwrenderer/data/hw_cvars.cpp
common/rendering/hwrenderer/data/hw_vrmodes.cpp
common/rendering/hwrenderer/data/hw_lightbuffer.cpp
common/rendering/hwrenderer/data/hw_bonebuffer.cpp
common/rendering/hwrenderer/data/hw_aabbtree.cpp
common/rendering/hwrenderer/data/hw_shadowmap.cpp

View file

@ -1,143 +0,0 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2014-2016 Christoph Oelckers
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
/*
** gl_lightbuffer.cpp
** Buffer data maintenance for dynamic lights
**
**/
#include "hw_lightbuffer.h"
#include "hw_dynlightdata.h"
#include "v_video.h"
static const int ELEMENTS_PER_LIGHT = 4; // each light needs 4 vec4's.
static const int ELEMENT_SIZE = (4*sizeof(float));
FLightBuffer::FLightBuffer(DFrameBuffer* fb, int pipelineNbr) : fb(fb), mPipelineNbr(pipelineNbr)
{
int maxNumberOfLights = 80000;
mBufferSize = maxNumberOfLights * ELEMENTS_PER_LIGHT;
mByteSize = mBufferSize * ELEMENT_SIZE;
//if (fb->useSSBO())
{
mBufferType = true;
mBlockAlign = 0;
mBlockSize = mBufferSize;
mMaxUploadSize = mBlockSize;
}
/*else
{
mBufferType = false;
mBlockSize = fb->maxuniformblock / ELEMENT_SIZE;
mBlockAlign = fb->uniformblockalignment / ELEMENT_SIZE;
mMaxUploadSize = (mBlockSize - mBlockAlign);
}*/
for (int n = 0; n < mPipelineNbr; n++)
{
mBufferPipeline[n] = fb->CreateLightBuffer();
mBufferPipeline[n]->SetData(mByteSize, nullptr, BufferUsageType::Persistent);
}
Clear();
}
FLightBuffer::~FLightBuffer()
{
delete mBuffer;
}
void FLightBuffer::Clear()
{
mIndex = 0;
mPipelinePos++;
mPipelinePos %= mPipelineNbr;
mBuffer = mBufferPipeline[mPipelinePos];
}
int FLightBuffer::UploadLights(FDynLightData &data)
{
// All meaasurements here are in vec4's.
int size0 = data.arrays[0].Size()/4;
int size1 = data.arrays[1].Size()/4;
int size2 = data.arrays[2].Size()/4;
int totalsize = size0 + size1 + size2 + 1;
if (totalsize > (int)mMaxUploadSize)
{
int diff = totalsize - (int)mMaxUploadSize;
size2 -= diff;
if (size2 < 0)
{
size1 += size2;
size2 = 0;
}
if (size1 < 0)
{
size0 += size1;
size1 = 0;
}
totalsize = size0 + size1 + size2 + 1;
}
float *mBufferPointer = (float*)mBuffer->Memory();
assert(mBufferPointer != nullptr);
if (mBufferPointer == nullptr) return -1;
if (totalsize <= 1) return -1; // there are no lights
unsigned thisindex = mIndex.fetch_add(totalsize);
float parmcnt[] = { 0, float(size0), float(size0 + size1), float(size0 + size1 + size2) };
if (thisindex + totalsize <= mBufferSize)
{
float *copyptr = mBufferPointer + thisindex*4;
memcpy(&copyptr[0], parmcnt, ELEMENT_SIZE);
memcpy(&copyptr[4], &data.arrays[0][0], size0 * ELEMENT_SIZE);
memcpy(&copyptr[4 + 4*size0], &data.arrays[1][0], size1 * ELEMENT_SIZE);
memcpy(&copyptr[4 + 4*(size0 + size1)], &data.arrays[2][0], size2 * ELEMENT_SIZE);
return thisindex;
}
else
{
return -1; // Buffer is full. Since it is being used live at the point of the upload we cannot do much here but to abort.
}
}
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;
*pOffset = offset * ELEMENT_SIZE;
*pSize = mBlockSize * ELEMENT_SIZE;
return (index - offset);
}

View file

@ -1,53 +0,0 @@
#ifndef __GL_LIGHTBUFFER_H
#define __GL_LIGHTBUFFER_H
#include "tarray.h"
#include "hw_dynlightdata.h"
#include "hwrenderer/data/buffers.h"
#include <atomic>
#include <mutex>
class DFrameBuffer;
class FRenderState;
class FLightBuffer
{
DFrameBuffer* fb = nullptr;
IBuffer* mBuffer;
IBuffer* mBufferPipeline[HW_MAX_PIPELINE_BUFFERS];
int mPipelineNbr;
int mPipelinePos = 0;
bool mBufferType;
std::atomic<unsigned int> mIndex;
unsigned int mBlockAlign;
unsigned int mBlockSize;
unsigned int mBufferSize;
unsigned int mByteSize;
unsigned int mMaxUploadSize;
void CheckSize();
public:
FLightBuffer(DFrameBuffer* fb, int pipelineNbr = 1);
~FLightBuffer();
void Clear();
int UploadLights(FDynLightData &data);
void Map() { mBuffer->Map(); }
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);
// OpenGL needs the buffer to mess around with the binding.
IBuffer* GetBuffer() const
{
return mBuffer;
}
};
#endif

View file

@ -68,6 +68,7 @@ public:
// Buffers
int SetViewpoint(const HWViewpointUniforms& vp) override { return 0; }
void SetViewpoint(int index) override { }
int UploadLights(const FDynLightData& lightdata) override { return -1; }
// Draw commands
void Draw(int dt, int index, int count, bool apply = true) override;

View file

@ -12,6 +12,7 @@
struct FColormap;
class IBuffer;
struct HWViewpointUniforms;
struct FDynLightData;
enum EClearTarget
{
@ -758,6 +759,7 @@ public:
// Buffers
virtual int SetViewpoint(const HWViewpointUniforms& vp) = 0;
virtual void SetViewpoint(int index) = 0;
virtual int UploadLights(const FDynLightData& lightdata) = 0;
// Draw commands
virtual void ClearScreen() = 0;

View file

@ -52,7 +52,6 @@ struct FPortalSceneState;
class FSkyVertexBuffer;
class IBuffer;
class FFlatVertexBuffer;
class FLightBuffer;
struct HWDrawInfo;
class FMaterial;
class FGameTexture;
@ -140,7 +139,6 @@ public:
const char *vendorstring; // We have to account for some issues with particular vendors.
FSkyVertexBuffer *mSkyData = nullptr; // the sky vertex buffer
FFlatVertexBuffer *mVertexData = nullptr; // Global vertex data
FLightBuffer *mLights = nullptr; // Dynamic lights
BoneBuffer* mBones = nullptr; // Model bones
ShadowMap* mShadowMap = nullptr;
@ -238,7 +236,6 @@ public:
bool BuffersArePersistent() { return !!(hwcaps & RFL_BUFFER_STORAGE); }
// To do: these buffers shouldn't be created by the hwrenderer layer - it will be simpler if the backend manages them completely
virtual IBuffer* CreateLightBuffer() { return nullptr; }
virtual IBuffer* CreateBoneBuffer() { return nullptr; }
virtual IBuffer* CreateShadowmapNodesBuffer() { return nullptr; }
virtual IBuffer* CreateShadowmapLinesBuffer() { return nullptr; }

View file

@ -42,15 +42,17 @@ void VkBufferManager::Init()
Viewpoint.BlockAlign = (sizeof(HWViewpointUniforms) + fb->uniformblockalignment - 1) / fb->uniformblockalignment * fb->uniformblockalignment;
Viewpoint.UBO.reset(new VkHardwareDataBuffer(fb, false, true));
Viewpoint.UBO->SetData(Viewpoint.Count * Viewpoint.BlockAlign, nullptr, BufferUsageType::Persistent);
Viewpoint.UBO->Map();
Lightbuffer.SSO.reset(new VkHardwareDataBuffer(fb, true, false));
Lightbuffer.SSO->SetData(Lightbuffer.Count * 4 * sizeof(FVector4), nullptr, BufferUsageType::Persistent);
CreateFanToTrisIndexBuffer();
}
void VkBufferManager::Deinit()
{
Viewpoint.UBO->Unmap();
Viewpoint.UBO.reset();
Lightbuffer.SSO.reset();
while (!Buffers.empty())
RemoveBuffer(Buffers.back());
@ -67,7 +69,7 @@ void VkBufferManager::RemoveBuffer(VkHardwareBuffer* buffer)
buffer->fb = nullptr;
Buffers.erase(buffer->it);
for (VkHardwareDataBuffer** knownbuf : { &LightBufferSSO, &LightNodes, &LightLines, &LightList, &BoneBufferSSO})
for (VkHardwareDataBuffer** knownbuf : { &LightNodes, &LightLines, &LightList, &BoneBufferSSO})
{
if (buffer == *knownbuf) *knownbuf = nullptr;
}
@ -83,12 +85,6 @@ IBuffer* VkBufferManager::CreateIndexBuffer()
return new VkHardwareIndexBuffer(fb);
}
IBuffer* VkBufferManager::CreateLightBuffer()
{
LightBufferSSO = new VkHardwareDataBuffer(fb, true, false);
return LightBufferSSO;
}
IBuffer* VkBufferManager::CreateBoneBuffer()
{
BoneBufferSSO = new VkHardwareDataBuffer(fb, true, false);

View file

@ -24,7 +24,6 @@ public:
IBuffer* CreateVertexBuffer(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute* attrs);
IBuffer* CreateIndexBuffer();
IBuffer* CreateLightBuffer();
IBuffer* CreateBoneBuffer();
IBuffer* CreateShadowmapNodesBuffer();
IBuffer* CreateShadowmapLinesBuffer();
@ -41,7 +40,13 @@ public:
std::unique_ptr<VkHardwareDataBuffer> UBO;
} Viewpoint;
VkHardwareDataBuffer* LightBufferSSO = nullptr;
struct
{
int UploadIndex = 0;
int Count = 80000;
std::unique_ptr<VkHardwareDataBuffer> SSO;
} Lightbuffer;
VkHardwareDataBuffer* LightNodes = nullptr;
VkHardwareDataBuffer* LightLines = nullptr;
VkHardwareDataBuffer* LightList = nullptr;

View file

@ -84,7 +84,7 @@ void VkDescriptorSetManager::UpdateHWBufferSet()
.AddBuffer(HWBufferSet.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->Viewpoint.UBO->mBuffer.get(), 0, sizeof(HWViewpointUniforms))
.AddBuffer(HWBufferSet.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->MatrixBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(MatricesUBO))
.AddBuffer(HWBufferSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->StreamBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(StreamUBO))
.AddBuffer(HWBufferSet.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightBufferSSO->mBuffer.get())
.AddBuffer(HWBufferSet.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->Lightbuffer.SSO->mBuffer.get())
.AddBuffer(HWBufferSet.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->BoneBufferSSO->mBuffer.get())
.Execute(fb->GetDevice());
}

View file

@ -38,7 +38,6 @@
#include "hw_cvars.h"
#include "hw_skydome.h"
#include "flatvertices.h"
#include "hw_lightbuffer.h"
#include "hw_bonebuffer.h"
#include "vk_renderdevice.h"
@ -133,7 +132,6 @@ VulkanRenderDevice::~VulkanRenderDevice()
delete mVertexData;
delete mSkyData;
delete mLights;
delete mBones;
delete mShadowMap;
@ -191,7 +189,6 @@ void VulkanRenderDevice::InitializeState()
mVertexData = new FFlatVertexBuffer(this, GetWidth(), GetHeight());
mSkyData = new FSkyVertexBuffer(this);
mLights = new FLightBuffer(this);
mBones = new BoneBuffer(this);
mShadowMap = new ShadowMap(this);
@ -319,11 +316,6 @@ IBuffer*VulkanRenderDevice::CreateIndexBuffer()
return GetBufferManager()->CreateIndexBuffer();
}
IBuffer* VulkanRenderDevice::CreateLightBuffer()
{
return GetBufferManager()->CreateLightBuffer();
}
IBuffer* VulkanRenderDevice::CreateBoneBuffer()
{
return GetBufferManager()->CreateBoneBuffer();
@ -478,7 +470,6 @@ TArray<uint8_t> VulkanRenderDevice::GetScreenshotBuffer(int &pitch, ESSType &col
void VulkanRenderDevice::BeginFrame()
{
SetViewportRects(nullptr);
mBufferManager->Viewpoint.UploadIndex = 0;
mCommands->BeginFrame();
mTextureManager->BeginFrame();
mScreenBuffers->BeginFrame(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height);
@ -506,11 +497,6 @@ void VulkanRenderDevice::WaitForCommands(bool finish)
mCommands->WaitForCommands(finish);
}
unsigned int VulkanRenderDevice::GetLightBufferBlockSize() const
{
return mLights->GetBlockSize();
}
void VulkanRenderDevice::PrintStartupLog()
{
const auto &props = mDevice->PhysicalDevice.Properties.Properties;

View file

@ -44,8 +44,6 @@ public:
VkRenderBuffers *GetBuffers() { return mActiveRenderBuffers; }
FRenderState* RenderState() override;
unsigned int GetLightBufferBlockSize() const;
bool IsVulkan() override { return true; }
void Update() override;
@ -76,7 +74,6 @@ public:
IBuffer* CreateVertexBuffer(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute* attrs) override;
IBuffer* CreateIndexBuffer() override;
IBuffer* CreateLightBuffer() override;
IBuffer* CreateBoneBuffer() override;
IBuffer* CreateShadowmapNodesBuffer() override;
IBuffer* CreateShadowmapLinesBuffer() override;

View file

@ -32,7 +32,7 @@
#include "hw_skydome.h"
#include "hw_viewpointuniforms.h"
#include "hw_lightbuffer.h"
#include "hw_dynlightdata.h"
#include "hw_cvars.h"
#include "hw_clock.h"
#include "flatvertices.h"
@ -503,10 +503,63 @@ void VkRenderState::SetViewpoint(int index)
mNeedApply = true;
}
int VkRenderState::UploadLights(const FDynLightData& data)
{
auto buffers = fb->GetBufferManager();
// All meaasurements here are in vec4's.
int size0 = data.arrays[0].Size() / 4;
int size1 = data.arrays[1].Size() / 4;
int size2 = data.arrays[2].Size() / 4;
int totalsize = size0 + size1 + size2 + 1;
if (totalsize > buffers->Lightbuffer.Count)
{
int diff = totalsize - buffers->Lightbuffer.Count;
size2 -= diff;
if (size2 < 0)
{
size1 += size2;
size2 = 0;
}
if (size1 < 0)
{
size0 += size1;
size1 = 0;
}
totalsize = size0 + size1 + size2 + 1;
}
if (totalsize <= 1) return -1; // there are no lights
int thisindex = buffers->Lightbuffer.UploadIndex;
buffers->Lightbuffer.UploadIndex += totalsize;
float parmcnt[] = { 0, float(size0), float(size0 + size1), float(size0 + size1 + size2) };
if (thisindex + totalsize <= buffers->Lightbuffer.Count)
{
float* copyptr = (float*)buffers->Lightbuffer.SSO->Memory() + thisindex * 4;
memcpy(&copyptr[0], parmcnt, sizeof(FVector4));
memcpy(&copyptr[4], &data.arrays[0][0], size0 * sizeof(FVector4));
memcpy(&copyptr[4 + 4 * size0], &data.arrays[1][0], size1 * sizeof(FVector4));
memcpy(&copyptr[4 + 4 * (size0 + size1)], &data.arrays[2][0], size2 * sizeof(FVector4));
return thisindex;
}
else
{
return -1; // Buffer is full. Since it is being used live at the point of the upload we cannot do much here but to abort.
}
}
void VkRenderState::BeginFrame()
{
mMaterial.Reset();
mApplyCount = 0;
fb->GetBufferManager()->Viewpoint.UploadIndex = 0;
fb->GetBufferManager()->Lightbuffer.UploadIndex = 0;
}
void VkRenderState::EndRenderPass()

View file

@ -47,8 +47,10 @@ public:
void EndRenderPass();
void EndFrame();
// Buffers
int SetViewpoint(const HWViewpointUniforms& vp) override;
void SetViewpoint(int index) override;
int UploadLights(const FDynLightData& lightdata) override;
protected:
void Apply(int dt);

View file

@ -43,7 +43,6 @@
#include "g_cvars.h"
#include "v_draw.h"
#include "hw_lightbuffer.h"
#include "hw_bonebuffer.h"
#include "hw_cvars.h"
#include "hwrenderer/scene/hw_fakeflat.h"
@ -279,7 +278,6 @@ void WriteSavePic(player_t* player, FileWriter* file, int width, int height)
hw_ClearFakeFlat();
screen->mVertexData->Reset();
RenderState.SetVertexBuffer(screen->mVertexData);
screen->mLights->Clear();
screen->mBones->Clear();
// This shouldn't overwrite the global viewpoint even for a short time.
@ -344,7 +342,6 @@ sector_t* RenderView(player_t* player)
if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.;
else r_viewpoint.TicFrac = I_GetTimeFrac();
screen->mLights->Clear();
screen->mBones->Clear();
// NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below.

View file

@ -39,7 +39,6 @@
#include "hw_clock.h"
#include "hw_cvars.h"
#include "flatvertices.h"
#include "hw_lightbuffer.h"
#include "hw_bonebuffer.h"
#include "hw_vrmodes.h"
#include "hw_clipper.h"
@ -450,7 +449,6 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state)
// clip the scene and fill the drawlists
screen->mVertexData->Map();
screen->mLights->Map();
screen->mBones->Map();
if (!gl_meshcache)
@ -464,7 +462,6 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state)
HandleHackedSubsectors(state); // open sector hacks for deep water
PrepareUnhandledMissingTextures(state);
DispatchRenderHacks(state);
screen->mLights->Unmap();
screen->mBones->Unmap();
screen->mVertexData->Unmap();

View file

@ -207,7 +207,7 @@ private:
void RenderThings(subsector_t * sub, sector_t * sector, FRenderState& state);
void RenderParticles(subsector_t *sub, sector_t *front, FRenderState& state);
void DoSubsector(subsector_t * sub, FRenderState& state);
int SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &lightdata, const secplane_t *plane);
int SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &lightdata, const secplane_t *plane, FRenderState& state);
int CreateOtherPlaneVertices(subsector_t *sub, const secplane_t *plane, FRenderState& state);
void DrawPSprite(HUDSprite *huds, FRenderState &state);
void SetColor(FRenderState &state, int sectorlightlevel, int rellight, bool fullbright, const FColormap &cm, float alpha, bool weapon = false);
@ -220,7 +220,7 @@ private:
WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int cm, area_t in_area, const DVector3 &playerpos);
void PreparePlayerSprites2D(sector_t * viewsector, area_t in_area, FRenderState& state);
void PreparePlayerSprites3D(sector_t * viewsector, area_t in_area);
void PreparePlayerSprites3D(sector_t * viewsector, area_t in_area, FRenderState& state);
public:
void SetCameraPos(const DVector3 &pos)

View file

@ -22,7 +22,6 @@
#include "hw_dynlightdata.h"
#include "hw_cvars.h"
#include "hw_lightbuffer.h"
#include "hwrenderer/scene/hw_drawstructs.h"
#include "hwrenderer/scene/hw_drawinfo.h"
#include "hw_material.h"
@ -86,7 +85,7 @@ void HWDrawInfo::AddMirrorSurface(HWWall *w, FRenderState& state)
bool hasDecals = newwall->seg->sidedef && newwall->seg->sidedef->AttachedDecals;
if (hasDecals && Level->HasDynamicLights && !isFullbrightScene())
{
newwall->SetupLights(this, lightdata);
newwall->SetupLights(this, state, lightdata);
}
newwall->ProcessDecals(this, state);
newwall->dynlightindex = -1; // the environment map should not be affected by lights - only the decals.

View file

@ -212,7 +212,7 @@ public:
bool SplitWallComplex(HWDrawInfo *di, FRenderState& state, sector_t * frontsector, bool translucent, float& maplightbottomleft, float& maplightbottomright);
void SplitWall(HWDrawInfo *di, FRenderState& state, sector_t * frontsector, bool translucent);
void SetupLights(HWDrawInfo *di, FDynLightData &lightdata);
void SetupLights(HWDrawInfo *di, FRenderState& state, FDynLightData &lightdata);
void MakeVertices(HWDrawInfo *di, FRenderState& state, bool nosplit);
@ -321,9 +321,9 @@ public:
int dynlightindex;
void CreateSkyboxVertices(FFlatVertex *buffer);
void SetupLights(HWDrawInfo *di, FLightNode *head, FDynLightData &lightdata, int portalgroup);
void SetupLights(HWDrawInfo *di, FRenderState& state, FLightNode *head, FDynLightData &lightdata, int portalgroup);
void PutFlat(HWDrawInfo *di, bool fog = false);
void PutFlat(HWDrawInfo *di, FRenderState& state, bool fog = false);
void Process(HWDrawInfo *di, FRenderState& state, sector_t * model, int whichplane, bool notexture);
void SetFrom3DFloor(F3DFloor *rover, bool top, bool underside);
void ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * frontsector, int which = 7 /*SSRF_RENDERALL*/); // cannot use constant due to circular dependencies.

View file

@ -43,7 +43,6 @@
#include "hw_material.h"
#include "hwrenderer/scene/hw_drawinfo.h"
#include "flatvertices.h"
#include "hw_lightbuffer.h"
#include "hw_drawstructs.h"
#include "hw_renderstate.h"
#include "texturemanager.h"
@ -147,7 +146,7 @@ void HWFlat::CreateSkyboxVertices(FFlatVertex *vert)
//
//==========================================================================
void HWFlat::SetupLights(HWDrawInfo *di, FLightNode * node, FDynLightData &lightdata, int portalgroup)
void HWFlat::SetupLights(HWDrawInfo *di, FRenderState& state, FLightNode * node, FDynLightData &lightdata, int portalgroup)
{
Plane p;
@ -182,7 +181,7 @@ void HWFlat::SetupLights(HWDrawInfo *di, FLightNode * node, FDynLightData &light
node = node->nextLight;
}
dynlightindex = screen->mLights->UploadLights(lightdata);
dynlightindex = state.UploadLights(lightdata);
}
//==========================================================================
@ -195,7 +194,7 @@ void HWFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
{
if (di->Level->HasDynamicLights && screen->BuffersArePersistent() && !di->isFullbrightScene())
{
SetupLights(di, section->lighthead, lightdata, sector->PortalGroup);
SetupLights(di, state, section->lighthead, lightdata, sector->PortalGroup);
}
state.SetLightIndex(dynlightindex);
@ -382,7 +381,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
//
//==========================================================================
inline void HWFlat::PutFlat(HWDrawInfo *di, bool fog)
inline void HWFlat::PutFlat(HWDrawInfo *di, FRenderState& state, bool fog)
{
if (di->isFullbrightScene())
{
@ -392,7 +391,7 @@ inline void HWFlat::PutFlat(HWDrawInfo *di, bool fog)
{
if (di->Level->HasDynamicLights && texture != nullptr && !di->isFullbrightScene() && !(hacktype & (SSRF_PLANEHACK|SSRF_FLOODHACK)) )
{
SetupLights(di, section->lighthead, lightdata, sector->PortalGroup);
SetupLights(di, state, section->lighthead, lightdata, sector->PortalGroup);
}
}
di->AddFlat(this, fog);
@ -439,7 +438,7 @@ void HWFlat::Process(HWDrawInfo *di, FRenderState& state, sector_t * model, int
}
// For hacks this won't go into a render list.
PutFlat(di, fog);
PutFlat(di, state, fog);
rendered_flats++;
}

View file

@ -38,7 +38,6 @@
#include "hw_clock.h"
#include "hw_dynlightdata.h"
#include "flatvertices.h"
#include "hw_lightbuffer.h"
#include "hwrenderer/scene/hw_portal.h"
#include "hw_fakeflat.h"
@ -108,7 +107,7 @@ static gl_floodrendernode *NewFloodRenderNode()
//
//==========================================================================
int HWDrawInfo::SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &lightdata, const secplane_t *plane)
int HWDrawInfo::SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &lightdata, const secplane_t *plane, FRenderState& state)
{
if (Level->HasDynamicLights && !isFullbrightScene())
{
@ -133,7 +132,7 @@ int HWDrawInfo::SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &light
node = node->nextLight;
}
return screen->mLights->UploadLights(lightdata);
return state.UploadLights(lightdata);
}
else return -1;
}
@ -172,7 +171,7 @@ void HWDrawInfo::AddOtherFloorPlane(int sector, gl_subsectorrendernode* node, FR
auto pNode = otherFloorPlanes.CheckKey(sector);
node->next = pNode? *pNode : nullptr;
node->lightindex = SetupLightsForOtherPlane(node->sub, lightdata, &Level->sectors[sector].floorplane);
node->lightindex = SetupLightsForOtherPlane(node->sub, lightdata, &Level->sectors[sector].floorplane, state);
node->vertexindex = CreateOtherPlaneVertices(node->sub, &Level->sectors[sector].floorplane, state);
otherFloorPlanes[sector] = node;
}
@ -182,7 +181,7 @@ void HWDrawInfo::AddOtherCeilingPlane(int sector, gl_subsectorrendernode* node,
auto pNode = otherCeilingPlanes.CheckKey(sector);
node->next = pNode? *pNode : nullptr;
node->lightindex = SetupLightsForOtherPlane(node->sub, lightdata, &Level->sectors[sector].ceilingplane);
node->lightindex = SetupLightsForOtherPlane(node->sub, lightdata, &Level->sectors[sector].ceilingplane, state);
node->vertexindex = CreateOtherPlaneVertices(node->sub, &Level->sectors[sector].ceilingplane, state);
otherCeilingPlanes[sector] = node;
}

View file

@ -56,7 +56,6 @@
#include "hw_lighting.h"
#include "hw_material.h"
#include "hw_dynlightdata.h"
#include "hw_lightbuffer.h"
#include "hw_renderstate.h"
extern TArray<spritedef_t> sprites;
@ -552,7 +551,7 @@ inline void HWSprite::PutSprite(HWDrawInfo *di, FRenderState& state, bool transl
if (modelframe && !modelframe->isVoxel && !(modelframe->flags & MDL_NOPERPIXELLIGHTING) && RenderStyle.BlendOp != STYLEOP_Shadow && gl_light_sprites && di->Level->HasDynamicLights && !di->isFullbrightScene() && !fullbright)
{
hw_GetDynModelLight(actor, lightdata);
dynlightindex = screen->mLights->UploadLights(lightdata);
dynlightindex = state.UploadLights(lightdata);
}
else
dynlightindex = -1;

View file

@ -40,7 +40,6 @@
#include "hwrenderer/scene/hw_drawinfo.h"
#include "hwrenderer/scene/hw_drawstructs.h"
#include "hwrenderer/scene/hw_portal.h"
#include "hw_lightbuffer.h"
#include "hw_renderstate.h"
#include "hw_skydome.h"
@ -344,7 +343,7 @@ void HWWall::DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent)
{
if (di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr)
{
SetupLights(di, lightdata);
SetupLights(di, state, lightdata);
}
MakeVertices(di, state, !!(flags & HWWall::HWF_TRANSLUCENT));
}
@ -379,7 +378,7 @@ void HWWall::DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent)
//
//==========================================================================
void HWWall::SetupLights(HWDrawInfo *di, FDynLightData &lightdata)
void HWWall::SetupLights(HWDrawInfo *di, FRenderState& state, FDynLightData &lightdata)
{
lightdata.Clear();
@ -471,7 +470,7 @@ void HWWall::SetupLights(HWDrawInfo *di, FDynLightData &lightdata)
}
node = node->nextLight;
}
dynlightindex = screen->mLights->UploadLights(lightdata);
dynlightindex = state.UploadLights(lightdata);
}
@ -521,7 +520,7 @@ void HWWall::PutWall(HWDrawInfo *di, FRenderState& state, bool translucent)
{
if (di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr)
{
SetupLights(di, lightdata);
SetupLights(di, state, lightdata);
}
MakeVertices(di, state, translucent);
}
@ -541,7 +540,7 @@ void HWWall::PutWall(HWDrawInfo *di, FRenderState& state, bool translucent)
{
if (di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr)
{
SetupLights(di, lightdata);
SetupLights(di, state, lightdata);
}
}
ProcessDecals(di, state);

View file

@ -44,7 +44,6 @@
#include "hwrenderer/scene/hw_drawinfo.h"
#include "hwrenderer/scene/hw_drawstructs.h"
#include "flatvertices.h"
#include "hw_lightbuffer.h"
#include "hw_renderstate.h"
#include "vm.h"
@ -747,7 +746,7 @@ void HWDrawInfo::PreparePlayerSprites2D(sector_t * viewsector, area_t in_area, F
lightmode = oldlightmode;
}
void HWDrawInfo::PreparePlayerSprites3D(sector_t * viewsector, area_t in_area)
void HWDrawInfo::PreparePlayerSprites3D(sector_t * viewsector, area_t in_area, FRenderState& state)
{
static PClass * wpCls = PClass::FindClass("Weapon");
@ -842,7 +841,7 @@ void HWDrawInfo::PreparePlayerSprites3D(sector_t * viewsector, area_t in_area)
if (hudsprite.RenderStyle.BlendOp != STYLEOP_Shadow && Level->HasDynamicLights && !isFullbrightScene() && gl_light_sprites)
{
hw_GetDynModelLight(playermo, lightdata);
hudsprite.lightindex = screen->mLights->UploadLights(lightdata);
hudsprite.lightindex = state.UploadLights(lightdata);
}
// [BB] In the HUD model step we just render the model and break out.
@ -876,7 +875,7 @@ void HWDrawInfo::PreparePlayerSprites(sector_t * viewsector, area_t in_area, FRe
if(hudModelStep)
{
PreparePlayerSprites3D(viewsector,in_area);
PreparePlayerSprites3D(viewsector,in_area,state);
}
else
{