diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 8d2e7a68e1..a11366f10b 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -26,6 +26,7 @@ #include "Common/Common.h" #include "Core/Reporting.h" +#include "GPU/Math3D.h" #include "GPU/GPUState.h" #include "GPU/ge_constants.h" #include "GPU/Directx9/ShaderManagerDX9.h" @@ -257,29 +258,10 @@ void LinkedShaderDX9::SetColorUniform3ExtraFloat(D3DXHANDLE uniform, u32 color, SetFloatArray(uniform, col, 4); } -static void ConvertMatrix4x3To4x4(const float *m4x3, float *m4x4) { - m4x4[0] = m4x3[0]; - m4x4[1] = m4x3[1]; - m4x4[2] = m4x3[2]; - m4x4[3] = 0.0f; - m4x4[4] = m4x3[3]; - m4x4[5] = m4x3[4]; - m4x4[6] = m4x3[5]; - m4x4[7] = 0.0f; - m4x4[8] = m4x3[6]; - m4x4[9] = m4x3[7]; - m4x4[10] = m4x3[8]; - m4x4[11] = 0.0f; - m4x4[12] = m4x3[9]; - m4x4[13] = m4x3[10]; - m4x4[14] = m4x3[11]; - m4x4[15] = 1.0f; -} - // Utility void LinkedShaderDX9::SetMatrix4x3(D3DXHANDLE uniform, const float *m4x3) { float m4x4[16]; - ConvertMatrix4x3To4x4(m4x3, m4x4); + ConvertMatrix4x3To4x4(m4x4, m4x3); if (m_vs->constant->SetMatrix(pD3Ddevice, uniform, (D3DXMATRIX*)m4x4) == D3D_OK); else @@ -423,7 +405,7 @@ void LinkedShaderDX9::updateUniforms() { bool allDirty = true; for (int i = 0; i < numBones; i++) { if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) { - ConvertMatrix4x3To4x4(gstate.boneMatrix + 12 * i, allBones + 16 * i); + ConvertMatrix4x3To4x4(allBones + 16 * i, gstate.boneMatrix + 12 * i); } else { allDirty = false; } @@ -444,7 +426,7 @@ void LinkedShaderDX9::updateUniforms() { float bonetemp[16]; for (int i = 0; i < numBones; i++) { if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) { - ConvertMatrix4x3To4x4(gstate.boneMatrix + 12 * i, bonetemp); + ConvertMatrix4x3To4x4(bonetemp, gstate.boneMatrix + 12 * i); if (u_bone[i] != 0) SetMatrix(u_bone[i], bonetemp); diff --git a/GPU/Directx9/TransformPipelineDX9.cpp b/GPU/Directx9/TransformPipelineDX9.cpp index af9ddaf3f4..d483e43bf4 100644 --- a/GPU/Directx9/TransformPipelineDX9.cpp +++ b/GPU/Directx9/TransformPipelineDX9.cpp @@ -137,7 +137,7 @@ using namespace DX9; // that's common between the many vertices of a draw call. class Lighter { public: - Lighter(); + Lighter(int vertType); void Light(float colorOut0[4], float colorOut1[4], const float colorIn[4], Vec3f pos, Vec3f normal); private: @@ -152,7 +152,7 @@ private: int materialUpdate_; }; -Lighter::Lighter() { +Lighter::Lighter(int vertType) { doShadeMapping_ = gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP; materialEmissive.GetFromRGB(gstate.materialemissive); materialEmissive.a = 0.0f; @@ -166,7 +166,8 @@ Lighter::Lighter() { materialSpecular.a = 1.0f; specCoef_ = getFloat24(gstate.materialspecularcoef); // viewer_ = Vec3f(-gstate.viewMatrix[9], -gstate.viewMatrix[10], -gstate.viewMatrix[11]); - materialUpdate_ = gstate.materialupdate & 7; + bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0; + materialUpdate_ = hasColor ? gstate.materialupdate & 7 : 0; } void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[4], Vec3f pos, Vec3f norm) @@ -560,7 +561,7 @@ void TransformDrawEngineDX9::SoftwareTransformAndDraw( float widthFactor = (float) w / (float) gstate_c.curTextureWidth; float heightFactor = (float) h / (float) gstate_c.curTextureHeight; - Lighter lighter; + Lighter lighter(vertType); float fog_end = getFloat24(gstate.fog1); float fog_slope = getFloat24(gstate.fog2); diff --git a/GPU/Directx9/VertexShaderGeneratorDX9.cpp b/GPU/Directx9/VertexShaderGeneratorDX9.cpp index 8cb2f71c91..32acf24c7a 100644 --- a/GPU/Directx9/VertexShaderGeneratorDX9.cpp +++ b/GPU/Directx9/VertexShaderGeneratorDX9.cpp @@ -210,7 +210,7 @@ void GenerateVertexShaderDX9(int prim, char *buffer, bool useHWTransform) { } if (gstate.isLightingEnabled()) { WRITE(p, "float4 u_ambient;\n"); - if ((gstate.materialupdate & 2) == 0) + if ((gstate.materialupdate & 2) == 0 || !hasColor) WRITE(p, "float3 u_matdiffuse;\n"); // if ((gstate.materialupdate & 4) == 0) WRITE(p, "float4 u_matspecular;\n"); // Specular coef is contained in alpha @@ -371,9 +371,9 @@ void GenerateVertexShaderDX9(int prim, char *buffer, bool useHWTransform) { // TODO: Declare variables for dots for shade mapping if needed. - const char *ambientStr = (gstate.materialupdate & 1) ? (hasColor ? "In.C1" : "u_matambientalpha") : "u_matambientalpha"; - const char *diffuseStr = (gstate.materialupdate & 2) ? (hasColor ? "In.C1.rgb" : "u_matambientalpha.rgb") : "u_matdiffuse"; - const char *specularStr = (gstate.materialupdate & 4) ? (hasColor ? "In.C1.rgb" : "u_matambientalpha.rgb") : "u_matspecular.rgb"; + const char *ambientStr = (gstate.materialupdate & 1) && hasColor ? "In.C1" : "u_matambientalpha"; + const char *diffuseStr = (gstate.materialupdate & 2) && hasColor ? "In.C1.rgb" : "u_matdiffuse"; + const char *specularStr = (gstate.materialupdate & 4) && hasColor ? "In.C1.rgb" : "u_matspecular.rgb"; bool diffuseIsZero = true; bool specularIsZero = true; diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index cfe94beb83..7c80bea049 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -32,6 +32,7 @@ #include "Core/Config.h" #include "Core/Reporting.h" +#include "GPU/Math3D.h" #include "GPU/GPUState.h" #include "GPU/ge_constants.h" #include "GPU/GLES/ShaderManager.h" @@ -307,28 +308,9 @@ static void SetColorUniform3ExtraFloat(int uniform, u32 color, float extra) { glUniform4fv(uniform, 1, col); } -static void ConvertMatrix4x3To4x4(const float *m4x3, float *m4x4) { - m4x4[0] = m4x3[0]; - m4x4[1] = m4x3[1]; - m4x4[2] = m4x3[2]; - m4x4[3] = 0.0f; - m4x4[4] = m4x3[3]; - m4x4[5] = m4x3[4]; - m4x4[6] = m4x3[5]; - m4x4[7] = 0.0f; - m4x4[8] = m4x3[6]; - m4x4[9] = m4x3[7]; - m4x4[10] = m4x3[8]; - m4x4[11] = 0.0f; - m4x4[12] = m4x3[9]; - m4x4[13] = m4x3[10]; - m4x4[14] = m4x3[11]; - m4x4[15] = 1.0f; -} - static void SetMatrix4x3(int uniform, const float *m4x3) { float m4x4[16]; - ConvertMatrix4x3To4x4(m4x3, m4x4); + ConvertMatrix4x3To4x4(m4x4, m4x3); glUniformMatrix4fv(uniform, 1, GL_FALSE, m4x4); } @@ -496,7 +478,7 @@ void LinkedShader::UpdateUniforms(u32 vertType) { bool allDirty = true; for (int i = 0; i < numBones; i++) { if (dirty & (DIRTY_BONEMATRIX0 << i)) { - ConvertMatrix4x3To4x4(gstate.boneMatrix + 12 * i, allBones + 16 * i); + ConvertMatrix4x3To4x4(allBones + 16 * i, gstate.boneMatrix + 12 * i); } else { allDirty = false; } @@ -517,7 +499,7 @@ void LinkedShader::UpdateUniforms(u32 vertType) { float bonetemp[16]; for (int i = 0; i < numBones; i++) { if (dirty & (DIRTY_BONEMATRIX0 << i)) { - ConvertMatrix4x3To4x4(gstate.boneMatrix + 12 * i, bonetemp); + ConvertMatrix4x3To4x4(bonetemp, gstate.boneMatrix + 12 * i); glUniformMatrix4fv(u_bone[i], 1, GL_FALSE, bonetemp); } } diff --git a/GPU/GLES/SoftwareTransform.cpp b/GPU/GLES/SoftwareTransform.cpp index 5c7e167326..d32c6be5e4 100644 --- a/GPU/GLES/SoftwareTransform.cpp +++ b/GPU/GLES/SoftwareTransform.cpp @@ -51,7 +51,7 @@ inline float clamp(float in, float min, float max) { // that's common between the many vertices of a draw call. class Lighter { public: - Lighter(); + Lighter(int vertType); void Light(float colorOut0[4], float colorOut1[4], const float colorIn[4], Vec3f pos, Vec3f normal); private: @@ -66,7 +66,7 @@ private: int materialUpdate_; }; -Lighter::Lighter() { +Lighter::Lighter(int vertType) { doShadeMapping_ = gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP; materialEmissive.GetFromRGB(gstate.materialemissive); materialEmissive.a = 0.0f; @@ -80,7 +80,8 @@ Lighter::Lighter() { materialSpecular.a = 1.0f; specCoef_ = getFloat24(gstate.materialspecularcoef); // viewer_ = Vec3f(-gstate.viewMatrix[9], -gstate.viewMatrix[10], -gstate.viewMatrix[11]); - materialUpdate_ = gstate.materialupdate & 7; + bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0; + materialUpdate_ = hasColor ? gstate.materialupdate & 7 : 0; } void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[4], Vec3f pos, Vec3f norm) @@ -307,7 +308,7 @@ void TransformDrawEngine::SoftwareTransformAndDraw( float widthFactor = (float) w / (float) gstate_c.curTextureWidth; float heightFactor = (float) h / (float) gstate_c.curTextureHeight; - Lighter lighter; + Lighter lighter(vertType); float fog_end = getFloat24(gstate.fog1); float fog_slope = getFloat24(gstate.fog2); diff --git a/GPU/GLES/Spline.cpp b/GPU/GLES/Spline.cpp index 2c59e53194..8ecd6c63a1 100644 --- a/GPU/GLES/Spline.cpp +++ b/GPU/GLES/Spline.cpp @@ -28,10 +28,9 @@ // The rest of the transform pipeline like lighting will go as normal, either hardware or software. // The implementation is initially a bit inefficient but shouldn't be a big deal. // An intermediate buffer of not-easy-to-predict size is stored at bufPtr. -u32 TransformDrawEngine::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType) { +u32 TransformDrawEngine::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, VertexDecoder *dec, int lowerBound, int upperBound, u32 vertType) { // First, decode the vertices into a GPU compatible format. This step can be eliminated but will need a separate // implementation of the vertex decoder. - VertexDecoder *dec = GetVertexDecoder(vertType); dec->DecodeVerts(bufPtr, inPtr, lowerBound, upperBound); // OK, morphing eliminated but bones still remain to be taken care of. @@ -128,6 +127,11 @@ u32 TransformDrawEngine::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inP return GE_VTYPE_TC_FLOAT | GE_VTYPE_COL_8888 | GE_VTYPE_NRM_FLOAT | GE_VTYPE_POS_FLOAT | (vertType & GE_VTYPE_IDX_MASK); } +u32 TransformDrawEngine::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType) { + VertexDecoder *dec = GetVertexDecoder(vertType); + return NormalizeVertices(outPtr, bufPtr, inPtr, dec, lowerBound, upperBound, vertType); +} + #define START_OPEN 1 #define END_OPEN 2 diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index b3de237982..4bf759d70a 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -751,25 +751,6 @@ void PlanesFromMatrix(float mtx[16], Plane planes[6]) { planes[5].Set(mtx[3]-mtx[2], mtx[7]-mtx[6], mtx[11]-mtx[10], mtx[15]-mtx[14]); // Far } -static void ConvertMatrix4x3To4x4(float *m4x4, const float *m4x3) { - m4x4[0] = m4x3[0]; - m4x4[1] = m4x3[1]; - m4x4[2] = m4x3[2]; - m4x4[3] = 0.0f; - m4x4[4] = m4x3[3]; - m4x4[5] = m4x3[4]; - m4x4[6] = m4x3[5]; - m4x4[7] = 0.0f; - m4x4[8] = m4x3[6]; - m4x4[9] = m4x3[7]; - m4x4[10] = m4x3[8]; - m4x4[11] = 0.0f; - m4x4[12] = m4x3[9]; - m4x4[13] = m4x3[10]; - m4x4[14] = m4x3[11]; - m4x4[15] = 1.0f; -} - // This code is HIGHLY unoptimized! // // It does the simplest and safest test possible: If all points of a bbox is outside a single of diff --git a/GPU/GLES/TransformPipeline.h b/GPU/GLES/TransformPipeline.h index 7d463237dc..8fb489c662 100644 --- a/GPU/GLES/TransformPipeline.h +++ b/GPU/GLES/TransformPipeline.h @@ -132,6 +132,9 @@ public: return decJitCache_->IsInSpace(ptr); } + // Really just for convenience to share with softgpu. + static u32 NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, VertexDecoder *dec, int lowerBound, int upperBound, u32 vertType); + private: void DecodeVerts(); void DecodeVertsStep(); diff --git a/GPU/GLES/VertexShaderGenerator.cpp b/GPU/GLES/VertexShaderGenerator.cpp index fe985e780c..afcb1ebfde 100644 --- a/GPU/GLES/VertexShaderGenerator.cpp +++ b/GPU/GLES/VertexShaderGenerator.cpp @@ -303,7 +303,7 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf } if (gstate.isLightingEnabled()) { WRITE(p, "uniform lowp vec4 u_ambient;\n"); - if ((gstate.materialupdate & 2) == 0) + if ((gstate.materialupdate & 2) == 0 || !hasColor) WRITE(p, "uniform lowp vec3 u_matdiffuse;\n"); // if ((gstate.materialupdate & 4) == 0) WRITE(p, "uniform lowp vec4 u_matspecular;\n"); // Specular coef is contained in alpha @@ -457,9 +457,9 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf // TODO: Declare variables for dots for shade mapping if needed. - const char *ambientStr = (gstate.materialupdate & 1) ? (hasColor ? "color0" : "u_matambientalpha") : "u_matambientalpha"; - const char *diffuseStr = (gstate.materialupdate & 2) ? (hasColor ? "color0.rgb" : "u_matambientalpha.rgb") : "u_matdiffuse"; - const char *specularStr = (gstate.materialupdate & 4) ? (hasColor ? "color0.rgb" : "u_matambientalpha.rgb") : "u_matspecular.rgb"; + const char *ambientStr = (gstate.materialupdate & 1) && hasColor ? "color0" : "u_matambientalpha"; + const char *diffuseStr = (gstate.materialupdate & 2) && hasColor ? "color0.rgb" : "u_matdiffuse"; + const char *specularStr = (gstate.materialupdate & 4) && hasColor ? "color0.rgb" : "u_matspecular.rgb"; bool diffuseIsZero = true; bool specularIsZero = true; diff --git a/GPU/Math3D.cpp b/GPU/Math3D.cpp index 48577017eb..a521628588 100644 --- a/GPU/Math3D.cpp +++ b/GPU/Math3D.cpp @@ -17,6 +17,8 @@ #include "Math3D.h" +namespace Math3D { + template<> float Vec2::Length() const { @@ -188,3 +190,5 @@ float Vec4::Normalize() (*this) = (*this)/len; return len; } + +}; // namespace Math3D \ No newline at end of file diff --git a/GPU/Math3D.h b/GPU/Math3D.h index e1095511b1..f5502c304c 100644 --- a/GPU/Math3D.h +++ b/GPU/Math3D.h @@ -19,6 +19,8 @@ #include +namespace Math3D { + // Helper for Vec classes to clamp values. template inline static T VecClamp(const T &v, const T &low, const T &high) @@ -318,8 +320,6 @@ public: #undef _DEFINE_SWIZZLER2 }; -typedef Vec3 Vec3f; - template class Vec4 { @@ -488,8 +488,6 @@ public: #undef _DEFINE_SWIZZLER3 }; -typedef Vec4 Vec4f; - template class Mat3x3 @@ -590,6 +588,11 @@ private: BaseType values[4*4]; }; +}; // namespace Math3D + +typedef Math3D::Vec3 Vec3f; +typedef Math3D::Vec4 Vec4f; + inline void Vec3ByMatrix43(float vecOut[3], const float v[3], const float m[12]) { @@ -629,12 +632,33 @@ inline void Matrix4ByMatrix4(float out[16], const float a[16], const float b[16] Vec4ByMatrix44(out + 12, a + 12, b); } +inline void ConvertMatrix4x3To4x4(float *m4x4, const float *m4x3) { + m4x4[0] = m4x3[0]; + m4x4[1] = m4x3[1]; + m4x4[2] = m4x3[2]; + m4x4[3] = 0.0f; + m4x4[4] = m4x3[3]; + m4x4[5] = m4x3[4]; + m4x4[6] = m4x3[5]; + m4x4[7] = 0.0f; + m4x4[8] = m4x3[6]; + m4x4[9] = m4x3[7]; + m4x4[10] = m4x3[8]; + m4x4[11] = 0.0f; + m4x4[12] = m4x3[9]; + m4x4[13] = m4x3[10]; + m4x4[14] = m4x3[11]; + m4x4[15] = 1.0f; +} + inline float Vec3Dot(const float v1[3], const float v2[3]) { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; } +namespace Math3D { + template inline T Dot(const Vec2& a, const Vec2& b) { @@ -659,6 +683,8 @@ inline Vec3 Cross(const Vec3& a, const Vec3& b) return Vec3(a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x); } +}; // namespace Math3D + // linear interpolation via float: 0.0=begin, 1.0=end template inline X Lerp(const X& begin, const X& end, const float t) diff --git a/GPU/Software/Lighting.cpp b/GPU/Software/Lighting.cpp index 4977873a67..d2a127373c 100644 --- a/GPU/Software/Lighting.cpp +++ b/GPU/Software/Lighting.cpp @@ -21,11 +21,11 @@ namespace Lighting { -void Process(VertexData& vertex) +void Process(VertexData& vertex, bool hasColor) { Vec3 mec = Vec3(gstate.getMaterialEmissiveR(), gstate.getMaterialEmissiveG(), gstate.getMaterialEmissiveB()); - Vec3 mac = (gstate.materialupdate&1) + Vec3 mac = hasColor && (gstate.materialupdate&1) ? vertex.color0.rgb() : Vec3(gstate.getMaterialAmbientR(), gstate.getMaterialAmbientG(), gstate.getMaterialAmbientB()); Vec3 final_color = mec + mac * Vec3(gstate.getAmbientR(), gstate.getAmbientG(), gstate.getAmbientB()) / 255; @@ -92,7 +92,7 @@ void Process(VertexData& vertex) // diffuse lighting Vec3 ldc = Vec3(gstate.getDiffuseColorR(light), gstate.getDiffuseColorG(light), gstate.getDiffuseColorB(light)); - Vec3 mdc = (gstate.materialupdate&2) + Vec3 mdc = hasColor && (gstate.materialupdate&2) ? vertex.color0.rgb() : Vec3(gstate.getMaterialDiffuseR(), gstate.getMaterialDiffuseG(), gstate.getMaterialDiffuseB()); @@ -115,7 +115,7 @@ void Process(VertexData& vertex) Vec3 H = worldE / worldE.Length() + L / L.Length(); Vec3 lsc = Vec3(gstate.getSpecularColorR(light), gstate.getSpecularColorG(light), gstate.getSpecularColorB(light)); - Vec3 msc = (gstate.materialupdate&4) + Vec3 msc = hasColor && (gstate.materialupdate&4) ? vertex.color0.rgb() : Vec3(gstate.getMaterialSpecularR(), gstate.getMaterialSpecularG(), gstate.getMaterialSpecularB()); @@ -144,7 +144,7 @@ void Process(VertexData& vertex) vertex.color1 = Vec3(0, 0, 0); } - int maa = (gstate.materialupdate&1) ? vertex.color0.a() : gstate.getMaterialAmbientA(); + int maa = hasColor && (gstate.materialupdate&1) ? vertex.color0.a() : gstate.getMaterialAmbientA(); vertex.color0.a() = gstate.getAmbientA() * maa / 255; vertex.color0 = vertex.color0.Clamp(0, 255); diff --git a/GPU/Software/Lighting.h b/GPU/Software/Lighting.h index 6d1aea34eb..9e08eacade 100644 --- a/GPU/Software/Lighting.h +++ b/GPU/Software/Lighting.h @@ -21,6 +21,6 @@ namespace Lighting { -void Process(VertexData& vertex); +void Process(VertexData& vertex, bool hasColor); } \ No newline at end of file diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 4fa96379ac..0aad8f6206 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -433,7 +433,7 @@ static inline bool DepthTestPassed(int x, int y, u16 z) } } -static inline bool IsRightSideOrFlatBottomLine(const Vec2& vertex, const Vec2& line1, const Vec2& line2) +static inline bool IsRightSideOrFlatBottomLine(const Vec2& vertex, const Vec2& line1, const Vec2& line2) { if (line1.y == line2.y) { // just check if vertex is above us => bottom line parallel to x-axis @@ -1260,14 +1260,16 @@ void DrawLine(const VertexData &v0, const VertexData &v1) bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) { - buffer.Allocate(gstate.DepthBufStride(), 512, GPU_DBG_FORMAT_8BIT); + int w = gstate.getRegionX2() - gstate.getRegionX1() + 1; + int h = gstate.getRegionY2() - gstate.getRegionY1() + 1; + buffer.Allocate(w, h, GPU_DBG_FORMAT_8BIT); u8 *row = buffer.GetData(); - for (int y = 0; y < 512; ++y) { - for (int x = 0; x < gstate.DepthBufStride(); ++x) { - row[x] = GetPixelStencil(x, y); + for (int y = gstate.getRegionY1(); y <= gstate.getRegionY2(); ++y) { + for (int x = gstate.getRegionX1(); x <= gstate.getRegionX2(); ++x) { + row[x - gstate.getRegionX1()] = GetPixelStencil(x, y); } - row += gstate.DepthBufStride(); + row += w; } return true; } diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 32e5461eda..4945fa9172 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -865,17 +865,35 @@ bool SoftGPU::FramebufferDirty() { bool SoftGPU::GetCurrentFramebuffer(GPUDebugBuffer &buffer) { - // We don't know the height, so just use 512, which should be the max (hopefully?) - // TODO: Could check clipping and such, though...? - buffer = GPUDebugBuffer(fb.data, gstate.FrameBufStride(), 512, gstate.FrameBufFormat()); + const int w = gstate.getRegionX2() - gstate.getRegionX1() + 1; + const int h = gstate.getRegionY2() - gstate.getRegionY1() + 1; + buffer.Allocate(w, h, gstate.FrameBufFormat()); + + const int depth = gstate.FrameBufFormat() == GE_FORMAT_8888 ? 4 : 2; + const u8 *src = fb.data + gstate.FrameBufStride() * depth * gstate.getRegionY1(); + u8 *dst = buffer.GetData(); + for (int y = gstate.getRegionY1(); y <= gstate.getRegionY2(); ++y) { + memcpy(dst, src + gstate.getRegionX1(), (gstate.getRegionX2() + 1) * depth); + dst += w * depth; + src += gstate.FrameBufStride() * depth; + } return true; } bool SoftGPU::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) { - // We don't know the height, so just use 512, which should be the max (hopefully?) - // TODO: Could check clipping and such, though...? - buffer = GPUDebugBuffer(depthbuf.data, gstate.DepthBufStride(), 512, GPU_DBG_FORMAT_16BIT); + const int w = gstate.getRegionX2() - gstate.getRegionX1() + 1; + const int h = gstate.getRegionY2() - gstate.getRegionY1() + 1; + buffer.Allocate(w, h, GPU_DBG_FORMAT_16BIT); + + const int depth = 2; + const u8 *src = depthbuf.data + gstate.DepthBufStride() * depth * gstate.getRegionY1(); + u8 *dst = buffer.GetData(); + for (int y = gstate.getRegionY1(); y <= gstate.getRegionY2(); ++y) { + memcpy(dst, src + gstate.getRegionX1(), (gstate.getRegionX2() + 1) * depth); + dst += w * depth; + src += gstate.DepthBufStride() * depth; + } return true; } @@ -888,3 +906,8 @@ bool SoftGPU::GetCurrentTexture(GPUDebugBuffer &buffer) { return Rasterizer::GetCurrentTexture(buffer); } + +bool SoftGPU::GetCurrentSimpleVertices(int count, std::vector &vertices, std::vector &indices) +{ + return TransformUnit::GetCurrentSimpleVertices(count, vertices, indices); +} diff --git a/GPU/Software/SoftGpu.h b/GPU/Software/SoftGpu.h index 5efb39afe9..575e18fea8 100644 --- a/GPU/Software/SoftGpu.h +++ b/GPU/Software/SoftGpu.h @@ -86,6 +86,7 @@ public: virtual bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer); virtual bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer); virtual bool GetCurrentTexture(GPUDebugBuffer &buffer); + bool GetCurrentSimpleVertices(int count, std::vector &vertices, std::vector &indices); protected: virtual void FastRunLoop(DisplayList &list); diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index d5f51b8bb9..0e964740e5 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -16,8 +16,11 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Core/Host.h" -#include "../GPUState.h" -#include "../GLES/VertexDecoder.h" +#include "Core/Config.h" +#include "GPU/GPUState.h" +#include "GPU/GLES/VertexDecoder.h" +#include "GPU/GLES/TransformPipeline.h" +#include "GPU/Common/SplineCommon.h" #include "TransformUnit.h" #include "Clipper.h" @@ -177,7 +180,7 @@ static VertexData ReadVertex(VertexReader& vreader) vertex.worldnormal /= vertex.worldnormal.Length(); } - Lighting::Process(vertex); + Lighting::Process(vertex, vreader.hasColor0()); } else { vertex.screenpos.x = (u32)pos[0] * 16 + gstate.getOffsetX16(); vertex.screenpos.y = (u32)pos[1] * 16 + gstate.getOffsetY16(); @@ -473,3 +476,82 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, u32 prim_type host->GPUNotifyDraw(); } + +// TODO: This probably is not the best interface. +bool TransformUnit::GetCurrentSimpleVertices(int count, std::vector &vertices, std::vector &indices) { + // This is always for the current vertices. + u16 indexLowerBound = 0; + u16 indexUpperBound = count - 1; + + if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { + const u8 *inds = Memory::GetPointer(gstate_c.indexAddr); + const u16 *inds16 = (const u16 *)inds; + + if (inds) { + GetIndexBounds(inds, count, gstate.vertType, &indexLowerBound, &indexUpperBound); + indices.resize(count); + switch (gstate.vertType & GE_VTYPE_IDX_MASK) { + case GE_VTYPE_IDX_16BIT: + for (int i = 0; i < count; ++i) { + indices[i] = inds16[i]; + } + break; + case GE_VTYPE_IDX_8BIT: + for (int i = 0; i < count; ++i) { + indices[i] = inds[i]; + } + break; + default: + return false; + } + } else { + indices.clear(); + } + } else { + indices.clear(); + } + + static std::vector temp_buffer; + static std::vector simpleVertices; + temp_buffer.resize(65536 * 24 / sizeof(u32)); + simpleVertices.resize(indexUpperBound + 1); + + VertexDecoder vdecoder; + vdecoder.SetVertexType(gstate.vertType); + TransformDrawEngine::NormalizeVertices((u8 *)(&simpleVertices[0]), (u8 *)(&temp_buffer[0]), Memory::GetPointer(gstate_c.vertexAddr), &vdecoder, indexLowerBound, indexUpperBound, gstate.vertType); + + float world[16]; + float view[16]; + float worldview[16]; + float worldviewproj[16]; + ConvertMatrix4x3To4x4(world, gstate.worldMatrix); + ConvertMatrix4x3To4x4(view, gstate.viewMatrix); + Matrix4ByMatrix4(worldview, world, view); + Matrix4ByMatrix4(worldviewproj, worldview, gstate.projMatrix); + + vertices.resize(indexUpperBound + 1); + for (int i = indexLowerBound; i <= indexUpperBound; ++i) { + const SimpleVertex &vert = simpleVertices[i]; + + if (gstate.isModeThrough()) { + vertices[i].u = vert.uv[0]; + vertices[i].v = vert.uv[1]; + vertices[i].x = vert.pos.x; + vertices[i].y = vert.pos.y; + vertices[i].z = vert.pos.z; + } else { + float clipPos[4]; + Vec3ByMatrix44(clipPos, vert.pos.AsArray(), worldviewproj); + ScreenCoords screenPos = ClipToScreen(clipPos); + DrawingCoords drawPos = ScreenToDrawing(screenPos); + + vertices[i].u = vert.uv[0]; + vertices[i].v = vert.uv[1]; + vertices[i].x = drawPos.x; + vertices[i].y = drawPos.y; + vertices[i].z = 1.0; + } + } + + return true; +} diff --git a/GPU/Software/TransformUnit.h b/GPU/Software/TransformUnit.h index ba616cc30d..fbcd459a22 100644 --- a/GPU/Software/TransformUnit.h +++ b/GPU/Software/TransformUnit.h @@ -18,8 +18,11 @@ #pragma once #include "CommonTypes.h" +#include "GPU/Common/GPUDebugInterface.h" #include "../Math3D.h" +using namespace Math3D; + typedef u16 fixed16; typedef u16 u10; // TODO: erm... :/ @@ -118,4 +121,6 @@ public: static void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type); static void SubmitPrimitive(void* vertices, void* indices, u32 prim_type, int vertex_count, u32 vertex_type, int *bytesRead); + + static bool GetCurrentSimpleVertices(int count, std::vector &vertices, std::vector &indices); };