mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-03 09:23:19 +00:00
- implement camera textures
This commit is contained in:
parent
be5ecce598
commit
a1229be5c6
17 changed files with 112 additions and 194 deletions
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
};
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue