mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 12:11:25 +00:00
- use the worker threads to clear the stencil buffer
This commit is contained in:
parent
8486cd2c0e
commit
de67393b4e
7 changed files with 66 additions and 20 deletions
|
@ -59,10 +59,9 @@ PolyStencilBuffer *PolyStencilBuffer::Instance()
|
||||||
return &buffer;
|
return &buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyStencilBuffer::Clear(int newwidth, int newheight, uint8_t stencil_value)
|
void PolyStencilBuffer::Resize(int newwidth, int newheight)
|
||||||
{
|
{
|
||||||
width = newwidth;
|
width = newwidth;
|
||||||
height = newheight;
|
height = newheight;
|
||||||
values.resize(width * height);
|
values.resize(width * height);
|
||||||
memset(Values(), stencil_value, width * height);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ class PolyStencilBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static PolyStencilBuffer *Instance();
|
static PolyStencilBuffer *Instance();
|
||||||
void Clear(int newwidth, int newheight, uint8_t stencil_value = 0);
|
void Resize(int newwidth, int newheight);
|
||||||
int Width() const { return width; }
|
int Width() const { return width; }
|
||||||
int Height() const { return height; }
|
int Height() const { return height; }
|
||||||
uint8_t *Values() { return values.data(); }
|
uint8_t *Values() { return values.data(); }
|
||||||
|
|
|
@ -41,9 +41,9 @@
|
||||||
|
|
||||||
static bool isBgraRenderTarget = false;
|
static bool isBgraRenderTarget = false;
|
||||||
|
|
||||||
void PolyTriangleDrawer::ClearBuffers(DCanvas *canvas)
|
void PolyTriangleDrawer::ResizeBuffers(DCanvas *canvas)
|
||||||
{
|
{
|
||||||
PolyStencilBuffer::Instance()->Clear(canvas->GetWidth(), canvas->GetHeight(), 0);
|
PolyStencilBuffer::Instance()->Resize(canvas->GetWidth(), canvas->GetHeight());
|
||||||
PolyZBuffer::Instance()->Resize(canvas->GetPitch(), canvas->GetHeight());
|
PolyZBuffer::Instance()->Resize(canvas->GetPitch(), canvas->GetHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,11 @@ bool PolyTriangleDrawer::IsBgra()
|
||||||
return isBgraRenderTarget;
|
return isBgraRenderTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PolyTriangleDrawer::ClearStencil(const DrawerCommandQueuePtr &queue, uint8_t value)
|
||||||
|
{
|
||||||
|
queue->Push<PolyClearStencilCommand>(value);
|
||||||
|
}
|
||||||
|
|
||||||
void PolyTriangleDrawer::SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas)
|
void PolyTriangleDrawer::SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas)
|
||||||
{
|
{
|
||||||
uint8_t *dest = (uint8_t*)canvas->GetPixels();
|
uint8_t *dest = (uint8_t*)canvas->GetPixels();
|
||||||
|
@ -99,6 +104,21 @@ void PolyTriangleDrawer::SetWeaponScene(const DrawerCommandQueuePtr &queue, bool
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void PolyTriangleThreadData::ClearStencil(uint8_t value)
|
||||||
|
{
|
||||||
|
auto buffer = PolyStencilBuffer::Instance();
|
||||||
|
int width = buffer->Width();
|
||||||
|
int height = buffer->Height();
|
||||||
|
uint8_t *data = buffer->Values();
|
||||||
|
|
||||||
|
data += core * width;
|
||||||
|
for (int y = core; y < height; y += num_cores)
|
||||||
|
{
|
||||||
|
memset(data, value, width);
|
||||||
|
data += num_cores * width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PolyTriangleThreadData::SetViewport(int x, int y, int width, int height, uint8_t *new_dest, int new_dest_width, int new_dest_height, int new_dest_pitch, bool new_dest_bgra)
|
void PolyTriangleThreadData::SetViewport(int x, int y, int width, int height, uint8_t *new_dest, int new_dest_width, int new_dest_height, int new_dest_pitch, bool new_dest_bgra)
|
||||||
{
|
{
|
||||||
viewport_x = x;
|
viewport_x = x;
|
||||||
|
@ -633,6 +653,17 @@ void PolySetWeaponSceneCommand::Execute(DrawerThread *thread)
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PolyClearStencilCommand::PolyClearStencilCommand(uint8_t value) : value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyClearStencilCommand::Execute(DrawerThread *thread)
|
||||||
|
{
|
||||||
|
PolyTriangleThreadData::Get(thread)->ClearStencil(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PolySetViewportCommand::PolySetViewportCommand(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra)
|
PolySetViewportCommand::PolySetViewportCommand(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra)
|
||||||
: x(x), y(y), width(width), height(height), dest(dest), dest_width(dest_width), dest_height(dest_height), dest_pitch(dest_pitch), dest_bgra(dest_bgra)
|
: x(x), y(y), width(width), height(height), dest(dest), dest_width(dest_width), dest_height(dest_height), dest_pitch(dest_pitch), dest_bgra(dest_bgra)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,8 @@
|
||||||
class PolyTriangleDrawer
|
class PolyTriangleDrawer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void ClearBuffers(DCanvas *canvas);
|
static void ResizeBuffers(DCanvas *canvas);
|
||||||
|
static void ClearStencil(const DrawerCommandQueuePtr &queue, uint8_t value);
|
||||||
static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas);
|
static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas);
|
||||||
static void SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw);
|
static void SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw);
|
||||||
static void SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided);
|
static void SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided);
|
||||||
|
@ -47,6 +48,7 @@ class PolyTriangleThreadData
|
||||||
public:
|
public:
|
||||||
PolyTriangleThreadData(int32_t core, int32_t num_cores) : core(core), num_cores(num_cores) { }
|
PolyTriangleThreadData(int32_t core, int32_t num_cores) : core(core), num_cores(num_cores) { }
|
||||||
|
|
||||||
|
void ClearStencil(uint8_t value);
|
||||||
void SetViewport(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra);
|
void SetViewport(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra);
|
||||||
void SetTransform(const Mat4f *objectToClip, const Mat4f *objectToWorld);
|
void SetTransform(const Mat4f *objectToClip, const Mat4f *objectToWorld);
|
||||||
void SetCullCCW(bool value) { ccw = value; }
|
void SetCullCCW(bool value) { ccw = value; }
|
||||||
|
@ -142,6 +144,18 @@ private:
|
||||||
bool value;
|
bool value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PolyClearStencilCommand : public DrawerCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PolyClearStencilCommand(uint8_t value);
|
||||||
|
|
||||||
|
void Execute(DrawerThread *thread) override;
|
||||||
|
FString DebugInfo() override { return "PolyClearStencilCommand"; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t value;
|
||||||
|
};
|
||||||
|
|
||||||
class PolySetViewportCommand : public DrawerCommand
|
class PolySetViewportCommand : public DrawerCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -162,7 +162,14 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
|
||||||
|
|
||||||
r_modelscene = r_models && Models.Size() > 0;
|
r_modelscene = r_models && Models.Size() > 0;
|
||||||
|
|
||||||
ClearBuffers();
|
NextStencilValue = 0;
|
||||||
|
Threads.Clear();
|
||||||
|
Threads.MainThread()->SectorPortals.clear();
|
||||||
|
Threads.MainThread()->LinePortals.clear();
|
||||||
|
Threads.MainThread()->TranslucentObjects.clear();
|
||||||
|
|
||||||
|
PolyTriangleDrawer::ResizeBuffers(RenderTarget);
|
||||||
|
PolyTriangleDrawer::ClearStencil(Threads.MainThread()->DrawQueue, 0);
|
||||||
SetSceneViewport();
|
SetSceneViewport();
|
||||||
|
|
||||||
PolyPortalViewpoint mainViewpoint = SetupPerspectiveMatrix();
|
PolyPortalViewpoint mainViewpoint = SetupPerspectiveMatrix();
|
||||||
|
@ -184,16 +191,6 @@ void PolyRenderer::RenderRemainingPlayerSprites()
|
||||||
PlayerSprites.RenderRemainingSprites();
|
PlayerSprites.RenderRemainingSprites();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyRenderer::ClearBuffers()
|
|
||||||
{
|
|
||||||
Threads.Clear();
|
|
||||||
PolyTriangleDrawer::ClearBuffers(RenderTarget);
|
|
||||||
NextStencilValue = 0;
|
|
||||||
Threads.MainThread()->SectorPortals.clear();
|
|
||||||
Threads.MainThread()->LinePortals.clear();
|
|
||||||
Threads.MainThread()->TranslucentObjects.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PolyRenderer::SetSceneViewport()
|
void PolyRenderer::SetSceneViewport()
|
||||||
{
|
{
|
||||||
using namespace swrenderer;
|
using namespace swrenderer;
|
||||||
|
|
|
@ -71,7 +71,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RenderActorView(AActor *actor, bool dontmaplines);
|
void RenderActorView(AActor *actor, bool dontmaplines);
|
||||||
void ClearBuffers();
|
|
||||||
void SetSceneViewport();
|
void SetSceneViewport();
|
||||||
|
|
||||||
RenderPolyPlayerSprites PlayerSprites;
|
RenderPolyPlayerSprites PlayerSprites;
|
||||||
|
|
|
@ -106,7 +106,10 @@ namespace swrenderer
|
||||||
|
|
||||||
r_modelscene = r_models && Models.Size() > 0;
|
r_modelscene = r_models && Models.Size() > 0;
|
||||||
if (r_modelscene)
|
if (r_modelscene)
|
||||||
PolyTriangleDrawer::ClearBuffers(viewport->RenderTarget);
|
{
|
||||||
|
PolyTriangleDrawer::ResizeBuffers(viewport->RenderTarget);
|
||||||
|
PolyTriangleDrawer::ClearStencil(MainThread()->DrawQueue, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (r_clearbuffer != 0 || r_debug_draw != 0)
|
if (r_clearbuffer != 0 || r_debug_draw != 0)
|
||||||
{
|
{
|
||||||
|
@ -271,6 +274,9 @@ namespace swrenderer
|
||||||
thread->OpaquePass->ResetFakingUnderwater(); // [RH] Hack to make windows into underwater areas possible
|
thread->OpaquePass->ResetFakingUnderwater(); // [RH] Hack to make windows into underwater areas possible
|
||||||
thread->Portal->SetMainPortal();
|
thread->Portal->SetMainPortal();
|
||||||
|
|
||||||
|
if (r_modelscene && thread->MainThread)
|
||||||
|
PolyTriangleDrawer::ClearStencil(MainThread()->DrawQueue, 0);
|
||||||
|
|
||||||
PolyTriangleDrawer::SetViewport(thread->DrawQueue, viewwindowx, viewwindowy, viewwidth, viewheight, thread->Viewport->RenderTarget);
|
PolyTriangleDrawer::SetViewport(thread->DrawQueue, viewwindowx, viewwindowy, viewwidth, viewheight, thread->Viewport->RenderTarget);
|
||||||
|
|
||||||
// Cull things outside the range seen by this thread
|
// Cull things outside the range seen by this thread
|
||||||
|
@ -376,7 +382,7 @@ namespace swrenderer
|
||||||
viewactive = true;
|
viewactive = true;
|
||||||
viewport->SetViewport(MainThread(), width, height, MainThread()->Viewport->viewwindow.WidescreenRatio);
|
viewport->SetViewport(MainThread(), width, height, MainThread()->Viewport->viewwindow.WidescreenRatio);
|
||||||
if (r_modelscene)
|
if (r_modelscene)
|
||||||
PolyTriangleDrawer::ClearBuffers(viewport->RenderTarget);
|
PolyTriangleDrawer::ResizeBuffers(viewport->RenderTarget);
|
||||||
|
|
||||||
// Render:
|
// Render:
|
||||||
RenderActorView(actor, dontmaplines);
|
RenderActorView(actor, dontmaplines);
|
||||||
|
|
Loading…
Reference in a new issue