mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Merge pull request #13569 from hrydgard/shader-refactor-prep
Automatic shader generation tester
This commit is contained in:
commit
77ec537d1f
@ -1291,8 +1291,6 @@ set(GPU_D3D9
|
||||
GPU/Directx9/DepalettizeShaderDX9.h
|
||||
GPU/Directx9/DrawEngineDX9.cpp
|
||||
GPU/Directx9/DrawEngineDX9.h
|
||||
GPU/Directx9/PixelShaderGeneratorDX9.cpp
|
||||
GPU/Directx9/PixelShaderGeneratorDX9.h
|
||||
GPU/Directx9/FramebufferManagerDX9.cpp
|
||||
GPU/Directx9/FramebufferManagerDX9.h
|
||||
GPU/Directx9/GPU_DX9.cpp
|
||||
@ -1306,8 +1304,10 @@ set(GPU_D3D9
|
||||
GPU/Directx9/TextureCacheDX9.h
|
||||
GPU/Directx9/TextureScalerDX9.cpp
|
||||
GPU/Directx9/TextureScalerDX9.h
|
||||
GPU/Directx9/VertexShaderGeneratorDX9.cpp
|
||||
GPU/Directx9/VertexShaderGeneratorDX9.h
|
||||
GPU/Directx9/FragmentShaderGeneratorHLSL.cpp
|
||||
GPU/Directx9/FragmentShaderGeneratorHLSL.h
|
||||
GPU/Directx9/VertexShaderGeneratorHLSL.cpp
|
||||
GPU/Directx9/VertexShaderGeneratorHLSL.h
|
||||
)
|
||||
|
||||
set(GPU_D3D11
|
||||
@ -1315,8 +1315,6 @@ set(GPU_D3D11
|
||||
GPU/D3D11/DepalettizeShaderD3D11.h
|
||||
GPU/D3D11/DrawEngineD3D11.cpp
|
||||
GPU/D3D11/DrawEngineD3D11.h
|
||||
GPU/D3D11/FragmentShaderGeneratorD3D11.cpp
|
||||
GPU/D3D11/FragmentShaderGeneratorD3D11.h
|
||||
GPU/D3D11/FramebufferManagerD3D11.cpp
|
||||
GPU/D3D11/FramebufferManagerD3D11.h
|
||||
GPU/D3D11/GPU_D3D11.cpp
|
||||
@ -1332,8 +1330,6 @@ set(GPU_D3D11
|
||||
GPU/D3D11/TextureCacheD3D11.h
|
||||
GPU/D3D11/TextureScalerD3D11.cpp
|
||||
GPU/D3D11/TextureScalerD3D11.h
|
||||
GPU/D3D11/VertexShaderGeneratorD3D11.cpp
|
||||
GPU/D3D11/VertexShaderGeneratorD3D11.h
|
||||
)
|
||||
|
||||
# We build Vulkan even on Apple to avoid annoying build differences.
|
||||
|
@ -131,3 +131,21 @@ protected:
|
||||
|
||||
struct TBuiltInResource;
|
||||
void init_resources(TBuiltInResource &Resources);
|
||||
|
||||
enum DoLightComputation {
|
||||
LIGHT_OFF,
|
||||
LIGHT_SHADE,
|
||||
LIGHT_FULL,
|
||||
};
|
||||
|
||||
struct GLSLShaderCompat {
|
||||
const char *varying;
|
||||
const char *attribute;
|
||||
const char *fragColor0;
|
||||
const char *fragColor1;
|
||||
const char *texture;
|
||||
const char *texelFetch;
|
||||
const char *lastFragData;
|
||||
bool glslES30;
|
||||
bool bitwiseOps;
|
||||
};
|
||||
|
@ -159,6 +159,8 @@ protected:
|
||||
void SetBit(int bit, bool value = true) {
|
||||
if (value) {
|
||||
d[bit >> 5] |= 1 << (bit & 31);
|
||||
} else {
|
||||
d[bit >> 5] &= ~(1 << (bit & 31));
|
||||
}
|
||||
}
|
||||
void SetBits(int bit, int count, int value) {
|
||||
|
@ -46,30 +46,30 @@ struct UB_VS_FS_Base {
|
||||
};
|
||||
|
||||
static const char *ub_baseStr =
|
||||
R"( mat4 proj_mtx;
|
||||
mat4 proj_through_mtx;
|
||||
mat3x4 view_mtx;
|
||||
mat3x4 world_mtx;
|
||||
mat3x4 tex_mtx;
|
||||
vec4 uvscaleoffset;
|
||||
vec4 depthRange;
|
||||
vec2 fogcoef;
|
||||
float stencilReplace;
|
||||
vec4 matambientalpha;
|
||||
uint spline_counts;
|
||||
uint depal_mask_shift_off_fmt;
|
||||
int pad2;
|
||||
int pad3;
|
||||
vec4 cullRangeMin;
|
||||
vec4 cullRangeMax;
|
||||
vec3 fogcolor;
|
||||
vec3 texenv;
|
||||
ivec4 alphacolorref;
|
||||
ivec4 alphacolormask;
|
||||
vec3 blendFixA;
|
||||
vec3 blendFixB;
|
||||
vec4 texclamp;
|
||||
vec2 texclampoff;
|
||||
R"( mat4 u_proj;
|
||||
mat4 u_proj_through;
|
||||
mat3x4 u_view;
|
||||
mat3x4 u_world;
|
||||
mat3x4 u_tex;
|
||||
vec4 u_uvscaleoffset;
|
||||
vec4 u_depthRange;
|
||||
vec2 u_fogcoef;
|
||||
float u_stencilReplaceValue;
|
||||
vec4 u_matambientalpha;
|
||||
uint u_spline_counts;
|
||||
uint u_depal_mask_shift_off_fmt;
|
||||
int u_pad2;
|
||||
int u_pad3;
|
||||
vec4 u_cullRangeMin;
|
||||
vec4 u_cullRangeMax;
|
||||
vec3 u_fogcolor;
|
||||
vec3 u_texenv;
|
||||
ivec4 u_alphacolorref;
|
||||
ivec4 u_alphacolormask;
|
||||
vec3 u_blendFixA;
|
||||
vec3 u_blendFixB;
|
||||
vec4 u_texclamp;
|
||||
vec2 u_texclampoff;
|
||||
)";
|
||||
|
||||
// HLSL code is shared so these names are changed to match those in DX9.
|
||||
@ -118,16 +118,37 @@ struct UB_VS_Lights {
|
||||
|
||||
static const char *ub_vs_lightsStr =
|
||||
R"( vec4 u_ambient;
|
||||
vec3 matdiffuse;
|
||||
vec4 matspecular;
|
||||
vec3 matemissive;
|
||||
vec3 pos[4];
|
||||
vec3 dir[4];
|
||||
vec3 att[4];
|
||||
vec2 angle_spotCoef[4];
|
||||
vec3 ambient[4];
|
||||
vec3 diffuse[4];
|
||||
vec3 specular[4];
|
||||
vec3 u_matdiffuse;
|
||||
vec4 u_matspecular;
|
||||
vec3 u_matemissive;
|
||||
vec3 u_lightpos0;
|
||||
vec3 u_lightpos1;
|
||||
vec3 u_lightpos2;
|
||||
vec3 u_lightpos3;
|
||||
vec3 u_lightdir0;
|
||||
vec3 u_lightdir1;
|
||||
vec3 u_lightdir2;
|
||||
vec3 u_lightdir3;
|
||||
vec3 u_lightatt0;
|
||||
vec3 u_lightatt1;
|
||||
vec3 u_lightatt2;
|
||||
vec3 u_lightatt3;
|
||||
vec4 u_lightangle_spotCoef0;
|
||||
vec4 u_lightangle_spotCoef1;
|
||||
vec4 u_lightangle_spotCoef2;
|
||||
vec4 u_lightangle_spotCoef3;
|
||||
vec3 u_lightambient0;
|
||||
vec3 u_lightambient1;
|
||||
vec3 u_lightambient2;
|
||||
vec3 u_lightambient3;
|
||||
vec3 u_lightdiffuse0;
|
||||
vec3 u_lightdiffuse1;
|
||||
vec3 u_lightdiffuse2;
|
||||
vec3 u_lightdiffuse3;
|
||||
vec3 u_lightspecular0;
|
||||
vec3 u_lightspecular1;
|
||||
vec3 u_lightspecular2;
|
||||
vec3 u_lightspecular3;
|
||||
)";
|
||||
|
||||
// HLSL code is shared so these names are changed to match those in DX9.
|
||||
@ -167,13 +188,13 @@ R"( float4 u_ambient;
|
||||
)";
|
||||
|
||||
// With some cleverness, we could get away with uploading just half this when only the four or five first
|
||||
// bones are being used. This is 512b, 256b would be great.
|
||||
// bones are being used. This is 384b.
|
||||
struct UB_VS_Bones {
|
||||
float bones[8][12];
|
||||
};
|
||||
|
||||
static const char *ub_vs_bonesStr =
|
||||
R"( mat3x4 m[8];
|
||||
R"( mat3x4 u_bone[8];
|
||||
)";
|
||||
|
||||
// HLSL code is shared so these names are changed to match those in DX9.
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include "D3D11Util.h"
|
||||
|
||||
static std::vector<uint8_t> CompileShaderToBytecode(const char *code, size_t codeSize, const char *target, UINT flags) {
|
||||
std::vector<uint8_t> CompileShaderToBytecodeD3D11(const char *code, size_t codeSize, const char *target, UINT flags) {
|
||||
ID3DBlob *compiledCode = nullptr;
|
||||
ID3DBlob *errorMsgs = nullptr;
|
||||
HRESULT result = ptr_D3DCompile(code, codeSize, nullptr, nullptr, nullptr, "main", target, flags, 0, &compiledCode, &errorMsgs);
|
||||
@ -31,8 +31,10 @@ static std::vector<uint8_t> CompileShaderToBytecode(const char *code, size_t cod
|
||||
errorMsgs->Release();
|
||||
}
|
||||
if (compiledCode) {
|
||||
// Success!
|
||||
const uint8_t *buf = (const uint8_t *)compiledCode->GetBufferPointer();
|
||||
std::vector<uint8_t> compiled = std::vector<uint8_t>(buf, buf + compiledCode->GetBufferSize());
|
||||
_assert_(compiled.size() != 0);
|
||||
compiledCode->Release();
|
||||
return compiled;
|
||||
}
|
||||
@ -41,7 +43,7 @@ static std::vector<uint8_t> CompileShaderToBytecode(const char *code, size_t cod
|
||||
|
||||
ID3D11VertexShader *CreateVertexShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, std::vector<uint8_t> *byteCodeOut, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
|
||||
const char *profile = featureLevel <= D3D_FEATURE_LEVEL_9_3 ? "vs_4_0_level_9_1" : "vs_4_0";
|
||||
std::vector<uint8_t> byteCode = CompileShaderToBytecode(code, codeSize, profile, flags);
|
||||
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, profile, flags);
|
||||
if (byteCode.empty())
|
||||
return nullptr;
|
||||
|
||||
@ -54,7 +56,7 @@ ID3D11VertexShader *CreateVertexShaderD3D11(ID3D11Device *device, const char *co
|
||||
|
||||
ID3D11PixelShader *CreatePixelShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
|
||||
const char *profile = featureLevel <= D3D_FEATURE_LEVEL_9_3 ? "ps_4_0_level_9_1" : "ps_4_0";
|
||||
std::vector<uint8_t> byteCode = CompileShaderToBytecode(code, codeSize, profile, flags);
|
||||
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, profile, flags);
|
||||
if (byteCode.empty())
|
||||
return nullptr;
|
||||
|
||||
@ -66,7 +68,7 @@ ID3D11PixelShader *CreatePixelShaderD3D11(ID3D11Device *device, const char *code
|
||||
ID3D11ComputeShader *CreateComputeShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
|
||||
if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
|
||||
return nullptr;
|
||||
std::vector<uint8_t> byteCode = CompileShaderToBytecode(code, codeSize, "cs_4_0", flags);
|
||||
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, "cs_4_0", flags);
|
||||
if (byteCode.empty())
|
||||
return nullptr;
|
||||
|
||||
@ -78,7 +80,7 @@ ID3D11ComputeShader *CreateComputeShaderD3D11(ID3D11Device *device, const char *
|
||||
ID3D11GeometryShader *CreateGeometryShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags) {
|
||||
if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
|
||||
return nullptr;
|
||||
std::vector<uint8_t> byteCode = CompileShaderToBytecode(code, codeSize, "gs_5_0", flags);
|
||||
std::vector<uint8_t> byteCode = CompileShaderToBytecodeD3D11(code, codeSize, "gs_5_0", flags);
|
||||
if (byteCode.empty())
|
||||
return nullptr;
|
||||
|
||||
|
@ -18,6 +18,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
class PushBufferD3D11 {
|
||||
@ -71,6 +73,8 @@ private:
|
||||
bool nextMapDiscard_ = false;
|
||||
};
|
||||
|
||||
std::vector<uint8_t> CompileShaderToBytecodeD3D11(const char *code, size_t codeSize, const char *target, UINT flags);
|
||||
|
||||
ID3D11VertexShader *CreateVertexShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, std::vector<uint8_t> *byteCodeOut, D3D_FEATURE_LEVEL featureLevel, UINT flags = 0);
|
||||
ID3D11PixelShader *CreatePixelShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags = 0);
|
||||
ID3D11ComputeShader *CreateComputeShaderD3D11(ID3D11Device *device, const char *code, size_t codeSize, D3D_FEATURE_LEVEL featureLevel, UINT flags = 0);
|
||||
@ -95,4 +99,4 @@ public:
|
||||
if (!SUCCEEDED((x))) \
|
||||
Crash();
|
||||
|
||||
extern StockObjectsD3D11 stockD3D11;
|
||||
extern StockObjectsD3D11 stockD3D11;
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "GPU/Common/VertexDecoderCommon.h"
|
||||
#include "GPU/Common/DrawEngineCommon.h"
|
||||
#include "GPU/Common/GPUStateUtils.h"
|
||||
#include "GPU/D3D11/FragmentShaderGeneratorD3D11.h"
|
||||
#include "GPU/Directx9/FragmentShaderGeneratorHLSL.h"
|
||||
#include "GPU/D3D11/StateMappingD3D11.h"
|
||||
#include "GPU/D3D11/D3D11Util.h"
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
// Copyright (c) 2017- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "GPU/Common/ShaderCommon.h"
|
||||
#include "GPU/D3D11/FragmentShaderGeneratorD3D11.h"
|
||||
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
|
||||
|
||||
void GenerateFragmentShaderD3D11(const FShaderID &id, char *buffer, ShaderLanguage lang) {
|
||||
DX9::GenerateFragmentShaderHLSL(id, buffer, lang);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// Copyright (c) 2017- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GPU/Common/ShaderId.h"
|
||||
|
||||
void GenerateFragmentShaderD3D11(const FShaderID &id, char *buffer, ShaderLanguage lang);
|
@ -35,8 +35,8 @@
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/D3D11/ShaderManagerD3D11.h"
|
||||
#include "GPU/D3D11/FragmentShaderGeneratorD3D11.h"
|
||||
#include "GPU/D3D11/VertexShaderGeneratorD3D11.h"
|
||||
#include "GPU/Directx9/FragmentShaderGeneratorHLSL.h"
|
||||
#include "GPU/Directx9/VertexShaderGeneratorHLSL.h"
|
||||
#include "GPU/D3D11/D3D11Util.h"
|
||||
|
||||
D3D11FragmentShader::D3D11FragmentShader(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel, FShaderID id, const char *code, bool useHWTransform)
|
||||
@ -208,7 +208,8 @@ void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **
|
||||
D3D11VertexShader *vs;
|
||||
if (vsIter == vsCache_.end()) {
|
||||
// Vertex shader not in cache. Let's compile it.
|
||||
GenerateVertexShaderD3D11(VSID, codeBuffer_, featureLevel_ <= D3D_FEATURE_LEVEL_9_3 ? HLSL_D3D11_LEVEL9 : HLSL_D3D11);
|
||||
std::string genErrorString;
|
||||
GenerateVertexShaderHLSL(VSID, codeBuffer_, featureLevel_ <= D3D_FEATURE_LEVEL_9_3 ? HLSL_D3D11_LEVEL9 : HLSL_D3D11, &genErrorString);
|
||||
vs = new D3D11VertexShader(device_, featureLevel_, VSID, codeBuffer_, vertType, useHWTransform);
|
||||
vsCache_[VSID] = vs;
|
||||
} else {
|
||||
@ -220,7 +221,8 @@ void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **
|
||||
D3D11FragmentShader *fs;
|
||||
if (fsIter == fsCache_.end()) {
|
||||
// Fragment shader not in cache. Let's compile it.
|
||||
GenerateFragmentShaderD3D11(FSID, codeBuffer_, featureLevel_ <= D3D_FEATURE_LEVEL_9_3 ? HLSL_D3D11_LEVEL9 : HLSL_D3D11);
|
||||
std::string genErrorString;
|
||||
GenerateFragmentShaderHLSL(FSID, codeBuffer_, featureLevel_ <= D3D_FEATURE_LEVEL_9_3 ? HLSL_D3D11_LEVEL9 : HLSL_D3D11, &genErrorString);
|
||||
fs = new D3D11FragmentShader(device_, featureLevel_, FSID, codeBuffer_, useHWTransform);
|
||||
fsCache_[FSID] = fs;
|
||||
} else {
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "Core/Reporting.h"
|
||||
#include "GPU/Common/StencilCommon.h"
|
||||
#include "GPU/D3D11/FramebufferManagerD3D11.h"
|
||||
#include "GPU/D3D11/FragmentShaderGeneratorD3D11.h"
|
||||
#include "GPU/Directx9/FragmentShaderGeneratorHLSL.h"
|
||||
#include "GPU/D3D11/ShaderManagerD3D11.h"
|
||||
#include "GPU/D3D11/TextureCacheD3D11.h"
|
||||
#include "GPU/D3D11/D3D11Util.h"
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/Common/GPUStateUtils.h"
|
||||
#include "GPU/D3D11/FragmentShaderGeneratorD3D11.h"
|
||||
#include "GPU/D3D11/TextureCacheD3D11.h"
|
||||
#include "GPU/D3D11/FramebufferManagerD3D11.h"
|
||||
#include "GPU/D3D11/ShaderManagerD3D11.h"
|
||||
|
@ -1,24 +0,0 @@
|
||||
// Copyright (c) 2017- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "GPU/Common/ShaderCommon.h"
|
||||
#include "GPU/D3D11/VertexShaderGeneratorD3D11.h"
|
||||
#include "GPU/Directx9/VertexShaderGeneratorDX9.h"
|
||||
|
||||
void GenerateVertexShaderD3D11(const VShaderID &id, char *buffer, ShaderLanguage lang) {
|
||||
DX9::GenerateVertexShaderHLSL(id, buffer, lang);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// Copyright (c) 2017- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GPU/Common/ShaderId.h"
|
||||
|
||||
void GenerateVertexShaderD3D11(const VShaderID &id, char *buffer, ShaderLanguage lang);
|
@ -26,7 +26,6 @@
|
||||
#include "GPU/Common/VertexDecoderCommon.h"
|
||||
#include "GPU/Common/DrawEngineCommon.h"
|
||||
#include "GPU/Common/GPUStateUtils.h"
|
||||
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
|
||||
|
||||
struct DecVtxFormat;
|
||||
struct UVScale;
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include "Core/Reporting.h"
|
||||
#include "Core/Config.h"
|
||||
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
|
||||
#include "GPU/Directx9/FragmentShaderGeneratorHLSL.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/Common/GPUStateUtils.h"
|
||||
#include "GPU/GPUState.h"
|
||||
@ -29,11 +29,9 @@
|
||||
|
||||
// #define DEBUG_SHADER
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
// Missing: Z depth range
|
||||
// Also, logic ops etc, of course, as they are not supported in DX9.
|
||||
bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguage lang) {
|
||||
bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguage lang, std::string *errorString) {
|
||||
char *p = buffer;
|
||||
|
||||
bool lmode = id.Bit(FS_BIT_LMODE);
|
||||
@ -68,6 +66,21 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
|
||||
StencilValueType replaceAlphaWithStencilType = (StencilValueType)id.Bits(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, 4);
|
||||
|
||||
// Output some compatibility defines
|
||||
switch (lang) {
|
||||
case ShaderLanguage::HLSL_DX9:
|
||||
WRITE(p, "#define DISCARD clip(-1)\n");
|
||||
break;
|
||||
case ShaderLanguage::HLSL_D3D11:
|
||||
case ShaderLanguage::HLSL_D3D11_LEVEL9:
|
||||
WRITE(p, "#define DISCARD discard\n");
|
||||
break;
|
||||
}
|
||||
WRITE(p, "#define vec2 float2\n");
|
||||
WRITE(p, "#define vec3 float3\n");
|
||||
WRITE(p, "#define vec4 float4\n");
|
||||
WRITE(p, "#define splat3(x) float3(x, x, x)\n");
|
||||
|
||||
if (lang == HLSL_DX9) {
|
||||
if (doTexture)
|
||||
WRITE(p, "sampler tex : register(s0);\n");
|
||||
@ -290,7 +303,7 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
} else {
|
||||
// NEVER has been logged as used by games, although it makes little sense - statically failing.
|
||||
// Maybe we could discard the drawcall, but it's pretty rare. Let's just statically discard here.
|
||||
WRITE(p, " clip(-1);\n");
|
||||
WRITE(p, " DISCARD;\n");
|
||||
}
|
||||
} else {
|
||||
const char *alphaTestFuncs[] = { "#", "#", " != ", " == ", " >= ", " > ", " <= ", " < " }; // never/always don't make sense
|
||||
@ -300,11 +313,11 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
WRITE(p, " if ((roundAndScaleTo255i(v.a) & u_alphacolormask.a) %s u_alphacolorref.a) discard;\n", alphaTestFuncs[alphaTestFunc]);
|
||||
} else {
|
||||
// TODO: Use a texture to lookup bitwise ops?
|
||||
WRITE(p, " if (roundAndScaleTo255f(v.a) %s u_alphacolorref.a) clip(-1);\n", alphaTestFuncs[alphaTestFunc]);
|
||||
WRITE(p, " if (roundAndScaleTo255f(v.a) %s u_alphacolorref.a) DISCARD;\n", alphaTestFuncs[alphaTestFunc]);
|
||||
}
|
||||
} else {
|
||||
// This means NEVER. See above.
|
||||
WRITE(p, lang == HLSL_DX9 ? " clip(-1);\n" : " discard;\n");
|
||||
WRITE(p, " DISCARD;\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -319,14 +332,14 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
// When testing against 0 (common), we can avoid some math.
|
||||
// 0.002 is approximately half of 1.0 / 255.0.
|
||||
if (colorTestFunc == GE_COMP_NOTEQUAL) {
|
||||
WRITE(p, " if (v.r < 0.002 && v.g < 0.002 && v.b < 0.002) clip(-1);\n");
|
||||
WRITE(p, " if (v.r < 0.002 && v.g < 0.002 && v.b < 0.002) DISCARD;\n");
|
||||
} else if (colorTestFunc != GE_COMP_NEVER) {
|
||||
// Anything else is a test for == 0.
|
||||
WRITE(p, " if (v.r > 0.002 || v.g > 0.002 || v.b > 0.002) clip(-1);\n");
|
||||
WRITE(p, " if (v.r > 0.002 || v.g > 0.002 || v.b > 0.002) DISCARD;\n");
|
||||
} else {
|
||||
// NEVER has been logged as used by games, although it makes little sense - statically failing.
|
||||
// Maybe we could discard the drawcall, but it's pretty rare. Let's just statically discard here.
|
||||
WRITE(p, lang == HLSL_DX9 ? " clip(-1);\n" : " discard;\n");
|
||||
WRITE(p, " DISCARD;\n");
|
||||
}
|
||||
} else {
|
||||
const char *colorTestFuncs[] = { "#", "#", " != ", " == " }; // never/always don't make sense
|
||||
@ -337,15 +350,15 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
WRITE(p, " uint3 v_masked = v_scaled & u_alphacolormask.rgb;\n");
|
||||
WRITE(p, " uint3 colorTestRef = u_alphacolorref.rgb & u_alphacolormask.rgb;\n");
|
||||
// We have to test the components separately, or we get incorrect results. See #10629.
|
||||
WRITE(p, " if (v_masked.r %s colorTestRef.r && v_masked.g %s colorTestRef.g && v_masked.b %s colorTestRef.b) discard;\n", test, test, test);
|
||||
WRITE(p, " if (v_masked.r %s colorTestRef.r && v_masked.g %s colorTestRef.g && v_masked.b %s colorTestRef.b) DISCARD;\n", test, test, test);
|
||||
} else {
|
||||
// TODO: Use a texture to lookup bitwise ops instead?
|
||||
WRITE(p, " float3 colortest = roundAndScaleTo255v(v.rgb);\n");
|
||||
WRITE(p, " if ((colortest.r %s u_alphacolorref.r) && (colortest.g %s u_alphacolorref.g) && (colortest.b %s u_alphacolorref.b)) clip(-1);\n", test, test, test);
|
||||
WRITE(p, " if ((colortest.r %s u_alphacolorref.r) && (colortest.g %s u_alphacolorref.g) && (colortest.b %s u_alphacolorref.b)) DISCARD;\n", test, test, test);
|
||||
}
|
||||
}
|
||||
else {
|
||||
WRITE(p, lang == HLSL_DX9 ? " clip(-1);\n" : " discard;\n");
|
||||
WRITE(p, " DISCARD;\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -372,6 +385,10 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
case GE_SRCBLEND_FIXA: srcFactor = "u_blendFixA"; break;
|
||||
default: srcFactor = "u_blendFixA"; break;
|
||||
}
|
||||
if (!strcmp(srcFactor, "ERROR")) {
|
||||
*errorString = "Bad srcfactor in replace blend";
|
||||
return false;
|
||||
}
|
||||
|
||||
WRITE(p, " v.rgb = v.rgb * %s;\n", srcFactor);
|
||||
}
|
||||
@ -379,8 +396,8 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
if ((lang == HLSL_D3D11 || lang == HLSL_D3D11_LEVEL9) && replaceBlend == REPLACE_BLEND_COPY_FBO) {
|
||||
WRITE(p, " float4 destColor = fboTex.Load(int3((int)In.pixelPos.x, (int)In.pixelPos.y, 0));\n");
|
||||
|
||||
const char *srcFactor = "float3(1.0)";
|
||||
const char *dstFactor = "float3(0.0)";
|
||||
const char *srcFactor = nullptr;
|
||||
const char *dstFactor = nullptr;
|
||||
|
||||
switch (replaceBlendFuncA) {
|
||||
case GE_SRCBLEND_DSTCOLOR: srcFactor = "destColor.rgb"; break;
|
||||
@ -408,7 +425,7 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
case GE_DSTBLEND_DOUBLEDSTALPHA: dstFactor = "destColor.aaa * 2.0"; break;
|
||||
case GE_DSTBLEND_DOUBLEINVDSTALPHA: dstFactor = "float3(1.0, 1.0, 1.0) - destColor.aaa * 2.0"; break;
|
||||
case GE_DSTBLEND_FIXB: dstFactor = "u_blendFixB"; break;
|
||||
default: srcFactor = "u_blendFixB"; break;
|
||||
default: dstFactor = "u_blendFixB"; break;
|
||||
}
|
||||
|
||||
switch (replaceBlendEq) {
|
||||
@ -430,6 +447,9 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
case GE_BLENDMODE_ABSDIFF:
|
||||
WRITE(p, " v.rgb = abs(v.rgb - destColor.rgb);\n");
|
||||
break;
|
||||
default:
|
||||
*errorString = "Bad replace blend eq";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -535,5 +555,3 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
WRITE(p, "}\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
@ -20,9 +20,7 @@
|
||||
#include "GPU/Common/ShaderId.h"
|
||||
#include "GPU/Common/ShaderCommon.h"
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguage lang = HLSL_DX9);
|
||||
bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguage lang, std::string *errorString);
|
||||
|
||||
#define CONST_PS_TEXENV 0
|
||||
#define CONST_PS_ALPHACOLORREF 1
|
||||
@ -37,5 +35,3 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
|
||||
// For stencil upload
|
||||
#define CONST_PS_STENCILVALUE 10
|
||||
|
||||
};
|
@ -584,15 +584,21 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat
|
||||
}
|
||||
|
||||
VSCache::iterator vsIter = vsCache_.find(VSID);
|
||||
VSShader *vs;
|
||||
VSShader *vs = nullptr;
|
||||
if (vsIter == vsCache_.end()) {
|
||||
// Vertex shader not in cache. Let's compile it.
|
||||
GenerateVertexShaderHLSL(VSID, codeBuffer_);
|
||||
vs = new VSShader(device_, VSID, codeBuffer_, useHWTransform);
|
||||
|
||||
if (vs->Failed()) {
|
||||
std::string genErrorString;
|
||||
if (GenerateVertexShaderHLSL(VSID, codeBuffer_, HLSL_DX9, &genErrorString)) {
|
||||
vs = new VSShader(device_, VSID, codeBuffer_, useHWTransform);
|
||||
}
|
||||
if (!vs || vs->Failed()) {
|
||||
auto gr = GetI18NCategory("Graphics");
|
||||
ERROR_LOG(G3D, "Shader compilation failed, falling back to software transform");
|
||||
if (!vs) {
|
||||
// TODO: Report this?
|
||||
ERROR_LOG(G3D, "Shader generation failed, falling back to software transform");
|
||||
} else {
|
||||
ERROR_LOG(G3D, "Shader compilation failed, falling back to software transform");
|
||||
}
|
||||
if (!g_Config.bHideSlowWarnings) {
|
||||
host->NotifyUserMessage(gr->T("hardware transform error - falling back to software"), 2.5f, 0xFF3030FF);
|
||||
}
|
||||
@ -605,7 +611,8 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat
|
||||
// next time and we'll do this over and over...
|
||||
|
||||
// Can still work with software transform.
|
||||
GenerateVertexShaderHLSL(VSID, codeBuffer_);
|
||||
bool success = GenerateVertexShaderHLSL(VSID, codeBuffer_, HLSL_DX9, &genErrorString);
|
||||
_assert_(success);
|
||||
vs = new VSShader(device_, VSID, codeBuffer_, false);
|
||||
}
|
||||
|
||||
@ -619,7 +626,10 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat
|
||||
PSShader *fs;
|
||||
if (fsIter == fsCache_.end()) {
|
||||
// Fragment shader not in cache. Let's compile it.
|
||||
GenerateFragmentShaderHLSL(FSID, codeBuffer_);
|
||||
std::string errorString;
|
||||
bool success = GenerateFragmentShaderHLSL(FSID, codeBuffer_, HLSL_DX9, &errorString);
|
||||
// We're supposed to handle all possible cases.
|
||||
_assert_(success);
|
||||
fs = new PSShader(device_, FSID, codeBuffer_);
|
||||
fsCache_[FSID] = fs;
|
||||
} else {
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "Common/Common.h"
|
||||
#include "GPU/Directx9/VertexShaderGeneratorDX9.h"
|
||||
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
|
||||
#include "GPU/Directx9/VertexShaderGeneratorHLSL.h"
|
||||
#include "GPU/Directx9/FragmentShaderGeneratorHLSL.h"
|
||||
#include "GPU/Common/ShaderCommon.h"
|
||||
#include "GPU/Common/ShaderId.h"
|
||||
#include "Common/Math/lin/matrix4x4.h"
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "GPU/Directx9/ShaderManagerDX9.h"
|
||||
#include "GPU/Directx9/TextureCacheDX9.h"
|
||||
#include "GPU/Directx9/FramebufferManagerDX9.h"
|
||||
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "Core/Reporting.h"
|
||||
#include "GPU/Common/StencilCommon.h"
|
||||
#include "GPU/Directx9/FramebufferManagerDX9.h"
|
||||
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
|
||||
#include "GPU/Directx9/ShaderManagerDX9.h"
|
||||
#include "GPU/Directx9/TextureCacheDX9.h"
|
||||
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
|
||||
#include "GPU/Directx9/TextureCacheDX9.h"
|
||||
#include "GPU/Directx9/FramebufferManagerDX9.h"
|
||||
#include "GPU/Directx9/ShaderManagerDX9.h"
|
||||
|
@ -1,60 +0,0 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GPU/Common/ShaderID.h"
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage lang = HLSL_DX9);
|
||||
|
||||
enum {
|
||||
CONST_VS_PROJ = 0,
|
||||
CONST_VS_PROJ_THROUGH = 4,
|
||||
CONST_VS_VIEW = 8,
|
||||
CONST_VS_WORLD = 11,
|
||||
CONST_VS_TEXMTX = 14,
|
||||
CONST_VS_UVSCALEOFFSET = 17,
|
||||
CONST_VS_FOGCOEF = 18,
|
||||
CONST_VS_AMBIENT = 19,
|
||||
CONST_VS_MATAMBIENTALPHA = 20,
|
||||
CONST_VS_MATDIFFUSE = 21,
|
||||
CONST_VS_MATSPECULAR = 22,
|
||||
CONST_VS_MATEMISSIVE = 23,
|
||||
CONST_VS_LIGHTPOS = 24,
|
||||
CONST_VS_LIGHTDIR = 28,
|
||||
CONST_VS_LIGHTATT = 32,
|
||||
CONST_VS_LIGHTANGLE_SPOTCOEF = 36,
|
||||
CONST_VS_LIGHTDIFFUSE = 40,
|
||||
CONST_VS_LIGHTSPECULAR = 44,
|
||||
CONST_VS_LIGHTAMBIENT = 48,
|
||||
CONST_VS_DEPTHRANGE = 52,
|
||||
CONST_VS_BONE0 = 53,
|
||||
CONST_VS_BONE1 = 56,
|
||||
CONST_VS_BONE2 = 59,
|
||||
CONST_VS_BONE3 = 62,
|
||||
CONST_VS_BONE4 = 65,
|
||||
CONST_VS_BONE5 = 68,
|
||||
CONST_VS_BONE6 = 71,
|
||||
CONST_VS_BONE7 = 74,
|
||||
CONST_VS_BONE8 = 77,
|
||||
CONST_VS_CULLRANGEMIN = 80,
|
||||
CONST_VS_CULLRANGEMAX = 81,
|
||||
};
|
||||
|
||||
};
|
@ -18,16 +18,12 @@
|
||||
#include <cstdio>
|
||||
#include <locale.h>
|
||||
|
||||
#if defined(_WIN32) && defined(_DEBUG)
|
||||
#include "Common/CommonWindows.h"
|
||||
#endif
|
||||
|
||||
#include "Common/StringUtils.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "Core/Config.h"
|
||||
|
||||
#include "GPU/Directx9/VertexShaderGeneratorDX9.h"
|
||||
#include "GPU/Directx9/VertexShaderGeneratorHLSL.h"
|
||||
#include "GPU/Common/VertexDecoderCommon.h"
|
||||
#include "GPU/Common/ShaderUniforms.h"
|
||||
|
||||
@ -35,8 +31,6 @@
|
||||
|
||||
#define WRITE p+=sprintf
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
static const char * const boneWeightAttrDecl[9] = {
|
||||
"#ERROR#",
|
||||
"float a_w1:TEXCOORD1;\n",
|
||||
@ -49,13 +43,7 @@ static const char * const boneWeightAttrDecl[9] = {
|
||||
"float4 a_w1:TEXCOORD1;\n float4 a_w2:TEXCOORD2;\n",
|
||||
};
|
||||
|
||||
enum DoLightComputation {
|
||||
LIGHT_OFF,
|
||||
LIGHT_SHADE,
|
||||
LIGHT_FULL,
|
||||
};
|
||||
|
||||
void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage lang) {
|
||||
bool GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage lang, std::string *errorString) {
|
||||
char *p = buffer;
|
||||
|
||||
bool isModeThrough = id.Bit(VS_BIT_IS_THROUGH);
|
||||
@ -107,6 +95,12 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
|
||||
numBoneWeights = 1 + id.Bits(VS_BIT_BONES, 3);
|
||||
}
|
||||
|
||||
// Output some compatibility defines
|
||||
WRITE(p, "#define vec2 float2\n");
|
||||
WRITE(p, "#define vec3 float3\n");
|
||||
WRITE(p, "#define vec4 float4\n");
|
||||
WRITE(p, "#define splat3(x) float3(x, x, x)\n");
|
||||
|
||||
if (lang == HLSL_DX9) {
|
||||
WRITE(p, "#pragma warning( disable : 3571 )\n");
|
||||
if (isModeThrough) {
|
||||
@ -730,8 +724,9 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
|
||||
break;
|
||||
|
||||
default:
|
||||
// ILLEGAL
|
||||
break;
|
||||
// Should be unreachable.
|
||||
_assert_(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -756,6 +751,5 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
|
||||
|
||||
WRITE(p, " return Out;\n");
|
||||
WRITE(p, "}\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
57
GPU/Directx9/VertexShaderGeneratorHLSL.h
Normal file
57
GPU/Directx9/VertexShaderGeneratorHLSL.h
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "GPU/Common/ShaderID.h"
|
||||
|
||||
bool GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage lang, std::string *errorString);
|
||||
|
||||
enum {
|
||||
CONST_VS_PROJ = 0,
|
||||
CONST_VS_PROJ_THROUGH = 4,
|
||||
CONST_VS_VIEW = 8,
|
||||
CONST_VS_WORLD = 11,
|
||||
CONST_VS_TEXMTX = 14,
|
||||
CONST_VS_UVSCALEOFFSET = 17,
|
||||
CONST_VS_FOGCOEF = 18,
|
||||
CONST_VS_AMBIENT = 19,
|
||||
CONST_VS_MATAMBIENTALPHA = 20,
|
||||
CONST_VS_MATDIFFUSE = 21,
|
||||
CONST_VS_MATSPECULAR = 22,
|
||||
CONST_VS_MATEMISSIVE = 23,
|
||||
CONST_VS_LIGHTPOS = 24,
|
||||
CONST_VS_LIGHTDIR = 28,
|
||||
CONST_VS_LIGHTATT = 32,
|
||||
CONST_VS_LIGHTANGLE_SPOTCOEF = 36,
|
||||
CONST_VS_LIGHTDIFFUSE = 40,
|
||||
CONST_VS_LIGHTSPECULAR = 44,
|
||||
CONST_VS_LIGHTAMBIENT = 48,
|
||||
CONST_VS_DEPTHRANGE = 52,
|
||||
CONST_VS_BONE0 = 53,
|
||||
CONST_VS_BONE1 = 56,
|
||||
CONST_VS_BONE2 = 59,
|
||||
CONST_VS_BONE3 = 62,
|
||||
CONST_VS_BONE4 = 65,
|
||||
CONST_VS_BONE5 = 68,
|
||||
CONST_VS_BONE6 = 71,
|
||||
CONST_VS_BONE7 = 74,
|
||||
CONST_VS_BONE8 = 77,
|
||||
CONST_VS_CULLRANGEMIN = 80,
|
||||
CONST_VS_CULLRANGEMAX = 81,
|
||||
};
|
@ -36,22 +36,22 @@
|
||||
// #define DEBUG_SHADER
|
||||
|
||||
// Missing: Z depth range
|
||||
bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniformMask) {
|
||||
bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, uint64_t *uniformMask, std::string *errorString) {
|
||||
char *p = buffer;
|
||||
|
||||
*uniformMask = 0;
|
||||
// In GLSL ES 3.0, you use "in" variables instead of varying.
|
||||
|
||||
bool glslES30 = false;
|
||||
const char *varying = "varying";
|
||||
const char *fragColor0 = "gl_FragColor";
|
||||
const char *fragColor1 = "fragColor1";
|
||||
const char *texture = "texture2D";
|
||||
const char *texelFetch = NULL;
|
||||
GLSLShaderCompat compat{};
|
||||
compat.varying = "varying";
|
||||
compat.fragColor0 = "gl_FragColor";
|
||||
compat.fragColor1 = "fragColor1";
|
||||
compat.texture = "texture2D";
|
||||
compat.texelFetch = NULL;
|
||||
compat.bitwiseOps = false;
|
||||
compat.lastFragData = nullptr;
|
||||
bool highpFog = false;
|
||||
bool highpTexcoord = false;
|
||||
bool bitwiseOps = false;
|
||||
const char *lastFragData = nullptr;
|
||||
|
||||
ReplaceAlphaType stencilToAlpha = static_cast<ReplaceAlphaType>(id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2));
|
||||
|
||||
@ -59,11 +59,11 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
// ES doesn't support dual source alpha :(
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300)) {
|
||||
WRITE(p, "#version 300 es\n"); // GLSL ES 3.0
|
||||
fragColor0 = "fragColor0";
|
||||
texture = "texture";
|
||||
glslES30 = true;
|
||||
bitwiseOps = true;
|
||||
texelFetch = "texelFetch";
|
||||
compat.fragColor0 = "fragColor0";
|
||||
compat.texture = "texture";
|
||||
compat.glslES30 = true;
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
|
||||
if (stencilToAlpha == REPLACE_ALPHA_DUALSOURCE && gl_extensions.EXT_blend_func_extended) {
|
||||
WRITE(p, "#extension GL_EXT_blend_func_extended : require\n");
|
||||
@ -72,12 +72,12 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
WRITE(p, "#version 100\n"); // GLSL ES 1.0
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
|
||||
bitwiseOps = true;
|
||||
texelFetch = "texelFetch2D";
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch2D";
|
||||
}
|
||||
if (gl_extensions.EXT_blend_func_extended) {
|
||||
// Oldy moldy GLES, so use the fixed output name.
|
||||
fragColor1 = "gl_SecondaryFragColorEXT";
|
||||
compat.fragColor1 = "gl_SecondaryFragColorEXT";
|
||||
|
||||
if (stencilToAlpha == REPLACE_ALPHA_DUALSOURCE && gl_extensions.EXT_blend_func_extended) {
|
||||
WRITE(p, "#extension GL_EXT_blend_func_extended : require\n");
|
||||
@ -93,17 +93,17 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300) && gl_extensions.EXT_shader_framebuffer_fetch) {
|
||||
WRITE(p, "#extension GL_EXT_shader_framebuffer_fetch : require\n");
|
||||
lastFragData = "fragColor0";
|
||||
compat.lastFragData = "fragColor0";
|
||||
} else if (gl_extensions.EXT_shader_framebuffer_fetch) {
|
||||
WRITE(p, "#extension GL_EXT_shader_framebuffer_fetch : require\n");
|
||||
lastFragData = "gl_LastFragData[0]";
|
||||
compat.lastFragData = "gl_LastFragData[0]";
|
||||
} else if (gl_extensions.NV_shader_framebuffer_fetch) {
|
||||
// GL_NV_shader_framebuffer_fetch is available on mobile platform and ES 2.0 only but not on desktop.
|
||||
WRITE(p, "#extension GL_NV_shader_framebuffer_fetch : require\n");
|
||||
lastFragData = "gl_LastFragData[0]";
|
||||
compat.lastFragData = "gl_LastFragData[0]";
|
||||
} else if (gl_extensions.ARM_shader_framebuffer_fetch) {
|
||||
WRITE(p, "#extension GL_ARM_shader_framebuffer_fetch : require\n");
|
||||
lastFragData = "gl_LastFragColorARM";
|
||||
compat.lastFragData = "gl_LastFragColorARM";
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,16 +111,16 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
} else {
|
||||
if (!gl_extensions.ForceGL2 || gl_extensions.IsCoreContext) {
|
||||
if (gl_extensions.VersionGEThan(3, 3, 0)) {
|
||||
fragColor0 = "fragColor0";
|
||||
texture = "texture";
|
||||
glslES30 = true;
|
||||
bitwiseOps = true;
|
||||
texelFetch = "texelFetch";
|
||||
compat.fragColor0 = "fragColor0";
|
||||
compat.texture = "texture";
|
||||
compat.glslES30 = true;
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
WRITE(p, "#version 330\n");
|
||||
} else if (gl_extensions.VersionGEThan(3, 0, 0)) {
|
||||
fragColor0 = "fragColor0";
|
||||
bitwiseOps = true;
|
||||
texelFetch = "texelFetch";
|
||||
compat.fragColor0 = "fragColor0";
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
WRITE(p, "#version 130\n");
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
|
||||
@ -129,8 +129,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
WRITE(p, "#version 110\n");
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
|
||||
bitwiseOps = true;
|
||||
texelFetch = "texelFetch2D";
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch2D";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -141,8 +141,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
WRITE(p, "#define highp\n");
|
||||
}
|
||||
|
||||
if (glslES30 || gl_extensions.IsCoreContext) {
|
||||
varying = "in";
|
||||
if (compat.glslES30 || gl_extensions.IsCoreContext) {
|
||||
compat.varying = "in";
|
||||
}
|
||||
|
||||
bool lmode = id.Bit(FS_BIT_LMODE);
|
||||
@ -180,7 +180,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
}
|
||||
|
||||
const char *shading = "";
|
||||
if (glslES30)
|
||||
if (compat.glslES30)
|
||||
shading = doFlatShading ? "flat" : "";
|
||||
|
||||
if (doTexture)
|
||||
@ -189,7 +189,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) {
|
||||
*uniformMask |= DIRTY_SHADERBLEND;
|
||||
if (!gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH) && replaceBlend == REPLACE_BLEND_COPY_FBO) {
|
||||
if (!texelFetch) {
|
||||
if (!compat.texelFetch) {
|
||||
WRITE(p, "uniform vec2 u_fbotexSize;\n");
|
||||
}
|
||||
WRITE(p, "uniform sampler2D fbotex;\n");
|
||||
@ -216,7 +216,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
} else {
|
||||
*uniformMask |= DIRTY_ALPHACOLORREF;
|
||||
WRITE(p, "uniform vec4 u_alphacolorref;\n");
|
||||
if (bitwiseOps && ((enableColorTest && !colorTestAgainstZero) || (enableAlphaTest && !alphaTestAgainstZero))) {
|
||||
if (compat.bitwiseOps && ((enableColorTest && !colorTestAgainstZero) || (enableAlphaTest && !alphaTestAgainstZero))) {
|
||||
*uniformMask |= DIRTY_ALPHACOLORMASK;
|
||||
WRITE(p, "uniform ivec4 u_alphacolormask;\n");
|
||||
}
|
||||
@ -239,21 +239,21 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
WRITE(p, "uniform vec3 u_texenv;\n");
|
||||
}
|
||||
|
||||
WRITE(p, "%s %s vec4 v_color0;\n", shading, varying);
|
||||
WRITE(p, "%s %s vec4 v_color0;\n", shading, compat.varying);
|
||||
if (lmode)
|
||||
WRITE(p, "%s %s vec3 v_color1;\n", shading, varying);
|
||||
WRITE(p, "%s %s vec3 v_color1;\n", shading, compat.varying);
|
||||
if (enableFog) {
|
||||
*uniformMask |= DIRTY_FOGCOLOR;
|
||||
WRITE(p, "uniform vec3 u_fogcolor;\n");
|
||||
WRITE(p, "%s %s float v_fogdepth;\n", varying, highpFog ? "highp" : "mediump");
|
||||
WRITE(p, "%s %s float v_fogdepth;\n", compat.varying, highpFog ? "highp" : "mediump");
|
||||
}
|
||||
if (doTexture) {
|
||||
WRITE(p, "%s %s vec3 v_texcoord;\n", varying, highpTexcoord ? "highp" : "mediump");
|
||||
WRITE(p, "%s %s vec3 v_texcoord;\n", compat.varying, highpTexcoord ? "highp" : "mediump");
|
||||
}
|
||||
|
||||
if (!g_Config.bFragmentTestCache) {
|
||||
if (enableAlphaTest && !alphaTestAgainstZero) {
|
||||
if (bitwiseOps) {
|
||||
if (compat.bitwiseOps) {
|
||||
WRITE(p, "int roundAndScaleTo255i(in float x) { return int(floor(x * 255.0 + 0.5)); }\n");
|
||||
} else if (gl_extensions.gpuVendor == GPU_VENDOR_IMGTEC) {
|
||||
WRITE(p, "float roundTo255thf(in mediump float x) { mediump float y = x + (0.5/255.0); return y - fract(y * 255.0) * (1.0 / 255.0); }\n");
|
||||
@ -262,7 +262,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
}
|
||||
}
|
||||
if (enableColorTest && !colorTestAgainstZero) {
|
||||
if (bitwiseOps) {
|
||||
if (compat.bitwiseOps) {
|
||||
WRITE(p, "ivec3 roundAndScaleTo255iv(in vec3 x) { return ivec3(floor(x * 255.0 + 0.5)); }\n");
|
||||
} else if (gl_extensions.gpuVendor == GPU_VENDOR_IMGTEC) {
|
||||
WRITE(p, "vec3 roundTo255thv(in vec3 x) { vec3 y = x + (0.5/255.0); return y - fract(y * 255.0) * (1.0 / 255.0); }\n");
|
||||
@ -272,9 +272,9 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(fragColor0, "fragColor0")) {
|
||||
if (!strcmp(compat.fragColor0, "fragColor0")) {
|
||||
const char *qualifierColor0 = "out";
|
||||
if (lastFragData && !strcmp(lastFragData, fragColor0)) {
|
||||
if (compat.lastFragData && !strcmp(compat.lastFragData, compat.fragColor0)) {
|
||||
qualifierColor0 = "inout";
|
||||
}
|
||||
// Output the output color definitions.
|
||||
@ -353,9 +353,9 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
|
||||
if (!shaderDepal) {
|
||||
if (doTextureProjection) {
|
||||
WRITE(p, " vec4 t = %sProj(tex, %s);\n", texture, texcoord);
|
||||
WRITE(p, " vec4 t = %sProj(tex, %s);\n", compat.texture, texcoord);
|
||||
} else {
|
||||
WRITE(p, " vec4 t = %s(tex, %s.xy);\n", texture, texcoord);
|
||||
WRITE(p, " vec4 t = %s(tex, %s.xy);\n", compat.texture, texcoord);
|
||||
}
|
||||
} else {
|
||||
if (doTextureProjection) {
|
||||
@ -375,10 +375,10 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
WRITE(p, " } else {\n");
|
||||
WRITE(p, " uv_round = uv;\n");
|
||||
WRITE(p, " }\n");
|
||||
WRITE(p, " vec4 t = %s(tex, uv_round);\n", texture);
|
||||
WRITE(p, " vec4 t1 = %sOffset(tex, uv_round, ivec2(1, 0));\n", texture);
|
||||
WRITE(p, " vec4 t2 = %sOffset(tex, uv_round, ivec2(0, 1));\n", texture);
|
||||
WRITE(p, " vec4 t3 = %sOffset(tex, uv_round, ivec2(1, 1));\n", texture);
|
||||
WRITE(p, " vec4 t = %s(tex, uv_round);\n", compat.texture);
|
||||
WRITE(p, " vec4 t1 = %sOffset(tex, uv_round, ivec2(1, 0));\n", compat.texture);
|
||||
WRITE(p, " vec4 t2 = %sOffset(tex, uv_round, ivec2(0, 1));\n", compat.texture);
|
||||
WRITE(p, " vec4 t3 = %sOffset(tex, uv_round, ivec2(1, 1));\n", compat.texture);
|
||||
WRITE(p, " int depalMask = (u_depal & 0xFF);\n");
|
||||
WRITE(p, " int depalShift = ((u_depal >> 8) & 0xFF);\n");
|
||||
WRITE(p, " int depalOffset = (((u_depal >> 16) & 0xFF) << 4);\n");
|
||||
@ -552,12 +552,12 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
WRITE(p, " %s\n", discardStatement);
|
||||
}
|
||||
} else if (g_Config.bFragmentTestCache) {
|
||||
WRITE(p, " float aResult = %s(testtex, vec2(%s, 0)).a;\n", texture, alphaTestXCoord.c_str());
|
||||
WRITE(p, " float aResult = %s(testtex, vec2(%s, 0)).a;\n", compat.texture, alphaTestXCoord.c_str());
|
||||
WRITE(p, " if (aResult < 0.5) %s\n", discardStatement);
|
||||
} else {
|
||||
const char *alphaTestFuncs[] = { "#", "#", " != ", " == ", " >= ", " > ", " <= ", " < " };
|
||||
if (alphaTestFuncs[alphaTestFunc][0] != '#') {
|
||||
if (bitwiseOps) {
|
||||
if (compat.bitwiseOps) {
|
||||
WRITE(p, " if ((roundAndScaleTo255i(v.a) & u_alphacolormask.a) %s int(u_alphacolorref.a)) %s\n", alphaTestFuncs[alphaTestFunc], discardStatement);
|
||||
} else if (gl_extensions.gpuVendor == GPU_VENDOR_IMGTEC) {
|
||||
// Work around bad PVR driver problem where equality check + discard just doesn't work.
|
||||
@ -589,9 +589,9 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
WRITE(p, " %s\n", discardStatement);
|
||||
}
|
||||
} else if (g_Config.bFragmentTestCache) {
|
||||
WRITE(p, " float rResult = %s(testtex, vec2(vScale256.r, 0)).r;\n", texture);
|
||||
WRITE(p, " float gResult = %s(testtex, vec2(vScale256.g, 0)).g;\n", texture);
|
||||
WRITE(p, " float bResult = %s(testtex, vec2(vScale256.b, 0)).b;\n", texture);
|
||||
WRITE(p, " float rResult = %s(testtex, vec2(vScale256.r, 0)).r;\n", compat.texture);
|
||||
WRITE(p, " float gResult = %s(testtex, vec2(vScale256.g, 0)).g;\n", compat.texture);
|
||||
WRITE(p, " float bResult = %s(testtex, vec2(vScale256.b, 0)).b;\n", compat.texture);
|
||||
if (colorTestFunc == GE_COMP_EQUAL) {
|
||||
// Equal means all parts must be equal (so discard if any is not.)
|
||||
WRITE(p, " if (rResult < 0.5 || gResult < 0.5 || bResult < 0.5) %s\n", discardStatement);
|
||||
@ -602,7 +602,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
} else {
|
||||
const char *colorTestFuncs[] = { "#", "#", " != ", " == " };
|
||||
if (colorTestFuncs[colorTestFunc][0] != '#') {
|
||||
if (bitwiseOps) {
|
||||
if (compat.bitwiseOps) {
|
||||
// Apparently GLES3 does not support vector bitwise ops.
|
||||
WRITE(p, " ivec3 v_scaled = roundAndScaleTo255iv(v.rgb);\n");
|
||||
const char *maskedFragColor = "ivec3(v_scaled.r & u_alphacolormask.r, v_scaled.g & u_alphacolormask.g, v_scaled.b & u_alphacolormask.b)";
|
||||
@ -649,11 +649,11 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
// If we have NV_shader_framebuffer_fetch / EXT_shader_framebuffer_fetch, we skip the blit.
|
||||
// We can just read the prev value more directly.
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) {
|
||||
WRITE(p, " lowp vec4 destColor = %s;\n", lastFragData);
|
||||
} else if (!texelFetch) {
|
||||
WRITE(p, " lowp vec4 destColor = %s(fbotex, gl_FragCoord.xy * u_fbotexSize.xy);\n", texture);
|
||||
WRITE(p, " lowp vec4 destColor = %s;\n", compat.lastFragData);
|
||||
} else if (!compat.texelFetch) {
|
||||
WRITE(p, " lowp vec4 destColor = %s(fbotex, gl_FragCoord.xy * u_fbotexSize.xy);\n", compat.texture);
|
||||
} else {
|
||||
WRITE(p, " lowp vec4 destColor = %s(fbotex, ivec2(gl_FragCoord.x, gl_FragCoord.y), 0);\n", texelFetch);
|
||||
WRITE(p, " lowp vec4 destColor = %s(fbotex, ivec2(gl_FragCoord.x, gl_FragCoord.y), 0);\n", compat.texelFetch);
|
||||
}
|
||||
|
||||
const char *srcFactor = "vec3(1.0)";
|
||||
@ -755,48 +755,39 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform
|
||||
|
||||
switch (stencilToAlpha) {
|
||||
case REPLACE_ALPHA_DUALSOURCE:
|
||||
WRITE(p, " %s = vec4(v.rgb, %s);\n", fragColor0, replacedAlpha.c_str());
|
||||
WRITE(p, " %s = vec4(0.0, 0.0, 0.0, v.a);\n", fragColor1);
|
||||
WRITE(p, " %s = vec4(v.rgb, %s);\n", compat.fragColor0, replacedAlpha.c_str());
|
||||
WRITE(p, " %s = vec4(0.0, 0.0, 0.0, v.a);\n", compat.fragColor1);
|
||||
break;
|
||||
|
||||
case REPLACE_ALPHA_YES:
|
||||
WRITE(p, " %s = vec4(v.rgb, %s);\n", fragColor0, replacedAlpha.c_str());
|
||||
WRITE(p, " %s = vec4(v.rgb, %s);\n", compat.fragColor0, replacedAlpha.c_str());
|
||||
break;
|
||||
|
||||
case REPLACE_ALPHA_NO:
|
||||
WRITE(p, " %s = v;\n", fragColor0);
|
||||
WRITE(p, " %s = v;\n", compat.fragColor0);
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG(G3D, "Bad stencil-to-alpha type, corrupt ID?");
|
||||
*errorString = "Bad stencil-to-alpha type, corrupt ID?";
|
||||
return false;
|
||||
}
|
||||
|
||||
LogicOpReplaceType replaceLogicOpType = (LogicOpReplaceType)id.Bits(FS_BIT_REPLACE_LOGIC_OP_TYPE, 2);
|
||||
switch (replaceLogicOpType) {
|
||||
case LOGICOPTYPE_ONE:
|
||||
WRITE(p, " %s.rgb = vec3(1.0, 1.0, 1.0);\n", fragColor0);
|
||||
WRITE(p, " %s.rgb = vec3(1.0, 1.0, 1.0);\n", compat.fragColor0);
|
||||
break;
|
||||
case LOGICOPTYPE_INVERT:
|
||||
WRITE(p, " %s.rgb = vec3(1.0, 1.0, 1.0) - %s.rgb;\n", fragColor0, fragColor0);
|
||||
WRITE(p, " %s.rgb = vec3(1.0, 1.0, 1.0) - %s.rgb;\n", compat.fragColor0, compat.fragColor0);
|
||||
break;
|
||||
case LOGICOPTYPE_NORMAL:
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG(G3D, "Bad logic op type, corrupt ID?");
|
||||
*errorString = "Bad logic op type, corrupt ID?";
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SHADER
|
||||
if (doTexture) {
|
||||
WRITE(p, " %s = texture2D(tex, v_texcoord.xy);\n", fragColor0);
|
||||
WRITE(p, " %s += vec4(0.3,0,0.3,0.3);\n", fragColor0);
|
||||
} else {
|
||||
WRITE(p, " %s = vec4(1,0,1,1);\n", fragColor0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT)) {
|
||||
const double scale = DepthSliceFactor() * 65535.0;
|
||||
|
||||
|
@ -19,4 +19,4 @@
|
||||
|
||||
struct FShaderID;
|
||||
|
||||
bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniformMask);
|
||||
bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, uint64_t *uniformMask, std::string *errorString);
|
||||
|
@ -629,7 +629,9 @@ void ShaderManagerGLES::DirtyLastShader() {
|
||||
|
||||
Shader *ShaderManagerGLES::CompileFragmentShader(FShaderID FSID) {
|
||||
uint64_t uniformMask;
|
||||
if (!GenerateFragmentShader(FSID, codeBuffer_, &uniformMask)) {
|
||||
std::string errorString;
|
||||
if (!GenerateFragmentShaderGLSL(FSID, codeBuffer_, &uniformMask, &errorString)) {
|
||||
ERROR_LOG(G3D, "Shader gen error: %s", errorString.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
std::string desc = FragmentShaderDesc(FSID);
|
||||
@ -640,7 +642,11 @@ Shader *ShaderManagerGLES::CompileVertexShader(VShaderID VSID) {
|
||||
bool useHWTransform = VSID.Bit(VS_BIT_USE_HW_TRANSFORM);
|
||||
uint32_t attrMask;
|
||||
uint64_t uniformMask;
|
||||
GenerateVertexShader(VSID, codeBuffer_, &attrMask, &uniformMask);
|
||||
std::string errorString;
|
||||
if (!GenerateVertexShaderGLSL(VSID, codeBuffer_, &attrMask, &uniformMask, &errorString)) {
|
||||
ERROR_LOG(G3D, "Shader gen error: %s", errorString.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
std::string desc = VertexShaderDesc(VSID);
|
||||
return new Shader(render_, codeBuffer_, desc, GL_VERTEX_SHADER, useHWTransform, attrMask, uniformMask);
|
||||
}
|
||||
|
@ -21,10 +21,6 @@
|
||||
|
||||
#include "Common/GPU/OpenGL/GLFeatures.h"
|
||||
|
||||
#if defined(_WIN32) && defined(_DEBUG)
|
||||
#include "Common/CommonWindows.h"
|
||||
#endif
|
||||
|
||||
#include "Common/StringUtils.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/GPUState.h"
|
||||
@ -62,13 +58,6 @@ static const char * const boneWeightInDecl[9] = {
|
||||
"in mediump vec4 w1, w2;\n",
|
||||
};
|
||||
|
||||
enum DoLightComputation {
|
||||
LIGHT_OFF,
|
||||
LIGHT_SHADE,
|
||||
LIGHT_FULL,
|
||||
};
|
||||
|
||||
|
||||
// Depth range and viewport
|
||||
//
|
||||
// After the multiplication with the projection matrix, we have a 4D vector in clip space.
|
||||
@ -98,32 +87,32 @@ enum DoLightComputation {
|
||||
// TODO: Skip all this if we can actually get a 16-bit depth buffer along with stencil, which
|
||||
// is a bit of a rare configuration, although quite common on mobile.
|
||||
|
||||
|
||||
void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, uint64_t *uniformMask) {
|
||||
bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString) {
|
||||
char *p = buffer;
|
||||
*attrMask = 0;
|
||||
*uniformMask = 0;
|
||||
// #define USE_FOR_LOOP
|
||||
|
||||
// In GLSL ES 3.0, you use "out" variables instead.
|
||||
bool glslES30 = false;
|
||||
const char *varying = "varying";
|
||||
const char *attribute = "attribute";
|
||||
GLSLShaderCompat compat{};
|
||||
compat.glslES30 = false;
|
||||
compat.varying = "varying";
|
||||
compat.attribute = "attribute";
|
||||
const char * const * boneWeightDecl = boneWeightAttrDecl;
|
||||
const char *texelFetch = NULL;
|
||||
compat.texelFetch = NULL;
|
||||
bool highpFog = false;
|
||||
bool highpTexcoord = false;
|
||||
|
||||
if (gl_extensions.IsGLES) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300)) {
|
||||
WRITE(p, "#version 300 es\n");
|
||||
glslES30 = true;
|
||||
texelFetch = "texelFetch";
|
||||
compat.glslES30 = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
} else {
|
||||
WRITE(p, "#version 100\n"); // GLSL ES 1.0
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
|
||||
texelFetch = "texelFetch2D";
|
||||
compat.texelFetch = "texelFetch2D";
|
||||
}
|
||||
}
|
||||
WRITE(p, "precision highp float;\n");
|
||||
@ -135,20 +124,20 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
|
||||
} else {
|
||||
if (!gl_extensions.ForceGL2 || gl_extensions.IsCoreContext) {
|
||||
if (gl_extensions.VersionGEThan(3, 3, 0)) {
|
||||
glslES30 = true;
|
||||
compat.glslES30 = true;
|
||||
WRITE(p, "#version 330\n");
|
||||
texelFetch = "texelFetch";
|
||||
compat.texelFetch = "texelFetch";
|
||||
} else if (gl_extensions.VersionGEThan(3, 0, 0)) {
|
||||
WRITE(p, "#version 130\n");
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
|
||||
texelFetch = "texelFetch";
|
||||
compat.texelFetch = "texelFetch";
|
||||
}
|
||||
} else {
|
||||
WRITE(p, "#version 110\n");
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
WRITE(p, "#extension GL_EXT_gpu_shader4 : enable\n");
|
||||
texelFetch = "texelFetch2D";
|
||||
compat.texelFetch = "texelFetch2D";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -158,10 +147,11 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
|
||||
WRITE(p, "#define mediump\n");
|
||||
WRITE(p, "#define highp\n");
|
||||
}
|
||||
WRITE(p, "#define splat3(x) vec3(x)\n");
|
||||
|
||||
if (glslES30 || gl_extensions.IsCoreContext) {
|
||||
attribute = "in";
|
||||
varying = "out";
|
||||
if (compat.glslES30 || gl_extensions.IsCoreContext) {
|
||||
compat.attribute = "in";
|
||||
compat.varying = "out";
|
||||
boneWeightDecl = boneWeightInDecl;
|
||||
}
|
||||
|
||||
@ -197,7 +187,7 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
|
||||
bool flipNormalTess = id.Bit(VS_BIT_NORM_REVERSE_TESS);
|
||||
|
||||
const char *shading = "";
|
||||
if (glslES30)
|
||||
if (compat.glslES30)
|
||||
shading = doFlatShading ? "flat " : "";
|
||||
|
||||
DoLightComputation doLight[4] = { LIGHT_OFF, LIGHT_OFF, LIGHT_OFF, LIGHT_OFF };
|
||||
@ -223,31 +213,31 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
|
||||
}
|
||||
|
||||
if (useHWTransform)
|
||||
WRITE(p, "%s vec3 position;\n", attribute);
|
||||
WRITE(p, "%s vec3 position;\n", compat.attribute);
|
||||
else
|
||||
WRITE(p, "%s vec4 position;\n", attribute); // need to pass the fog coord in w
|
||||
WRITE(p, "%s vec4 position;\n", compat.attribute); // need to pass the fog coord in w
|
||||
*attrMask |= 1 << ATTR_POSITION;
|
||||
|
||||
if (useHWTransform && hasNormal) {
|
||||
WRITE(p, "%s mediump vec3 normal;\n", attribute);
|
||||
WRITE(p, "%s mediump vec3 normal;\n", compat.attribute);
|
||||
*attrMask |= 1 << ATTR_NORMAL;
|
||||
}
|
||||
|
||||
bool texcoordVec3In = false;
|
||||
if (doTexture && hasTexcoord) {
|
||||
if (!useHWTransform && doTextureProjection && !isModeThrough) {
|
||||
WRITE(p, "%s vec3 texcoord;\n", attribute);
|
||||
WRITE(p, "%s vec3 texcoord;\n", compat.attribute);
|
||||
texcoordVec3In = true;
|
||||
} else {
|
||||
WRITE(p, "%s vec2 texcoord;\n", attribute);
|
||||
WRITE(p, "%s vec2 texcoord;\n", compat.attribute);
|
||||
}
|
||||
*attrMask |= 1 << ATTR_TEXCOORD;
|
||||
}
|
||||
if (hasColor) {
|
||||
WRITE(p, "%s lowp vec4 color0;\n", attribute);
|
||||
WRITE(p, "%s lowp vec4 color0;\n", compat.attribute);
|
||||
*attrMask |= 1 << ATTR_COLOR0;
|
||||
if (lmode && !useHWTransform) { // only software transform supplies color1 as vertex data
|
||||
WRITE(p, "%s lowp vec3 color1;\n", attribute);
|
||||
WRITE(p, "%s lowp vec3 color1;\n", compat.attribute);
|
||||
*attrMask |= 1 << ATTR_COLOR1;
|
||||
}
|
||||
}
|
||||
@ -346,21 +336,21 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
|
||||
*uniformMask |= DIRTY_CULLRANGE;
|
||||
}
|
||||
|
||||
WRITE(p, "%s%s lowp vec4 v_color0;\n", shading, varying);
|
||||
WRITE(p, "%s%s lowp vec4 v_color0;\n", shading, compat.varying);
|
||||
if (lmode) {
|
||||
WRITE(p, "%s%s lowp vec3 v_color1;\n", shading, varying);
|
||||
WRITE(p, "%s%s lowp vec3 v_color1;\n", shading, compat.varying);
|
||||
}
|
||||
|
||||
if (doTexture) {
|
||||
WRITE(p, "%s %s vec3 v_texcoord;\n", varying, highpTexcoord ? "highp" : "mediump");
|
||||
WRITE(p, "%s %s vec3 v_texcoord;\n", compat.varying, highpTexcoord ? "highp" : "mediump");
|
||||
}
|
||||
|
||||
if (enableFog) {
|
||||
// See the fragment shader generator
|
||||
if (highpFog) {
|
||||
WRITE(p, "%s highp float v_fogdepth;\n", varying);
|
||||
WRITE(p, "%s highp float v_fogdepth;\n", compat.varying);
|
||||
} else {
|
||||
WRITE(p, "%s mediump float v_fogdepth;\n", varying);
|
||||
WRITE(p, "%s mediump float v_fogdepth;\n", compat.varying);
|
||||
}
|
||||
}
|
||||
|
||||
@ -427,17 +417,17 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
|
||||
for (int j = 0; j < 4; j++) {
|
||||
WRITE(p, " index_u = (%i + point_pos.x);\n", j);
|
||||
WRITE(p, " index_v = (%i + point_pos.y);\n", i);
|
||||
WRITE(p, " _pos[%i] = %s(u_tess_points, ivec2(index_u, index_v), 0).xyz;\n", i * 4 + j, texelFetch);
|
||||
WRITE(p, " _pos[%i] = %s(u_tess_points, ivec2(index_u, index_v), 0).xyz;\n", i * 4 + j, compat.texelFetch);
|
||||
if (doTexture && hasTexcoordTess)
|
||||
WRITE(p, " _tex[%i] = %s(u_tess_points, ivec2(index_u + u_spline_counts, index_v), 0).xy;\n", i * 4 + j, texelFetch);
|
||||
WRITE(p, " _tex[%i] = %s(u_tess_points, ivec2(index_u + u_spline_counts, index_v), 0).xy;\n", i * 4 + j, compat.texelFetch);
|
||||
if (hasColorTess)
|
||||
WRITE(p, " _col[%i] = %s(u_tess_points, ivec2(index_u + u_spline_counts * 2, index_v), 0).rgba;\n", i * 4 + j, texelFetch);
|
||||
WRITE(p, " _col[%i] = %s(u_tess_points, ivec2(index_u + u_spline_counts * 2, index_v), 0).rgba;\n", i * 4 + j, compat.texelFetch);
|
||||
}
|
||||
}
|
||||
|
||||
// Basis polynomials as weight coefficients
|
||||
WRITE(p, " vec4 basis_u = %s(u_tess_weights_u, %s, 0);\n", texelFetch, "ivec2(weight_idx.x * 2, 0)");
|
||||
WRITE(p, " vec4 basis_v = %s(u_tess_weights_v, %s, 0);\n", texelFetch, "ivec2(weight_idx.y * 2, 0)");
|
||||
WRITE(p, " vec4 basis_u = %s(u_tess_weights_u, %s, 0);\n", compat.texelFetch, "ivec2(weight_idx.x * 2, 0)");
|
||||
WRITE(p, " vec4 basis_v = %s(u_tess_weights_v, %s, 0);\n", compat.texelFetch, "ivec2(weight_idx.y * 2, 0)");
|
||||
WRITE(p, " mat4 basis = outerProduct(basis_u, basis_v);\n");
|
||||
|
||||
// Tessellate
|
||||
@ -454,8 +444,8 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
|
||||
WRITE(p, " tess.col = u_matambientalpha;\n");
|
||||
if (hasNormalTess) {
|
||||
// Derivatives as weight coefficients
|
||||
WRITE(p, " vec4 deriv_u = %s(u_tess_weights_u, %s, 0);\n", texelFetch, "ivec2(weight_idx.x * 2 + 1, 0)");
|
||||
WRITE(p, " vec4 deriv_v = %s(u_tess_weights_v, %s, 0);\n", texelFetch, "ivec2(weight_idx.y * 2 + 1, 0)");
|
||||
WRITE(p, " vec4 deriv_u = %s(u_tess_weights_u, %s, 0);\n", compat.texelFetch, "ivec2(weight_idx.x * 2 + 1, 0)");
|
||||
WRITE(p, " vec4 deriv_v = %s(u_tess_weights_v, %s, 0);\n", compat.texelFetch, "ivec2(weight_idx.y * 2 + 1, 0)");
|
||||
|
||||
WRITE(p, " vec3 du = tess_sample(_pos, outerProduct(deriv_u, basis_v));\n");
|
||||
WRITE(p, " vec3 dv = tess_sample(_pos, outerProduct(basis_u, deriv_v));\n");
|
||||
@ -849,4 +839,5 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
|
||||
WRITE(p, " gl_Position = outPos;\n");
|
||||
|
||||
WRITE(p, "}\n");
|
||||
return true;
|
||||
}
|
||||
|
@ -23,4 +23,4 @@
|
||||
|
||||
struct VShaderID;
|
||||
|
||||
void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, uint64_t *uniformMask);
|
||||
bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString);
|
||||
|
@ -370,14 +370,12 @@
|
||||
<ClInclude Include="D3D11\D3D11Util.h" />
|
||||
<ClInclude Include="D3D11\DepalettizeShaderD3D11.h" />
|
||||
<ClInclude Include="D3D11\DrawEngineD3D11.h" />
|
||||
<ClInclude Include="D3D11\FragmentShaderGeneratorD3D11.h" />
|
||||
<ClInclude Include="D3D11\FramebufferManagerD3D11.h" />
|
||||
<ClInclude Include="D3D11\GPU_D3D11.h" />
|
||||
<ClInclude Include="D3D11\ShaderManagerD3D11.h" />
|
||||
<ClInclude Include="D3D11\StateMappingD3D11.h" />
|
||||
<ClInclude Include="D3D11\TextureCacheD3D11.h" />
|
||||
<ClInclude Include="D3D11\TextureScalerD3D11.h" />
|
||||
<ClInclude Include="D3D11\VertexShaderGeneratorD3D11.h" />
|
||||
<ClInclude Include="Debugger\Breakpoints.h" />
|
||||
<ClInclude Include="Debugger\Debugger.h" />
|
||||
<ClInclude Include="Debugger\Playback.h" />
|
||||
@ -387,12 +385,12 @@
|
||||
<ClInclude Include="Directx9\DepalettizeShaderDX9.h" />
|
||||
<ClInclude Include="Directx9\FramebufferManagerDX9.h" />
|
||||
<ClInclude Include="Directx9\GPU_DX9.h" />
|
||||
<ClInclude Include="Directx9\PixelShaderGeneratorDX9.h" />
|
||||
<ClInclude Include="Directx9\FragmentShaderGeneratorHLSL.h" />
|
||||
<ClInclude Include="Directx9\ShaderManagerDX9.h" />
|
||||
<ClInclude Include="Directx9\TextureCacheDX9.h" />
|
||||
<ClInclude Include="Directx9\TextureScalerDX9.h" />
|
||||
<ClInclude Include="Directx9\DrawEngineDX9.h" />
|
||||
<ClInclude Include="Directx9\VertexShaderGeneratorDX9.h" />
|
||||
<ClInclude Include="Directx9\VertexShaderGeneratorHLSL.h" />
|
||||
<ClInclude Include="ge_constants.h" />
|
||||
<ClInclude Include="GeDisasm.h" />
|
||||
<ClInclude Include="GLES\DepalettizeShaderGLES.h">
|
||||
@ -549,7 +547,6 @@
|
||||
<ClCompile Include="D3D11\D3D11Util.cpp" />
|
||||
<ClCompile Include="D3D11\DepalettizeShaderD3D11.cpp" />
|
||||
<ClCompile Include="D3D11\DrawEngineD3D11.cpp" />
|
||||
<ClCompile Include="D3D11\FragmentShaderGeneratorD3D11.cpp" />
|
||||
<ClCompile Include="D3D11\FramebufferManagerD3D11.cpp" />
|
||||
<ClCompile Include="D3D11\GPU_D3D11.cpp" />
|
||||
<ClCompile Include="D3D11\ShaderManagerD3D11.cpp" />
|
||||
@ -557,7 +554,6 @@
|
||||
<ClCompile Include="D3D11\StencilBufferD3D11.cpp" />
|
||||
<ClCompile Include="D3D11\TextureCacheD3D11.cpp" />
|
||||
<ClCompile Include="D3D11\TextureScalerD3D11.cpp" />
|
||||
<ClCompile Include="D3D11\VertexShaderGeneratorD3D11.cpp" />
|
||||
<ClCompile Include="Debugger\Breakpoints.cpp" />
|
||||
<ClCompile Include="Debugger\Debugger.cpp" />
|
||||
<ClCompile Include="Debugger\Playback.cpp" />
|
||||
@ -566,14 +562,14 @@
|
||||
<ClCompile Include="Directx9\DepalettizeShaderDX9.cpp" />
|
||||
<ClCompile Include="Directx9\FramebufferManagerDX9.cpp" />
|
||||
<ClCompile Include="Directx9\GPU_DX9.cpp" />
|
||||
<ClCompile Include="Directx9\PixelShaderGeneratorDX9.cpp" />
|
||||
<ClCompile Include="Directx9\FragmentShaderGeneratorHLSL.cpp" />
|
||||
<ClCompile Include="Directx9\ShaderManagerDX9.cpp" />
|
||||
<ClCompile Include="Directx9\StateMappingDX9.cpp" />
|
||||
<ClCompile Include="Directx9\StencilBufferDX9.cpp" />
|
||||
<ClCompile Include="Directx9\TextureCacheDX9.cpp" />
|
||||
<ClCompile Include="Directx9\TextureScalerDX9.cpp" />
|
||||
<ClCompile Include="Directx9\DrawEngineDX9.cpp" />
|
||||
<ClCompile Include="Directx9\VertexShaderGeneratorDX9.cpp" />
|
||||
<ClCompile Include="Directx9\VertexShaderGeneratorHLSL.cpp" />
|
||||
<ClCompile Include="GeDisasm.cpp" />
|
||||
<ClCompile Include="GeConstants.cpp" />
|
||||
<ClCompile Include="GLES\DepalettizeShaderGLES.cpp">
|
||||
|
@ -66,9 +66,6 @@
|
||||
<ClInclude Include="Directx9\GPU_DX9.h">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Directx9\VertexShaderGeneratorDX9.h">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Directx9\DrawEngineDX9.h">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClInclude>
|
||||
@ -81,9 +78,6 @@
|
||||
<ClInclude Include="Directx9\ShaderManagerDX9.h">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Directx9\PixelShaderGeneratorDX9.h">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\IndexGenerator.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
@ -219,12 +213,6 @@
|
||||
<ClInclude Include="D3D11\ShaderManagerD3D11.h">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3D11\VertexShaderGeneratorD3D11.h">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3D11\FragmentShaderGeneratorD3D11.h">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3D11\TextureCacheD3D11.h">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClInclude>
|
||||
@ -288,6 +276,12 @@
|
||||
<ClInclude Include="ge_constants.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Directx9\VertexShaderGeneratorHLSL.h">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Directx9\FragmentShaderGeneratorHLSL.h">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Math3D.cpp">
|
||||
@ -326,9 +320,6 @@
|
||||
<ClCompile Include="Directx9\GPU_DX9.cpp">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Directx9\VertexShaderGeneratorDX9.cpp">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Directx9\DrawEngineDX9.cpp">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClCompile>
|
||||
@ -341,9 +332,6 @@
|
||||
<ClCompile Include="Directx9\ShaderManagerDX9.cpp">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Directx9\PixelShaderGeneratorDX9.cpp">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Directx9\TextureScalerDX9.cpp">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClCompile>
|
||||
@ -494,12 +482,6 @@
|
||||
<ClCompile Include="D3D11\ShaderManagerD3D11.cpp">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3D11\VertexShaderGeneratorD3D11.cpp">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3D11\FragmentShaderGeneratorD3D11.cpp">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3D11\TextureCacheD3D11.cpp">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClCompile>
|
||||
@ -575,5 +557,11 @@
|
||||
<ClCompile Include="GeConstants.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Directx9\VertexShaderGeneratorHLSL.cpp">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Directx9\FragmentShaderGeneratorHLSL.cpp">
|
||||
<Filter>DirectX9</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -43,8 +43,7 @@ static const char *vulkan_glsl_preamble =
|
||||
|
||||
#define WRITE p+=sprintf
|
||||
|
||||
// Missing: Z depth range
|
||||
bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_t vulkanVendorId) {
|
||||
bool GenerateFragmentShaderVulkanGLSL(const FShaderID &id, char *buffer, uint32_t vulkanVendorId, std::string *errorString) {
|
||||
char *p = buffer;
|
||||
|
||||
const char *lastFragData = nullptr;
|
||||
@ -93,7 +92,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
WRITE(p, "layout (depth_unchanged) out float gl_FragDepth;\n");
|
||||
}
|
||||
|
||||
WRITE(p, "layout (std140, set = 0, binding = 3) uniform baseUBO {\n%s} base;\n", ub_baseStr);
|
||||
WRITE(p, "layout (std140, set = 0, binding = 3) uniform baseUBO {\n%s};\n", ub_baseStr);
|
||||
if (doTexture) {
|
||||
WRITE(p, "layout (binding = 0) uniform sampler2D tex;\n");
|
||||
}
|
||||
@ -167,18 +166,18 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
std::string modulo = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) ? "mymod" : "mod";
|
||||
|
||||
if (id.Bit(FS_BIT_CLAMP_S)) {
|
||||
ucoord = "clamp(" + ucoord + ", base.texclamp.z, base.texclamp.x - base.texclamp.z)";
|
||||
ucoord = "clamp(" + ucoord + ", u_texclamp.z, u_texclamp.x - u_texclamp.z)";
|
||||
} else {
|
||||
ucoord = modulo + "(" + ucoord + ", base.texclamp.x)";
|
||||
ucoord = modulo + "(" + ucoord + ", u_texclamp.x)";
|
||||
}
|
||||
if (id.Bit(FS_BIT_CLAMP_T)) {
|
||||
vcoord = "clamp(" + vcoord + ", base.texclamp.w, base.texclamp.y - base.texclamp.w)";
|
||||
vcoord = "clamp(" + vcoord + ", u_texclamp.w, u_texclamp.y - u_texclamp.w)";
|
||||
} else {
|
||||
vcoord = modulo + "(" + vcoord + ", base.texclamp.y)";
|
||||
vcoord = modulo + "(" + vcoord + ", u_texclamp.y)";
|
||||
}
|
||||
if (textureAtOffset) {
|
||||
ucoord = "(" + ucoord + " + base.texclampoff.x)";
|
||||
vcoord = "(" + vcoord + " + base.texclampoff.y)";
|
||||
ucoord = "(" + ucoord + " + u_texclampoff.x)";
|
||||
vcoord = "(" + vcoord + " + u_texclampoff.y)";
|
||||
}
|
||||
|
||||
WRITE(p, " vec2 fixedcoord = vec2(%s, %s);\n", ucoord.c_str(), vcoord.c_str());
|
||||
@ -203,7 +202,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
}
|
||||
WRITE(p, " vec2 tsize = textureSize(tex, 0);\n");
|
||||
WRITE(p, " vec2 fraction;\n");
|
||||
WRITE(p, " bool bilinear = (base.depal_mask_shift_off_fmt >> 31) != 0;\n");
|
||||
WRITE(p, " bool bilinear = (u_depal_mask_shift_off_fmt >> 31) != 0;\n");
|
||||
WRITE(p, " if (bilinear) {\n");
|
||||
WRITE(p, " uv_round = uv * tsize - vec2(0.5, 0.5);\n");
|
||||
WRITE(p, " fraction = fract(uv_round);\n");
|
||||
@ -215,10 +214,10 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
WRITE(p, " vec4 t1 = textureOffset(tex, uv_round, ivec2(1, 0));\n");
|
||||
WRITE(p, " vec4 t2 = textureOffset(tex, uv_round, ivec2(0, 1));\n");
|
||||
WRITE(p, " vec4 t3 = textureOffset(tex, uv_round, ivec2(1, 1));\n");
|
||||
WRITE(p, " uint depalMask = (base.depal_mask_shift_off_fmt & 0xFF);\n");
|
||||
WRITE(p, " uint depalShift = (base.depal_mask_shift_off_fmt >> 8) & 0xFF;\n");
|
||||
WRITE(p, " uint depalOffset = ((base.depal_mask_shift_off_fmt >> 16) & 0xFF) << 4;\n");
|
||||
WRITE(p, " uint depalFmt = (base.depal_mask_shift_off_fmt >> 24) & 0x3;\n");
|
||||
WRITE(p, " uint depalMask = (u_depal_mask_shift_off_fmt & 0xFF);\n");
|
||||
WRITE(p, " uint depalShift = (u_depal_mask_shift_off_fmt >> 8) & 0xFF;\n");
|
||||
WRITE(p, " uint depalOffset = ((u_depal_mask_shift_off_fmt >> 16) & 0xFF) << 4;\n");
|
||||
WRITE(p, " uint depalFmt = (u_depal_mask_shift_off_fmt >> 24) & 0x3;\n");
|
||||
WRITE(p, " uvec4 col; uint index0; uint index1; uint index2; uint index3;\n");
|
||||
WRITE(p, " switch (depalFmt) {\n"); // We might want to include fmt in the shader ID if this is a performance issue.
|
||||
WRITE(p, " case 0:\n"); // 565
|
||||
@ -299,7 +298,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
break;
|
||||
|
||||
case GE_TEXFUNC_BLEND:
|
||||
WRITE(p, " vec4 v = vec4(mix(p.rgb, base.texenv.rgb, t.rgb), p.a * t.a)%s;\n", secondary);
|
||||
WRITE(p, " vec4 v = vec4(mix(p.rgb, u_texenv.rgb, t.rgb), p.a * t.a)%s;\n", secondary);
|
||||
break;
|
||||
|
||||
case GE_TEXFUNC_REPLACE:
|
||||
@ -326,7 +325,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
break;
|
||||
|
||||
case GE_TEXFUNC_BLEND:
|
||||
WRITE(p, " vec4 v = vec4(mix(p.rgb, base.texenv.rgb, t.rgb), p.a)%s;\n", secondary);
|
||||
WRITE(p, " vec4 v = vec4(mix(p.rgb, u_texenv.rgb, t.rgb), p.a)%s;\n", secondary);
|
||||
break;
|
||||
|
||||
case GE_TEXFUNC_REPLACE:
|
||||
@ -374,7 +373,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
} else {
|
||||
const char *alphaTestFuncs[] = { "#", "#", " != ", " == ", " >= ", " > ", " <= ", " < " };
|
||||
if (alphaTestFuncs[alphaTestFunc][0] != '#') {
|
||||
WRITE(p, " if ((roundAndScaleTo255i(v.a) & base.alphacolormask.a) %s base.alphacolorref.a) %s\n", alphaTestFuncs[alphaTestFunc], discardStatement);
|
||||
WRITE(p, " if ((roundAndScaleTo255i(v.a) & u_alphacolormask.a) %s u_alphacolorref.a) %s\n", alphaTestFuncs[alphaTestFunc], discardStatement);
|
||||
} else {
|
||||
// This means NEVER. See above.
|
||||
WRITE(p, " %s\n", discardStatement);
|
||||
@ -384,7 +383,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
|
||||
if (enableFog) {
|
||||
WRITE(p, " float fogCoef = clamp(v_fogdepth, 0.0, 1.0);\n");
|
||||
WRITE(p, " v = mix(vec4(base.fogcolor, v.a), v, fogCoef);\n");
|
||||
WRITE(p, " v = mix(vec4(u_fogcolor, v.a), v, fogCoef);\n");
|
||||
// WRITE(p, " v.x = v_depth;\n");
|
||||
}
|
||||
|
||||
@ -407,7 +406,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
const char *colorTestFuncs[] = { "#", "#", " != ", " == " };
|
||||
if (colorTestFuncs[colorTestFunc][0] != '#') {
|
||||
WRITE(p, " ivec3 v_scaled = roundAndScaleTo255iv(v.rgb);\n");
|
||||
WRITE(p, " if ((v_scaled & base.alphacolormask.rgb) %s (base.alphacolorref.rgb & base.alphacolormask.rgb)) %s\n", colorTestFuncs[colorTestFunc], discardStatement);
|
||||
WRITE(p, " if ((v_scaled & u_alphacolormask.rgb) %s (u_alphacolorref.rgb & u_alphacolormask.rgb)) %s\n", colorTestFuncs[colorTestFunc], discardStatement);
|
||||
} else {
|
||||
WRITE(p, " %s\n", discardStatement);
|
||||
}
|
||||
@ -431,7 +430,12 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
case GE_SRCBLEND_DOUBLEINVSRCALPHA: srcFactor = "vec3(1.0 - v.a * 2.0)"; break;
|
||||
case GE_SRCBLEND_DOUBLEDSTALPHA: srcFactor = "ERROR"; break;
|
||||
case GE_SRCBLEND_DOUBLEINVDSTALPHA: srcFactor = "ERROR"; break;
|
||||
case GE_SRCBLEND_FIXA: srcFactor = "base.blendFixA"; break;
|
||||
case GE_SRCBLEND_FIXA: srcFactor = "u_blendFixA"; break;
|
||||
}
|
||||
|
||||
if (!strcmp(srcFactor, "ERROR")) {
|
||||
*errorString = "Bad replaceblend src factor";
|
||||
return false;
|
||||
}
|
||||
|
||||
WRITE(p, " v.rgb = v.rgb * %s;\n", srcFactor);
|
||||
@ -454,7 +458,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
case GE_SRCBLEND_DOUBLEINVSRCALPHA: srcFactor = "vec3(1.0 - v.a * 2.0)"; break;
|
||||
case GE_SRCBLEND_DOUBLEDSTALPHA: srcFactor = "vec3(destColor.a * 2.0)"; break;
|
||||
case GE_SRCBLEND_DOUBLEINVDSTALPHA: srcFactor = "vec3(1.0 - destColor.a * 2.0)"; break;
|
||||
case GE_SRCBLEND_FIXA: srcFactor = "base.blendFixA"; break;
|
||||
case GE_SRCBLEND_FIXA: srcFactor = "u_blendFixA"; break;
|
||||
}
|
||||
switch (replaceBlendFuncB) {
|
||||
case GE_DSTBLEND_SRCCOLOR: dstFactor = "v.rgb"; break;
|
||||
@ -467,7 +471,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
case GE_DSTBLEND_DOUBLEINVSRCALPHA: dstFactor = "vec3(1.0 - v.a * 2.0)"; break;
|
||||
case GE_DSTBLEND_DOUBLEDSTALPHA: dstFactor = "vec3(destColor.a * 2.0)"; break;
|
||||
case GE_DSTBLEND_DOUBLEINVDSTALPHA: dstFactor = "vec3(1.0 - destColor.a * 2.0)"; break;
|
||||
case GE_DSTBLEND_FIXB: dstFactor = "base.blendFixB"; break;
|
||||
case GE_DSTBLEND_FIXB: dstFactor = "u_blendFixB"; break;
|
||||
}
|
||||
|
||||
switch (replaceBlendEq) {
|
||||
@ -502,7 +506,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
if (stencilToAlpha != REPLACE_ALPHA_NO) {
|
||||
switch (replaceAlphaWithStencilType) {
|
||||
case STENCIL_VALUE_UNIFORM:
|
||||
replacedAlpha = "base.stencilReplace";
|
||||
replacedAlpha = "u_stencilReplaceValue";
|
||||
break;
|
||||
|
||||
case STENCIL_VALUE_ZERO:
|
||||
@ -550,7 +554,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG(G3D, "Bad stencil-to-alpha type, corrupt ID?");
|
||||
*errorString = "Bad stencil-to-alpha type, corrupt ID?";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -566,7 +570,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG(G3D, "Bad logic op type, corrupt ID?");
|
||||
*errorString = "Bad logic op type, corrupt ID?";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -20,4 +20,4 @@
|
||||
|
||||
struct FShaderID;
|
||||
|
||||
bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_t vulkanVendorId);
|
||||
bool GenerateFragmentShaderVulkanGLSL(const FShaderID &id, char *buffer, uint32_t vulkanVendorId, std::string *errorString);
|
||||
|
@ -262,7 +262,8 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader
|
||||
VulkanVertexShader *vs = vsCache_.Get(VSID);
|
||||
if (!vs) {
|
||||
// Vertex shader not in cache. Let's compile it.
|
||||
GenerateVulkanGLSLVertexShader(VSID, codeBuffer_);
|
||||
std::string genErrorString;
|
||||
GenerateVertexShaderVulkanGLSL(VSID, codeBuffer_, &genErrorString);
|
||||
vs = new VulkanVertexShader(vulkan_, VSID, codeBuffer_, useHWTransform);
|
||||
vsCache_.Insert(VSID, vs);
|
||||
}
|
||||
@ -272,7 +273,9 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader
|
||||
if (!fs) {
|
||||
uint32_t vendorID = vulkan_->GetPhysicalDeviceProperties().properties.vendorID;
|
||||
// Fragment shader not in cache. Let's compile it.
|
||||
GenerateVulkanGLSLFragmentShader(FSID, codeBuffer_, vendorID);
|
||||
std::string genErrorString;
|
||||
bool success = GenerateFragmentShaderVulkanGLSL(FSID, codeBuffer_, vendorID, &genErrorString);
|
||||
_assert_(success);
|
||||
fs = new VulkanFragmentShader(vulkan_, FSID, codeBuffer_);
|
||||
fsCache_.Insert(FSID, fs);
|
||||
}
|
||||
@ -388,7 +391,10 @@ bool ShaderManagerVulkan::LoadCache(FILE *f) {
|
||||
break;
|
||||
}
|
||||
bool useHWTransform = id.Bit(VS_BIT_USE_HW_TRANSFORM);
|
||||
GenerateVulkanGLSLVertexShader(id, codeBuffer_);
|
||||
std::string genErrorString;
|
||||
if (!GenerateVertexShaderVulkanGLSL(id, codeBuffer_, &genErrorString)) {
|
||||
return false;
|
||||
}
|
||||
VulkanVertexShader *vs = new VulkanVertexShader(vulkan_, id, codeBuffer_, useHWTransform);
|
||||
vsCache_.Insert(id, vs);
|
||||
}
|
||||
@ -399,7 +405,10 @@ bool ShaderManagerVulkan::LoadCache(FILE *f) {
|
||||
ERROR_LOG(G3D, "Vulkan shader cache truncated");
|
||||
break;
|
||||
}
|
||||
GenerateVulkanGLSLFragmentShader(id, codeBuffer_, vendorID);
|
||||
std::string genErrorString;
|
||||
if (!GenerateFragmentShaderVulkanGLSL(id, codeBuffer_, vendorID, &genErrorString)) {
|
||||
return false;
|
||||
}
|
||||
VulkanFragmentShader *fs = new VulkanFragmentShader(vulkan_, id, codeBuffer_);
|
||||
fsCache_.Insert(id, fs);
|
||||
}
|
||||
|
@ -39,7 +39,8 @@
|
||||
static const char *vulkan_glsl_preamble =
|
||||
"#version 450\n"
|
||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||
"#extension GL_ARB_shading_language_420pack : enable\n\n";
|
||||
"#extension GL_ARB_shading_language_420pack : enable\n"
|
||||
"#define splat3(x) vec3(x)\n\n";
|
||||
|
||||
// "Varying" layout - must match fragment shader
|
||||
// color0 = 0
|
||||
@ -63,12 +64,6 @@ static const char * const boneWeightDecl[9] = {
|
||||
"layout(location = 3) in vec4 w1;\nlayout(location = 4) in vec4 w2;\n",
|
||||
};
|
||||
|
||||
enum DoLightComputation {
|
||||
LIGHT_OFF,
|
||||
LIGHT_SHADE,
|
||||
LIGHT_FULL,
|
||||
};
|
||||
|
||||
// Depth range and viewport
|
||||
//
|
||||
// After the multiplication with the projection matrix, we have a 4D vector in clip space.
|
||||
@ -94,7 +89,7 @@ enum DoLightComputation {
|
||||
// TODO: Skip all this if we can actually get a 16-bit depth buffer along with stencil, which
|
||||
// is a bit of a rare configuration, although quite common on mobile.
|
||||
|
||||
bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
bool GenerateVertexShaderVulkanGLSL(const VShaderID &id, char *buffer, std::string *errorString) {
|
||||
char *p = buffer;
|
||||
|
||||
WRITE(p, "%s", vulkan_glsl_preamble);
|
||||
@ -134,11 +129,11 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
bool flipNormalTess = id.Bit(VS_BIT_NORM_REVERSE_TESS);
|
||||
|
||||
WRITE(p, "\n");
|
||||
WRITE(p, "layout (std140, set = 0, binding = 3) uniform baseVars {\n%s} base;\n", ub_baseStr);
|
||||
WRITE(p, "layout (std140, set = 0, binding = 3) uniform baseVars {\n%s};\n", ub_baseStr);
|
||||
if (enableLighting || doShadeMapping)
|
||||
WRITE(p, "layout (std140, set = 0, binding = 4) uniform lightVars {\n%s} light;\n", ub_vs_lightsStr);
|
||||
WRITE(p, "layout (std140, set = 0, binding = 4) uniform lightVars {\n%s};\n", ub_vs_lightsStr);
|
||||
if (enableBones)
|
||||
WRITE(p, "layout (std140, set = 0, binding = 5) uniform boneVars {\n%s} bone;\n", ub_vs_bonesStr);
|
||||
WRITE(p, "layout (std140, set = 0, binding = 5) uniform boneVars {\n%s};\n", ub_vs_bonesStr);
|
||||
|
||||
const char *shading = doFlatShading ? "flat " : "";
|
||||
|
||||
@ -203,9 +198,9 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
// Apply the projection and viewport to get the Z buffer value, floor to integer, undo the viewport and projection.
|
||||
WRITE(p, "\nvec4 depthRoundZVP(vec4 v) {\n");
|
||||
WRITE(p, " float z = v.z / v.w;\n");
|
||||
WRITE(p, " z = z * base.depthRange.x + base.depthRange.y;\n");
|
||||
WRITE(p, " z = z * u_depthRange.x + u_depthRange.y;\n");
|
||||
WRITE(p, " z = floor(z);\n");
|
||||
WRITE(p, " z = (z - base.depthRange.z) * base.depthRange.w;\n");
|
||||
WRITE(p, " z = (z - u_depthRange.z) * u_depthRange.w;\n");
|
||||
WRITE(p, " return vec4(v.x, v.y, z * v.w, v.w);\n");
|
||||
WRITE(p, "}\n\n");
|
||||
}
|
||||
@ -263,7 +258,7 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
WRITE(p, " int index;\n");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
WRITE(p, " index = (%i + point_pos.y) * int(base.spline_counts) + (%i + point_pos.x);\n", i, j);
|
||||
WRITE(p, " index = (%i + point_pos.y) * int(u_spline_counts) + (%i + point_pos.x);\n", i, j);
|
||||
WRITE(p, " _pos[%i] = tess_data.data[index].pos.xyz;\n", i * 4 + j);
|
||||
if (doTexture && hasTexcoordTess)
|
||||
WRITE(p, " _tex[%i] = tess_data.data[index].uv.xy;\n", i * 4 + j);
|
||||
@ -288,7 +283,7 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
if (hasColorTess)
|
||||
WRITE(p, " tess.col = tess_sample(_col, basis);\n");
|
||||
else
|
||||
WRITE(p, " tess.col = base.matambientalpha;\n");
|
||||
WRITE(p, " tess.col = u_matambientalpha;\n");
|
||||
if (hasNormalTess) {
|
||||
// Derivatives as weight coefficients
|
||||
WRITE(p, " vec4 deriv_u = tess_weights_u.data[weight_idx.x].deriv;\n");
|
||||
@ -317,7 +312,7 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
if (lmode)
|
||||
WRITE(p, " v_color1 = color1;\n");
|
||||
} else {
|
||||
WRITE(p, " v_color0 = base.matambientalpha;\n");
|
||||
WRITE(p, " v_color0 = u_matambientalpha;\n");
|
||||
if (lmode)
|
||||
WRITE(p, " v_color1 = vec3(0.0);\n");
|
||||
}
|
||||
@ -325,13 +320,13 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
WRITE(p, " v_fogdepth = position.w;\n");
|
||||
}
|
||||
if (isModeThrough) {
|
||||
WRITE(p, " vec4 outPos = base.proj_through_mtx * vec4(position.xyz, 1.0);\n");
|
||||
WRITE(p, " vec4 outPos = u_proj_through * vec4(position.xyz, 1.0);\n");
|
||||
} else {
|
||||
// The viewport is used in this case, so need to compensate for that.
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(base.proj_mtx * vec4(position.xyz, 1.0));\n");
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(u_proj * vec4(position.xyz, 1.0));\n");
|
||||
} else {
|
||||
WRITE(p, " vec4 outPos = base.proj_mtx * vec4(position.xyz, 1.0);\n");
|
||||
WRITE(p, " vec4 outPos = u_proj * vec4(position.xyz, 1.0);\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -342,17 +337,17 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
WRITE(p, " Tess tess;\n");
|
||||
WRITE(p, " tessellate(tess);\n");
|
||||
|
||||
WRITE(p, " vec3 worldpos = vec4(tess.pos.xyz, 1.0) * base.world_mtx;\n");
|
||||
WRITE(p, " vec3 worldpos = vec4(tess.pos.xyz, 1.0) * u_world;\n");
|
||||
if (hasNormalTess) {
|
||||
WRITE(p, " mediump vec3 worldnormal = normalize(vec4(%stess.nrm, 0.0) * base.world_mtx);\n", flipNormalTess ? "-" : "");
|
||||
WRITE(p, " mediump vec3 worldnormal = normalize(vec4(%stess.nrm, 0.0) * u_world);\n", flipNormalTess ? "-" : "");
|
||||
} else {
|
||||
WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n");
|
||||
}
|
||||
} else {
|
||||
// No skinning, just standard T&L.
|
||||
WRITE(p, " vec3 worldpos = vec4(position.xyz, 1.0) * base.world_mtx;\n");
|
||||
WRITE(p, " vec3 worldpos = vec4(position.xyz, 1.0) * u_world;\n");
|
||||
if (hasNormal)
|
||||
WRITE(p, " mediump vec3 worldnormal = normalize(vec4(%snormal, 0.0) * base.world_mtx);\n", flipNormal ? "-" : "");
|
||||
WRITE(p, " mediump vec3 worldnormal = normalize(vec4(%snormal, 0.0) * u_world);\n", flipNormal ? "-" : "");
|
||||
else
|
||||
WRITE(p, " mediump vec3 worldnormal = vec3(0.0, 0.0, 1.0);\n");
|
||||
}
|
||||
@ -365,10 +360,10 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
"w2.x", "w2.y", "w2.z", "w2.w",
|
||||
};
|
||||
|
||||
WRITE(p, " mat3x4 skinMatrix = w1.x * bone.m[0];\n");
|
||||
WRITE(p, " mat3x4 skinMatrix = w1.x * u_bone[0];\n");
|
||||
if (numBoneWeights > 1) {
|
||||
for (int i = 1; i < numBoneWeights; i++) {
|
||||
WRITE(p, " skinMatrix += %s * bone.m[%i];\n", boneWeightAttr[i], i);
|
||||
WRITE(p, " skinMatrix += %s * u_bone[%i];\n", boneWeightAttr[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -376,35 +371,35 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
|
||||
// Trying to simplify this results in bugs in LBP...
|
||||
WRITE(p, " vec3 skinnedpos = (vec4(position, 1.0) * skinMatrix) %s;\n", factor);
|
||||
WRITE(p, " vec3 worldpos = vec4(skinnedpos, 1.0) * base.world_mtx;\n");
|
||||
WRITE(p, " vec3 worldpos = vec4(skinnedpos, 1.0) * u_world;\n");
|
||||
|
||||
if (hasNormal) {
|
||||
WRITE(p, " mediump vec3 skinnednormal = vec4(%snormal, 0.0) * skinMatrix %s;\n", flipNormal ? "-" : "", factor);
|
||||
} else {
|
||||
WRITE(p, " mediump vec3 skinnednormal = vec4(0.0, 0.0, %s1.0, 0.0) * skinMatrix %s;\n", flipNormal ? "-" : "", factor);
|
||||
}
|
||||
WRITE(p, " mediump vec3 worldnormal = normalize(vec4(skinnednormal, 0.0) * base.world_mtx);\n");
|
||||
WRITE(p, " mediump vec3 worldnormal = normalize(vec4(skinnednormal, 0.0) * u_world);\n");
|
||||
}
|
||||
|
||||
WRITE(p, " vec4 viewPos = vec4(vec4(worldpos, 1.0) * base.view_mtx, 1.0);\n");
|
||||
WRITE(p, " vec4 viewPos = vec4(vec4(worldpos, 1.0) * u_view, 1.0);\n");
|
||||
|
||||
// Final view and projection transforms.
|
||||
if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(base.proj_mtx * viewPos);\n");
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(u_proj * viewPos);\n");
|
||||
} else {
|
||||
WRITE(p, " vec4 outPos = base.proj_mtx * viewPos;\n");
|
||||
WRITE(p, " vec4 outPos = u_proj * viewPos;\n");
|
||||
}
|
||||
|
||||
// TODO: Declare variables for dots for shade mapping if needed.
|
||||
|
||||
const char *ambientStr = ((matUpdate & 1) && hasColor) ? "color0" : "base.matambientalpha";
|
||||
const char *diffuseStr = ((matUpdate & 2) && hasColor) ? "color0.rgb" : "light.matdiffuse";
|
||||
const char *specularStr = ((matUpdate & 4) && hasColor) ? "color0.rgb" : "light.matspecular.rgb";
|
||||
const char *ambientStr = ((matUpdate & 1) && hasColor) ? "color0" : "u_matambientalpha";
|
||||
const char *diffuseStr = ((matUpdate & 2) && hasColor) ? "color0.rgb" : "u_matdiffuse";
|
||||
const char *specularStr = ((matUpdate & 4) && hasColor) ? "color0.rgb" : "u_matspecular.rgb";
|
||||
if (doBezier || doSpline) {
|
||||
// TODO: Probably, should use hasColorTess but FF4 has a problem with drawing the background.
|
||||
ambientStr = (matUpdate & 1) && hasColor ? "tess.col" : "base.matambientalpha";
|
||||
diffuseStr = (matUpdate & 2) && hasColor ? "tess.col.rgb" : "light.matdiffuse";
|
||||
specularStr = (matUpdate & 4) && hasColor ? "tess.col.rgb" : "light.matspecular.rgb";
|
||||
ambientStr = (matUpdate & 1) && hasColor ? "tess.col" : "u_matambientalpha";
|
||||
diffuseStr = (matUpdate & 2) && hasColor ? "tess.col.rgb" : "u_matdiffuse";
|
||||
specularStr = (matUpdate & 4) && hasColor ? "tess.col.rgb" : "u_matspecular.rgb";
|
||||
}
|
||||
|
||||
bool diffuseIsZero = true;
|
||||
@ -412,7 +407,7 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
bool distanceNeeded = false;
|
||||
|
||||
if (enableLighting) {
|
||||
WRITE(p, " vec4 lightSum0 = light.u_ambient * %s + vec4(light.matemissive, 0.0);\n", ambientStr);
|
||||
WRITE(p, " vec4 lightSum0 = u_ambient * %s + vec4(u_matemissive, 0.0);\n", ambientStr);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
GELightType type = static_cast<GELightType>(id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2));
|
||||
@ -450,9 +445,9 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
|
||||
if (type == GE_LIGHTTYPE_DIRECTIONAL) {
|
||||
// We prenormalize light positions for directional lights.
|
||||
WRITE(p, " toLight = light.pos[%i];\n", i);
|
||||
WRITE(p, " toLight = u_lightpos%d;\n", i);
|
||||
} else {
|
||||
WRITE(p, " toLight = light.pos[%i] - worldpos;\n", i);
|
||||
WRITE(p, " toLight = u_lightpos%d - worldpos;\n", i);
|
||||
WRITE(p, " distance = length(toLight);\n");
|
||||
WRITE(p, " toLight /= distance;\n");
|
||||
}
|
||||
@ -464,10 +459,10 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
if (poweredDiffuse) {
|
||||
// pow(0.0, 0.0) may be undefined, but the PSP seems to treat it as 1.0.
|
||||
// Seen in Tales of the World: Radiant Mythology (#2424.)
|
||||
WRITE(p, " if (light.matspecular.a <= 0.0) {\n");
|
||||
WRITE(p, " if (u_matspecular.a <= 0.0) {\n");
|
||||
WRITE(p, " dot%i = 1.0;\n", i);
|
||||
WRITE(p, " } else {\n");
|
||||
WRITE(p, " dot%i = pow(max(dot%i, 0.0), light.matspecular.a);\n", i, i);
|
||||
WRITE(p, " dot%i = pow(max(dot%i, 0.0), u_matspecular.a);\n", i, i);
|
||||
WRITE(p, " }\n");
|
||||
}
|
||||
|
||||
@ -479,13 +474,13 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
timesLightScale = "";
|
||||
break;
|
||||
case GE_LIGHTTYPE_POINT:
|
||||
WRITE(p, " lightScale = clamp(1.0 / dot(light.att[%i], vec3(1.0, distance, distance*distance)), 0.0, 1.0);\n", i);
|
||||
WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%d, vec3(1.0, distance, distance*distance)), 0.0, 1.0);\n", i);
|
||||
break;
|
||||
case GE_LIGHTTYPE_SPOT:
|
||||
case GE_LIGHTTYPE_UNKNOWN:
|
||||
WRITE(p, " float angle%i = length(light.dir[%i]) == 0.0 ? 0.0 : dot(normalize(light.dir[%i]), toLight);\n", i, i, i);
|
||||
WRITE(p, " if (angle%i >= light.angle_spotCoef[%i].x) {\n", i, i);
|
||||
WRITE(p, " lightScale = clamp(1.0 / dot(light.att[%i], vec3(1.0, distance, distance*distance)), 0.0, 1.0) * (light.angle_spotCoef[%i].y <= 0.0 ? 1.0 : pow(angle%i, light.angle_spotCoef[%i].y));\n", i, i, i, i);
|
||||
WRITE(p, " float angle%i = length(u_lightdir%d) == 0.0 ? 0.0 : dot(normalize(u_lightdir%d), toLight);\n", i, i, i);
|
||||
WRITE(p, " if (angle%i >= u_lightangle_spotCoef%d.x) {\n", i, i);
|
||||
WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%d, vec3(1.0, distance, distance*distance)), 0.0, 1.0) * (u_lightangle_spotCoef%d.y <= 0.0 ? 1.0 : pow(angle%i, u_lightangle_spotCoef%d.y));\n", i, i, i, i);
|
||||
WRITE(p, " } else {\n");
|
||||
WRITE(p, " lightScale = 0.0;\n");
|
||||
WRITE(p, " }\n");
|
||||
@ -495,20 +490,20 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
break;
|
||||
}
|
||||
|
||||
WRITE(p, " diffuse = (light.diffuse[%i] * %s) * max(dot%i, 0.0);\n", i, diffuseStr, i);
|
||||
WRITE(p, " diffuse = (u_lightdiffuse%d * %s) * max(dot%i, 0.0);\n", i, diffuseStr, i);
|
||||
if (doSpecular) {
|
||||
WRITE(p, " if (dot%i >= 0.0) {\n", i);
|
||||
WRITE(p, " dot%i = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);\n", i);
|
||||
WRITE(p, " if (light.matspecular.a <= 0.0) {\n");
|
||||
WRITE(p, " if (u_matspecular.a <= 0.0) {\n");
|
||||
WRITE(p, " dot%i = 1.0;\n", i);
|
||||
WRITE(p, " } else {\n");
|
||||
WRITE(p, " dot%i = pow(max(dot%i, 0.0), light.matspecular.a);\n", i, i);
|
||||
WRITE(p, " dot%i = pow(max(dot%i, 0.0), u_matspecular.a);\n", i, i);
|
||||
WRITE(p, " }\n");
|
||||
WRITE(p, " if (dot%i > 0.0)\n", i);
|
||||
WRITE(p, " lightSum1 += light.specular[%i] * %s * dot%i %s;\n", i, specularStr, i, timesLightScale);
|
||||
WRITE(p, " lightSum1 += u_lightspecular%d * %s * dot%i %s;\n", i, specularStr, i, timesLightScale);
|
||||
WRITE(p, " }\n");
|
||||
}
|
||||
WRITE(p, " lightSum0.rgb += (light.ambient[%i] * %s.rgb + diffuse)%s;\n", i, ambientStr, timesLightScale);
|
||||
WRITE(p, " lightSum0.rgb += (u_lightambient%d * %s.rgb + diffuse)%s;\n", i, ambientStr, timesLightScale);
|
||||
}
|
||||
|
||||
if (enableLighting) {
|
||||
@ -536,7 +531,7 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
else
|
||||
WRITE(p, " v_color0 = color0;\n");
|
||||
} else {
|
||||
WRITE(p, " v_color0 = base.matambientalpha;\n");
|
||||
WRITE(p, " v_color0 = u_matambientalpha;\n");
|
||||
}
|
||||
if (lmode) {
|
||||
WRITE(p, " v_color1 = vec3(0.0);\n");
|
||||
@ -553,17 +548,17 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
if (scaleUV) {
|
||||
if (hasTexcoord) {
|
||||
if (doBezier || doSpline)
|
||||
WRITE(p, " v_texcoord = vec3(tess.tex.xy * base.uvscaleoffset.xy + base.uvscaleoffset.zw, 0.0);\n");
|
||||
WRITE(p, " v_texcoord = vec3(tess.tex.xy * u_uvscaleoffset.xy + u_uvscaleoffset.zw, 0.0);\n");
|
||||
else
|
||||
WRITE(p, " v_texcoord = vec3(texcoord.xy * base.uvscaleoffset.xy, 0.0);\n");
|
||||
WRITE(p, " v_texcoord = vec3(texcoord.xy * u_uvscaleoffset.xy, 0.0);\n");
|
||||
} else {
|
||||
WRITE(p, " v_texcoord = vec3(0.0);\n");
|
||||
}
|
||||
} else {
|
||||
if (hasTexcoord) {
|
||||
WRITE(p, " v_texcoord = vec3(texcoord.xy * base.uvscaleoffset.xy + base.uvscaleoffset.zw, 0.0);\n");
|
||||
WRITE(p, " v_texcoord = vec3(texcoord.xy * u_uvscaleoffset.xy + u_uvscaleoffset.zw, 0.0);\n");
|
||||
} else {
|
||||
WRITE(p, " v_texcoord = vec3(base.uvscaleoffset.zw, 0.0);\n");
|
||||
WRITE(p, " v_texcoord = vec3(u_uvscaleoffset.zw, 0.0);\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -599,15 +594,15 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
break;
|
||||
}
|
||||
// Transform by texture matrix. XYZ as we are doing projection mapping.
|
||||
WRITE(p, " v_texcoord = (%s * base.tex_mtx).xyz * vec3(base.uvscaleoffset.xy, 1.0);\n", temp_tc.c_str());
|
||||
WRITE(p, " v_texcoord = (%s * u_tex).xyz * vec3(u_uvscaleoffset.xy, 1.0);\n", temp_tc.c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources.
|
||||
{
|
||||
std::string lightFactor0 = StringFromFormat("(length(light.pos[%i]) == 0.0 ? worldnormal.z : dot(normalize(light.pos[%i]), worldnormal))", ls0, ls0);
|
||||
std::string lightFactor1 = StringFromFormat("(length(light.pos[%i]) == 0.0 ? worldnormal.z : dot(normalize(light.pos[%i]), worldnormal))", ls1, ls1);
|
||||
WRITE(p, " v_texcoord = vec3(base.uvscaleoffset.xy * vec2(1.0 + %s, 1.0 + %s) * 0.5, 1.0);\n", lightFactor0.c_str(), lightFactor1.c_str());
|
||||
std::string lightFactor0 = StringFromFormat("(length(u_lightpos%d) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%d), worldnormal))", ls0, ls0);
|
||||
std::string lightFactor1 = StringFromFormat("(length(u_lightpos%d) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%d), worldnormal))", ls1, ls1);
|
||||
WRITE(p, " v_texcoord = vec3(u_uvscaleoffset.xy * vec2(1.0 + %s, 1.0 + %s) * 0.5, 1.0);\n", lightFactor0.c_str(), lightFactor1.c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
@ -619,17 +614,17 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
|
||||
|
||||
// Compute fogdepth
|
||||
if (enableFog)
|
||||
WRITE(p, " v_fogdepth = (viewPos.z + base.fogcoef.x) * base.fogcoef.y;\n");
|
||||
WRITE(p, " v_fogdepth = (viewPos.z + u_fogcoef.x) * u_fogcoef.y;\n");
|
||||
}
|
||||
|
||||
if (!isModeThrough && gstate_c.Supports(GPU_SUPPORTS_VS_RANGE_CULLING)) {
|
||||
WRITE(p, " vec3 projPos = outPos.xyz / outPos.w;\n");
|
||||
// Vertex range culling doesn't happen when depth is clamped, so only do this if in range.
|
||||
WRITE(p, " if (base.cullRangeMin.w <= 0.0 || (projPos.z >= base.cullRangeMin.z && projPos.z <= base.cullRangeMax.z)) {\n");
|
||||
const char *outMin = "projPos.x < base.cullRangeMin.x || projPos.y < base.cullRangeMin.y || projPos.z < base.cullRangeMin.z";
|
||||
const char *outMax = "projPos.x > base.cullRangeMax.x || projPos.y > base.cullRangeMax.y || projPos.z > base.cullRangeMax.z";
|
||||
WRITE(p, " if (u_cullRangeMin.w <= 0.0 || (projPos.z >= u_cullRangeMin.z && projPos.z <= u_cullRangeMax.z)) {\n");
|
||||
const char *outMin = "projPos.x < u_cullRangeMin.x || projPos.y < u_cullRangeMin.y || projPos.z < u_cullRangeMin.z";
|
||||
const char *outMax = "projPos.x > u_cullRangeMax.x || projPos.y > u_cullRangeMax.y || projPos.z > u_cullRangeMax.z";
|
||||
WRITE(p, " if (%s || %s) {\n", outMin, outMax);
|
||||
WRITE(p, " outPos.xyzw = vec4(base.cullRangeMax.w);\n");
|
||||
WRITE(p, " outPos.xyzw = vec4(u_cullRangeMax.w);\n");
|
||||
WRITE(p, " }\n");
|
||||
WRITE(p, " }\n");
|
||||
}
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
#include "GPU/Common/ShaderId.h"
|
||||
|
||||
bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer);
|
||||
bool GenerateVertexShaderVulkanGLSL(const VShaderID &id, char *buffer, std::string *errorString);
|
||||
|
@ -404,22 +404,20 @@
|
||||
<ClInclude Include="..\..\GPU\D3D11\D3D11Util.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\DepalettizeShaderD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\DrawEngineD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\FragmentShaderGeneratorD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\FramebufferManagerD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\GPU_D3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\ShaderManagerD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\StateMappingD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\TextureCacheD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\TextureScalerD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\VertexShaderGeneratorD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\Debugger\Breakpoints.h" />
|
||||
<ClInclude Include="..\..\GPU\Debugger\Debugger.h" />
|
||||
<ClInclude Include="..\..\GPU\Debugger\Playback.h" />
|
||||
<ClInclude Include="..\..\GPU\Debugger\Record.h" />
|
||||
<ClInclude Include="..\..\GPU\Debugger\RecordFormat.h" />
|
||||
<ClInclude Include="..\..\GPU\Debugger\Stepping.h" />
|
||||
<ClInclude Include="..\..\GPU\Directx9\PixelShaderGeneratorDX9.h" />
|
||||
<ClInclude Include="..\..\GPU\Directx9\VertexShaderGeneratorDX9.h" />
|
||||
<ClInclude Include="..\..\GPU\Directx9\FragmentShaderGeneratorHLSL.h" />
|
||||
<ClInclude Include="..\..\GPU\Directx9\VertexShaderGeneratorHLSL.h" />
|
||||
<ClInclude Include="..\..\GPU\GeDisasm.h" />
|
||||
<ClInclude Include="..\..\GPU\ge_constants.h" />
|
||||
<ClInclude Include="..\..\GPU\GPU.h" />
|
||||
@ -466,7 +464,6 @@
|
||||
<ClCompile Include="..\..\GPU\D3D11\D3D11Util.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\DepalettizeShaderD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\DrawEngineD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\FragmentShaderGeneratorD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\FramebufferManagerD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\GPU_D3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\ShaderManagerD3D11.cpp" />
|
||||
@ -474,14 +471,13 @@
|
||||
<ClCompile Include="..\..\GPU\D3D11\StencilBufferD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\TextureCacheD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\TextureScalerD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\VertexShaderGeneratorD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Debugger\Breakpoints.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Debugger\Debugger.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Debugger\Playback.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Debugger\Record.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Debugger\Stepping.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Directx9\PixelShaderGeneratorDX9.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Directx9\VertexShaderGeneratorDX9.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Directx9\FragmentShaderGeneratorHLSL.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Directx9\VertexShaderGeneratorHLSL.cpp" />
|
||||
<ClCompile Include="..\..\GPU\GeConstants.cpp" />
|
||||
<ClCompile Include="..\..\GPU\GeDisasm.cpp" />
|
||||
<ClCompile Include="..\..\GPU\GPU.cpp" />
|
||||
|
@ -29,7 +29,6 @@
|
||||
<ClCompile Include="..\..\GPU\D3D11\D3D11Util.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\DepalettizeShaderD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\DrawEngineD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\FragmentShaderGeneratorD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\FramebufferManagerD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\GPU_D3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\ShaderManagerD3D11.cpp" />
|
||||
@ -37,14 +36,13 @@
|
||||
<ClCompile Include="..\..\GPU\D3D11\StencilBufferD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\TextureCacheD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\TextureScalerD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\VertexShaderGeneratorD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Debugger\Breakpoints.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Debugger\Debugger.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Debugger\Playback.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Debugger\Record.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Debugger\Stepping.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Directx9\PixelShaderGeneratorDX9.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Directx9\VertexShaderGeneratorDX9.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Directx9\FragmentShaderGeneratorHLSL.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Directx9\VertexShaderGeneratorHLSL.cpp" />
|
||||
<ClCompile Include="..\..\GPU\GeConstants.cpp" />
|
||||
<ClCompile Include="..\..\GPU\GeDisasm.cpp" />
|
||||
<ClCompile Include="..\..\GPU\GPU.cpp" />
|
||||
@ -86,22 +84,20 @@
|
||||
<ClInclude Include="..\..\GPU\D3D11\D3D11Util.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\DepalettizeShaderD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\DrawEngineD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\FragmentShaderGeneratorD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\FramebufferManagerD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\GPU_D3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\ShaderManagerD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\StateMappingD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\TextureCacheD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\TextureScalerD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\VertexShaderGeneratorD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\Debugger\Breakpoints.h" />
|
||||
<ClInclude Include="..\..\GPU\Debugger\Debugger.h" />
|
||||
<ClInclude Include="..\..\GPU\Debugger\Playback.h" />
|
||||
<ClInclude Include="..\..\GPU\Debugger\Record.h" />
|
||||
<ClInclude Include="..\..\GPU\Debugger\RecordFormat.h" />
|
||||
<ClInclude Include="..\..\GPU\Debugger\Stepping.h" />
|
||||
<ClInclude Include="..\..\GPU\Directx9\PixelShaderGeneratorDX9.h" />
|
||||
<ClInclude Include="..\..\GPU\Directx9\VertexShaderGeneratorDX9.h" />
|
||||
<ClInclude Include="..\..\GPU\Directx9\FragmentShaderGeneratorHLSL.h" />
|
||||
<ClInclude Include="..\..\GPU\Directx9\VertexShaderGeneratorHLSL.h" />
|
||||
<ClInclude Include="..\..\GPU\GeDisasm.h" />
|
||||
<ClInclude Include="..\..\GPU\ge_constants.h" />
|
||||
<ClInclude Include="..\..\GPU\GPU.h" />
|
||||
|
@ -526,7 +526,7 @@ ifeq ($(WITH_DYNAREC),1)
|
||||
$(COREDIR)/MIPS/ARM/ArmJit.cpp \
|
||||
$(COREDIR)/MIPS/ARM/ArmRegCache.cpp \
|
||||
$(COREDIR)/MIPS/ARM/ArmRegCacheFPU.cpp \
|
||||
$(EXTDIR)/disarm.cpp \
|
||||
$(EXTDIR)/disarm.cpp \
|
||||
$(GPUCOMMONDIR)/VertexDecoderArm.cpp
|
||||
|
||||
ifeq ($(HAVE_NEON),1)
|
||||
@ -663,7 +663,7 @@ ifeq ($(PLATFORM_EXT), win32)
|
||||
SOURCES_CXX += \
|
||||
$(GPUDIR)/Directx9/DepalettizeShaderDX9.cpp \
|
||||
$(GPUDIR)/Directx9/DrawEngineDX9.cpp \
|
||||
$(GPUDIR)/Directx9/PixelShaderGeneratorDX9.cpp \
|
||||
$(GPUDIR)/Directx9/FragmentShaderGeneratorHLSL.cpp \
|
||||
$(GPUDIR)/Directx9/FramebufferManagerDX9.cpp \
|
||||
$(GPUDIR)/Directx9/GPU_DX9.cpp \
|
||||
$(GPUDIR)/Directx9/ShaderManagerDX9.cpp \
|
||||
@ -671,12 +671,11 @@ SOURCES_CXX += \
|
||||
$(GPUDIR)/Directx9/StencilBufferDX9.cpp \
|
||||
$(GPUDIR)/Directx9/TextureCacheDX9.cpp \
|
||||
$(GPUDIR)/Directx9/TextureScalerDX9.cpp \
|
||||
$(GPUDIR)/Directx9/VertexShaderGeneratorDX9.cpp
|
||||
$(GPUDIR)/Directx9/VertexShaderGeneratorHLSL.cpp
|
||||
|
||||
SOURCES_CXX += \
|
||||
$(GPUDIR)/D3D11/DepalettizeShaderD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/DrawEngineD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/FragmentShaderGeneratorD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/FramebufferManagerD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/GPU_D3D11.cpp \
|
||||
$(GPUDIR)/D3D11/D3D11Util.cpp \
|
||||
@ -685,7 +684,6 @@ SOURCES_CXX += \
|
||||
$(GPUDIR)/D3D11/StencilBufferD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/TextureCacheD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/TextureScalerD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/VertexShaderGeneratorD3D11.cpp \
|
||||
$(LIBRETRODIR)/LibretroD3D11Context.cpp
|
||||
|
||||
SOURCES_CXX += \
|
||||
|
195
unittest/TestShaderGenerators.cpp
Normal file
195
unittest/TestShaderGenerators.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
#include "Common/StringUtils.h"
|
||||
|
||||
#include "GPU/Common/ShaderId.h"
|
||||
#include "GPU/Common/ShaderCommon.h"
|
||||
#include "Common/Data/Random/Rng.h"
|
||||
|
||||
#include "GPU/Vulkan/VulkanContext.h"
|
||||
|
||||
#include "GPU/Vulkan/FragmentShaderGeneratorVulkan.h"
|
||||
#include "GPU/Directx9/FragmentShaderGeneratorHLSL.h"
|
||||
#include "GPU/GLES/FragmentShaderGeneratorGLES.h"
|
||||
|
||||
#include "GPU/Vulkan/VertexShaderGeneratorVulkan.h"
|
||||
#include "GPU/Directx9/VertexShaderGeneratorHLSL.h"
|
||||
#include "GPU/GLES/VertexShaderGeneratorGLES.h"
|
||||
|
||||
#include "GPU/D3D11/D3D11Util.h"
|
||||
#include "GPU/D3D11/D3D11Loader.h"
|
||||
|
||||
#include "GPU/D3D9/D3DCompilerLoader.h"
|
||||
#include "GPU/D3D9/D3D9ShaderCompiler.h"
|
||||
|
||||
bool GenerateFShader(FShaderID id, char *buffer, ShaderLanguage lang, std::string *errorString) {
|
||||
switch (lang) {
|
||||
case ShaderLanguage::HLSL_D3D11:
|
||||
return GenerateFragmentShaderHLSL(id, buffer, ShaderLanguage::HLSL_D3D11, errorString);
|
||||
case ShaderLanguage::HLSL_DX9:
|
||||
GenerateFragmentShaderHLSL(id, buffer, ShaderLanguage::HLSL_DX9, errorString);
|
||||
// TODO: Need a device :( Returning false here so it doesn't get tried.
|
||||
return false;
|
||||
case ShaderLanguage::GLSL_VULKAN:
|
||||
return GenerateFragmentShaderVulkanGLSL(id, buffer, 0, errorString);
|
||||
case ShaderLanguage::GLSL_140:
|
||||
case ShaderLanguage::GLSL_300:
|
||||
// TODO: Need a device - except that maybe glslang could be used to verify these ....
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool GenerateVShader(VShaderID id, char *buffer, ShaderLanguage lang, std::string *errorString) {
|
||||
switch (lang) {
|
||||
case ShaderLanguage::HLSL_D3D11:
|
||||
return GenerateVertexShaderHLSL(id, buffer, ShaderLanguage::HLSL_D3D11, errorString);
|
||||
case ShaderLanguage::HLSL_DX9:
|
||||
GenerateVertexShaderHLSL(id, buffer, ShaderLanguage::HLSL_DX9, errorString);
|
||||
// TODO: Need a device :( Returning false here so it doesn't get tried.
|
||||
return false;
|
||||
// return DX9::GenerateFragmentShaderHLSL(id, buffer, ShaderLanguage::HLSL_DX9);
|
||||
case ShaderLanguage::GLSL_VULKAN:
|
||||
return GenerateVertexShaderVulkanGLSL(id, buffer, errorString);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool TestCompileShader(const char *buffer, ShaderLanguage lang, bool vertex) {
|
||||
switch (lang) {
|
||||
case ShaderLanguage::HLSL_D3D11:
|
||||
{
|
||||
auto output = CompileShaderToBytecodeD3D11(buffer, strlen(buffer), vertex ? "vs_4_0" : "ps_4_0", 0);
|
||||
return !output.empty();
|
||||
}
|
||||
case ShaderLanguage::HLSL_DX9:
|
||||
return false;
|
||||
case ShaderLanguage::GLSL_VULKAN:
|
||||
{
|
||||
std::vector<uint32_t> spirv;
|
||||
std::string errorMessage;
|
||||
bool result = GLSLtoSPV(vertex ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT, buffer, spirv, &errorMessage);
|
||||
if (!result) {
|
||||
printf("GLSLtoSPV ERROR:\n%s\n\n", errorMessage.c_str());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case ShaderLanguage::GLSL_140:
|
||||
|
||||
return false;
|
||||
case ShaderLanguage::GLSL_300:
|
||||
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool TestShaderGenerators() {
|
||||
LoadD3D11();
|
||||
init_glslang();
|
||||
LoadD3DCompilerDynamic();
|
||||
|
||||
ShaderLanguage languages[] = {
|
||||
ShaderLanguage::HLSL_D3D11,
|
||||
ShaderLanguage::GLSL_VULKAN,
|
||||
ShaderLanguage::GLSL_140,
|
||||
ShaderLanguage::GLSL_300,
|
||||
ShaderLanguage::HLSL_DX9,
|
||||
};
|
||||
const int numLanguages = ARRAY_SIZE(languages);
|
||||
|
||||
char *buffer[numLanguages];
|
||||
|
||||
for (int i = 0; i < numLanguages; i++) {
|
||||
buffer[i] = new char[65536];
|
||||
}
|
||||
GMRng rng;
|
||||
int successes = 0;
|
||||
int count = 200;
|
||||
|
||||
// Generate a bunch of random fragment shader IDs, try to generate shader source.
|
||||
// Then compile it and check that it's ok.
|
||||
for (int i = 0; i < count; i++) {
|
||||
uint32_t bottom = rng.R32();
|
||||
uint32_t top = rng.R32();
|
||||
FShaderID id;
|
||||
id.d[0] = bottom;
|
||||
id.d[1] = top;
|
||||
|
||||
bool generateSuccess[numLanguages]{};
|
||||
|
||||
for (int j = 0; j < numLanguages; j++) {
|
||||
std::string genErrorString;
|
||||
generateSuccess[j] = GenerateFShader(id, buffer[j], languages[j], &genErrorString);
|
||||
if (!genErrorString.empty()) {
|
||||
printf("%s\n", genErrorString.c_str());
|
||||
}
|
||||
// We ignore the contents of the error string here, not even gonna try to compile if it errors.
|
||||
}
|
||||
|
||||
// Now that we have the strings ready for easy comparison (buffer,4 in the watch window),
|
||||
// let's try to compile them.
|
||||
for (int j = 0; j < numLanguages; j++) {
|
||||
if (generateSuccess[j]) {
|
||||
if (!TestCompileShader(buffer[j], languages[j], false)) {
|
||||
printf("Error compiling fragment shader:\n\n%s\n\n", LineNumberString(buffer[j]).c_str());
|
||||
return false;
|
||||
}
|
||||
successes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("%d/%d fragment shaders generated (it's normal that it's not all, there are invalid bit combos)\n", successes, count * numLanguages);
|
||||
|
||||
successes = 0;
|
||||
count = 200;
|
||||
|
||||
// Generate a bunch of random vertex shader IDs, try to generate shader source.
|
||||
// Then compile it and check that it's ok.
|
||||
for (int i = 0; i < count; i++) {
|
||||
uint32_t bottom = rng.R32();
|
||||
uint32_t top = rng.R32();
|
||||
VShaderID id;
|
||||
id.d[0] = bottom;
|
||||
id.d[1] = top;
|
||||
|
||||
// Skip testing beziers for now. I'll deal with those bugs later.
|
||||
id.SetBit(VS_BIT_BEZIER, false);
|
||||
id.SetBit(VS_BIT_SPLINE, false);
|
||||
|
||||
bool generateSuccess[numLanguages]{};
|
||||
|
||||
for (int j = 0; j < numLanguages; j++) {
|
||||
std::string genErrorString;
|
||||
generateSuccess[j] = GenerateVShader(id, buffer[j], languages[j], &genErrorString);
|
||||
if (!genErrorString.empty()) {
|
||||
printf("%s\n", genErrorString.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have the strings ready for easy comparison (buffer,4 in the watch window),
|
||||
// let's try to compile them.
|
||||
for (int j = 0; j < numLanguages; j++) {
|
||||
if (generateSuccess[j]) {
|
||||
if (!TestCompileShader(buffer[j], languages[j], true)) {
|
||||
printf("Error compiling vertex shader:\n\n%s\n\n", LineNumberString(buffer[j]).c_str());
|
||||
return false;
|
||||
}
|
||||
successes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("%d/%d vertex shaders generated (it's normal that it's not all, there are invalid bit combos)\n", successes, count * numLanguages);
|
||||
|
||||
successes = 0;
|
||||
count = 200;
|
||||
|
||||
for (int i = 0; i < numLanguages; i++) {
|
||||
delete[] buffer[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -571,6 +571,7 @@ struct TestItem {
|
||||
bool TestArmEmitter();
|
||||
bool TestArm64Emitter();
|
||||
bool TestX64Emitter();
|
||||
bool TestShaderGenerators();
|
||||
|
||||
TestItem availableTests[] = {
|
||||
#if PPSSPP_ARCH(ARM64) || PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86)
|
||||
@ -593,7 +594,7 @@ TestItem availableTests[] = {
|
||||
TEST_ITEM(ParseLBN),
|
||||
TEST_ITEM(QuickTexHash),
|
||||
TEST_ITEM(CLZ),
|
||||
TEST_ITEM(MemMap),
|
||||
TEST_ITEM(ShaderGenerators),
|
||||
};
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
|
@ -382,6 +382,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TestShaderGenerators.cpp" />
|
||||
<ClCompile Include="TestVertexJit.cpp" />
|
||||
<ClCompile Include="UnitTest.cpp" />
|
||||
<ClCompile Include="TestArmEmitter.cpp">
|
||||
@ -426,4 +427,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
@ -11,6 +11,7 @@
|
||||
<ClCompile Include="..\Windows\CaptureDevice.cpp">
|
||||
<Filter>Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TestShaderGenerators.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="JitHarness.h" />
|
||||
|
Loading…
Reference in New Issue
Block a user