- reduced gl_spritelight.cpp to pure data setup so that it can be moved out of gl/.

- added thread_local to some static arrays being used for setting up dynamic lights.

Right now it's of little consequence but these will have to be maintained per thread if the render data setup is done by worker tasks.
This commit is contained in:
Christoph Oelckers 2018-04-29 09:33:36 +02:00
parent 64b108ff44
commit 819ea8f937
10 changed files with 79 additions and 52 deletions

View File

@ -2,7 +2,7 @@
#define __GL_LIGHTBUFFER_H
#include "tarray.h"
struct FDynLightData;
#include "hwrenderer/dynlights/hw_dynlightdata.h"
class FLightBuffer
{
@ -35,5 +35,9 @@ public:
int GetIndex(int i) const { return mIndices[i]; }
};
int gl_SetDynModelLight(AActor *self, int dynlightindex);
extern thread_local FDynLightData lightdata;
#endif

View File

@ -535,7 +535,7 @@ public:
void SetPlaneTextureRotation(GLSectorPlane *plane, FMaterial *texture)
{
if (gl_SetPlaneTextureRotation(plane, texture, mTextureMatrix))
if (hw_SetPlaneTextureRotation(plane, texture, mTextureMatrix))
{
EnableTextureMatrix(true);
}

View File

@ -53,7 +53,6 @@
// Flats
//
//==========================================================================
extern FDynLightData lightdata;
void FDrawInfo::SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub, int *dli)
{
@ -63,7 +62,7 @@ void FDrawInfo::SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub,
(*dli)++;
return;
}
if (flat->SetupSubsectorLights(pass, sub))
if (flat->SetupSubsectorLights(pass, sub, lightdata))
{
int d = GLRenderer->mLights->UploadLights(lightdata);
if (pass == GLPASS_LIGHTSONLY)

View File

@ -42,6 +42,7 @@
#include "gl/system/gl_interface.h"
#include "hwrenderer/utility/hw_cvars.h"
#include "hwrenderer/scene/hw_drawstructs.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/renderer/gl_renderer.h"
@ -49,6 +50,7 @@
#include "gl/scene/gl_scenedrawer.h"
#include "gl/models/gl_models.h"
#include "gl/renderer/gl_quaddrawer.h"
#include "gl/dynlights/gl_lightbuffer.h"
extern uint32_t r_renderercaps;
@ -62,6 +64,36 @@ void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend
gl_RenderState.SetTextureMode(tm);
}
int gl_SetDynModelLight(AActor *self, int dynlightindex)
{
if (gl.legacyMode)
{
float out[3];
hw_GetDynSpriteLight(self, nullptr, out);
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
return -1;
}
else
{
// For deferred light mode this function gets called twice. First time for list upload, and second for draw.
if (gl.lightmethod == LM_DEFERRED && dynlightindex != -1)
{
gl_RenderState.SetDynLight(0, 0, 0);
return dynlightindex;
}
hw_GetDynModelLight(self, lightdata);
dynlightindex = GLRenderer->mLights->UploadLights(lightdata);
if (gl.lightmethod != LM_DEFERRED)
{
gl_RenderState.SetDynLight(0, 0, 0);
}
return dynlightindex;
}
}
//==========================================================================
//
//
@ -164,7 +196,11 @@ void FDrawInfo::DrawSprite(GLSprite *sprite, int pass)
if (sprite->modelframe && !sprite->particle)
sprite->dynlightindex = gl_SetDynModelLight(gl_light_sprites ? sprite->actor : nullptr, sprite->dynlightindex);
else
gl_SetDynSpriteLight(gl_light_sprites ? sprite->actor : nullptr, gl_light_particles ? sprite->particle : nullptr);
{
float out[3];
hw_GetDynSpriteLight(gl_light_sprites ? sprite->actor : nullptr, gl_light_particles ? sprite->particle : nullptr, out);
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
}
}
sector_t *cursec = sprite->actor ? sprite->actor->Sector : sprite->particle ? sprite->particle->subsector->sector : nullptr;
if (cursec != nullptr)

View File

@ -54,13 +54,13 @@ T smoothstep(const T edge0, const T edge1, const T x)
//
//==========================================================================
void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * subsec)
void hw_GetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * subsec, float *out)
{
ADynamicLight *light;
float frac, lr, lg, lb;
float radius;
float out[3] = { 0.0f, 0.0f, 0.0f };
out[0] = out[1] = out[2] = 0.f;
// Go through both light lists
FLightNode * node = subsec->lighthead;
while (node)
@ -131,18 +131,17 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
}
node = node->nextLight;
}
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
}
void gl_SetDynSpriteLight(AActor *thing, particle_t *particle)
void hw_GetDynSpriteLight(AActor *thing, particle_t *particle, float *out)
{
if (thing != NULL)
{
gl_SetDynSpriteLight(thing, thing->X(), thing->Y(), thing->Center(), thing->subsector);
hw_GetDynSpriteLight(thing, thing->X(), thing->Y(), thing->Center(), thing->subsector, out);
}
else if (particle != NULL)
{
gl_SetDynSpriteLight(NULL, particle->Pos.X, particle->Pos.Y, particle->Pos.Z, particle->subsector);
hw_GetDynSpriteLight(NULL, particle->Pos.X, particle->Pos.Y, particle->Pos.Z, particle->subsector, out);
}
}
@ -189,31 +188,19 @@ void BSPWalkCircle(float x, float y, float radiusSquared, const Callback &callba
BSPNodeWalkCircle(level.HeadNode(), x, y, radiusSquared, callback);
}
int gl_SetDynModelLight(AActor *self, int dynlightindex)
// static so that we build up a reserve (memory allocations stop)
// For multithread processing each worker thread needs its own copy, though.
static thread_local TArray<ADynamicLight*> addedLightsArray;
void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata)
{
static FDynLightData modellightdata; // If this ever gets multithreaded, this variable must either be made non-static or thread_local.
// For deferred light mode this function gets called twice. First time for list upload, and second for draw.
if (gl.lightmethod == LM_DEFERRED && dynlightindex != -1)
{
gl_RenderState.SetDynLight(0, 0, 0);
return dynlightindex;
}
// Legacy render path gets the old flat model light
if (gl.lightmethod == LM_LEGACY)
{
gl_SetDynSpriteLight(self, nullptr);
return -1;
}
modellightdata.Clear();
if (self)
{
static std::vector<ADynamicLight*> addedLights; // static so that we build up a reserve (memory allocations stop)
auto &addedLights = addedLightsArray; // avoid going through the thread local storage for each use.
addedLights.clear();
addedLights.Clear();
float x = self->X();
float y = self->Y();
@ -240,7 +227,7 @@ int gl_SetDynModelLight(AActor *self, int dynlightindex)
if (std::find(addedLights.begin(), addedLights.end(), light) == addedLights.end()) // Check if we already added this light from a different subsector
{
modellightdata.AddLightToList(group, light);
addedLights.push_back(light);
addedLights.Push(light);
}
}
}
@ -248,12 +235,4 @@ int gl_SetDynModelLight(AActor *self, int dynlightindex)
}
});
}
dynlightindex = GLRenderer->mLights->UploadLights(modellightdata);
if (gl.lightmethod != LM_DEFERRED)
{
gl_RenderState.SetDynLight(0, 0, 0);
}
return dynlightindex;
}

View File

@ -19,8 +19,5 @@ struct particle_t;
// Light + color
void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *subsec);
void gl_SetDynSpriteLight(AActor *actor, particle_t *particle);
int gl_SetDynModelLight(AActor *self, int dynlightindex);
#endif

View File

@ -42,8 +42,8 @@
EXTERN_CVAR(Bool, gl_seamless)
FDynLightData lightdata;
// If we want to share the array to avoid constant allocations it needs to be thread local unless it'd be littered with expensive synchronization.
thread_local FDynLightData lightdata;
//==========================================================================
//
@ -489,8 +489,10 @@ void FDrawInfo::DrawDecal(GLDecal *gldecal)
{
// Note: This should be replaced with proper shader based lighting.
double x, y;
float out[3];
decal->GetXY(seg->sidedef, x, y);
gl_SetDynSpriteLight(nullptr, x, y, gldecal->zcenter, wall->sub);
hw_GetDynSpriteLight(nullptr, x, y, gldecal->zcenter, wall->sub, out);
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
}
// alpha color only has an effect when using an alpha texture.

View File

@ -44,6 +44,7 @@
#include "gl/models/gl_models.h"
#include "gl/renderer/gl_quaddrawer.h"
#include "gl/stereo3d/gl_stereo3d.h"
#include "gl/dynlights/gl_lightbuffer.h"
EXTERN_CVAR (Bool, r_drawplayersprites)
EXTERN_CVAR(Float, transsouls)
@ -449,10 +450,16 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
if (gl_lights && GLRenderer->mLightCount && FixedColormap == CM_DEFAULT && gl_light_sprites)
{
FSpriteModelFrame *smf = playermo->player->ReadyWeapon ? gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false) : nullptr;
if (smf)
if (smf && !gl.legacyMode)
{
gl_SetDynModelLight(playermo, weapondynlightindex[psp]);
}
else
gl_SetDynSpriteLight(playermo, NULL);
{
float out[3];
hw_GetDynSpriteLight(playermo, nullptr, out);
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
}
}
SetColor(ll, 0, cmc, trans, true);
}

View File

@ -311,7 +311,7 @@ public:
int dynlightindex;
bool SetupSubsectorLights(int pass, subsector_t * sub);
bool SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata);
void PutFlat(HWDrawInfo *di, bool fog = false);
void Process(HWDrawInfo *di, sector_t * model, int whichplane, bool notexture);
@ -431,5 +431,9 @@ inline float Dist2(float x1,float y1,float x2,float y2)
return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture, VSMatrix &mat);
bool hw_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture, VSMatrix &mat);
void hw_GetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *subsec, float *out);
void hw_GetDynSpriteLight(AActor *actor, particle_t *particle, float *out);
void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata);
extern const float LARGE_VALUE;

View File

@ -54,7 +54,7 @@ CVAR(Int, gl_breaksec, -1, 0)
//
//==========================================================================
bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture, VSMatrix &dest)
bool hw_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture, VSMatrix &dest)
{
// only manipulate the texture matrix if needed.
if (!secplane->Offs.isZero() ||
@ -92,9 +92,8 @@ bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte
// Flats
//
//==========================================================================
extern FDynLightData lightdata;
bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub)
bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata)
{
Plane p;