diff --git a/GPU/D3D11/D3D11Util.cpp b/GPU/D3D11/D3D11Util.cpp index 2760b786bf..10766491c9 100644 --- a/GPU/D3D11/D3D11Util.cpp +++ b/GPU/D3D11/D3D11Util.cpp @@ -2,8 +2,10 @@ #include #include #include + #include "thin3d/d3d11_loader.h" #include "base/logging.h" +#include "base/stringutil.h" #include "D3D11Util.h" @@ -14,7 +16,8 @@ static std::vector CompileShaderToBytecode(const char *code, size_t cod std::string errors; if (errorMsgs) { errors = std::string((const char *)errorMsgs->GetBufferPointer(), errorMsgs->GetBufferSize()); - ELOG("%s: %s\n%s", SUCCEEDED(result) ? "warnings" : "errors", errors.c_str(), code); + ELOG("%s: %s", SUCCEEDED(result) ? "warnings" : "errors", errors.c_str()); + OutputDebugStringA(LineNumberString(code).c_str()); errorMsgs->Release(); } if (compiledCode) { diff --git a/GPU/D3D11/DepalettizeShaderD3D11.cpp b/GPU/D3D11/DepalettizeShaderD3D11.cpp index 3c8c143469..b524922d37 100644 --- a/GPU/D3D11/DepalettizeShaderD3D11.cpp +++ b/GPU/D3D11/DepalettizeShaderD3D11.cpp @@ -40,8 +40,8 @@ static const char *depalVShaderHLSL = " float2 a_texcoord0 : TEXCOORD0;\n" "};\n" "struct VS_OUT {\n" -" float4 Position : SV_Position;\n" " float2 Texcoord : TEXCOORD0;\n" +" float4 Position : SV_Position;\n" "};\n" "VS_OUT main(VS_IN input) {\n" " VS_OUT output;\n" @@ -66,7 +66,7 @@ DepalShaderCacheD3D11::DepalShaderCacheD3D11(ID3D11Device *device, ID3D11DeviceC sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; - sampDesc.Filter = D3D11_FILTER_MINIMUM_MIN_MAG_MIP_POINT; + sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; device_->CreateSamplerState(&sampDesc, &clutSampler); } diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 50281dda6d..9db91ee6ea 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -677,13 +677,13 @@ void DrawEngineD3D11::DoFlush() { // TODO: Combine these two into one buffer? void * pVb; u32 size = dec_->GetDecVtxFmt().stride * indexGen.MaxIndex(); - D3D11_BUFFER_DESC desc{ size, D3D11_USAGE_IMMUTABLE, D3D11_BIND_VERTEX_BUFFER, D3D11_CPU_ACCESS_WRITE }; + D3D11_BUFFER_DESC desc{ size, D3D11_USAGE_IMMUTABLE, D3D11_BIND_VERTEX_BUFFER, 0 }; D3D11_SUBRESOURCE_DATA data{ decoded }; device_->CreateBuffer(&desc, &data, &vai->vbo); if (useElements) { void * pIb; u32 size = sizeof(short) * indexGen.VertexCount(); - D3D11_BUFFER_DESC desc{ size, D3D11_USAGE_IMMUTABLE, D3D11_BIND_INDEX_BUFFER, D3D11_CPU_ACCESS_WRITE }; + D3D11_BUFFER_DESC desc{ size, D3D11_USAGE_IMMUTABLE, D3D11_BIND_INDEX_BUFFER, 0 }; D3D11_SUBRESOURCE_DATA data{ decoded }; device_->CreateBuffer(&desc, &data, &vai->ebo); } else { @@ -763,6 +763,8 @@ rotateVBO: D3D11FragmentShader *fshader; shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, useHWTransform); ID3D11InputLayout *pHardwareVertexDecl = SetupDecFmtForDraw(vshader, dec_->GetDecVtxFmt(), dec_->VertexType()); + context_->PSSetShader(fshader->GetShader(), nullptr, 0); + context_->VSSetShader(vshader->GetShader(), nullptr, 0); context_->IASetInputLayout(pHardwareVertexDecl); if (!vb_) { @@ -829,6 +831,10 @@ rotateVBO: D3D11VertexShader *vshader; D3D11FragmentShader *fshader; shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, false); + context_->PSSetShader(fshader->GetShader(), nullptr, 0); + context_->VSSetShader(vshader->GetShader(), nullptr, 0); + shaderManager_->UpdateUniforms(); + shaderManager_->BindUniforms(); // TODO: Implement clear properly when possible. Colormask no longer applies to clearing unfortunately (though wonder if it ever did in hardware..) which makes it trickier. if (result.action == SW_DRAW_PRIMITIVES || result.action == SW_CLEAR) { diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 69070ddbda..c52a22ea7a 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -49,8 +49,8 @@ static const char * vscode = " float2 Uv : TEXCOORD0;\n" "};" "struct VS_OUT {\n" - " float4 ProjPos : SV_Position;\n" " float2 Uv : TEXCOORD0;\n" + " float4 ProjPos : SV_Position;\n" "};\n" "VS_OUT main(VS_IN In) {\n" " VS_OUT Out;\n" diff --git a/GPU/D3D11/ShaderManagerD3D11.cpp b/GPU/D3D11/ShaderManagerD3D11.cpp index 25d45f6ea8..fe631c97c8 100644 --- a/GPU/D3D11/ShaderManagerD3D11.cpp +++ b/GPU/D3D11/ShaderManagerD3D11.cpp @@ -15,10 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#ifdef _WIN32 -#define SHADERLOG -#endif - #include #include @@ -45,10 +41,6 @@ D3D11FragmentShader::D3D11FragmentShader(ID3D11Device *device, ShaderID id, cons : device_(device), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(0) { source_ = code; -#ifdef SHADERLOG - OutputDebugStringA(code); -#endif - module_ = CreatePixelShaderD3D11(device, code, strlen(code)); if (!module_) failed_ = true; @@ -74,10 +66,6 @@ D3D11VertexShader::D3D11VertexShader(ID3D11Device *device, ShaderID id, const ch : device_(device), id_(id), failed_(false), useHWTransform_(useHWTransform), module_(nullptr), usesLighting_(usesLighting) { source_ = code; -#ifdef SHADERLOG - OutputDebugStringA(code); -#endif - module_ = CreateVertexShaderD3D11(device, code, strlen(code), &bytecode_); if (!module_) failed_ = true; @@ -182,6 +170,13 @@ uint64_t ShaderManagerD3D11::UpdateUniforms() { return dirty; } +void ShaderManagerD3D11::BindUniforms() { + ID3D11Buffer *vs_cbs[3] = { push_base, push_lights, push_bones }; + ID3D11Buffer *ps_cbs[1] = { push_base }; + context_->VSSetConstantBuffers(0, 3, vs_cbs); + context_->PSSetConstantBuffers(0, 1, ps_cbs); +} + void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform) { ShaderID VSID; ShaderID FSID; diff --git a/GPU/D3D11/ShaderManagerD3D11.h b/GPU/D3D11/ShaderManagerD3D11.h index b7cbbbe24c..aaface9dd9 100644 --- a/GPU/D3D11/ShaderManagerD3D11.h +++ b/GPU/D3D11/ShaderManagerD3D11.h @@ -73,7 +73,7 @@ public: } std::string GetShaderString(DebugShaderStringType type) const; - ID3D11VertexShader *GetModule() const { return module_; } + ID3D11VertexShader *GetShader() const { return module_; } protected: ID3D11VertexShader *module_; @@ -107,6 +107,7 @@ public: std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType); uint64_t UpdateUniforms(); + void BindUniforms(); // TODO: Avoid copying these buffers if same as last draw, can still point to it assuming we're still in the same pushbuffer. // Applies dirty changes and copies the buffer. diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index fa3693a5aa..edf023ae92 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -153,9 +153,9 @@ struct D3D11DepthStencilKey { // Depth/Stencil unsigned int depthTestEnable : 1; unsigned int depthWriteEnable : 1; - unsigned int depthCompareOp : 3; // D3D11_COMPARISON + unsigned int depthCompareOp : 4; // D3D11_COMPARISON (-1 and we could fit it in 3 bits) unsigned int stencilTestEnable : 1; - unsigned int stencilCompareOp : 3; // D3D11_COMPARISON + unsigned int stencilCompareOp : 4; // D3D11_COMPARISON unsigned int stencilPassOp : 4; // D3D11_STENCIL_OP unsigned int stencilFailOp : 4; // D3D11_STENCIL_OP unsigned int stencilDepthFailOp : 4; // D3D11_STENCIL_OP @@ -419,7 +419,9 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { D3D11_DEPTH_STENCIL_DESC desc{}; desc.DepthEnable = keys.depthStencil.depthTestEnable; desc.DepthWriteMask = keys.depthStencil.depthWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; - desc.StencilEnable = keys.depthStencil.stencilTestEnable; + desc.DepthFunc = (D3D11_COMPARISON_FUNC)keys.depthStencil.depthCompareOp; + desc.StencilEnable = FALSE; // keys.depthStencil.stencilTestEnable; + // ... device_->CreateDepthStencilState(&desc, &ds); depthStencilCache_.insert(std::pair(depthKey, ds)); @@ -434,7 +436,6 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { void DrawEngineD3D11::ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRef) { if (applyStencilRef) { - ID3D11DepthStencilState *state; - context_->OMSetDepthStencilState(state, stencilRef); + // context_->OMSetDepthStencilState(state, stencilRef); } } \ No newline at end of file diff --git a/GPU/Directx9/PixelShaderGeneratorDX9.cpp b/GPU/Directx9/PixelShaderGeneratorDX9.cpp index 29dca6be7c..382bf440c1 100644 --- a/GPU/Directx9/PixelShaderGeneratorDX9.cpp +++ b/GPU/Directx9/PixelShaderGeneratorDX9.cpp @@ -105,6 +105,8 @@ bool GenerateFragmentShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage WRITE(p, "float3 u_fogcolor : register(c%i);\n", CONST_PS_FOGCOLOR); } } else { + WRITE(p, "SamplerState samp : register(s0);\n"); + WRITE(p, "Texture2D tex : register(t0);\n"); WRITE(p, "cbuffer base : register(b0) {\n%s};\n", cb_baseStr); } @@ -183,10 +185,18 @@ bool GenerateFragmentShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage doTextureProjection = false; } - if (doTextureProjection) { - WRITE(p, " float4 t = tex2Dproj(tex, float4(In.v_texcoord.x, In.v_texcoord.y, 0, In.v_texcoord.z))%s;\n", bgraTexture ? ".bgra" : ""); + if (lang == HLSL_D3D11) { + if (doTextureProjection) { + WRITE(p, " float4 t = tex.Sample(samp, In.v_texcoord.xy / In.v_texcoord.z)%s;\n", bgraTexture ? ".bgra" : ""); + } else { + WRITE(p, " float4 t = tex.Sample(samp, %s.xy)%s;\n", texcoord, bgraTexture ? ".bgra" : ""); + } } else { - WRITE(p, " float4 t = tex2D(tex, %s.xy)%s;\n", texcoord, bgraTexture ? ".bgra" : ""); + if (doTextureProjection) { + WRITE(p, " float4 t = tex2Dproj(tex, float4(In.v_texcoord.x, In.v_texcoord.y, 0, In.v_texcoord.z))%s;\n", bgraTexture ? ".bgra" : ""); + } else { + WRITE(p, " float4 t = tex2D(tex, %s.xy)%s;\n", texcoord, bgraTexture ? ".bgra" : ""); + } } WRITE(p, " float4 p = In.v_color0;\n"); diff --git a/GPU/Directx9/VertexShaderGeneratorDX9.cpp b/GPU/Directx9/VertexShaderGeneratorDX9.cpp index 7d8bda2170..7293f88ea1 100644 --- a/GPU/Directx9/VertexShaderGeneratorDX9.cpp +++ b/GPU/Directx9/VertexShaderGeneratorDX9.cpp @@ -222,11 +222,6 @@ void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage l } WRITE(p, "struct VS_OUT {\n"); - if (lang == HLSL_DX9) { - WRITE(p, " float4 gl_Position : POSITION;\n"); - } else { - WRITE(p, " float4 gl_Position : SV_Position;\n"); - } if (doTexture) { WRITE(p, " float3 v_texcoord : TEXCOORD0;\n"); } @@ -237,6 +232,11 @@ void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage l if (enableFog) { WRITE(p, " float2 v_fogdepth: TEXCOORD1;\n"); } + if (lang == HLSL_DX9) { + WRITE(p, " float4 gl_Position : POSITION;\n"); + } else { + WRITE(p, " float4 gl_Position : SV_Position;\n"); + } WRITE(p, "};\n"); // Confirmed: Through mode gets through exactly the same in GL and D3D in Phantasy Star: Text is 38023.0 in the test scene. @@ -289,7 +289,11 @@ void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage l // Step 1: World Transform / Skinning if (!enableBones) { // No skinning, just standard T&L. - WRITE(p, " float3 worldpos = mul(float4(In.position.xyz, 1.0), u_world);\n"); + if (lang == HLSL_D3D11) { + WRITE(p, " float3 worldpos = mul(float4(In.position.xyz, 1.0), u_world).xyz;\n"); + } else { + WRITE(p, " float3 worldpos = mul(float4(In.position.xyz, 1.0), u_world);\n"); + } if (hasNormal) WRITE(p, " float3 worldnormal = normalize( mul(float4(%sIn.normal, 0.0), u_world));\n", flipNormal ? "-" : ""); else @@ -367,7 +371,11 @@ void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage l WRITE(p, " float3 worldnormal = normalize(mul(float4(skinnednormal, 0.0), u_world));\n"); } - WRITE(p, " float4 viewPos = float4(mul(float4(worldpos, 1.0), u_view), 1.0);\n"); + if (lang == HLSL_D3D11) { + WRITE(p, " float4 viewPos = mul(float4(worldpos, 1.0), u_view);\n"); + } else { + WRITE(p, " float4 viewPos = float4(mul(float4(worldpos, 1.0), u_view), 1.0);\n"); + } // Final view and projection transforms. if (gstate_c.Supports(GPU_ROUND_DEPTH_TO_16BIT)) { @@ -554,7 +562,11 @@ void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage l break; } // Transform by texture matrix. XYZ as we are doing projection mapping. - WRITE(p, " Out.v_texcoord.xyz = mul(%s,u_texmtx) * float3(u_uvscaleoffset.xy, 1.0);\n", temp_tc.c_str()); + if (lang == HLSL_D3D11) { + WRITE(p, " Out.v_texcoord.xyz = (mul(%s, u_texmtx) * float4(u_uvscaleoffset.xy, 1.0, 0.0)).xyz;\n", temp_tc.c_str()); + } else { + WRITE(p, " Out.v_texcoord.xyz = mul(%s, u_texmtx) * float3(u_uvscaleoffset.xy, 1.0);\n", temp_tc.c_str()); + } } break; diff --git a/ext/native/base/stringutil.cpp b/ext/native/base/stringutil.cpp index d2dc16d22b..4c72959b39 100644 --- a/ext/native/base/stringutil.cpp +++ b/ext/native/base/stringutil.cpp @@ -39,6 +39,19 @@ void OutputDebugStringUTF8(const char *p) { #endif +std::string LineNumberString(const std::string &str) { + std::stringstream input(str); + std::stringstream output; + std::string line; + + int lineNumber = 1; + while (std::getline(input, line)) { + output << std::setw(4) << lineNumber++ << ": " << line << std::endl; + } + + return output.str(); +} + void StringTrimEndNonAlphaNum(char *str) { ssize_t n = strlen(str); while (!isalnum(str[n]) && n >= 0) { diff --git a/ext/native/base/stringutil.h b/ext/native/base/stringutil.h index 34ceb6076d..e001f42532 100644 --- a/ext/native/base/stringutil.h +++ b/ext/native/base/stringutil.h @@ -25,6 +25,9 @@ public: } }; +// Useful for shaders with error messages.. +std::string LineNumberString(const std::string &str); + // Other simple string utilities. inline bool startsWith(const std::string &str, const std::string &what) {