diff --git a/src/Graphics_Dreamcast.c b/src/Graphics_Dreamcast.c index ac8629234..b03bf5325 100644 --- a/src/Graphics_Dreamcast.c +++ b/src/Graphics_Dreamcast.c @@ -787,7 +787,7 @@ void DrawQuads(int count, void* src) { list->length += (end - beg); if (list != direct) return; - SceneListSubmit((Vertex*)list->data, list->length); + SubmitCommands((Vertex*)list->data, list->length); list->length = 0; } @@ -885,7 +885,7 @@ static void SubmitList(struct CommandsList* list) { if (!list->length || list == direct) return; BeginList(list->list_type); - SceneListSubmit((Vertex*)list->data, list->length); + SubmitCommands((Vertex*)list->data, list->length); FinishList(); list->length = 0; } diff --git a/third_party/gldc/gldc.h b/third_party/gldc/gldc.h index 375b5378e..02f4b8342 100644 --- a/third_party/gldc/gldc.h +++ b/third_party/gldc/gldc.h @@ -21,6 +21,6 @@ typedef struct { uint16_t height; } TextureObject; -void GLDC_NO_INLINE SceneListSubmit(Vertex* v2, int n); +void GLDC_NO_INLINE SubmitCommands(Vertex* v3, int n); #endif // PRIVATE_H diff --git a/third_party/gldc/sh4.c b/third_party/gldc/sh4.c index 241a3a992..2c3278fb2 100644 --- a/third_party/gldc/sh4.c +++ b/third_party/gldc/sh4.c @@ -2,47 +2,43 @@ #include #include "gldc.h" -static GLDC_FORCE_INLINE void PushVertex(Vertex* v, volatile Vertex* dst) { - asm volatile ( -"fmov.d @%0+, dr0\n" // LS, FX = *src, src += 8 -"fmov.d @%0+, dr2\n" // LS, YW = *src, src += 8 -"add #32, %1 \n" // EX, dst += 32 -"fmul fr3, fr3\n" // FE, W = W * W -"fmov.d @%0+, dr4\n" // LS, UV = *src, src += 8 -"fmov.d @%0+, dr6\n" // LS, C? = *src, src += 8 -"fsrra fr3\n" // FE, W = 1/sqrt(W*W) ~ 1/W -"fmov.d dr6, @-%1\n" // LS, dst -= 8, *dst = C? -"fmov.d dr4, @-%1\n" // LS, dst -= 8, *dst = UV -"fmul fr3, fr2\n" // FE, Y = W * Y -"add #-32, %0 \n" // EX, src -= 32 -"fmov.d dr2, @-%1\n" // LS, dst -= 8, *dst = YW -"fmul fr3, fr1\n" // FE, Y = X * X -"fmov.d dr0, @-%1\n" // LS, dst -= 8, *dst = FX -"pref @%1 \n" // LS, flush store queue - : - : "r" (v), "r" (dst) - : "memory", "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7" +#define PushVertex(src, dst) __asm__ volatile ( \ +"fmov.d @%1+, dr0 ! LS, FX = *src, src += 8\n" \ +"fmov.d @%1+, dr2 ! LS, YW = *src, src += 8\n" \ +"add #64, %0 ! EX, dst += 64\n" \ +"fmul fr3, fr3 ! FE, W = W * W\n" \ +"fmov.d @%1+, dr4 ! LS, UV = *src, src += 8\n" \ +"fmov.d @%1+, dr6 ! LS, C? = *src, src += 8\n" \ +"fsrra fr3 ! FE, W = 1/sqrt(W*W) ~ 1/W\n" \ +"fmov.d dr6, @-%0 ! LS, dst -= 8, *dst = C?\n" \ +"fmov.d dr4, @-%0 ! LS, dst -= 8, *dst = UV\n" \ +"fmul fr3, fr2 ! FE, Y = W * Y\n" \ +"add #-32, %1 ! EX, src -= 32\n" \ +"fmov.d dr2, @-%0 ! LS, dst -= 8, *dst = YW\n" \ +"fmul fr3, fr1 ! FE, Y = X * X\n" \ +"fmov.d dr0, @-%0 ! LS, dst -= 8, *dst = FX\n" \ +"pref @%0 ! LS, flush store queue\n" \ + : "+r" (dst) \ + : "r" (src) \ + : "memory", "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7" \ ); -} -static inline void PushCommand(Vertex* v, volatile Vertex* dst) { - asm volatile ( -"add #32, %1 \n" // EX, dst += 32 -"fmov.d @%0+, dr0\n" // LS, fr0_fr1 = *src, src += 8 -"fmov.d @%0+, dr2\n" // LS, fr2_fr3 = *src, src += 8 -"fmov.d @%0+, dr4\n" // LS, fr4_fr5 = *src, src += 8 -"fmov.d @%0+, dr6\n" // LS, fr6_fr7 = *src, src += 8 -"fmov.d dr6, @-%1\n" // LS, dst -= 8, *dst = fr6_fr7 -"fmov.d dr4, @-%1\n" // LS, dst -= 8, *dst = fr4_fr5 -"fmov.d dr2, @-%1\n" // LS, dst -= 8, *dst = fr2_fr3 -"fmov.d dr0, @-%1\n" // LS, dst -= 8, *dst = fr0_fr1 -"pref @%1 \n" // LS, flush store queue -"add #-32, %0 \n" // EX, src -= 32 - : - : "r" (v), "r" (dst) - : "memory", "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7" +#define PushCommand(src, dst) __asm__ volatile ( \ +"fmov.d @%1+, dr0 ! LS, D01 = *src, src += 8\n" \ +"fmov.d @%1+, dr2 ! LS, D23 = *src, src += 8\n" \ +"fmov.d @%1+, dr4 ! LS, D45 = *src, src += 8\n" \ +"fmov.d @%1+, dr6 ! LS, D67 = *src, src += 8\n" \ +"add #64, %0 ! EX, dst += 64\n" \ +"fmov.d dr6, @-%0 ! LS, dst -= 8, *dst = D67\n" \ +"fmov.d dr4, @-%0 ! LS, dst -= 8, *dst = D45\n" \ +"fmov.d dr2, @-%0 ! LS, dst -= 8, *dst = D23\n" \ +"fmov.d dr0, @-%0 ! LS, dst -= 8, *dst = D01\n" \ +"pref @%0 ! LS, flush store queue\n" \ +"add #-32, %1 ! EX, src -= 32\n" \ + : "+r" (dst) \ + : "r" (src) \ + : "memory", "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7" \ ); -} extern void ClipEdge(Vertex* const v1, Vertex* const v2, volatile Vertex* vout, char type); @@ -56,11 +52,12 @@ extern void ClipEdge(Vertex* const v1, Vertex* const v2, volatile Vertex* vout, extern void ProcessVertexList(Vertex* v3, int n, void* sq_addr); -void SceneListSubmit(Vertex* v3, int n) { +void SubmitCommands(Vertex* v3, int n) { volatile Vertex* dst = (volatile Vertex*)MEM_AREA_SQ_BASE; + Vertex* vEnd = v3 + n; asm volatile ("fschg"); // swap to 64 bit loads/stores - for (int i = 0; i < n; i++, v3++) + for (; v3 < vEnd; v3++) { // Preload next vertex into memory __builtin_prefetch(v3 + 1); @@ -71,7 +68,7 @@ void SceneListSubmit(Vertex* v3, int n) { case PVR_CMD_VERTEX: continue; default: - PushCommand(v3, dst++); + PushCommand(v3, dst); continue; }; @@ -84,10 +81,10 @@ void SceneListSubmit(Vertex* v3, int n) { // Check if all vertices visible if (__builtin_expect(mask == (V0_VIS | V1_VIS | V2_VIS | V3_VIS), 1)) { // Triangle strip: {1,2,0} {2,0,3} - PushVertex(v1, dst++); - PushVertex(v2, dst++); - PushVertex(v0, dst++); - PushVertex(v3, dst++); + PushVertex(v1, dst); + PushVertex(v2, dst); + PushVertex(v0, dst); + PushVertex(v3, dst); continue; } @@ -102,7 +99,7 @@ void SceneListSubmit(Vertex* v3, int n) { // .....A....B... // / | // v3--v2---v1 - PushVertex(v0, dst++); // v0 + PushVertex(v0, dst); // v0 ClipEdge(v0, v1, dst++, TYPE_VTX); // B ClipEdge(v3, v0, dst++, TYPE_EOS); // A break; @@ -115,7 +112,7 @@ void SceneListSubmit(Vertex* v3, int n) { // / | // v0--v3---v2 ClipEdge(v0, v1, dst++, TYPE_VTX); // A - PushVertex(v1, dst++); // v1 + PushVertex(v1, dst); // v1 ClipEdge(v1, v2, dst++, TYPE_EOS); // B break; @@ -127,7 +124,7 @@ void SceneListSubmit(Vertex* v3, int n) { // / | // v1--v0---v3 ClipEdge(v1, v2, dst++, TYPE_VTX); // A - PushVertex(v2, dst++); // v2 + PushVertex(v2, dst); // v2 ClipEdge(v2, v3, dst++, TYPE_EOS); // B break; @@ -139,8 +136,8 @@ void SceneListSubmit(Vertex* v3, int n) { // / | // v2--v1---v0 ClipEdge(v3, v0, dst++, TYPE_VTX); // B - ClipEdge(v2, v3, dst++, TYPE_EOS); // A - PushVertex(v3, dst++); // v3 + ClipEdge(v2, v3, dst++, TYPE_VTX); // A + PushVertex(v3, dst); // v3 break; case V0_VIS | V1_VIS: @@ -149,9 +146,9 @@ void SceneListSubmit(Vertex* v3, int n) { // ....B..........A... // \ | // v3-----v2 - PushVertex(v1, dst++); // v1 + PushVertex(v1, dst); // v1 ClipEdge(v1, v2, dst++, TYPE_VTX); // A - PushVertex(v0, dst++); // v0 + PushVertex(v0, dst); // v0 ClipEdge(v3, v0, dst++, TYPE_EOS); // B break; @@ -164,8 +161,8 @@ void SceneListSubmit(Vertex* v3, int n) { // v2-----v1 ClipEdge(v0, v1, dst++, TYPE_VTX); // A ClipEdge(v2, v3, dst++, TYPE_VTX); // B - PushVertex(v0, dst++); // v0 - PushVertex(v3, dst++); // v3 + PushVertex(v0, dst); // v0 + PushVertex(v3, dst); // v3 break; case V1_VIS | V2_VIS: @@ -174,8 +171,8 @@ void SceneListSubmit(Vertex* v3, int n) { // ....B..........A... // \ | // v0-----v3 - PushVertex(v1, dst++); // v1 - PushVertex(v2, dst++); // v2 + PushVertex(v1, dst); // v1 + PushVertex(v2, dst); // v2 ClipEdge(v0, v1, dst++, TYPE_VTX); // B ClipEdge(v2, v3, dst++, TYPE_EOS); // A break; @@ -188,9 +185,9 @@ void SceneListSubmit(Vertex* v3, int n) { // \ | // v1-----v0 ClipEdge(v1, v2, dst++, TYPE_VTX); // B - PushVertex(v2, dst++); // v2 + PushVertex(v2, dst); // v2 ClipEdge(v3, v0, dst++, TYPE_VTX); // A - PushVertex(v3, dst++); // v3 + PushVertex(v3, dst); // v3 break; case V0_VIS | V1_VIS | V2_VIS: @@ -201,9 +198,9 @@ void SceneListSubmit(Vertex* v3, int n) { // \ | // v3 // v1,v2,v0 v2,v0,A v0,A,B - PushVertex(v1, dst++); // v1 - PushVertex(v2, dst++); // v2 - PushVertex(v0, dst++); // v0 + PushVertex(v1, dst); // v1 + PushVertex(v2, dst); // v2 + PushVertex(v0, dst); // v0 ClipEdge(v2, v3, dst++, TYPE_VTX); // A ClipEdge(v3, v0, dst++, TYPE_EOS); // B break; @@ -217,9 +214,9 @@ void SceneListSubmit(Vertex* v3, int n) { // v2 // v0,v1,v3 v1,v3,A v3,A,B v3->flags = PVR_CMD_VERTEX; - PushVertex(v0, dst++); // v0 - PushVertex(v1, dst++); // v1 - PushVertex(v3, dst++); // v3 + PushVertex(v0, dst); // v0 + PushVertex(v1, dst); // v1 + PushVertex(v3, dst); // v3 ClipEdge(v1, v2, dst++, TYPE_VTX); // A ClipEdge(v2, v3, dst++, TYPE_EOS); // B break; @@ -233,9 +230,9 @@ void SceneListSubmit(Vertex* v3, int n) { // v1 // v3,v0,v2 v0,v2,A v2,A,B v3->flags = PVR_CMD_VERTEX; - PushVertex(v3, dst++); // v3 - PushVertex(v0, dst++); // v0 - PushVertex(v2, dst++); // v2 + PushVertex(v3, dst); // v3 + PushVertex(v0, dst); // v0 + PushVertex(v2, dst); // v2 ClipEdge(v0, v1, dst++, TYPE_VTX); // A ClipEdge(v1, v2, dst++, TYPE_EOS); // B break; @@ -249,9 +246,9 @@ void SceneListSubmit(Vertex* v3, int n) { // v0 // v2,v3,v1 v3,v1,A v1,A,B v3->flags = PVR_CMD_VERTEX; - PushVertex(v2, dst++); // v2 - PushVertex(v3, dst++); // v3 - PushVertex(v1, dst++); // v1 + PushVertex(v2, dst); // v2 + PushVertex(v3, dst); // v3 + PushVertex(v1, dst); // v1 ClipEdge(v3, v0, dst++, TYPE_VTX); // A ClipEdge(v0, v1, dst++, TYPE_EOS); // B break;