diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 43c6628a14..6b24608855 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -1087,8 +1087,9 @@ void Renderer::ApplyState(bool bUseDstAlpha) SetLogicOpMode(); } - D3D::context->PSSetConstantBuffers(0, 1, &PixelShaderCache::GetConstantBuffer()); - D3D::context->VSSetConstantBuffers(0, 1, &VertexShaderCache::GetConstantBuffer()); + ID3D11Buffer* const_buffers[2] = {PixelShaderCache::GetConstantBuffer(), VertexShaderCache::GetConstantBuffer()}; + D3D::context->PSSetConstantBuffers(0, 1 + g_ActiveConfig.bEnablePixelLighting, const_buffers); + D3D::context->VSSetConstantBuffers(0, 1, const_buffers+1); D3D::context->PSSetShader(PixelShaderCache::GetActiveShader(), nullptr, 0); D3D::context->VSSetShader(VertexShaderCache::GetActiveShader(), nullptr, 0); diff --git a/Source/Core/VideoBackends/Software/TransformUnit.cpp b/Source/Core/VideoBackends/Software/TransformUnit.cpp index 2c4c495087..f79c57be00 100644 --- a/Source/Core/VideoBackends/Software/TransformUnit.cpp +++ b/Source/Core/VideoBackends/Software/TransformUnit.cpp @@ -210,7 +210,7 @@ inline float SafeDivide(float n, float d) void LightColor(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, Vec3 &lightCol) { - const LightPointer *light = (const LightPointer*)&xfmem.lights[0x10*lightNum]; + const LightPointer *light = (const LightPointer*)&xfmem.lights[lightNum]; if (!(chan.attnfunc & 1)) { @@ -295,7 +295,7 @@ void LightColor(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChann void LightAlpha(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, float &lightCol) { - const LightPointer *light = (const LightPointer*)&xfmem.lights[0x10*lightNum]; + const LightPointer *light = (const LightPointer*)&xfmem.lights[lightNum]; if (!(chan.attnfunc & 1)) { @@ -476,7 +476,7 @@ void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst, bool s break; case XF_TEXGEN_EMBOSS_MAP: { - const LightPointer *light = (const LightPointer*)&xfmem.lights[0x10*texinfo.embosslightshift]; + const LightPointer *light = (const LightPointer*)&xfmem.lights[texinfo.embosslightshift]; Vec3 ldir = (light->pos - dst->mvPosition).normalized(); float d1 = ldir * dst->normal[1]; diff --git a/Source/Core/VideoBackends/Software/XFMemLoader.cpp b/Source/Core/VideoBackends/Software/XFMemLoader.cpp index d175e6b6dc..bdf8967667 100644 --- a/Source/Core/VideoBackends/Software/XFMemLoader.cpp +++ b/Source/Core/VideoBackends/Software/XFMemLoader.cpp @@ -23,7 +23,7 @@ void XFWritten(u32 transferSize, u32 baseAddress) // fix lights so invalid values don't trash the lighting computations if (baseAddress <= 0x067f && topAddress >= 0x0604) { - u32* x = xfmem.lights; + u32* x = (u32*)xfmem.lights; // go through all lights for (int light = 0; light < 8; light++) diff --git a/Source/Core/VideoCommon/ConstantManager.h b/Source/Core/VideoCommon/ConstantManager.h index b03d2ced6d..7a487b7ee7 100644 --- a/Source/Core/VideoCommon/ConstantManager.h +++ b/Source/Core/VideoCommon/ConstantManager.h @@ -21,11 +21,6 @@ struct PixelShaderConstants int4 fogcolor; int4 fogi; float4 fogf[2]; - - // For pixel lighting - int4 plight_colors[8]; - float4 plights[32]; - int4 pmaterials[4]; }; struct VertexShaderConstants @@ -33,11 +28,18 @@ struct VertexShaderConstants float4 posnormalmatrix[6]; float4 projection[4]; int4 materials[4]; - int4 light_colors[8]; // 8 lights - float4 lights[32]; // 8 lights * 4 parameters + struct Light + { + int4 color; + float4 cosatt; + float4 distatt; + float4 pos; + float4 dir; + } lights [8]; float4 texmatrices[24]; float4 transformmatrices[64]; float4 normalmatrices[32]; float4 posttransformmatrices[64]; float4 depthparams; }; + diff --git a/Source/Core/VideoCommon/LightingShaderGen.h b/Source/Core/VideoCommon/LightingShaderGen.h index 7104b65d36..05f4e607c5 100644 --- a/Source/Core/VideoCommon/LightingShaderGen.h +++ b/Source/Core/VideoCommon/LightingShaderGen.h @@ -4,25 +4,26 @@ #pragma once +#include "VideoCommon/ConstantManager.h" #include "VideoCommon/NativeVertexFormat.h" #include "VideoCommon/ShaderGenCommon.h" #include "VideoCommon/XFMemory.h" -#define LIGHT_COL "%s[%d].%s" -#define LIGHT_COL_PARAMS(lightsColName, index, swizzle) (lightsColName), (index), (swizzle) +#define LIGHT_COL "%s[%d].color.%s" +#define LIGHT_COL_PARAMS(index, swizzle) (I_LIGHTS), (index), (swizzle) -#define LIGHT_COSATT "%s[4*%d]" -#define LIGHT_COSATT_PARAMS(lightsName, index) (lightsName), (index) +#define LIGHT_COSATT "%s[%d].cosatt" +#define LIGHT_COSATT_PARAMS(index) (I_LIGHTS), (index) -#define LIGHT_DISTATT "%s[4*%d+1]" -#define LIGHT_DISTATT_PARAMS(lightsName, index) (lightsName), (index) +#define LIGHT_DISTATT "%s[%d].distatt" +#define LIGHT_DISTATT_PARAMS(index) (I_LIGHTS), (index) -#define LIGHT_POS "%s[4*%d+2]" -#define LIGHT_POS_PARAMS(lightsName, index) (lightsName), (index) +#define LIGHT_POS "%s[%d].pos" +#define LIGHT_POS_PARAMS(index) (I_LIGHTS), (index) -#define LIGHT_DIR "%s[4*%d+3]" -#define LIGHT_DIR_PARAMS(lightsName, index) (lightsName), (index) +#define LIGHT_DIR "%s[%d].dir" +#define LIGHT_DIR_PARAMS(index) (I_LIGHTS), (index) /** * Common uid data used for shader generators that use lighting calculations. @@ -37,9 +38,17 @@ struct LightingUidData u32 light_mask : 32; // 4x8 bits }; +static const char s_lighting_struct[] = + "struct Light {\n" + "\tint4 color;\n" + "\tfloat4 cosatt;\n" + "\tfloat4 distatt;\n" + "\tfloat4 pos;\n" + "\tfloat4 dir;\n" + "};\n"; template -static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, int litchan_index, const char* lightsColName, const char* lightsName, int coloralpha) +static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, int litchan_index, int coloralpha) { const LitChannel& chan = (litchan_index > 1) ? xfmem.alpha[litchan_index-2] : xfmem.color[litchan_index]; const char* swizzle = (coloralpha == 1) ? "xyz" : (coloralpha == 2) ? "w" : "xyzw"; @@ -53,14 +62,14 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, switch (chan.diffusefunc) { case LIGHTDIF_NONE: - object.Write("lacc.%s += " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(lightsColName, index, swizzle)); + object.Write("lacc.%s += " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(index, swizzle)); break; case LIGHTDIF_SIGN: case LIGHTDIF_CLAMP: - object.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(lightsName, index)); + object.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(index)); object.Write("lacc.%s += int%s(round(%sdot(ldir, _norm0)) * float%s(" LIGHT_COL")));\n", swizzle, swizzle_components, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(", - swizzle_components, LIGHT_COL_PARAMS(lightsColName, index, swizzle)); + swizzle_components, LIGHT_COL_PARAMS(index, swizzle)); break; default: _assert_(0); } @@ -69,24 +78,24 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, { if (chan.attnfunc == 3) { // spot - object.Write("ldir = " LIGHT_POS".xyz - pos.xyz;\n", LIGHT_POS_PARAMS(lightsName, index)); + object.Write("ldir = " LIGHT_POS".xyz - pos.xyz;\n", LIGHT_POS_PARAMS(index)); object.Write("dist2 = dot(ldir, ldir);\n" "dist = sqrt(dist2);\n" "ldir = ldir / dist;\n" "attn = max(0.0, dot(ldir, " LIGHT_DIR".xyz));\n", - LIGHT_DIR_PARAMS(lightsName, index)); + LIGHT_DIR_PARAMS(index)); // attn*attn may overflow object.Write("attn = max(0.0, " LIGHT_COSATT".x + " LIGHT_COSATT".y*attn + " LIGHT_COSATT".z*attn*attn) / dot(" LIGHT_DISTATT".xyz, float3(1.0,dist,dist2));\n", - LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_DISTATT_PARAMS(lightsName, index)); + LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index), LIGHT_DISTATT_PARAMS(index)); } else if (chan.attnfunc == 1) { // specular - object.Write("ldir = normalize(" LIGHT_POS".xyz);\n", LIGHT_POS_PARAMS(lightsName, index)); - object.Write("attn = (dot(_norm0,ldir) >= 0.0) ? max(0.0, dot(_norm0, " LIGHT_DIR".xyz)) : 0.0;\n", LIGHT_DIR_PARAMS(lightsName, index)); + object.Write("ldir = normalize(" LIGHT_POS".xyz);\n", LIGHT_POS_PARAMS(index)); + object.Write("attn = (dot(_norm0,ldir) >= 0.0) ? max(0.0, dot(_norm0, " LIGHT_DIR".xyz)) : 0.0;\n", LIGHT_DIR_PARAMS(index)); // attn*attn may overflow object.Write("attn = max(0.0, " LIGHT_COSATT".x + " LIGHT_COSATT".y*attn + " LIGHT_COSATT".z*attn*attn) / (" LIGHT_DISTATT".x + " LIGHT_DISTATT".y*attn + " LIGHT_DISTATT".z*attn*attn);\n", - LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_COSATT_PARAMS(lightsName, index), - LIGHT_DISTATT_PARAMS(lightsName, index), LIGHT_DISTATT_PARAMS(lightsName, index), LIGHT_DISTATT_PARAMS(lightsName, index)); + LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index), + LIGHT_DISTATT_PARAMS(index), LIGHT_DISTATT_PARAMS(index), LIGHT_DISTATT_PARAMS(index)); } switch (chan.diffusefunc) @@ -94,14 +103,14 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, case LIGHTDIF_NONE: object.Write("lacc.%s += int%s(round(attn * float%s(" LIGHT_COL")));\n", swizzle, swizzle_components, - swizzle_components, LIGHT_COL_PARAMS(lightsColName, index, swizzle)); + swizzle_components, LIGHT_COL_PARAMS(index, swizzle)); break; case LIGHTDIF_SIGN: case LIGHTDIF_CLAMP: object.Write("lacc.%s += int%s(round(attn * %sdot(ldir, _norm0)) * float%s(" LIGHT_COL")));\n", swizzle, swizzle_components, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(", - swizzle_components, LIGHT_COL_PARAMS(lightsColName, index, swizzle)); + swizzle_components, LIGHT_COL_PARAMS(index, swizzle)); break; default: _assert_(0); } @@ -115,7 +124,7 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, // inColorName is color in vs and colors_ in ps // dest is o.colors_ in vs and colors_ in ps template -static void GenerateLightingShader(T& object, LightingUidData& uid_data, int components, const char* materialsName, const char* lightsColName, const char* lightsName, const char* inColorName, const char* dest) +static void GenerateLightingShader(T& object, LightingUidData& uid_data, int components, const char* inColorName, const char* dest) { for (unsigned int j = 0; j < xfmem.numChan.numColorChans; j++) { @@ -136,7 +145,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com } else // from color { - object.Write("int4 mat = %s[%d];\n", materialsName, j+2); + object.Write("int4 mat = %s[%d];\n", I_MATERIALS, j+2); } uid_data.enablelighting |= xfmem.color[j].enablelighting << j; @@ -157,7 +166,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com } else // from color { - object.Write("lacc = %s[%d];\n", materialsName, j); + object.Write("lacc = %s[%d];\n", I_MATERIALS, j); } } else @@ -179,7 +188,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com } else // from color { - object.Write("mat.w = %s[%d].w;\n", materialsName, j+2); + object.Write("mat.w = %s[%d].w;\n", I_MATERIALS, j+2); } } @@ -199,7 +208,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com } else // from color { - object.Write("lacc.w = %s[%d].w;\n", materialsName, j); + object.Write("lacc.w = %s[%d].w;\n", I_MATERIALS, j); } } else @@ -226,7 +235,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com { if (mask & (1<(object, uid_data, i, j, lightsColName, lightsName, 3); + GenerateLightShader(object, uid_data, i, j, 3); } } } @@ -236,9 +245,9 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com for (int i = 0; i < 8; ++i) { if (!(mask&(1<(object, uid_data, i, j, lightsColName, lightsName, 1); + GenerateLightShader(object, uid_data, i, j, 1); if (!(mask&(1<(object, uid_data, i, j+2, lightsColName, lightsName, 2); + GenerateLightShader(object, uid_data, i, j+2, 2); } } else if (color.enablelighting || alpha.enablelighting) @@ -252,7 +261,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com for (int i = 0; i < 8; ++i) { if (workingchannel.GetFullLightMask() & (1<(object, uid_data, i, lit_index, lightsColName, lightsName, coloralpha); + GenerateLightShader(object, uid_data, i, lit_index, coloralpha); } } object.Write("lacc = clamp(lacc, 0, 255);"); diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index b3db7ec6a5..0b4ed68892 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -11,6 +11,7 @@ #endif #include "VideoCommon/BPMemory.h" +#include "VideoCommon/ConstantManager.h" #include "VideoCommon/LightingShaderGen.h" #include "VideoCommon/NativeVertexFormat.h" #include "VideoCommon/PixelShaderGen.h" @@ -218,9 +219,13 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T out.Write("\n"); if (ApiType == API_OPENGL) + { out.Write("layout(std140%s) uniform PSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 1" : ""); + } else - out.Write("cbuffer PSBlock {\n"); + { + out.Write("cbuffer PSBlock : register(b0) {\n"); + } out.Write( "\tint4 " I_COLORS"[4];\n" "\tint4 " I_KCOLORS"[4];\n" @@ -232,13 +237,32 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T "\tint4 " I_FOGCOLOR";\n" "\tint4 " I_FOGI";\n" "\tfloat4 " I_FOGF"[2];\n" - - // For pixel lighting - TODO: Should only be defined when per pixel lighting is enabled! - "\tint4 " I_PLIGHT_COLORS"[8];\n" - "\tfloat4 " I_PLIGHTS"[32];\n" - "\tint4 " I_PMATERIALS"[4];\n" "};\n"); + if (g_ActiveConfig.bEnablePixelLighting) + { + out.Write("%s", s_lighting_struct); + + if (ApiType == API_OPENGL) + { + out.Write("layout(std140%s) uniform VSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 2" : ""); + } + else + { + out.Write("cbuffer VSBlock : register(b1) {\n"); + } + out.Write( + "\tfloat4 " I_POSNORMALMATRIX"[6];\n" + "\tfloat4 " I_PROJECTION"[4];\n" + "\tint4 " I_MATERIALS"[4];\n" + "\tLight " I_LIGHTS"[8];\n" + "\tfloat4 " I_TEXMATRICES"[24];\n" + "\tfloat4 " I_TRANSFORMMATRICES"[64];\n" + "\tfloat4 " I_NORMALMATRICES"[32];\n" + "\tfloat4 " I_POSTTRANSFORMMATRICES"[64];\n" + "\tfloat4 " I_DEPTHPARAMS";\n" + "};\n"); + } const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED); const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) || (!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !forced_early_z); @@ -351,11 +375,13 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T "\tfloat3 ldir, h;\n" "\tfloat dist, dist2, attn;\n"); - out.SetConstantsUsed(C_PLIGHT_COLORS, C_PLIGHT_COLORS+7); // TODO: Can be optimized further - out.SetConstantsUsed(C_PLIGHTS, C_PLIGHTS+31); // TODO: Can be optimized further - out.SetConstantsUsed(C_PMATERIALS, C_PMATERIALS+3); + // TODO: Our current constant usage code isn't able to handle more than one buffer. + // So we can't mark the VS constant as used here. But keep them here as reference. + //out.SetConstantsUsed(C_PLIGHT_COLORS, C_PLIGHT_COLORS+7); // TODO: Can be optimized further + //out.SetConstantsUsed(C_PLIGHTS, C_PLIGHTS+31); // TODO: Can be optimized further + //out.SetConstantsUsed(C_PMATERIALS, C_PMATERIALS+3); uid_data.components = components; - GenerateLightingShader(out, uid_data.lighting, components, I_PMATERIALS, I_PLIGHT_COLORS, I_PLIGHTS, "colors_", "colors_"); + GenerateLightingShader(out, uid_data.lighting, components, "colors_", "colors_"); } // HACK to handle cases where the tex gen is not enabled diff --git a/Source/Core/VideoCommon/PixelShaderGen.h b/Source/Core/VideoCommon/PixelShaderGen.h index 135e4928f1..2be3f59ba3 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.h +++ b/Source/Core/VideoCommon/PixelShaderGen.h @@ -9,20 +9,6 @@ #include "VideoCommon/ShaderGenCommon.h" #include "VideoCommon/VideoCommon.h" -#define I_COLORS "color" -#define I_KCOLORS "k" -#define I_ALPHA "alphaRef" -#define I_TEXDIMS "texdim" -#define I_ZBIAS "czbias" -#define I_INDTEXSCALE "cindscale" -#define I_INDTEXMTX "cindmtx" -#define I_FOGCOLOR "cfogcolor" -#define I_FOGI "cfogi" -#define I_FOGF "cfogf" -#define I_PLIGHT_COLORS "cPLightColors" -#define I_PLIGHTS "cPLights" -#define I_PMATERIALS "cPmtrl" - // TODO: get rid of them as they aren't used #define C_COLORMATRIX 0 // 0 #define C_COLORS 0 // 0 @@ -36,10 +22,7 @@ #define C_FOGI (C_FOGCOLOR + 1) //28 #define C_FOGF (C_FOGI + 1) //29 -#define C_PLIGHT_COLORS (C_FOGF + 2) -#define C_PLIGHTS (C_PLIGHT_COLORS + 8) -#define C_PMATERIALS (C_PLIGHTS + 32) -#define C_PENVCONST_END (C_PMATERIALS + 4) +#define C_PENVCONST_END (C_FOGF + 2) // Different ways to achieve rendering with destination alpha enum DSTALPHA_MODE diff --git a/Source/Core/VideoCommon/PixelShaderManager.cpp b/Source/Core/VideoCommon/PixelShaderManager.cpp index 551f881c3e..3ea6713ebd 100644 --- a/Source/Core/VideoCommon/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/PixelShaderManager.cpp @@ -14,7 +14,6 @@ static bool s_bFogRangeAdjustChanged; static bool s_bViewPortChanged; -static int nLightsChanged[2]; // min,max PixelShaderConstants PixelShaderManager::constants; bool PixelShaderManager::dirty; @@ -29,7 +28,6 @@ void PixelShaderManager::Dirty() { s_bFogRangeAdjustChanged = true; s_bViewPortChanged = true; - nLightsChanged[0] = 0; nLightsChanged[1] = 0x80; SetColorChanged(0, 0); SetColorChanged(0, 1); @@ -100,45 +98,6 @@ void PixelShaderManager::SetConstants() s_bFogRangeAdjustChanged = false; } - if (g_ActiveConfig.bEnablePixelLighting) // config check added because the code in here was crashing for me inside SetPSConstant4f - { - if (nLightsChanged[0] >= 0) - { - // TODO: Outdated comment - // lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats - int istart = nLightsChanged[0] / 0x10; - int iend = (nLightsChanged[1] + 15) / 0x10; - const float* xfmemptr = (const float*)&xfmem.lights[0x10 * istart]; - - for (int i = istart; i < iend; ++i) - { - u32 color = *(const u32*)(xfmemptr + 3); - constants.plight_colors[i][0] = (color >> 24) & 0xFF; - constants.plight_colors[i][1] = (color >> 16) & 0xFF; - constants.plight_colors[i][2] = (color >> 8) & 0xFF; - constants.plight_colors[i][3] = (color) & 0xFF; - xfmemptr += 4; - - for (int j = 0; j < 4; ++j, xfmemptr += 3) - { - if (j == 1 && - fabs(xfmemptr[0]) < 0.00001f && - fabs(xfmemptr[1]) < 0.00001f && - fabs(xfmemptr[2]) < 0.00001f) - // dist attenuation, make sure not equal to 0!!! - constants.plights[4*i+j][0] = 0.00001f; - else - constants.plights[4*i+j][0] = xfmemptr[0]; - constants.plights[4*i+j][1] = xfmemptr[1]; - constants.plights[4*i+j][2] = xfmemptr[2]; - } - } - dirty = true; - - nLightsChanged[0] = nLightsChanged[1] = -1; - } - } - if (s_bViewPortChanged) { constants.zbias[1][0] = xfmem.viewport.farZ; @@ -304,38 +263,6 @@ void PixelShaderManager::SetFogRangeAdjustChanged() s_bFogRangeAdjustChanged = true; } -void PixelShaderManager::InvalidateXFRange(int start, int end) -{ - if (start < XFMEM_LIGHTS_END && end > XFMEM_LIGHTS) - { - int _start = start < XFMEM_LIGHTS ? XFMEM_LIGHTS : start-XFMEM_LIGHTS; - int _end = end < XFMEM_LIGHTS_END ? end-XFMEM_LIGHTS : XFMEM_LIGHTS_END-XFMEM_LIGHTS; - - if (nLightsChanged[0] == -1 ) - { - nLightsChanged[0] = _start; - nLightsChanged[1] = _end; - } - else - { - if (nLightsChanged[0] > _start) nLightsChanged[0] = _start; - if (nLightsChanged[1] < _end) nLightsChanged[1] = _end; - } - } -} - -void PixelShaderManager::SetMaterialColorChanged(int index, u32 color) -{ - if (g_ActiveConfig.bEnablePixelLighting) - { - constants.pmaterials[index][0] = (color >> 24) & 0xFF; - constants.pmaterials[index][1] = (color >> 16) & 0xFF; - constants.pmaterials[index][2] = (color >> 8) & 0xFF; - constants.pmaterials[index][3] = (color) & 0xFF; - dirty = true; - } -} - void PixelShaderManager::DoState(PointerWrap &p) { p.Do(constants); diff --git a/Source/Core/VideoCommon/PixelShaderManager.h b/Source/Core/VideoCommon/PixelShaderManager.h index bd0c904b43..5c07b0522a 100644 --- a/Source/Core/VideoCommon/PixelShaderManager.h +++ b/Source/Core/VideoCommon/PixelShaderManager.h @@ -39,8 +39,6 @@ public: static void SetFogColorChanged(); static void SetFogParamChanged(); static void SetFogRangeAdjustChanged(); - static void InvalidateXFRange(int start, int end); - static void SetMaterialColorChanged(int index, u32 color); static PixelShaderConstants constants; static bool dirty; diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h index af58342f1a..4f97865d54 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/ShaderGenCommon.h @@ -215,3 +215,25 @@ private: std::map m_shaders; std::vector m_uids; }; + +// Constant variable names +#define I_COLORS "color" +#define I_KCOLORS "k" +#define I_ALPHA "alphaRef" +#define I_TEXDIMS "texdim" +#define I_ZBIAS "czbias" +#define I_INDTEXSCALE "cindscale" +#define I_INDTEXMTX "cindmtx" +#define I_FOGCOLOR "cfogcolor" +#define I_FOGI "cfogi" +#define I_FOGF "cfogf" + +#define I_POSNORMALMATRIX "cpnmtx" +#define I_PROJECTION "cproj" +#define I_MATERIALS "cmtrl" +#define I_LIGHTS "clights" +#define I_TEXMATRICES "ctexmtx" +#define I_TRANSFORMMATRICES "ctrmtx" +#define I_NORMALMATRICES "cnmtx" +#define I_POSTTRANSFORMMATRICES "cpostmtx" +#define I_DEPTHPARAMS "cDepth" // farZ, zRange diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index d337537ff1..f02d4133b6 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -81,6 +81,8 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ _assert_(bpmem.genMode.numtexgens == xfmem.numTexGen.numTexGens); _assert_(bpmem.genMode.numcolchans == xfmem.numChan.numColorChans); + out.Write("%s", s_lighting_struct); + // uniforms if (api_type == API_OPENGL) out.Write("layout(std140%s) uniform VSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 2" : ""); @@ -90,8 +92,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ "\tfloat4 " I_POSNORMALMATRIX"[6];\n" "\tfloat4 " I_PROJECTION"[4];\n" "\tint4 " I_MATERIALS"[4];\n" - "\tint4 " I_LIGHT_COLORS"[8];\n" - "\tfloat4 " I_LIGHTS"[32];\n" + "\tLight " I_LIGHTS"[8];\n" "\tfloat4 " I_TEXMATRICES"[24];\n" "\tfloat4 " I_TRANSFORMMATRICES"[64];\n" "\tfloat4 " I_NORMALMATRICES"[32];\n" @@ -229,7 +230,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ out.Write("o.colors_0 = float4(1.0, 1.0, 1.0, 1.0);\n"); } - GenerateLightingShader(out, uid_data.lighting, components, I_MATERIALS, I_LIGHT_COLORS, I_LIGHTS, "color", "o.colors_"); + GenerateLightingShader(out, uid_data.lighting, components, "color", "o.colors_"); if (xfmem.numChan.numColorChans < 2) { @@ -304,7 +305,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ // transform the light dir into tangent space uid_data.texMtxInfo[i].embosslightshift = xfmem.texMtxInfo[i].embosslightshift; uid_data.texMtxInfo[i].embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift; - out.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(I_LIGHTS, texinfo.embosslightshift)); + out.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(texinfo.embosslightshift)); out.Write("o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0);\n", i, texinfo.embosssourceshift); } else diff --git a/Source/Core/VideoCommon/VertexShaderGen.h b/Source/Core/VideoCommon/VertexShaderGen.h index 43d5273f4a..718b62b04e 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.h +++ b/Source/Core/VideoCommon/VertexShaderGen.h @@ -28,19 +28,6 @@ #define SHADER_TEXTURE7_ATTRIB 15 - -// shader variables -#define I_POSNORMALMATRIX "cpnmtx" -#define I_PROJECTION "cproj" -#define I_MATERIALS "cmtrl" -#define I_LIGHT_COLORS "clight_colors" -#define I_LIGHTS "clights" -#define I_TEXMATRICES "ctexmtx" -#define I_TRANSFORMMATRICES "ctrmtx" -#define I_NORMALMATRICES "cnmtx" -#define I_POSTTRANSFORMMATRICES "cpostmtx" -#define I_DEPTHPARAMS "cDepth" // farZ, zRange - //TODO: get rid of them, they aren't used at all #define C_POSNORMALMATRIX 0 #define C_PROJECTION (C_POSNORMALMATRIX + 6) diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index ede4ddd9c7..b09ff4d32a 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -247,32 +247,44 @@ void VertexShaderManager::SetConstants() // lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats int istart = nLightsChanged[0] / 0x10; int iend = (nLightsChanged[1] + 15) / 0x10; - const float* xfmemptr = (const float*)&xfmem.lights[0x10 * istart]; for (int i = istart; i < iend; ++i) { - u32 color = *(const u32*)(xfmemptr + 3); - constants.light_colors[i][0] = (color >> 24) & 0xFF; - constants.light_colors[i][1] = (color >> 16) & 0xFF; - constants.light_colors[i][2] = (color >> 8) & 0xFF; - constants.light_colors[i][3] = (color) & 0xFF; - xfmemptr += 4; + const Light& light = xfmem.lights[i]; + VertexShaderConstants::Light& dstlight = constants.lights[i]; - for (int j = 0; j < 4; ++j, xfmemptr += 3) + // xfmem.light.color is packed as abgr in u8[4], so we have to swap the order + dstlight.color[0] = light.color[3]; + dstlight.color[1] = light.color[2]; + dstlight.color[2] = light.color[1]; + dstlight.color[3] = light.color[0]; + + dstlight.cosatt[0] = light.cosatt[0]; + dstlight.cosatt[1] = light.cosatt[1]; + dstlight.cosatt[2] = light.cosatt[2]; + + if (fabs(light.distatt[0]) < 0.00001f && + fabs(light.distatt[1]) < 0.00001f && + fabs(light.distatt[2]) < 0.00001f) { - if (j == 1 && - fabs(xfmemptr[0]) < 0.00001f && - fabs(xfmemptr[1]) < 0.00001f && - fabs(xfmemptr[2]) < 0.00001f) - { - // dist attenuation, make sure not equal to 0!!! - constants.lights[4*i+j][0] = 0.00001f; - } - else - constants.lights[4*i+j][0] = xfmemptr[0]; - constants.lights[4*i+j][1] = xfmemptr[1]; - constants.lights[4*i+j][2] = xfmemptr[2]; + // dist attenuation, make sure not equal to 0!!! + dstlight.distatt[0] = .00001f; } + else + { + dstlight.distatt[0] = light.distatt[0]; + } + dstlight.distatt[1] = light.distatt[1]; + dstlight.distatt[2] = light.distatt[2]; + + dstlight.pos[0] = light.dpos[0]; + dstlight.pos[1] = light.dpos[1]; + dstlight.pos[2] = light.dpos[2]; + + // TODO: these likely have to be normalized + dstlight.dir[0] = light.ddir[0]; + dstlight.dir[1] = light.ddir[1]; + dstlight.dir[2] = light.ddir[2]; } dirty = true; diff --git a/Source/Core/VideoCommon/XFMemory.h b/Source/Core/VideoCommon/XFMemory.h index 07ae526bb4..f36378b1e9 100644 --- a/Source/Core/VideoCommon/XFMemory.h +++ b/Source/Core/VideoCommon/XFMemory.h @@ -194,13 +194,9 @@ union DualTexInfo struct Light { u32 useless[3]; - u32 color; // rgba - float a0; // attenuation - float a1; - float a2; - float k0; // k stuff - float k1; - float k2; + u8 color[4]; + float cosatt[3]; // cos attenuation + float distatt[3]; // dist attenuation union { @@ -241,7 +237,7 @@ struct XFMemory u32 normalMatrices[96]; // 0x0400 - 0x045f u32 unk1[160]; // 0x0460 - 0x04ff u32 postMatrices[256]; // 0x0500 - 0x05ff - u32 lights[128]; // 0x0600 - 0x067f + Light lights[8]; // 0x0600 - 0x067f u32 unk2[2432]; // 0x0680 - 0x0fff u32 error; // 0x1000 u32 diag; // 0x1001 diff --git a/Source/Core/VideoCommon/XFStructs.cpp b/Source/Core/VideoCommon/XFStructs.cpp index 62a17ad829..fb20c3d289 100644 --- a/Source/Core/VideoCommon/XFStructs.cpp +++ b/Source/Core/VideoCommon/XFStructs.cpp @@ -15,7 +15,6 @@ void XFMemWritten(u32 transferSize, u32 baseAddress) { VertexManager::Flush(); VertexShaderManager::InvalidateXFRange(baseAddress, baseAddress + transferSize); - PixelShaderManager::InvalidateXFRange(baseAddress, baseAddress + transferSize); } void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData) @@ -61,7 +60,6 @@ void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData) { VertexManager::Flush(); VertexShaderManager::SetMaterialColorChanged(chan, newValue); - PixelShaderManager::SetMaterialColorChanged(chan, newValue); } break; } @@ -74,7 +72,6 @@ void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData) { VertexManager::Flush(); VertexShaderManager::SetMaterialColorChanged(chan + 2, newValue); - PixelShaderManager::SetMaterialColorChanged(chan + 2, newValue); } break; }