diff --git a/ref_gu/gu_backend.c b/ref_gu/gu_backend.c index e6ca717e..18a1a79e 100644 --- a/ref_gu/gu_backend.c +++ b/ref_gu/gu_backend.c @@ -154,10 +154,10 @@ GL_LoadMatrix */ void GL_LoadMatrix( const matrix4x4 source ) { - float dest[16]; + ScePspFMatrix4 dest; - Matrix4x4_ToArrayFloatGL( source, dest ); - sceGumLoadMatrix( ( const ScePspFMatrix4 * ) dest ); + Matrix4x4_ToFMatrix4( source, &dest ); + sceGumLoadMatrix( &dest ); } /* diff --git a/ref_gu/gu_clipping.c b/ref_gu/gu_clipping.c index eb92c09d..84c359f6 100644 --- a/ref_gu/gu_clipping.c +++ b/ref_gu/gu_clipping.c @@ -18,25 +18,20 @@ GNU General Public License for more details. Based on clipping system from PSP Quake by Peter Mackay and Chris Swindle. */ +/* + VFPU REGS: + + M700 - current frustum + M600 - world frustum + C010 - current plane ( GU_Clip2Plane ) +*/ #include "gu_local.h" #define MAX_CLIPPED_VERTICES 32 -#define CPLANE_BOTTOM 0 -#define CPLANE_LEFT 1 -#define CPLANE_RIGHT 2 -#define CPLANE_TOP 3 -#define MAX_CPLANES 4 - -// Types. -typedef ScePspFVector4 plane_type; -typedef plane_type frustum_t[MAX_CPLANES]; - -// Transformed frustum. -static ScePspFMatrix4 projection_view_matrix __attribute__(( aligned( 16 ))); -static frustum_t projection_view_frustum __attribute__(( aligned( 16 ))); -static frustum_t clipping_frustum __attribute__(( aligned( 16 ))); +// Cache +static ScePspFMatrix4 projection_view_matrix; // The temporary working buffers. static gu_vert_t work_buffer[2][MAX_CLIPPED_VERTICES] __attribute__(( aligned( 16 ))); @@ -46,16 +41,16 @@ static gu_vert_t work_buffer[2][MAX_CLIPPED_VERTICES] __attribute__(( aligned( 1 GU_ClipGetFrustum ================= */ -_inline void GU_ClipGetFrustum(const ScePspFMatrix4 *matrix, frustum_t* frustum) +_inline void GU_ClipGetAndStoreFrustum( const ScePspFMatrix4 *matrix ) { __asm__ ( ".set push\n" // save assembler option ".set noreorder\n" // suppress reordering "vzero.q C210\n" // set zero vector - "lv.q C100, 0(%4)\n" // C000 = matrix->x - "lv.q C110, 16(%4)\n" // C010 = matrix->y - "lv.q C120, 32(%4)\n" // C020 = matrix->z - "lv.q C130, 48(%4)\n" // C030 = matrix->w + "lv.q C100, 0(%0)\n" // C000 = matrix->x + "lv.q C110, 16(%0)\n" // C010 = matrix->y + "lv.q C120, 32(%0)\n" // C020 = matrix->z + "lv.q C130, 48(%0)\n" // C030 = matrix->w "vadd.q C000, R103, R101\n" // C000 = R103 + R101 ( BOTTOM ) "vadd.q C010, R103, R100\n" // C010 = R103 + R100 ( LEFT ) "vsub.q C020, R103, R100\n" // C020 = R103 - R100 ( RIGHT ) @@ -64,23 +59,15 @@ _inline void GU_ClipGetFrustum(const ScePspFMatrix4 *matrix, frustum_t* frustum) "vdot.q S201, C010, C010\n" // S110 = S100*S100 + S101*S101 + S102*S102 + S103*S103 ( LEFT ) "vdot.q S202, C020, C020\n" // S110 = S100*S100 + S101*S101 + S102*S102 + S103*S103 ( RIGHT ) "vdot.q S203, C030, C030\n" // S110 = S100*S100 + S101*S101 + S102*S102 + S103*S103 ( TOP ) - "vcmp.q EZ, C200\n" // CC[0] = ( C200 == 0.0f ) + "vcmp.q EZ, C200\n" // CC[*] = ( C200 == 0.0f ) "vrsq.q C200, C200\n" // C200 = 1.0 / sqrt( C200 ) - "vcmovt.q C200, C210, 0\n" // if ( CC[*] ) C200 = C210 - "vscl.q C000, C000, S200\n" // C000 = C000 * S200 ( BOTTOM ) - "vscl.q C010, C010, S201\n" // C010 = C010 * S201 ( LEFT ) - "vscl.q C020, C020, S202\n" // C020 = C020 * S202 ( RIGHT ) - "vscl.q C030, C030, S203\n" // C030 = C030 * S203 ( TOP ) - "sv.q C000, %0\n" // Store plane from register - "sv.q C010, %1\n" // Store plane from register - "sv.q C020, %2\n" // Store plane from register - "sv.q C030, %3\n" // Store plane from register + "vcmovt.q C200, C210, 6\n" // if ( CC[*] ) C200 = C210 + "vscl.q C700, C000, S200\n" // C700 = C000 * S200 ( BOTTOM ) + "vscl.q C710, C010, S201\n" // C710 = C010 * S201 ( LEFT ) + "vscl.q C720, C020, S202\n" // C720 = C020 * S202 ( RIGHT ) + "vscl.q C730, C030, S203\n" // C730 = C030 * S203 ( TOP ) ".set pop\n" // Restore assembler option - : "=m"( ( *frustum )[CPLANE_BOTTOM] ), - "=m"( ( *frustum )[CPLANE_LEFT] ), - "=m"( ( *frustum )[CPLANE_RIGHT] ), - "=m"( ( *frustum )[CPLANE_TOP] ) - : "r"( matrix ) /* addr */ + :: "r"( matrix ) ); } @@ -91,117 +78,63 @@ GU_ClipBeginFrame Calculate the clipping frustum for static objects ================= */ -void GU_ClipBeginFrame( void ) +void GU_ClipSetWorldFrustum( const matrix4x4 in ) { - // Get the projection matrix. - sceGumMatrixMode( GU_PROJECTION ); - ScePspFMatrix4 proj; - sceGumStoreMatrix( &proj ); - - // Get the view matrix. - sceGumMatrixMode( GU_VIEW ); - ScePspFMatrix4 view; - sceGumStoreMatrix( &view ); - - // Restore matrix mode. - sceGumMatrixMode( GU_MODEL ); - - // Combine the two matrices (multiply projection by view). - gumMultMatrix( &projection_view_matrix, &proj, &view ); + // Get matrix. + Matrix4x4_ToFMatrix4( in, &projection_view_matrix ); // Calculate and cache the clipping frustum. - GU_ClipGetFrustum( &projection_view_matrix, &projection_view_frustum ); + GU_ClipGetAndStoreFrustum( &projection_view_matrix ); + // Save the clipping frustum. __asm__ volatile( ".set push\n" // save assembler option ".set noreorder\n" // suppress reordering - "lv.q C700, %4\n" // Load plane into register - "lv.q C710, %5\n" // Load plane into register - "lv.q C720, %6\n" // Load plane into register - "lv.q C730, %7\n" // Load plane into register - "sv.q C700, %0\n" // Store plane from register - "sv.q C710, %1\n" // Store plane from register - "sv.q C720, %2\n" // Store plane from register - "sv.q C730, %3\n" // Store plane from register + "vmmov.q M600, M700\n" // Save frustum ".set pop\n" // Restore assembler option - : "=m"( clipping_frustum[CPLANE_BOTTOM] ), - "=m"( clipping_frustum[CPLANE_LEFT] ), - "=m"( clipping_frustum[CPLANE_RIGHT] ), - "=m"( clipping_frustum[CPLANE_TOP] ) - : "m"( projection_view_frustum[CPLANE_BOTTOM] ), - "m"( projection_view_frustum[CPLANE_LEFT] ), - "m"( projection_view_frustum[CPLANE_RIGHT] ), - "m"( projection_view_frustum[CPLANE_TOP] ) ); } /* ================= -GU_ClipBeginBrush - -Calculate the clipping frustum for dynamic objects -================= -*/ -void GU_ClipBeginBrush( void ) -{ - // Get the model matrix. - ScePspFMatrix4 model_matrix; - sceGumStoreMatrix( &model_matrix ); - - // Combine the matrices (multiply projection-view by model). - ScePspFMatrix4 projection_view_model_matrix; - gumMultMatrix( &projection_view_model_matrix, &projection_view_matrix, &model_matrix ); - - // Calculate the clipping frustum. - GU_ClipGetFrustum( &projection_view_model_matrix, &clipping_frustum ); - - __asm__ volatile( - ".set push\n" // save assembler option - ".set noreorder\n" // suppress reordering - "lv.q C700, %0\n" // Load plane into register - "lv.q C710, %1\n" // Load plane into register - "lv.q C720, %2\n" // Load plane into register - "lv.q C730, %3\n" // Load plane into register - ".set pop\n" // Restore assembler option - :: "m"( clipping_frustum[CPLANE_BOTTOM] ), - "m"( clipping_frustum[CPLANE_LEFT] ), - "m"( clipping_frustum[CPLANE_RIGHT] ), - "m"( clipping_frustum[CPLANE_TOP] ) - ); -} - -/* -================= -GU_ClipEndBrush +GU_ClipRestoreWorldFrustum Restore the clipping frustum ================= */ -void GU_ClipEndBrush( void ) +void GU_ClipRestoreWorldFrustum( void ) { + // Restore the clipping frustum. __asm__ volatile( ".set push\n" // save assembler option ".set noreorder\n" // suppress reordering - "lv.q C700, %4\n" // Load plane into register - "lv.q C710, %5\n" // Load plane into register - "lv.q C720, %6\n" // Load plane into register - "lv.q C730, %7\n" // Load plane into register - "sv.q C700, %0\n" // Store plane from register - "sv.q C710, %1\n" // Store plane from register - "sv.q C720, %2\n" // Store plane from register - "sv.q C730, %3\n" // Store plane from register + "vmmov.q M700, M600\n" // Restore frustum ".set pop\n" // Restore assembler option - : "=m"( clipping_frustum[CPLANE_BOTTOM] ), - "=m"( clipping_frustum[CPLANE_LEFT] ), - "=m"( clipping_frustum[CPLANE_RIGHT] ), - "=m"( clipping_frustum[CPLANE_TOP] ) - : "m"( projection_view_frustum[CPLANE_BOTTOM] ), - "m"( projection_view_frustum[CPLANE_LEFT] ), - "m"( projection_view_frustum[CPLANE_RIGHT] ), - "m"( projection_view_frustum[CPLANE_TOP] ) ); } +/* +================= +GU_ClipSetModelFrustum + +Calculate the clipping frustum for dynamic objects +================= +*/ +void GU_ClipSetModelFrustum( const matrix4x4 in ) +{ + ScePspFMatrix4 model_matrix; + ScePspFMatrix4 projection_view_model_matrix; + + // Get matrix. + Matrix4x4_ToFMatrix4( in, &model_matrix ); + + // Combine the matrices (multiply projection-view by model). + gumMultMatrix( &projection_view_model_matrix, &projection_view_matrix, &model_matrix ); + + // Calculate and cache the clipping frustum. + GU_ClipGetAndStoreFrustum( &projection_view_model_matrix ); +} + /* ================= GU_ClipLoadFrustum @@ -215,21 +148,13 @@ void GU_ClipLoadFrustum( const mplane_t *plane ) __asm__ volatile( ".set push\n" // save assembler option ".set noreorder\n" // suppress reordering - "ulv.q C700, %4\n" // Load plane into register - "ulv.q C710, %5\n" // Load plane into register - "ulv.q C720, %6\n" // Load plane into register - "ulv.q C730, %7\n" // Load plane into register + "ulv.q C700, %0\n" // Load plane into register + "ulv.q C710, %1\n" // Load plane into register + "ulv.q C720, %2\n" // Load plane into register + "ulv.q C730, %3\n" // Load plane into register "vneg.q R703, R703\n" // R703 = -R703 = -dist - "sv.q C700, %0\n" // Store plane from register - "sv.q C710, %1\n" // Store plane from register - "sv.q C720, %2\n" // Store plane from register - "sv.q C730, %3\n" // Store plane from register ".set pop\n" // Restore assembler option - : "=m"( clipping_frustum[CPLANE_BOTTOM] ), - "=m"( clipping_frustum[CPLANE_LEFT] ), - "=m"( clipping_frustum[CPLANE_RIGHT] ), - "=m"( clipping_frustum[CPLANE_TOP] ) - : "m"( plane[FRUSTUM_BOTTOM] ), + :: "m"( plane[FRUSTUM_BOTTOM] ), "m"( plane[FRUSTUM_LEFT] ), "m"( plane[FRUSTUM_RIGHT] ), "m"( plane[FRUSTUM_TOP] ) @@ -253,13 +178,13 @@ int GU_ClipIsRequired( gu_vert_t* uv, int uvc ) __asm__ ( ".set push\n" // save assembler option ".set noreorder\n" // suppress reordering - "vzero.q C600\n" // C600 = [0.0f, 0.0f, 0.0f. 0.0f] + "vzero.q C000\n" // C000 = [0.0f, 0.0f, 0.0f. 0.0f] "0:\n" // loop - "lv.s S610, 8(%1)\n" // S610 = v[i].xyz[0] - "lv.s S611, 12(%1)\n" // S611 = v[i].xyz[1] - "lv.s S612, 16(%1)\n" // S612 = v[i].xyz[2] - "vhtfm4.q C620, M700, C610\n" // C620 = frustrum * v[i].xyz - "vcmp.q LT, C620, C600\n" // S620 < 0.0f || S621 < 0.0f || S622 < 0.0f || S623 < 0.0f + "lv.s S010, 8(%1)\n" // S010 = v[i].xyz[0] + "lv.s S011, 12(%1)\n" // S011 = v[i].xyz[1] + "lv.s S012, 16(%1)\n" // S012 = v[i].xyz[2] + "vhtfm4.q C020, M700, C010\n" // C020 = frustrum * v[i].xyz + "vcmp.q LT, C020, C000\n" // S020 < 0.0f || S021 < 0.0f || S022 < 0.0f || S023 < 0.0f "bvt 4, 1f\n" // if ( CC[4] == 1 ) jump to exit "nop\n" // ( delay slot ) "bne %1, %2, 0b\n" // if ( $10 != $8 ) jump to loop @@ -282,7 +207,7 @@ GU_Clip2Plane Clips a polygon against a plane. ================= */ -_inline void GU_Clip2Plane( plane_type *plane, gu_vert_t *uv, int uvc, gu_vert_t *cv, int *cvc ) +_inline void GU_Clip2Plane( gu_vert_t *uv, int uvc, gu_vert_t *cv, int *cvc ) { gu_vert_t *uv_end = uv + ( uvc - 1 ); gu_vert_t *cv_start = cv; @@ -291,7 +216,6 @@ _inline void GU_Clip2Plane( plane_type *plane, gu_vert_t *uv, int uvc, gu_vert_t ".set push\n" // save assembler option ".set noreorder\n" // suppress reordering "vzero.q C000\n" // set zero vector - "lv.q C010, 0(%3)\n" // plane "lv.s S200, 8(%2)\n" // Load vertex P XYZ(4b) X into register "lv.s S201, 12(%2)\n" // Load vertex P XYZ(4b) Y into register "lv.s S202, 16(%2)\n" // Load vertex P XYZ(4b) Z into register @@ -313,7 +237,7 @@ _inline void GU_Clip2Plane( plane_type *plane, gu_vert_t *uv, int uvc, gu_vert_t "sv.s S200, 8(%0)\n" // cv->xyz[0] = C030 X "sv.s S201, 12(%0)\n" // cv->xyz[1] = C031 Y "sv.s S202, 16(%0)\n" // cv->xyz[2] = C032 Z - "addiu %0, %0, 20\n" + "addiu %0, %0, %3\n" // cv + sizeof(gu_vert_t) "1:\n" "vmul.s S020, S232, S212\n" // (dS * dP) "vcmp.s LT, S020, S000\n" // if (dS * dP < 0) @@ -341,15 +265,15 @@ _inline void GU_Clip2Plane( plane_type *plane, gu_vert_t *uv, int uvc, gu_vert_t "sv.s S200, 8(%0)\n" // cv->xyz[0] = S200 X "sv.s S201, 12(%0)\n" // cv->xyz[1] = S201 Y "sv.s S202, 16(%0)\n" // cv->xyz[2] = S202 Z - "addiu %0, %0, %4\n" // cv + sizeof(gu_vert_t) + "addiu %0, %0, %3\n" // cv + sizeof(gu_vert_t) "2:\n" "vmov.t C200, C220\n" // P = S XYZ "vmov.t C210, C230\n" // P = S UV and dS "bne %1, %2, 0b\n" // if (uv != uv_end) goto 0: - "addiu %1, %1, %4\n" // uv + sizeof(gu_vert_t) ( delay slot ) + "addiu %1, %1, %3\n" // uv + sizeof(gu_vert_t) ( delay slot ) ".set pop\n" // suppress reordering : "+r"( cv ), "+r"( uv ) - : "r"( uv_end ), "r"( plane ), + : "r"( uv_end ), "n"( sizeof( gu_vert_t )) : "memory" ) ; @@ -373,14 +297,41 @@ void GU_Clip( gu_vert_t *uv, int uvc, gu_vert_t **cv, int* cvc ) vc = uvc; *cvc = 0; - GU_Clip2Plane( &clipping_frustum[CPLANE_BOTTOM], uv, vc, work_buffer[0], &vc ); + __asm__ volatile( + ".set push\n" // save assembler option + ".set noreorder\n" // suppress reordering + "vmov.q C010, C700\n" // CPLANE_BOTTOM + ".set pop\n" // suppress reordering + ); + GU_Clip2Plane( uv, vc, work_buffer[0], &vc ); if ( !vc ) return; - GU_Clip2Plane( &clipping_frustum[CPLANE_LEFT], work_buffer[0], vc, work_buffer[1], &vc ); + + __asm__ volatile( + ".set push\n" // save assembler option + ".set noreorder\n" // suppress reordering + "vmov.q C010, C710\n" // CPLANE_LEFT + ".set pop\n" // suppress reordering + ); + GU_Clip2Plane( work_buffer[0], vc, work_buffer[1], &vc ); if ( !vc ) return; - GU_Clip2Plane( &clipping_frustum[CPLANE_RIGHT], work_buffer[1], vc, work_buffer[0], &vc ); + + __asm__ volatile( + ".set push\n" // save assembler option + ".set noreorder\n" // suppress reordering + "vmov.q C010, C720\n" // CPLANE_RIGHT + ".set pop\n" // suppress reordering + ); + GU_Clip2Plane( work_buffer[1], vc, work_buffer[0], &vc ); if ( !vc ) return; + + __asm__ volatile( + ".set push\n" // save assembler option + ".set noreorder\n" // suppress reordering + "vmov.q C010, C730\n" // CPLANE_TOP + ".set pop\n" // suppress reordering + ); *cv = extGuBeginPacket( NULL ); // uncached - GU_Clip2Plane( &clipping_frustum[CPLANE_TOP], work_buffer[0], vc, *cv, cvc ); + GU_Clip2Plane( work_buffer[0], vc, *cv, cvc ); if (!( *cvc )) return; extGuEndPacket(( void * )( *cv + *cvc )); -} \ No newline at end of file +} diff --git a/ref_gu/gu_local.h b/ref_gu/gu_local.h index b9ed4365..c193d935 100644 --- a/ref_gu/gu_local.h +++ b/ref_gu/gu_local.h @@ -497,8 +497,8 @@ int CL_FxBlend( cl_entity_t *e ); // // gu_rmath.c // -void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] ); -void Matrix4x4_FromArrayFloatGL( matrix4x4 out, const float in[16] ); +void Matrix4x4_ToFMatrix4( const matrix4x4 in, ScePspFMatrix4 *out ); +void Matrix4x4_FromFMatrix4( matrix4x4 out, ScePspFMatrix4 *in ); void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 ); void Matrix4x4_ConcatTranslate( matrix4x4 out, float x, float y, float z ); void Matrix4x4_ConcatRotate( matrix4x4 out, float angle, float x, float y, float z ); @@ -690,9 +690,9 @@ int getTriAPI( int version, triangleapi_t *api ); // gu_clipping.c // #define CLIPPING_DEBUGGING 0 -void GU_ClipBeginFrame( void ); -void GU_ClipBeginBrush( void ); -void GU_ClipEndBrush( void ); +void GU_ClipSetWorldFrustum( const matrix4x4 in ); +void GU_ClipRestoreWorldFrustum( void ); +void GU_ClipSetModelFrustum( const matrix4x4 in ); void GU_ClipLoadFrustum( const mplane_t *plane ); // Experimental int GU_ClipIsRequired( gu_vert_t* uv, int uvc ); void GU_Clip( gu_vert_t *uv, int uvc, gu_vert_t **cv, int* cvc ); diff --git a/ref_gu/gu_rmain.c b/ref_gu/gu_rmain.c index 4baf4f38..ea74802f 100644 --- a/ref_gu/gu_rmain.c +++ b/ref_gu/gu_rmain.c @@ -625,7 +625,7 @@ void R_SetupGL( qboolean set_gl_state ) sceGuDisable( GU_ALPHA_TEST ); sceGuColor( GUCOLOR4F( 1.0f, 1.0f, 1.0f, 1.0f ) ); - GU_ClipBeginFrame(); + GU_ClipSetWorldFrustum( RI.worldviewProjectionMatrix ); } diff --git a/ref_gu/gu_rmath.c b/ref_gu/gu_rmath.c index 78b91e3e..60c530a8 100644 --- a/ref_gu/gu_rmath.c +++ b/ref_gu/gu_rmath.c @@ -27,22 +27,22 @@ void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 ) { #if 1 __asm__ ( - ".set push\n" // save assembler option - ".set noreorder\n" // suppress reordering - "lv.q C100, 0 + %1\n" // C100 = in1[0] - "lv.q C110, 16 + %1\n" // C110 = in1[1] - "lv.q C120, 32 + %1\n" // C120 = in1[2] - "lv.q C130, 48 + %1\n" // C130 = in1[3] - "lv.q C200, 0 + %2\n" // C200 = in2[0] - "lv.q C210, 16 + %2\n" // C210 = in2[1] - "lv.q C220, 32 + %2\n" // C220 = in2[2] - "lv.q C230, 48 + %2\n" // C230 = in2[3] - "vmmul.q E000, E100, E200\n" // E000 = E100 * E200 - "sv.q C000, 0 + %0\n" // out[0] = C000 - "sv.q C010, 16 + %0\n" // out[1] = C010 - "sv.q C020, 32 + %0\n" // out[2] = C020 - "sv.q C030, 48 + %0\n" // out[3] = C030 - ".set pop\n" // restore assembler option + ".set push\n" // save assembler option + ".set noreorder\n" // suppress reordering + "lv.q C100, 0 + %1\n" // C100 = in1[0] + "lv.q C110, 16 + %1\n" // C110 = in1[1] + "lv.q C120, 32 + %1\n" // C120 = in1[2] + "lv.q C130, 48 + %1\n" // C130 = in1[3] + "lv.q C200, 0 + %2\n" // C200 = in2[0] + "lv.q C210, 16 + %2\n" // C210 = in2[1] + "lv.q C220, 32 + %2\n" // C220 = in2[2] + "lv.q C230, 48 + %2\n" // C230 = in2[3] + "vmmul.q E000, E100, E200\n" // E000 = E100 * E200 + "sv.q C000, 0 + %0\n" // out[0] = C000 + "sv.q C010, 16 + %0\n" // out[1] = C010 + "sv.q C020, 32 + %0\n" // out[2] = C020 + "sv.q C030, 48 + %0\n" // out[3] = C030 + ".set pop\n" // restore assembler option : "=m"( *out ) : "m"( *in1 ), "m"( *in2 ) ); @@ -122,44 +122,44 @@ void Matrix4x4_CreateModelview( matrix4x4 out ) out[1][2] = 1.0f; } -void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] ) +void Matrix4x4_ToFMatrix4( const matrix4x4 in, ScePspFMatrix4 *out ) { - out[ 0] = in[0][0]; - out[ 1] = in[1][0]; - out[ 2] = in[2][0]; - out[ 3] = in[3][0]; - out[ 4] = in[0][1]; - out[ 5] = in[1][1]; - out[ 6] = in[2][1]; - out[ 7] = in[3][1]; - out[ 8] = in[0][2]; - out[ 9] = in[1][2]; - out[10] = in[2][2]; - out[11] = in[3][2]; - out[12] = in[0][3]; - out[13] = in[1][3]; - out[14] = in[2][3]; - out[15] = in[3][3]; + // transpose matrix + __asm__ ( + ".set push\n" // save assembler option + ".set noreorder\n" // suppress reordering + "lv.q C000, 0 + %1\n" // C000 = in->x + "lv.q C010, 16 + %1\n" // C010 = in->y + "lv.q C020, 32 + %1\n" // C020 = in->z + "lv.q C030, 48 + %1\n" // C030 = in->w + "sv.q R000, 0 + %0\n" // out->x = R000 + "sv.q R001, 16 + %0\n" // out->y = R010 + "sv.q R002, 32 + %0\n" // out->z = R020 + "sv.q R003, 48 + %0\n" // out->w = R030 + ".set pop\n" // restore assembler option + : "=m"( *out ) + : "m"( *in ) + ); } -void Matrix4x4_FromArrayFloatGL( matrix4x4 out, const float in[16] ) +void Matrix4x4_FromFMatrix4( matrix4x4 out, ScePspFMatrix4 *in ) { - out[0][0] = in[0]; - out[1][0] = in[1]; - out[2][0] = in[2]; - out[3][0] = in[3]; - out[0][1] = in[4]; - out[1][1] = in[5]; - out[2][1] = in[6]; - out[3][1] = in[7]; - out[0][2] = in[8]; - out[1][2] = in[9]; - out[2][2] = in[10]; - out[3][2] = in[11]; - out[0][3] = in[12]; - out[1][3] = in[13]; - out[2][3] = in[14]; - out[3][3] = in[15]; + // transpose matrix + __asm__ ( + ".set push\n" // save assembler option + ".set noreorder\n" // suppress reordering + "lv.q C000, 0 + %1\n" // C000 = in->x + "lv.q C010, 16 + %1\n" // C010 = in->y + "lv.q C020, 32 + %1\n" // C020 = in->z + "lv.q C030, 48 + %1\n" // C030 = in->w + "sv.q R000, 0 + %0\n" // out->x = R000 + "sv.q R001, 16 + %0\n" // out->y = R010 + "sv.q R002, 32 + %0\n" // out->z = R020 + "sv.q R003, 48 + %0\n" // out->w = R030 + ".set pop\n" // restore assembler option + : "=m"( *out ) + : "m"( *in ) + ); } void Matrix4x4_CreateTranslate( matrix4x4 out, float x, float y, float z ) diff --git a/ref_gu/gu_rsurf.c b/ref_gu/gu_rsurf.c index 05266fed..1c53814c 100644 --- a/ref_gu/gu_rsurf.c +++ b/ref_gu/gu_rsurf.c @@ -1663,7 +1663,7 @@ void R_DrawBrushModel( cl_entity_t *e ) psurf = &clmodel->surfaces[clmodel->firstmodelsurface]; - GU_ClipBeginBrush(); + GU_ClipSetModelFrustum( RI.objectMatrix ); // sorting is not required, +Z_Realloc in Mod_LoadSubmodels (mod_bmodel.c) for( i = 0; i < clmodel->nummodelsurfaces; i++, psurf++ ) @@ -1697,7 +1697,6 @@ void R_DrawBrushModel( cl_entity_t *e ) R_BlendLightmaps(); R_RenderFullbrights(); R_RenderDetails(); - GU_ClipEndBrush(); // restore fog here if( e->curstate.rendermode == kRenderTransAdd ) @@ -1711,6 +1710,7 @@ void R_DrawBrushModel( cl_entity_t *e ) sceGuDepthMask( GU_FALSE ); R_DrawModelHull(); // draw before restore + GU_ClipRestoreWorldFrustum(); R_LoadIdentity(); // restore worldmatrix }