Make triangle drawers compatible with LLVMDrawers

This commit is contained in:
Magnus Norddahl 2016-11-11 19:54:27 +01:00
parent 3cc5cec5a0
commit 0938420871
5 changed files with 135 additions and 120 deletions

View file

@ -181,6 +181,85 @@ struct DrawSkyArgs
}
};
struct TriVertex
{
TriVertex() { }
TriVertex(float x, float y, float z, float w, float u, float v) : x(x), y(y), z(z), w(w) { varying[0] = u; varying[1] = v; }
enum { NumVarying = 2 };
float x, y, z, w;
float varying[NumVarying];
};
struct TriMatrix
{
static TriMatrix null();
static TriMatrix identity();
static TriMatrix translate(float x, float y, float z);
static TriMatrix scale(float x, float y, float z);
static TriMatrix rotate(float angle, float x, float y, float z);
static TriMatrix swapYZ();
static TriMatrix perspective(float fovy, float aspect, float near, float far);
static TriMatrix frustum(float left, float right, float bottom, float top, float near, float far);
static TriMatrix worldToView(); // Software renderer world to view space transform
static TriMatrix viewToClip(); // Software renderer shearing projection
TriVertex operator*(TriVertex v) const;
TriMatrix operator*(const TriMatrix &m) const;
float matrix[16];
};
struct TriUniforms
{
uint32_t light;
uint32_t subsectorDepth;
uint16_t light_alpha;
uint16_t light_red;
uint16_t light_green;
uint16_t light_blue;
uint16_t fade_alpha;
uint16_t fade_red;
uint16_t fade_green;
uint16_t fade_blue;
uint16_t desaturate;
uint32_t flags;
enum Flags
{
simple_shade = 1,
nearest_filter = 2,
diminishing_lighting = 4
};
TriMatrix objectToClip;
};
struct ScreenPolyTriangleDrawerArgs
{
uint8_t *dest;
int pitch;
TriVertex *v1;
TriVertex *v2;
TriVertex *v3;
int clipleft;
int clipright;
int cliptop;
int clipbottom;
const uint8_t *texturePixels;
int textureWidth;
int textureHeight;
uint32_t solidcolor;
const TriUniforms *uniforms;
uint8_t *stencilValues;
uint32_t *stencilMasks;
int stencilPitch;
uint8_t stencilTestValue;
uint8_t stencilWriteValue;
uint32_t *subsectorGBuffer;
};
class LLVMDrawers
{
public:

View file

@ -48,12 +48,12 @@ void PolyTriangleDrawer::draw(const PolyDrawArgs &args, PolyDrawVariant variant)
draw_arrays(args, variant, nullptr);
}
void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, PolyDrawVariant variant, DrawerThread *thread)
void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, PolyDrawVariant variant, WorkerThreadData *thread)
{
if (drawargs.vcount < 3)
return;
void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *);
void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, WorkerThreadData *);
switch (variant)
{
default:
@ -128,7 +128,7 @@ TriVertex PolyTriangleDrawer::shade_vertex(const TriUniforms &uniforms, TriVerte
return uniforms.objectToClip * v;
}
void PolyTriangleDrawer::draw_shaded_triangle(const TriVertex *vert, bool ccw, ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *))
void PolyTriangleDrawer::draw_shaded_triangle(const TriVertex *vert, bool ccw, ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, WorkerThreadData *))
{
// Cull, clip and generate additional vertices as needed
TriVertex clippedvert[max_additional_vertices];
@ -288,7 +288,7 @@ void PolyTriangleDrawer::clipedge(const TriVertex *verts, TriVertex *clippedvert
/////////////////////////////////////////////////////////////////////////////
void ScreenPolyTriangleDrawer::draw(const ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread)
void ScreenPolyTriangleDrawer::draw(const ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread)
{
uint8_t *dest = args->dest;
int pitch = args->pitch;
@ -373,7 +373,7 @@ void ScreenPolyTriangleDrawer::draw(const ScreenPolyTriangleDrawerArgs *args, Dr
for (int y = miny; y < maxy; y += q, dest += q * pitch)
{
// Is this row of blocks done by this thread?
if (thread && thread->skipped_by_thread(y / q)) continue;
if (thread && ((y / q) % thread->num_cores != thread->core)) continue;
for (int x = minx; x < maxx; x += q)
{
@ -523,7 +523,7 @@ void ScreenPolyTriangleDrawer::draw(const ScreenPolyTriangleDrawerArgs *args, Dr
}
}
void ScreenPolyTriangleDrawer::fill(const ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread)
void ScreenPolyTriangleDrawer::fill(const ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread)
{
uint8_t *dest = args->dest;
int pitch = args->pitch;
@ -594,7 +594,7 @@ void ScreenPolyTriangleDrawer::fill(const ScreenPolyTriangleDrawerArgs *args, Dr
for (int y = miny; y < maxy; y += q, dest += q * pitch)
{
// Is this row of blocks done by this thread?
if (thread && thread->skipped_by_thread(y / q)) continue;
if (thread && ((y / q) % thread->num_cores != thread->core)) continue;
for (int x = minx; x < maxx; x += q)
{
@ -681,7 +681,7 @@ void ScreenPolyTriangleDrawer::fill(const ScreenPolyTriangleDrawerArgs *args, Dr
}
}
void ScreenPolyTriangleDrawer::stencil(const ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread)
void ScreenPolyTriangleDrawer::stencil(const ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread)
{
const TriVertex &v1 = *args->v1;
const TriVertex &v2 = *args->v2;
@ -753,7 +753,7 @@ void ScreenPolyTriangleDrawer::stencil(const ScreenPolyTriangleDrawerArgs *args,
for (int y = miny; y < maxy; y += q)
{
// Is this row of blocks done by this thread?
if (thread && thread->skipped_by_thread(y / q)) continue;
if (thread && ((y / q) % thread->num_cores != thread->core)) continue;
for (int x = minx; x < maxx; x += q)
{
@ -833,7 +833,7 @@ void ScreenPolyTriangleDrawer::stencil(const ScreenPolyTriangleDrawerArgs *args,
}
}
void ScreenPolyTriangleDrawer::draw32(const ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread)
void ScreenPolyTriangleDrawer::draw32(const ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread)
{
uint32_t *dest = (uint32_t *)args->dest;
int pitch = args->pitch;
@ -926,7 +926,7 @@ void ScreenPolyTriangleDrawer::draw32(const ScreenPolyTriangleDrawerArgs *args,
for (int y = miny; y < maxy; y += q, dest += q * pitch, subsectorGBuffer += q * pitch)
{
// Is this row of blocks done by this thread?
if (thread->skipped_by_thread(y / q)) continue;
if ((y / q) % thread->num_cores != thread->core) continue;
for (int x = minx; x < maxx; x += q)
{
@ -1145,7 +1145,7 @@ void ScreenPolyTriangleDrawer::draw32(const ScreenPolyTriangleDrawerArgs *args,
}
}
void ScreenPolyTriangleDrawer::drawsubsector32(const ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread)
void ScreenPolyTriangleDrawer::drawsubsector32(const ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread)
{
uint32_t *dest = (uint32_t *)args->dest;
int pitch = args->pitch;
@ -1234,7 +1234,7 @@ void ScreenPolyTriangleDrawer::drawsubsector32(const ScreenPolyTriangleDrawerArg
for (int y = miny; y < maxy; y += q, dest += q * pitch, subsectorGBuffer += q * pitch)
{
// Is this row of blocks done by this thread?
if (thread->skipped_by_thread(y / q)) continue;
if ((y / q) % thread->num_cores != thread->core) continue;
for (int x = minx; x < maxx; x += q)
{
@ -1412,7 +1412,7 @@ void ScreenPolyTriangleDrawer::drawsubsector32(const ScreenPolyTriangleDrawerArg
}
}
void ScreenPolyTriangleDrawer::fill32(const ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread)
void ScreenPolyTriangleDrawer::fill32(const ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread)
{
uint32_t *dest = (uint32_t *)args->dest;
int pitch = args->pitch;
@ -1487,7 +1487,7 @@ void ScreenPolyTriangleDrawer::fill32(const ScreenPolyTriangleDrawerArgs *args,
for (int y = miny; y < maxy; y += q, dest += q * pitch)
{
// Is this row of blocks done by this thread?
if (thread->skipped_by_thread(y / q)) continue;
if ((y / q) % thread->num_cores != thread->core) continue;
for (int x = minx; x < maxx; x += q)
{
@ -1603,7 +1603,14 @@ DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, Pol
void DrawPolyTrianglesCommand::Execute(DrawerThread *thread)
{
PolyTriangleDrawer::draw_arrays(args, variant, thread);
WorkerThreadData thread_data;
thread_data.core = thread->core;
thread_data.num_cores = thread->num_cores;
thread_data.pass_start_y = thread->pass_start_y;
thread_data.pass_end_y = thread->pass_end_y;
thread_data.temp = thread->dc_temp_rgba;
PolyTriangleDrawer::draw_arrays(args, variant, &thread_data);
}
FString DrawPolyTrianglesCommand::DebugInfo()

View file

@ -73,8 +73,8 @@ public:
private:
static TriVertex shade_vertex(const TriUniforms &uniforms, TriVertex v);
static void draw_arrays(const PolyDrawArgs &args, PolyDrawVariant variant, DrawerThread *thread);
static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *));
static void draw_arrays(const PolyDrawArgs &args, PolyDrawVariant variant, WorkerThreadData *thread);
static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, WorkerThreadData *));
static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2);
static void clipedge(const TriVertex *verts, TriVertex *clippedvert, int &numclipvert);
@ -225,41 +225,17 @@ private:
std::vector<uint32_t> masks;
};
struct ScreenPolyTriangleDrawerArgs
{
uint8_t *dest;
int pitch;
TriVertex *v1;
TriVertex *v2;
TriVertex *v3;
int clipleft;
int clipright;
int cliptop;
int clipbottom;
const uint8_t *texturePixels;
int textureWidth;
int textureHeight;
uint32_t solidcolor;
const TriUniforms *uniforms;
uint8_t *stencilValues;
uint32_t *stencilMasks;
int stencilPitch;
uint8_t stencilTestValue;
uint8_t stencilWriteValue;
uint32_t *subsectorGBuffer;
};
class ScreenPolyTriangleDrawer
{
public:
static void draw(const ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread);
static void fill(const ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread);
static void draw(const ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread);
static void fill(const ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread);
static void stencil(const ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread);
static void stencil(const ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread);
static void draw32(const ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread);
static void drawsubsector32(const ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread);
static void fill32(const ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread);
static void draw32(const ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread);
static void drawsubsector32(const ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread);
static void fill32(const ScreenPolyTriangleDrawerArgs *args, WorkerThreadData *thread);
private:
static float gradx(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2);

View file

@ -75,7 +75,7 @@ void TriangleDrawer::queue_arrays(const TriUniforms &uniforms, const TriVertex *
DrawerCommandQueue::QueueCommand<DrawTrianglesCommand>(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, clipdata, texturePixels, textureWidth, textureHeight, solidcolor);
}
void TriangleDrawer::draw_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, DrawerThread *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, DrawerThread *))
void TriangleDrawer::draw_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, WorkerThreadData *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, WorkerThreadData *))
{
if (vcount < 3)
return;
@ -135,7 +135,7 @@ TriVertex TriangleDrawer::shade_vertex(const TriUniforms &uniforms, TriVertex v)
return uniforms.objectToClip * v;
}
void TriangleDrawer::draw_shaded_triangle(const TriVertex *vert, bool ccw, ScreenTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, DrawerThread *))
void TriangleDrawer::draw_shaded_triangle(const TriVertex *vert, bool ccw, ScreenTriangleDrawerArgs *args, WorkerThreadData *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, WorkerThreadData *))
{
// Cull, clip and generate additional vertices as needed
TriVertex clippedvert[max_additional_vertices];
@ -295,7 +295,7 @@ void TriangleDrawer::clipedge(const TriVertex *verts, TriVertex *clippedvert, in
/////////////////////////////////////////////////////////////////////////////
void ScreenTriangleDrawer::draw(const ScreenTriangleDrawerArgs *args, DrawerThread *thread)
void ScreenTriangleDrawer::draw(const ScreenTriangleDrawerArgs *args, WorkerThreadData *thread)
{
uint8_t *dest = args->dest;
int pitch = args->pitch;
@ -538,7 +538,7 @@ void ScreenTriangleDrawer::draw(const ScreenTriangleDrawerArgs *args, DrawerThre
}
}
void ScreenTriangleDrawer::fill(const ScreenTriangleDrawerArgs *args, DrawerThread *thread)
void ScreenTriangleDrawer::fill(const ScreenTriangleDrawerArgs *args, WorkerThreadData *thread)
{
uint8_t *dest = args->dest;
int pitch = args->pitch;
@ -706,7 +706,7 @@ void ScreenTriangleDrawer::fill(const ScreenTriangleDrawerArgs *args, DrawerThre
}
}
void ScreenTriangleDrawer::draw32(const ScreenTriangleDrawerArgs *args, DrawerThread *thread)
void ScreenTriangleDrawer::draw32(const ScreenTriangleDrawerArgs *args, WorkerThreadData *thread)
{
uint32_t *dest = (uint32_t *)args->dest;
int pitch = args->pitch;
@ -873,7 +873,7 @@ void ScreenTriangleDrawer::draw32(const ScreenTriangleDrawerArgs *args, DrawerTh
varyingStep[i] = (uint32_t)(step * 0x100000000LL);
}
if (!thread->skipped_by_thread(y + iy))
if ((y + iy) % thread->num_cores == thread->core)
{
for (int ix = x; ix < x + q; ix++)
{
@ -920,7 +920,7 @@ void ScreenTriangleDrawer::draw32(const ScreenTriangleDrawerArgs *args, DrawerTh
varyingStep[i] = (varyingTR[i] + varyingBR[i] * iy - varying[i]) * (1.0f / q);
}
if (!thread->skipped_by_thread(y + iy))
if ((y + iy) % thread->num_cores == thread->core)
{
for (int ix = x; ix < x + q; ix++)
{
@ -967,7 +967,7 @@ void ScreenTriangleDrawer::draw32(const ScreenTriangleDrawerArgs *args, DrawerTh
}
}
void ScreenTriangleDrawer::fill32(const ScreenTriangleDrawerArgs *args, DrawerThread *thread)
void ScreenTriangleDrawer::fill32(const ScreenTriangleDrawerArgs *args, WorkerThreadData *thread)
{
uint32_t *dest = (uint32_t *)args->dest;
int pitch = args->pitch;
@ -1088,7 +1088,7 @@ void ScreenTriangleDrawer::fill32(const ScreenTriangleDrawerArgs *args, DrawerTh
{
for (int iy = 0; iy < q; iy++)
{
if (!thread->skipped_by_thread(y + iy))
if ((y + iy) % thread->num_cores == thread->core)
{
for (int ix = x; ix < x + q; ix++)
{
@ -1111,7 +1111,7 @@ void ScreenTriangleDrawer::fill32(const ScreenTriangleDrawerArgs *args, DrawerTh
int CX2 = CY2;
int CX3 = CY3;
if (!thread->skipped_by_thread(y + iy))
if ((y + iy) % thread->num_cores == thread->core)
{
for (int ix = x; ix < x + q; ix++)
{
@ -1318,11 +1318,18 @@ void DrawTrianglesCommand::Execute(DrawerThread *thread)
thread->triangle_clip_bottom[clipleft + i] = clipdata[cliplength + i];
}
WorkerThreadData thread_data;
thread_data.core = thread->core;
thread_data.num_cores = thread->num_cores;
thread_data.pass_start_y = thread->pass_start_y;
thread_data.pass_end_y = thread->pass_end_y;
thread_data.temp = thread->dc_temp_rgba;
TriangleDrawer::draw_arrays(
uniforms, vinput, vcount, mode, ccw,
clipleft, clipright, thread->triangle_clip_top, thread->triangle_clip_bottom,
texturePixels, textureWidth, textureHeight, solidcolor,
thread, texturePixels ? ScreenTriangleDrawer::draw32 : ScreenTriangleDrawer::fill32);
&thread_data, texturePixels ? ScreenTriangleDrawer::draw32 : ScreenTriangleDrawer::fill32);
}
FString DrawTrianglesCommand::DebugInfo()

View file

@ -26,65 +26,11 @@
#include "r_draw.h"
#include "r_thread.h"
#include "r_compiler/llvmdrawers.h"
class FTexture;
struct ScreenTriangleDrawerArgs;
struct TriVertex
{
TriVertex() { }
TriVertex(float x, float y, float z, float w, float u, float v) : x(x), y(y), z(z), w(w) { varying[0] = u; varying[1] = v; }
enum { NumVarying = 2 };
float x, y, z, w;
float varying[NumVarying];
};
struct TriMatrix
{
static TriMatrix null();
static TriMatrix identity();
static TriMatrix translate(float x, float y, float z);
static TriMatrix scale(float x, float y, float z);
static TriMatrix rotate(float angle, float x, float y, float z);
static TriMatrix swapYZ();
static TriMatrix perspective(float fovy, float aspect, float near, float far);
static TriMatrix frustum(float left, float right, float bottom, float top, float near, float far);
static TriMatrix worldToView(); // Software renderer world to view space transform
static TriMatrix viewToClip(); // Software renderer shearing projection
TriVertex operator*(TriVertex v) const;
TriMatrix operator*(const TriMatrix &m) const;
float matrix[16];
};
struct TriUniforms
{
uint32_t light;
uint32_t subsectorDepth;
uint16_t light_alpha;
uint16_t light_red;
uint16_t light_green;
uint16_t light_blue;
uint16_t fade_alpha;
uint16_t fade_red;
uint16_t fade_green;
uint16_t fade_blue;
uint16_t desaturate;
uint32_t flags;
enum Flags
{
simple_shade = 1,
nearest_filter = 2,
diminishing_lighting = 4
};
TriMatrix objectToClip;
};
enum class TriangleDrawMode
{
Normal,
@ -100,8 +46,8 @@ public:
private:
static TriVertex shade_vertex(const TriUniforms &uniforms, TriVertex v);
static void draw_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, DrawerThread *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, DrawerThread *));
static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, ScreenTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, DrawerThread *));
static void draw_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, WorkerThreadData *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, WorkerThreadData *));
static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, ScreenTriangleDrawerArgs *args, WorkerThreadData *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, WorkerThreadData *));
static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2);
static void clipedge(const TriVertex *verts, TriVertex *clippedvert, int &numclipvert);
@ -133,11 +79,11 @@ struct ScreenTriangleDrawerArgs
class ScreenTriangleDrawer
{
public:
static void draw(const ScreenTriangleDrawerArgs *args, DrawerThread *thread);
static void fill(const ScreenTriangleDrawerArgs *args, DrawerThread *thread);
static void draw(const ScreenTriangleDrawerArgs *args, WorkerThreadData *thread);
static void fill(const ScreenTriangleDrawerArgs *args, WorkerThreadData *thread);
static void draw32(const ScreenTriangleDrawerArgs *args, DrawerThread *thread);
static void fill32(const ScreenTriangleDrawerArgs *args, DrawerThread *thread);
static void draw32(const ScreenTriangleDrawerArgs *args, WorkerThreadData *thread);
static void fill32(const ScreenTriangleDrawerArgs *args, WorkerThreadData *thread);
private:
static float gradx(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2);