Revert "- removed the 8x8 block drawing code from softpoly"

This reverts commit d086c3d4dc.

# Conflicts:
#	src/polyrenderer/drawers/poly_triangle.cpp
#	src/polyrenderer/drawers/poly_triangle.h

The softpoly renderer crashed at high resolutions without them.
This commit is contained in:
drfrag666 2018-10-26 19:51:30 +02:00
parent 2c8b5e700f
commit eebd6c8319
9 changed files with 1173 additions and 216 deletions

View file

@ -48,7 +48,8 @@ void PolyZBuffer::Resize(int newwidth, int newheight)
{ {
width = newwidth; width = newwidth;
height = newheight; height = newheight;
values.resize(width * height); int count = BlockWidth() * BlockHeight();
values.resize(count * 64);
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -63,6 +64,14 @@ void PolyStencilBuffer::Clear(int newwidth, int newheight, uint8_t stencil_value
{ {
width = newwidth; width = newwidth;
height = newheight; height = newheight;
values.resize(width * height); int count = BlockWidth() * BlockHeight();
memset(Values(), stencil_value, width * height); values.resize(count * 64);
masks.resize(count);
uint8_t *v = Values();
uint32_t *m = Masks();
for (int i = 0; i < count; i++)
{
m[i] = 0xffffff00 | stencil_value;
}
} }

View file

@ -33,6 +33,8 @@ public:
void Resize(int newwidth, int newheight); 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; }
int BlockWidth() const { return (width + 7) / 8; }
int BlockHeight() const { return (height + 7) / 8; }
float *Values() { return values.data(); } float *Values() { return values.data(); }
private: private:
@ -48,10 +50,16 @@ public:
void Clear(int newwidth, int newheight, uint8_t stencil_value = 0); void Clear(int newwidth, int newheight, uint8_t stencil_value = 0);
int Width() const { return width; } int Width() const { return width; }
int Height() const { return height; } int Height() const { return height; }
int BlockWidth() const { return (width + 7) / 8; }
int BlockHeight() const { return (height + 7) / 8; }
uint8_t *Values() { return values.data(); } uint8_t *Values() { return values.data(); }
uint32_t *Masks() { return masks.data(); }
private: private:
int width; int width;
int height; int height;
// 8x8 blocks of stencil values, plus a mask for each block indicating if values are the same for early out stencil testing
std::vector<uint8_t> values; std::vector<uint8_t> values;
std::vector<uint32_t> masks;
}; };

View file

@ -53,7 +53,7 @@ bool PolyTriangleDrawer::IsBgra()
return isBgraRenderTarget; return isBgraRenderTarget;
} }
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, bool span_drawers)
{ {
uint8_t *dest = (uint8_t*)canvas->GetBuffer(); uint8_t *dest = (uint8_t*)canvas->GetBuffer();
int dest_width = canvas->GetWidth(); int dest_width = canvas->GetWidth();
@ -75,7 +75,7 @@ void PolyTriangleDrawer::SetViewport(const DrawerCommandQueuePtr &queue, int x,
dest_width = clamp(viewport_x + viewport_width, 0, dest_width - offsetx); dest_width = clamp(viewport_x + viewport_width, 0, dest_width - offsetx);
dest_height = clamp(viewport_y + viewport_height, 0, dest_height - offsety); dest_height = clamp(viewport_y + viewport_height, 0, dest_height - offsety);
queue->Push<PolySetViewportCommand>(viewport_x, viewport_y, viewport_width, viewport_height, dest, dest_width, dest_height, dest_pitch, dest_bgra); queue->Push<PolySetViewportCommand>(viewport_x, viewport_y, viewport_width, viewport_height, dest, dest_width, dest_height, dest_pitch, dest_bgra, span_drawers);
} }
void PolyTriangleDrawer::SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip, const Mat4f *objectToWorld) void PolyTriangleDrawer::SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip, const Mat4f *objectToWorld)
@ -115,7 +115,7 @@ void PolyTriangleDrawer::DrawElements(const DrawerCommandQueuePtr &queue, const
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
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, bool new_span_drawers)
{ {
viewport_x = x; viewport_x = x;
viewport_y = y; viewport_y = y;
@ -126,6 +126,7 @@ void PolyTriangleThreadData::SetViewport(int x, int y, int width, int height, ui
dest_height = new_dest_height; dest_height = new_dest_height;
dest_pitch = new_dest_pitch; dest_pitch = new_dest_pitch;
dest_bgra = new_dest_bgra; dest_bgra = new_dest_bgra;
span_drawers = new_span_drawers;
ccw = true; ccw = true;
weaponScene = false; weaponScene = false;
} }
@ -148,7 +149,9 @@ void PolyTriangleThreadData::DrawElements(const PolyDrawArgs &drawargs, const vo
args.clipbottom = dest_height; args.clipbottom = dest_height;
args.uniforms = &drawargs; args.uniforms = &drawargs;
args.destBgra = dest_bgra; args.destBgra = dest_bgra;
args.stencilbuffer = PolyStencilBuffer::Instance()->Values(); args.stencilPitch = PolyStencilBuffer::Instance()->BlockWidth();
args.stencilValues = PolyStencilBuffer::Instance()->Values();
args.stencilMasks = PolyStencilBuffer::Instance()->Masks();
args.zbuffer = PolyZBuffer::Instance()->Values(); args.zbuffer = PolyZBuffer::Instance()->Values();
args.depthOffset = weaponScene ? 1.0f : 0.0f; args.depthOffset = weaponScene ? 1.0f : 0.0f;
@ -201,7 +204,9 @@ void PolyTriangleThreadData::DrawArray(const PolyDrawArgs &drawargs, const void
args.clipbottom = dest_height; args.clipbottom = dest_height;
args.uniforms = &drawargs; args.uniforms = &drawargs;
args.destBgra = dest_bgra; args.destBgra = dest_bgra;
args.stencilbuffer = PolyStencilBuffer::Instance()->Values(); args.stencilPitch = PolyStencilBuffer::Instance()->BlockWidth();
args.stencilValues = PolyStencilBuffer::Instance()->Values();
args.stencilMasks = PolyStencilBuffer::Instance()->Masks();
args.zbuffer = PolyZBuffer::Instance()->Values(); args.zbuffer = PolyZBuffer::Instance()->Values();
args.depthOffset = weaponScene ? 1.0f : 0.0f; args.depthOffset = weaponScene ? 1.0f : 0.0f;
@ -424,7 +429,10 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *vert, boo
args->v3 = &clippedvert[i - 2]; args->v3 = &clippedvert[i - 2];
if (IsFrontfacing(args) == ccw && args->CalculateGradients()) if (IsFrontfacing(args) == ccw && args->CalculateGradients())
{ {
ScreenTriangle::Draw(args, this); if (!span_drawers)
ScreenTriangle::Draw(args, this);
else
ScreenTriangle::DrawSWRender(args, this);
} }
} }
} }
@ -437,7 +445,10 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *vert, boo
args->v3 = &clippedvert[i]; args->v3 = &clippedvert[i];
if (IsFrontfacing(args) != ccw && args->CalculateGradients()) if (IsFrontfacing(args) != ccw && args->CalculateGradients())
{ {
ScreenTriangle::Draw(args, this); if (!span_drawers)
ScreenTriangle::Draw(args, this);
else
ScreenTriangle::DrawSWRender(args, this);
} }
} }
} }
@ -681,14 +692,14 @@ void PolySetModelVertexShaderCommand::Execute(DrawerThread *thread)
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
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, bool span_drawers)
: 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), span_drawers(span_drawers)
{ {
} }
void PolySetViewportCommand::Execute(DrawerThread *thread) void PolySetViewportCommand::Execute(DrawerThread *thread)
{ {
PolyTriangleThreadData::Get(thread)->SetViewport(x, y, width, height, dest, dest_width, dest_height, dest_pitch, dest_bgra); PolyTriangleThreadData::Get(thread)->SetViewport(x, y, width, height, dest, dest_width, dest_height, dest_pitch, dest_bgra, span_drawers);
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -33,7 +33,7 @@ class PolyTriangleDrawer
{ {
public: public:
static void ClearBuffers(DCanvas *canvas); static void ClearBuffers(DCanvas *canvas);
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, bool span_drawers);
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);
static void SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable); static void SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable);
@ -49,7 +49,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 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, bool span_drawers);
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; }
void SetTwoSided(bool value) { twosided = value; } void SetTwoSided(bool value) { twosided = value; }
@ -95,6 +95,7 @@ private:
int modelFrame1 = -1; int modelFrame1 = -1;
int modelFrame2 = -1; int modelFrame2 = -1;
float modelInterpolationFactor = 0.0f; float modelInterpolationFactor = 0.0f;
bool span_drawers = false;
enum { max_additional_vertices = 16 }; enum { max_additional_vertices = 16 };
}; };
@ -160,7 +161,7 @@ private:
class PolySetViewportCommand : public DrawerCommand class PolySetViewportCommand : public DrawerCommand
{ {
public: public:
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(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra, bool span_drawers);
void Execute(DrawerThread *thread) override; void Execute(DrawerThread *thread) override;
@ -174,6 +175,7 @@ private:
int dest_height; int dest_height;
int dest_pitch; int dest_pitch;
bool dest_bgra; bool dest_bgra;
bool span_drawers;
}; };
class DrawPolyTrianglesCommand : public DrawerCommand class DrawPolyTrianglesCommand : public DrawerCommand

File diff suppressed because it is too large Load diff

View file

@ -52,7 +52,9 @@ struct TriDrawTriangleArgs
ShadedTriVertex *v3; ShadedTriVertex *v3;
int32_t clipright; int32_t clipright;
int32_t clipbottom; int32_t clipbottom;
uint8_t *stencilbuffer; uint8_t *stencilValues;
uint32_t *stencilMasks;
int32_t stencilPitch;
float *zbuffer; float *zbuffer;
const PolyDrawArgs *uniforms; const PolyDrawArgs *uniforms;
bool destBgra; bool destBgra;
@ -140,6 +142,7 @@ class ScreenTriangle
{ {
public: public:
static void Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); static void Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread);
static void DrawSWRender(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread);
static void(*SpanDrawers8[])(int y, int x0, int x1, const TriDrawTriangleArgs *args); static void(*SpanDrawers8[])(int y, int x0, int x1, const TriDrawTriangleArgs *args);
static void(*SpanDrawers32[])(int y, int x0, int x1, const TriDrawTriangleArgs *args); static void(*SpanDrawers32[])(int y, int x0, int x1, const TriDrawTriangleArgs *args);

View file

@ -210,11 +210,11 @@ void PolyRenderer::SetSceneViewport()
height = (screenblocks*SCREENHEIGHT / 10) & ~7; height = (screenblocks*SCREENHEIGHT / 10) & ~7;
int bottom = SCREENHEIGHT - (height + viewwindowy - ((height - viewheight) / 2)); int bottom = SCREENHEIGHT - (height + viewwindowy - ((height - viewheight) / 2));
PolyTriangleDrawer::SetViewport(Threads.MainThread()->DrawQueue, viewwindowx, SCREENHEIGHT - bottom - height, viewwidth, height, RenderTarget); PolyTriangleDrawer::SetViewport(Threads.MainThread()->DrawQueue, viewwindowx, SCREENHEIGHT - bottom - height, viewwidth, height, RenderTarget, false);
} }
else // Rendering to camera texture else // Rendering to camera texture
{ {
PolyTriangleDrawer::SetViewport(Threads.MainThread()->DrawQueue, 0, 0, RenderTarget->GetWidth(), RenderTarget->GetHeight(), RenderTarget); PolyTriangleDrawer::SetViewport(Threads.MainThread()->DrawQueue, 0, 0, RenderTarget->GetWidth(), RenderTarget->GetHeight(), RenderTarget, false);
} }
} }

View file

@ -270,7 +270,7 @@ namespace swrenderer
void Execute(DrawerThread *thread) override void Execute(DrawerThread *thread) override
{ {
auto zbuffer = PolyZBuffer::Instance(); auto zbuffer = PolyZBuffer::Instance();
int pitch = PolyStencilBuffer::Instance()->Width(); int pitch = PolyStencilBuffer::Instance()->BlockWidth() * 8;
float *values = zbuffer->Values() + y * pitch + x; float *values = zbuffer->Values() + y * pitch + x;
int cnt = count; int cnt = count;
@ -312,7 +312,7 @@ namespace swrenderer
return; return;
auto zbuffer = PolyZBuffer::Instance(); auto zbuffer = PolyZBuffer::Instance();
int pitch = PolyStencilBuffer::Instance()->Width(); int pitch = PolyStencilBuffer::Instance()->BlockWidth() * 8;
float *values = zbuffer->Values() + y * pitch; float *values = zbuffer->Values() + y * pitch;
int end = x2; int end = x2;

View file

@ -285,7 +285,7 @@ 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();
PolyTriangleDrawer::SetViewport(thread->DrawQueue, viewwindowx, viewwindowy, viewwidth, viewheight, thread->Viewport->RenderTarget); PolyTriangleDrawer::SetViewport(thread->DrawQueue, viewwindowx, viewwindowy, viewwidth, viewheight, thread->Viewport->RenderTarget, true);
// Cull things outside the range seen by this thread // Cull things outside the range seen by this thread
VisibleSegmentRenderer visitor; VisibleSegmentRenderer visitor;