From 57577ede26d0dd157881b6dd4b34d62a83208b2a Mon Sep 17 00:00:00 2001 From: XProger Date: Sun, 13 Jan 2019 16:09:47 +0300 Subject: [PATCH] #15 PSV shader variations for different blendMode and colorMask --- src/gapi_gxm.h | 68 ++++++++++++++++------- src/level.h | 2 + src/platform/win/OpenLara.vcxproj | 1 + src/platform/win/OpenLara.vcxproj.filters | 1 + 4 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/gapi_gxm.h b/src/gapi_gxm.h index 70936ec..b9d4701 100644 --- a/src/gapi_gxm.h +++ b/src/gapi_gxm.h @@ -384,9 +384,13 @@ namespace GAPI { struct Shader { SceGxmVertexProgram *vp; - SceGxmFragmentProgram *fp; + SceGxmShaderPatcherId vpUID; SceGxmProgram *vpPtr, *fpPtr; - SceGxmShaderPatcherId vpUID, fpUID; + + struct PSO { + SceGxmFragmentProgram *fp; + SceGxmShaderPatcherId fpUID; + } pso[2 * bmMAX]; const SceGxmProgramParameter *vParams[uMAX]; const SceGxmProgramParameter *fParams[uMAX]; @@ -395,10 +399,13 @@ namespace GAPI { int cbCount[uMAX]; int colorMask, blendMode; + int psoIndex; bool rebind; void init(Pass pass, int type, int *def, int defCount) { + memset(pso, 0, sizeof(pso)); + const uint8 *vpSrc, *fpSrc; switch (pass) { case passCompose : vpSrc = COMPOSE_VP; fpSrc = COMPOSE_FP; break; @@ -430,7 +437,6 @@ namespace GAPI { fpPtr = (SceGxmProgram*)fpSrc; sceGxmShaderPatcherRegisterProgram(shaderPatcher, vpPtr, &vpUID); - sceGxmShaderPatcherRegisterProgram(shaderPatcher, fpPtr, &fpUID); SceGxmVertexStream vStream; vStream.stride = sizeof(Vertex); @@ -467,20 +473,27 @@ namespace GAPI { } sceGxmShaderPatcherCreateVertexProgram(shaderPatcher, vpUID, vAttrib, vAttribCount, &vStream, 1, &vp); - sceGxmShaderPatcherCreateFragmentProgram(shaderPatcher, fpUID, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, SCE_GXM_MULTISAMPLE_NONE, NULL, vpPtr, &fp); for (int ut = 0; ut < uMAX; ut++) { vParams[ut] = sceGxmProgramFindParameterByName(vpPtr, UniformName[ut]); fParams[ut] = sceGxmProgramFindParameterByName(fpPtr, UniformName[ut]); } - colorMask = SCE_GXM_COLOR_MASK_ALL; - blendMode = 0; + colorMask = blendMode = -1; } void deinit() { + sceGxmDisplayQueueFinish(); + + sceGxmShaderPatcherReleaseVertexProgram(shaderPatcher, vp); sceGxmShaderPatcherUnregisterProgram(shaderPatcher, vpUID); - sceGxmShaderPatcherUnregisterProgram(shaderPatcher, fpUID); + + for (int i = 0; i < COUNT(pso); i++) { + if (pso[i].fp) { + sceGxmShaderPatcherReleaseFragmentProgram(shaderPatcher, pso[i].fp); + sceGxmShaderPatcherUnregisterProgram(shaderPatcher, pso[i].fpUID); + } + } } void setBlendInfo(int colorMask, int blendMode) { @@ -493,30 +506,47 @@ namespace GAPI { blendInfo.colorMask = SceGxmColorMask(colorMask); blendInfo.colorFunc = SCE_GXM_BLEND_FUNC_ADD; blendInfo.alphaFunc = SCE_GXM_BLEND_FUNC_ADD; + blendInfo.alphaSrc = SCE_GXM_BLEND_FACTOR_ONE; + blendInfo.alphaDst = SCE_GXM_BLEND_FACTOR_ZERO; + psoIndex = 0; switch (blendMode) { case RS_BLEND_ALPHA : - blendInfo.colorSrc = blendInfo.alphaSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA; - blendInfo.colorDst = blendInfo.alphaDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + psoIndex = bmAlpha; + blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA; + blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; break; case RS_BLEND_ADD : - blendInfo.colorSrc = blendInfo.alphaSrc = SCE_GXM_BLEND_FACTOR_ONE; - blendInfo.colorDst = blendInfo.alphaDst = SCE_GXM_BLEND_FACTOR_ONE; + psoIndex = bmAdd; + blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_ONE; + blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ONE; break; case RS_BLEND_MULT : - blendInfo.colorSrc = blendInfo.alphaSrc = SCE_GXM_BLEND_FACTOR_DST_COLOR; - blendInfo.colorDst = blendInfo.alphaDst = SCE_GXM_BLEND_FACTOR_ZERO; + psoIndex = bmMult; + blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_DST_COLOR; + blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ZERO; break; case RS_BLEND_PREMULT : - blendInfo.colorSrc = blendInfo.alphaSrc = SCE_GXM_BLEND_FACTOR_ONE; - blendInfo.colorDst = blendInfo.alphaDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + psoIndex = bmPremult; + blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_ONE; + blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; break; default : - blendInfo.colorSrc = blendInfo.alphaSrc = SCE_GXM_BLEND_FACTOR_ONE; - blendInfo.colorDst = blendInfo.alphaDst = SCE_GXM_BLEND_FACTOR_ZERO; + psoIndex = bmNone; + blendInfo.colorSrc = SCE_GXM_BLEND_FACTOR_ONE; + blendInfo.colorDst = SCE_GXM_BLEND_FACTOR_ZERO; } - sceGxmShaderPatcherCreateFragmentProgram(shaderPatcher, fpUID, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, SCE_GXM_MULTISAMPLE_NONE, &blendInfo, vpPtr, &fp); + if (colorMask != SCE_GXM_COLOR_MASK_ALL) { + psoIndex += bmMAX; + } + + PSO &p = pso[psoIndex]; + + if (!p.fp) { + sceGxmShaderPatcherRegisterProgram(shaderPatcher, fpPtr, &p.fpUID); + sceGxmShaderPatcherCreateFragmentProgram(shaderPatcher, p.fpUID, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, SCE_GXM_MULTISAMPLE_NONE, &blendInfo, vpPtr, &p.fp); + } rebind = true; } @@ -535,7 +565,7 @@ namespace GAPI { void setup() { if (rebind) { sceGxmSetVertexProgram(Context::gxmContext, vp); - sceGxmSetFragmentProgram(Context::gxmContext, fp); + sceGxmSetFragmentProgram(Context::gxmContext, pso[psoIndex].fp); rebind = false; } diff --git a/src/level.h b/src/level.h index 5934da6..bfbd4bb 100644 --- a/src/level.h +++ b/src/level.h @@ -374,8 +374,10 @@ struct Level : IGame { Stream::cacheWrite("settings", (char*)&settings, sizeof(settings)); if (rebuildShaders) { + #if !defined(_GAPI_D3D9) && !defined(_GAPI_GXM) delete shaderCache; shaderCache = new ShaderCache(); + #endif } if (rebuildMesh) { diff --git a/src/platform/win/OpenLara.vcxproj b/src/platform/win/OpenLara.vcxproj index c76a9aa..6fbdae4 100644 --- a/src/platform/win/OpenLara.vcxproj +++ b/src/platform/win/OpenLara.vcxproj @@ -204,6 +204,7 @@ + diff --git a/src/platform/win/OpenLara.vcxproj.filters b/src/platform/win/OpenLara.vcxproj.filters index eaac777..a36e930 100644 --- a/src/platform/win/OpenLara.vcxproj.filters +++ b/src/platform/win/OpenLara.vcxproj.filters @@ -57,6 +57,7 @@ +