summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/swgfx.h13
-rw-r--r--src/swgfx.c21
2 files changed, 34 insertions, 0 deletions
diff --git a/include/swgfx.h b/include/swgfx.h
index 9c3361d..72164b1 100644
--- a/include/swgfx.h
+++ b/include/swgfx.h
@@ -22,6 +22,8 @@ Multi-threading:
22#include <stddef.h> 22#include <stddef.h>
23#include <stdint.h> 23#include <stdint.h>
24 24
25#define SWGFX_PROFILING 1 // TODO: Move this to client project cmake.
26
25typedef float R; 27typedef float R;
26 28
27typedef struct sgVec2i { int x, y; } sgVec2i; 29typedef struct sgVec2i { int x, y; } sgVec2i;
@@ -66,6 +68,15 @@ typedef struct sgImage {
66 68
67typedef struct swgfx swgfx; 69typedef struct swgfx swgfx;
68 70
71#if SWGFX_PROFILING
72typedef struct sgCounters {
73 uint64_t frames; // Frames drawn.
74 uint64_t triangles3; // 3D triangles processed.
75 uint64_t triangles2; // 2D triangles processed.
76 uint64_t pixels; // Pixels written.
77} sgCounters;
78#endif // SWGFX_PROFILING
79
69size_t sgMem(int width, int height); // Get memory requirements. 80size_t sgMem(int width, int height); // Get memory requirements.
70swgfx* sgNew(int width, int height, void* mem); 81swgfx* sgNew(int width, int height, void* mem);
71void sgDel(swgfx**); 82void sgDel(swgfx**);
@@ -98,4 +109,6 @@ void sgTrianglesIndexedNonUniform(swgfx*, size_t numTris, const sgTriIdx* tris,
98void sgGamma (swgfx*, sgPixel*, int width, int height); 109void sgGamma (swgfx*, sgPixel*, int width, int height);
99void sgGammaInv(swgfx*, sgPixel*, int width, int height); 110void sgGammaInv(swgfx*, sgPixel*, int width, int height);
100 111
112sgCounters sgGetCounters(const swgfx*);
113
101void sgCheck(swgfx*); 114void sgCheck(swgfx*);
diff --git a/src/swgfx.c b/src/swgfx.c
index bbf9a5b..78d5434 100644
--- a/src/swgfx.c
+++ b/src/swgfx.c
@@ -19,6 +19,8 @@ Coordinate systems:
19#include <stdint.h> 19#include <stdint.h>
20#include <string.h> 20#include <string.h>
21 21
22
23
22static constexpr sgVec3 Up3 = (sgVec3){0,1,0}; 24static constexpr sgVec3 Up3 = (sgVec3){0,1,0};
23 25
24typedef struct sgViewport_t { int x0, y0, width, height; } sgViewport_t; 26typedef struct sgViewport_t { int x0, y0, width, height; } sgViewport_t;
@@ -50,6 +52,7 @@ typedef struct swgfx {
50 sgTextureFilter textureFilter; // Filter method for the texture. 52 sgTextureFilter textureFilter; // Filter method for the texture.
51 sgImage defaultTexture; // A default for when no texture is provided. 53 sgImage defaultTexture; // A default for when no texture is provided.
52 sgPixel defaultPixel; // The single-pixel of the default texture. 54 sgPixel defaultPixel; // The single-pixel of the default texture.
55 sgCounters counters;
53} swgfx; 56} swgfx;
54 57
55static inline int mod(int a, int m) { return (m + (a % m)) % m; } 58static inline int mod(int a, int m) { return (m + (a % m)) % m; }
@@ -306,6 +309,9 @@ static inline R* Depth(swgfx* gfx, int x, int y) {
306static inline void SetPixel(swgfx* gfx, const sgVec2i p, sgPixel colour) { 309static inline void SetPixel(swgfx* gfx, const sgVec2i p, sgPixel colour) {
307 assert(gfx); 310 assert(gfx);
308 *Pixel(gfx, p.x, p.y) = colour; 311 *Pixel(gfx, p.x, p.y) = colour;
312#if SWGFX_PROFILING
313 gfx->counters.pixels++;
314#endif // SWGFX_PROFILING
309} 315}
310 316
311static inline void SetDepth(swgfx* gfx, const sgVec2i p, R depth) { 317static inline void SetDepth(swgfx* gfx, const sgVec2i p, R depth) {
@@ -448,6 +454,9 @@ static void DrawTriangle2(swgfx* gfx, const sgTri2* const tri) {
448 } 454 }
449 } 455 }
450 } 456 }
457#if SWGFX_PROFILING
458 gfx->counters.triangles2++;
459#endif // SWGFX_PROFILING
451} 460}
452 461
453static inline sgVec4 PerspDivide(sgVec4 v) { 462static inline sgVec4 PerspDivide(sgVec4 v) {
@@ -677,6 +686,9 @@ static void DrawTriangle3(swgfx* gfx, const sgTri3* const tri) {
677 for (int i = 0; i < numTris; ++i) { 686 for (int i = 0; i < numTris; ++i) {
678 DrawTriangle3PostClip(gfx, &tris[i]); 687 DrawTriangle3PostClip(gfx, &tris[i]);
679 } 688 }
689#if SWGFX_PROFILING
690 gfx->counters.triangles3++;
691#endif // SWGFX_PROFILING
680} 692}
681 693
682#define is_pow2_or_0(X) ((X & (X - 1)) == 0) 694#define is_pow2_or_0(X) ((X & (X - 1)) == 0)
@@ -768,6 +780,10 @@ void sgPresent(swgfx* gfx, sgVec2i dimensions, sgScreenPixel* screen) {
768 } 780 }
769 } 781 }
770 } 782 }
783
784#if SWGFX_PROFILING
785 gfx->counters.frames++;
786#endif // SWGFX_PROFILING
771} 787}
772 788
773static void sgUpdateViewProjection(swgfx* gfx) { 789static void sgUpdateViewProjection(swgfx* gfx) {
@@ -930,6 +946,11 @@ static bool ViewportWithinBuffer(swgfx* gfx) {
930 ((vp.y0 + vp.height) <= gfx->dims.y); 946 ((vp.y0 + vp.height) <= gfx->dims.y);
931} 947}
932 948
949sgCounters sgGetCounters(const swgfx* gfx) {
950 assert(gfx);
951 return gfx->counters;
952}
953
933void sgCheck(swgfx* gfx) { 954void sgCheck(swgfx* gfx) {
934 assert(gfx); 955 assert(gfx);
935 assert(ViewportWithinBuffer(gfx)); 956 assert(ViewportWithinBuffer(gfx));