- implement camera textures

This commit is contained in:
Magnus Norddahl 2019-05-29 05:45:19 +02:00
parent be5ecce598
commit a1229be5c6
17 changed files with 112 additions and 194 deletions

View file

@ -785,7 +785,6 @@ set ( SWRENDER_SOURCES
) )
set( POLYRENDER_SOURCES set( POLYRENDER_SOURCES
rendering/polyrenderer/drawers/poly_buffer.cpp
rendering/polyrenderer/drawers/poly_triangle.cpp rendering/polyrenderer/drawers/poly_triangle.cpp
rendering/polyrenderer/drawers/poly_draw_args.cpp rendering/polyrenderer/drawers/poly_draw_args.cpp
rendering/polyrenderer/drawers/screen_triangle.cpp rendering/polyrenderer/drawers/screen_triangle.cpp

View file

@ -102,9 +102,10 @@ void PolyFrameBuffer::CheckCanvas()
mCanvas.reset(new DCanvas(0, 0, true)); mCanvas.reset(new DCanvas(0, 0, true));
mCanvas->Resize(GetWidth(), GetHeight(), false); mCanvas->Resize(GetWidth(), GetHeight(), false);
mDepthStencil.reset();
mDepthStencil.reset(new PolyDepthStencil(GetWidth(), GetHeight()));
PolyTriangleDrawer::ResizeBuffers(mCanvas.get()); mRenderState->SetRenderTarget(GetCanvas(), GetDepthStencil());
PolyTriangleDrawer::SetViewport(GetDrawCommands(), 0, 0, mCanvas->GetWidth(), mCanvas->GetHeight(), mCanvas.get());
} }
} }
@ -308,42 +309,28 @@ sector_t *PolyFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor * ca
void PolyFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) void PolyFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV)
{ {
#if 0
// This doesn't need to clear the fake flat cache. It can be shared between camera textures and the main view of a scene. // This doesn't need to clear the fake flat cache. It can be shared between camera textures and the main view of a scene.
FMaterial *mat = FMaterial::ValidateTexture(tex, false); FMaterial *mat = FMaterial::ValidateTexture(tex, false);
auto BaseLayer = static_cast<PolyHardwareTexture*>(mat->GetLayer(0, 0)); auto BaseLayer = static_cast<PolyHardwareTexture*>(mat->GetLayer(0, 0));
int width = mat->TextureWidth(); int width = mat->TextureWidth();
int height = mat->TextureHeight(); int height = mat->TextureHeight();
PolyTextureImage *image = BaseLayer->GetImage(tex, 0, 0); DCanvas *image = BaseLayer->GetImage(tex, 0, 0);
PolyTextureImage *depthStencil = BaseLayer->GetDepthStencil(tex); PolyDepthStencil *depthStencil = BaseLayer->GetDepthStencil(tex);
mRenderState->SetRenderTarget(image, depthStencil);
mRenderState->EndRenderPass();
PolyImageTransition barrier0;
barrier0.addImage(image, Poly_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true);
barrier0.execute(GetDrawCommands());
mRenderState->SetRenderTarget(image->View.get(), depthStencil->View.get(), image->Image->width, image->Image->height, Poly_FORMAT_R8G8B8A8_UNORM, Poly_SAMPLE_COUNT_1_BIT);
IntRect bounds; IntRect bounds;
bounds.left = bounds.top = 0; bounds.left = bounds.top = 0;
bounds.width = MIN(mat->GetWidth(), image->Image->width); bounds.width = MIN(mat->GetWidth(), image->GetWidth());
bounds.height = MIN(mat->GetHeight(), image->Image->height); bounds.height = MIN(mat->GetHeight(), image->GetHeight());
FRenderViewpoint texvp; FRenderViewpoint texvp;
RenderViewpoint(texvp, Viewpoint, &bounds, FOV, (float)width / height, (float)width / height, false, false); RenderViewpoint(texvp, Viewpoint, &bounds, FOV, (float)width / height, (float)width / height, false, false);
mRenderState->EndRenderPass(); DrawerThreads::WaitForWorkers();
mRenderState->SetRenderTarget(GetCanvas(), GetDepthStencil());
PolyImageTransition barrier1;
barrier1.addImage(image, Poly_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false);
barrier1.execute(GetDrawCommands());
mRenderState->SetRenderTarget(GetBuffers()->SceneColor.View.get(), GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), Poly_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples());
tex->SetUpdated(true); tex->SetUpdated(true);
#endif
} }
void PolyFrameBuffer::DrawScene(HWDrawInfo *di, int drawmode) void PolyFrameBuffer::DrawScene(HWDrawInfo *di, int drawmode)

View file

@ -18,6 +18,7 @@ public:
RenderMemory *GetFrameMemory() { return &mFrameMemory; } RenderMemory *GetFrameMemory() { return &mFrameMemory; }
PolyRenderState *GetRenderState() { return mRenderState.get(); } PolyRenderState *GetRenderState() { return mRenderState.get(); }
DCanvas *GetCanvas() { return mCanvas.get(); } DCanvas *GetCanvas() { return mCanvas.get(); }
PolyDepthStencil *GetDepthStencil() { return mDepthStencil.get(); }
const DrawerCommandQueuePtr &GetDrawCommands(); const DrawerCommandQueuePtr &GetDrawCommands();
void FlushDrawCommands(); void FlushDrawCommands();
@ -75,6 +76,7 @@ private:
std::unique_ptr<PolyRenderState> mRenderState; std::unique_ptr<PolyRenderState> mRenderState;
std::unique_ptr<DCanvas> mCanvas; std::unique_ptr<DCanvas> mCanvas;
std::unique_ptr<PolyDepthStencil> mDepthStencil;
std::shared_ptr<DrawerCommandQueue> mDrawCommands; std::shared_ptr<DrawerCommandQueue> mDrawCommands;
RenderMemory mFrameMemory; RenderMemory mFrameMemory;
}; };

View file

@ -84,6 +84,17 @@ DCanvas *PolyHardwareTexture::GetImage(FTexture *tex, int translation, int flags
return mCanvas.get(); return mCanvas.get();
} }
PolyDepthStencil *PolyHardwareTexture::GetDepthStencil(FTexture *tex)
{
if (!mDepthStencil)
{
int w = tex->GetWidth();
int h = tex->GetHeight();
mDepthStencil.reset(new PolyDepthStencil(w, h));
}
return mDepthStencil.get();
}
void PolyHardwareTexture::AllocateBuffer(int w, int h, int texelsize) void PolyHardwareTexture::AllocateBuffer(int w, int h, int texelsize)
{ {
if (!mCanvas || mCanvas->GetWidth() != w || mCanvas->GetHeight() != h) if (!mCanvas || mCanvas->GetWidth() != w || mCanvas->GetHeight() != h)

View file

@ -27,6 +27,7 @@ public:
DCanvas *GetImage(const FMaterialState &state); DCanvas *GetImage(const FMaterialState &state);
DCanvas *GetImage(FTexture *tex, int translation, int flags); DCanvas *GetImage(FTexture *tex, int translation, int flags);
PolyDepthStencil *GetDepthStencil(FTexture *tex);
// Software renderer stuff // Software renderer stuff
void AllocateBuffer(int w, int h, int texelsize) override; void AllocateBuffer(int w, int h, int texelsize) override;
@ -43,4 +44,5 @@ private:
PolyHardwareTexture *Prev = nullptr; PolyHardwareTexture *Prev = nullptr;
PolyHardwareTexture *Next = nullptr; PolyHardwareTexture *Next = nullptr;
std::unique_ptr<DCanvas> mCanvas; std::unique_ptr<DCanvas> mCanvas;
std::unique_ptr<PolyDepthStencil> mDepthStencil;
}; };

View file

@ -125,10 +125,10 @@ void PolyRenderState::SetScissor(int x, int y, int w, int h)
{ {
x = 0; x = 0;
y = 0; y = 0;
w = fb->GetCanvas()->GetWidth(); w = mRenderTarget.Canvas->GetWidth();
h = fb->GetCanvas()->GetHeight(); h = mRenderTarget.Canvas->GetHeight();
} }
PolyTriangleDrawer::SetScissor(fb->GetDrawCommands(), x, fb->GetCanvas()->GetHeight() - y - h, w, h); PolyTriangleDrawer::SetScissor(fb->GetDrawCommands(), x, mRenderTarget.Canvas->GetHeight() - y - h, w, h);
} }
void PolyRenderState::SetViewport(int x, int y, int w, int h) void PolyRenderState::SetViewport(int x, int y, int w, int h)
@ -138,10 +138,10 @@ void PolyRenderState::SetViewport(int x, int y, int w, int h)
{ {
x = 0; x = 0;
y = 0; y = 0;
w = fb->GetCanvas()->GetWidth(); w = mRenderTarget.Canvas->GetWidth();
h = fb->GetCanvas()->GetHeight(); h = mRenderTarget.Canvas->GetHeight();
} }
PolyTriangleDrawer::SetViewport(fb->GetDrawCommands(), x, fb->GetCanvas()->GetHeight() - y - h, w, h, fb->GetCanvas()); PolyTriangleDrawer::SetViewport(fb->GetDrawCommands(), x, mRenderTarget.Canvas->GetHeight() - y - h, w, h, mRenderTarget.Canvas, mRenderTarget.DepthStencil);
} }
void PolyRenderState::EnableDepthTest(bool on) void PolyRenderState::EnableDepthTest(bool on)
@ -288,6 +288,13 @@ void PolyRenderState::ApplyMatrices()
} }
} }
void PolyRenderState::SetRenderTarget(DCanvas *canvas, PolyDepthStencil *depthStencil)
{
mRenderTarget.Canvas = canvas;
mRenderTarget.DepthStencil = depthStencil;
PolyTriangleDrawer::SetViewport(GetPolyFrameBuffer()->GetDrawCommands(), 0, 0, canvas->GetWidth(), canvas->GetHeight(), canvas, depthStencil);
}
void PolyRenderState::Bind(PolyDataBuffer *buffer, uint32_t offset, uint32_t length) void PolyRenderState::Bind(PolyDataBuffer *buffer, uint32_t offset, uint32_t length)
{ {
if (buffer->bindingpoint == VIEWPOINT_BINDINGPOINT) if (buffer->bindingpoint == VIEWPOINT_BINDINGPOINT)

View file

@ -40,8 +40,8 @@ public:
void EnableLineSmooth(bool on) override; void EnableLineSmooth(bool on) override;
void EnableDrawBuffers(int count) override; void EnableDrawBuffers(int count) override;
void SetRenderTarget(DCanvas *canvas, PolyDepthStencil *depthStencil);
void Bind(PolyDataBuffer *buffer, uint32_t offset, uint32_t length); void Bind(PolyDataBuffer *buffer, uint32_t offset, uint32_t length);
PolyVertexInputAssembly *GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs); PolyVertexInputAssembly *GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs);
private: private:
@ -63,4 +63,10 @@ private:
bool mDepthClamp = true; bool mDepthClamp = true;
int mTempTM = TM_NORMAL; int mTempTM = TM_NORMAL;
struct RenderTarget
{
DCanvas *Canvas = nullptr;
PolyDepthStencil *DepthStencil = nullptr;
} mRenderTarget;
}; };

View file

@ -1,67 +0,0 @@
/*
** Polygon Doom software renderer
** Copyright (c) 2016 Magnus Norddahl
**
** This software is provided 'as-is', without any express or implied
** warranty. In no event will the authors be held liable for any damages
** arising from the use of this software.
**
** Permission is granted to anyone to use this software for any purpose,
** including commercial applications, and to alter it and redistribute it
** freely, subject to the following restrictions:
**
** 1. The origin of this software must not be misrepresented; you must not
** claim that you wrote the original software. If you use this software
** in a product, an acknowledgment in the product documentation would be
** appreciated but is not required.
** 2. Altered source versions must be plainly marked as such, and must not be
** misrepresented as being the original software.
** 3. This notice may not be removed or altered from any source distribution.
**
*/
#include <stddef.h>
#include "templates.h"
#include "doomdef.h"
#include "w_wad.h"
#include "v_video.h"
#include "doomstat.h"
#include "st_stuff.h"
#include "g_game.h"
#include "g_level.h"
#include "r_data/r_translate.h"
#include "v_palette.h"
#include "r_data/colormaps.h"
#include "poly_buffer.h"
#include "screen_triangle.h"
/////////////////////////////////////////////////////////////////////////////
PolyZBuffer *PolyZBuffer::Instance()
{
static PolyZBuffer buffer;
return &buffer;
}
void PolyZBuffer::Resize(int newwidth, int newheight)
{
width = newwidth;
height = newheight;
values.resize(width * height);
}
/////////////////////////////////////////////////////////////////////////////
PolyStencilBuffer *PolyStencilBuffer::Instance()
{
static PolyStencilBuffer buffer;
return &buffer;
}
void PolyStencilBuffer::Resize(int newwidth, int newheight)
{
width = newwidth;
height = newheight;
values.resize(width * height);
}

View file

@ -1,55 +0,0 @@
/*
** Polygon Doom software renderer
** Copyright (c) 2016 Magnus Norddahl
**
** This software is provided 'as-is', without any express or implied
** warranty. In no event will the authors be held liable for any damages
** arising from the use of this software.
**
** Permission is granted to anyone to use this software for any purpose,
** including commercial applications, and to alter it and redistribute it
** freely, subject to the following restrictions:
**
** 1. The origin of this software must not be misrepresented; you must not
** claim that you wrote the original software. If you use this software
** in a product, an acknowledgment in the product documentation would be
** appreciated but is not required.
** 2. Altered source versions must be plainly marked as such, and must not be
** misrepresented as being the original software.
** 3. This notice may not be removed or altered from any source distribution.
**
*/
#pragma once
#include <vector>
class PolyZBuffer
{
public:
static PolyZBuffer *Instance();
void Resize(int newwidth, int newheight);
int Width() const { return width; }
int Height() const { return height; }
float *Values() { return values.data(); }
private:
int width;
int height;
std::vector<float> values;
};
class PolyStencilBuffer
{
public:
static PolyStencilBuffer *Instance();
void Resize(int newwidth, int newheight);
int Width() const { return width; }
int Height() const { return height; }
uint8_t *Values() { return values.data(); }
private:
int width;
int height;
std::vector<uint8_t> values;
};

View file

@ -41,12 +41,6 @@
static bool isBgraRenderTarget = false; static bool isBgraRenderTarget = false;
void PolyTriangleDrawer::ResizeBuffers(DCanvas *canvas)
{
PolyStencilBuffer::Instance()->Resize(canvas->GetWidth(), canvas->GetHeight());
PolyZBuffer::Instance()->Resize(canvas->GetPitch(), canvas->GetHeight());
}
bool PolyTriangleDrawer::IsBgra() bool PolyTriangleDrawer::IsBgra()
{ {
return isBgraRenderTarget; return isBgraRenderTarget;
@ -62,7 +56,7 @@ void PolyTriangleDrawer::ClearStencil(const DrawerCommandQueuePtr &queue, uint8_
queue->Push<PolyClearStencilCommand>(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, PolyDepthStencil *depthstencil)
{ {
uint8_t *dest = (uint8_t*)canvas->GetPixels(); uint8_t *dest = (uint8_t*)canvas->GetPixels();
int dest_width = canvas->GetWidth(); int dest_width = canvas->GetWidth();
@ -71,7 +65,7 @@ void PolyTriangleDrawer::SetViewport(const DrawerCommandQueuePtr &queue, int x,
bool dest_bgra = canvas->IsBgra(); bool dest_bgra = canvas->IsBgra();
isBgraRenderTarget = dest_bgra; isBgraRenderTarget = dest_bgra;
queue->Push<PolySetViewportCommand>(x, y, width, height, dest, dest_width, dest_height, dest_pitch, dest_bgra); queue->Push<PolySetViewportCommand>(x, y, width, height, dest, dest_width, dest_height, dest_pitch, dest_bgra, depthstencil);
} }
void PolyTriangleDrawer::SetInputAssembly(const DrawerCommandQueuePtr &queue, PolyInputAssembly *input) void PolyTriangleDrawer::SetInputAssembly(const DrawerCommandQueuePtr &queue, PolyInputAssembly *input)
@ -223,10 +217,9 @@ void PolyTriangleDrawer::DrawIndexed(const DrawerCommandQueuePtr &queue, int ind
void PolyTriangleThreadData::ClearDepth(float value) void PolyTriangleThreadData::ClearDepth(float value)
{ {
auto buffer = PolyZBuffer::Instance(); int width = depthstencil->Width();
int width = buffer->Width(); int height = depthstencil->Height();
int height = buffer->Height(); float *data = depthstencil->DepthValues();
float *data = buffer->Values();
int skip = skipped_by_thread(0); int skip = skipped_by_thread(0);
int count = count_for_thread(0, height); int count = count_for_thread(0, height);
@ -242,10 +235,9 @@ void PolyTriangleThreadData::ClearDepth(float value)
void PolyTriangleThreadData::ClearStencil(uint8_t value) void PolyTriangleThreadData::ClearStencil(uint8_t value)
{ {
auto buffer = PolyStencilBuffer::Instance(); int width = depthstencil->Width();
int width = buffer->Width(); int height = depthstencil->Height();
int height = buffer->Height(); uint8_t *data = depthstencil->StencilValues();
uint8_t *data = buffer->Values();
int skip = skipped_by_thread(0); int skip = skipped_by_thread(0);
int count = count_for_thread(0, height); int count = count_for_thread(0, height);
@ -258,7 +250,7 @@ void PolyTriangleThreadData::ClearStencil(uint8_t value)
} }
} }
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, PolyDepthStencil *new_depthstencil)
{ {
viewport_x = x; viewport_x = x;
viewport_y = y; viewport_y = y;
@ -269,6 +261,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;
depthstencil = new_depthstencil;
UpdateClip(); UpdateClip();
} }

View file

@ -26,23 +26,19 @@
#include "swrenderer/drawers/r_thread.h" #include "swrenderer/drawers/r_thread.h"
#include "polyrenderer/drawers/screen_triangle.h" #include "polyrenderer/drawers/screen_triangle.h"
#include "polyrenderer/math/gpu_types.h" #include "polyrenderer/math/gpu_types.h"
#include "polyrenderer/drawers/poly_buffer.h"
#include "polyrenderer/drawers/poly_draw_args.h" #include "polyrenderer/drawers/poly_draw_args.h"
#include "polyrenderer/drawers/poly_vertex_shader.h" #include "polyrenderer/drawers/poly_vertex_shader.h"
class DCanvas; class DCanvas;
class PolyDrawerCommand; class PolyDrawerCommand;
class PolyInputAssembly; class PolyInputAssembly;
class PolyPipeline; class PolyDepthStencil;
struct PolyPushConstants; struct PolyPushConstants;
class PolyTriangleDrawer class PolyTriangleDrawer
{ {
public: public:
static void ResizeBuffers(DCanvas *canvas); static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas, PolyDepthStencil *depthStencil);
static void ClearDepth(const DrawerCommandQueuePtr &queue, float value);
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 SetInputAssembly(const DrawerCommandQueuePtr &queue, PolyInputAssembly *input); static void SetInputAssembly(const DrawerCommandQueuePtr &queue, PolyInputAssembly *input);
static void SetVertexBuffer(const DrawerCommandQueuePtr &queue, const void *vertices); static void SetVertexBuffer(const DrawerCommandQueuePtr &queue, const void *vertices);
static void SetIndexBuffer(const DrawerCommandQueuePtr &queue, const void *elements); static void SetIndexBuffer(const DrawerCommandQueuePtr &queue, const void *elements);
@ -64,6 +60,8 @@ public:
static void SetShader(const DrawerCommandQueuePtr &queue, int specialEffect, int effectState, bool alphaTest); static void SetShader(const DrawerCommandQueuePtr &queue, int specialEffect, int effectState, bool alphaTest);
static void PushStreamData(const DrawerCommandQueuePtr &queue, const StreamData &data, const PolyPushConstants &constants); static void PushStreamData(const DrawerCommandQueuePtr &queue, const StreamData &data, const PolyPushConstants &constants);
static void PushMatrices(const DrawerCommandQueuePtr &queue, const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix); static void PushMatrices(const DrawerCommandQueuePtr &queue, const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix);
static void ClearDepth(const DrawerCommandQueuePtr &queue, float value);
static void ClearStencil(const DrawerCommandQueuePtr &queue, uint8_t value);
static void Draw(const DrawerCommandQueuePtr &queue, int index, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles); static void Draw(const DrawerCommandQueuePtr &queue, int index, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles);
static void DrawIndexed(const DrawerCommandQueuePtr &queue, int index, int count, PolyDrawMode mode = PolyDrawMode::Triangles); static void DrawIndexed(const DrawerCommandQueuePtr &queue, int index, int count, PolyDrawMode mode = PolyDrawMode::Triangles);
static bool IsBgra(); static bool IsBgra();
@ -77,6 +75,23 @@ public:
static void PushDrawArgs(const DrawerCommandQueuePtr &queue, const PolyDrawArgs &args); static void PushDrawArgs(const DrawerCommandQueuePtr &queue, const PolyDrawArgs &args);
}; };
class PolyDepthStencil
{
public:
PolyDepthStencil(int width, int height) : width(width), height(height), depthbuffer(width * height), stencilbuffer(width * height) { }
int Width() const { return width; }
int Height() const { return height; }
float *DepthValues() { return depthbuffer.data(); }
uint8_t *StencilValues() { return stencilbuffer.data(); }
private:
int width;
int height;
std::vector<float> depthbuffer;
std::vector<uint8_t> stencilbuffer;
};
struct PolyPushConstants struct PolyPushConstants
{ {
int uTextureMode; int uTextureMode;
@ -117,7 +132,7 @@ public:
void ClearDepth(float value); void ClearDepth(float value);
void ClearStencil(uint8_t value); 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, PolyDepthStencil *depthstencil);
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; }
@ -198,6 +213,8 @@ public:
int dest_height = 0; int dest_height = 0;
bool dest_bgra = false; bool dest_bgra = false;
uint8_t *dest = nullptr; uint8_t *dest = nullptr;
PolyDepthStencil *depthstencil = nullptr;
float depthbias = 0.0f; float depthbias = 0.0f;
int viewport_y = 0; int viewport_y = 0;
@ -521,9 +538,9 @@ private:
class PolySetViewportCommand : public PolyDrawerCommand class PolySetViewportCommand : public PolyDrawerCommand
{ {
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, PolyDepthStencil *depthstencil)
: 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), depthstencil(depthstencil) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetViewport(x, y, width, height, dest, dest_width, dest_height, dest_pitch, dest_bgra); } void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetViewport(x, y, width, height, dest, dest_width, dest_height, dest_pitch, dest_bgra, depthstencil); }
private: private:
int x; int x;
@ -535,6 +552,7 @@ private:
int dest_height; int dest_height;
int dest_pitch; int dest_pitch;
bool dest_bgra; bool dest_bgra;
PolyDepthStencil *depthstencil;
}; };
class PolySetViewpointUniformsCommand : public PolyDrawerCommand class PolySetViewpointUniformsCommand : public PolyDrawerCommand

View file

@ -201,16 +201,16 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa
v1X = args->v1->x; v1X = args->v1->x;
v1Y = args->v1->y; v1Y = args->v1->y;
v1W = args->v1->w; v1W = args->v1->w;
zbuffer = PolyZBuffer::Instance()->Values(); zbuffer = thread->depthstencil->DepthValues();
} }
if ((OptT::Flags & SWTRI_StencilTest) || (OptT::Flags & SWTRI_WriteStencil)) if ((OptT::Flags & SWTRI_StencilTest) || (OptT::Flags & SWTRI_WriteStencil))
{ {
stencilbuffer = PolyStencilBuffer::Instance()->Values(); stencilbuffer = thread->depthstencil->StencilValues();
} }
if ((OptT::Flags & SWTRI_StencilTest) || (OptT::Flags & SWTRI_WriteStencil) || (OptT::Flags & SWTRI_DepthTest) || (OptT::Flags & SWTRI_WriteDepth)) if ((OptT::Flags & SWTRI_StencilTest) || (OptT::Flags & SWTRI_WriteStencil) || (OptT::Flags & SWTRI_DepthTest) || (OptT::Flags & SWTRI_WriteDepth))
pitch = PolyStencilBuffer::Instance()->Width(); pitch = thread->depthstencil->Width();
if (OptT::Flags & SWTRI_StencilTest) if (OptT::Flags & SWTRI_StencilTest)
stencilTestValue = args->uniforms->StencilTestValue(); stencilTestValue = args->uniforms->StencilTestValue();

View file

@ -1,5 +1,4 @@
#include "../swrenderer/textures/r_swtexture.h" #include "../swrenderer/textures/r_swtexture.h"
#include "drawers/poly_buffer.cpp"
#include "drawers/poly_draw_args.cpp" #include "drawers/poly_draw_args.cpp"
#include "drawers/poly_triangle.cpp" #include "drawers/poly_triangle.cpp"
#include "drawers/screen_triangle.cpp" #include "drawers/screen_triangle.cpp"

View file

@ -51,7 +51,7 @@
#include "r_draw_pal.h" #include "r_draw_pal.h"
#include "r_thread.h" #include "r_thread.h"
#include "swrenderer/scene/r_light.h" #include "swrenderer/scene/r_light.h"
#include "polyrenderer/drawers/poly_buffer.h" #include "polyrenderer/drawers/poly_triangle.h"
CVAR(Bool, r_dynlights, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR(Bool, r_dynlights, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR(Bool, r_fuzzscale, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR(Bool, r_fuzzscale, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
@ -270,9 +270,9 @@ namespace swrenderer
void Execute(DrawerThread *thread) override void Execute(DrawerThread *thread) override
{ {
auto zbuffer = PolyZBuffer::Instance(); auto zbuffer = PolyTriangleThreadData::Get(thread)->depthstencil;
int pitch = PolyStencilBuffer::Instance()->Width(); int pitch = zbuffer->Width();
float *values = zbuffer->Values() + y * pitch + x; float *values = zbuffer->DepthValues() + y * pitch + x;
int cnt = count; int cnt = count;
values = thread->dest_for_thread(y, pitch, values); values = thread->dest_for_thread(y, pitch, values);
@ -312,9 +312,9 @@ namespace swrenderer
if (thread->skipped_by_thread(y)) if (thread->skipped_by_thread(y))
return; return;
auto zbuffer = PolyZBuffer::Instance(); auto zbuffer = PolyTriangleThreadData::Get(thread)->depthstencil;
int pitch = PolyStencilBuffer::Instance()->Width(); int pitch = zbuffer->Width();
float *values = zbuffer->Values() + y * pitch; float *values = zbuffer->DepthValues() + y * pitch;
int end = x2; int end = x2;
if (idepth1 == idepth2) if (idepth1 == idepth2)

View file

@ -107,7 +107,12 @@ namespace swrenderer
r_modelscene = r_models && Models.Size() > 0; r_modelscene = r_models && Models.Size() > 0;
if (r_modelscene) if (r_modelscene)
{ {
PolyTriangleDrawer::ResizeBuffers(viewport->RenderTarget); if (!DepthStencil || DepthStencil->Width() != viewport->RenderTarget->GetWidth() || DepthStencil->Height() != viewport->RenderTarget->GetHeight())
{
DepthStencil.reset();
DepthStencil.reset(new PolyDepthStencil(viewport->RenderTarget->GetWidth(), viewport->RenderTarget->GetHeight()));
}
PolyTriangleDrawer::SetViewport(MainThread()->DrawQueue, 0, 0, viewport->RenderTarget->GetWidth(), viewport->RenderTarget->GetHeight(), viewport->RenderTarget, DepthStencil.get());
PolyTriangleDrawer::ClearStencil(MainThread()->DrawQueue, 0); PolyTriangleDrawer::ClearStencil(MainThread()->DrawQueue, 0);
} }
@ -275,7 +280,7 @@ namespace swrenderer
if (r_modelscene && thread->MainThread) if (r_modelscene && thread->MainThread)
PolyTriangleDrawer::ClearStencil(MainThread()->DrawQueue, 0); 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, DepthStencil.get());
PolyTriangleDrawer::SetScissor(thread->DrawQueue, viewwindowx, viewwindowy, viewwidth, viewheight); PolyTriangleDrawer::SetScissor(thread->DrawQueue, viewwindowx, viewwindowy, viewwidth, viewheight);
// Cull things outside the range seen by this thread // Cull things outside the range seen by this thread
@ -372,7 +377,13 @@ namespace swrenderer
viewactive = true; viewactive = true;
viewport->SetViewport(actor->Level, MainThread(), width, height, MainThread()->Viewport->viewwindow.WidescreenRatio); viewport->SetViewport(actor->Level, MainThread(), width, height, MainThread()->Viewport->viewwindow.WidescreenRatio);
if (r_modelscene) if (r_modelscene)
PolyTriangleDrawer::ResizeBuffers(viewport->RenderTarget); {
if (!DepthStencil || DepthStencil->Width() != viewport->RenderTarget->GetWidth() || DepthStencil->Height() != viewport->RenderTarget->GetHeight())
{
DepthStencil.reset();
DepthStencil.reset(new PolyDepthStencil(viewport->RenderTarget->GetWidth(), viewport->RenderTarget->GetHeight()));
}
}
// Render: // Render:
RenderActorView(actor, false, dontmaplines); RenderActorView(actor, false, dontmaplines);

View file

@ -32,6 +32,8 @@
extern cycle_t FrameCycles; extern cycle_t FrameCycles;
class PolyDepthStencil;
namespace swrenderer namespace swrenderer
{ {
extern cycle_t WallCycles, PlaneCycles, MaskedCycles, DrawerWaitCycles; extern cycle_t WallCycles, PlaneCycles, MaskedCycles, DrawerWaitCycles;
@ -67,6 +69,7 @@ namespace swrenderer
bool dontmaplines = false; bool dontmaplines = false;
int clearcolor = 0; int clearcolor = 0;
std::unique_ptr<PolyDepthStencil> DepthStencil;
std::vector<std::unique_ptr<RenderThread>> Threads; std::vector<std::unique_ptr<RenderThread>> Threads;
std::mutex start_mutex; std::mutex start_mutex;
std::condition_variable start_condition; std::condition_variable start_condition;

View file

@ -11,6 +11,8 @@
#define MINZ double((2048*4) / double(1 << 20)) #define MINZ double((2048*4) / double(1 << 20))
class PolyDepthStencil;
namespace swrenderer namespace swrenderer
{ {
class RenderThread; class RenderThread;