From 796539ad7fc7b6187528e058fd1fabf8b30dd56f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Oct 2019 00:51:55 +0200 Subject: [PATCH] DarkStalkers: Fix display in the D3D backends. Still broken in OpenGL. --- GPU/Software/SoftGpu.cpp | 18 +++++++++--- GPU/Software/SoftGpu.h | 1 + ext/native/thin3d/thin3d.cpp | 47 ++++++++++++++++++++++++++++++- ext/native/thin3d/thin3d.h | 1 + ext/native/thin3d/thin3d_d3d9.cpp | 9 ++++++ 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 6b13a34f2e..c468b45b65 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -73,8 +73,6 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *draw) }, }; - ShaderModule *vshader = draw_->GetVshaderPreset(VS_TEXTURE_COLOR_2D); - vdata = draw_->CreateBuffer(sizeof(Vertex) * 4, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA); idata = draw_->CreateBuffer(sizeof(int) * 6, BufferUsageFlag::DYNAMIC | BufferUsageFlag::INDEXDATA); @@ -92,6 +90,14 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *draw) inputLayout, depth, blendstateOff, rasterNoCull, &vsTexColBufDesc }; texColor = draw_->CreateGraphicsPipeline(pipelineDesc); + + PipelineDesc pipelineDescRBSwizzle{ + Primitive::TRIANGLE_LIST, + { draw_->GetVshaderPreset(VS_TEXTURE_COLOR_2D), draw_->GetFshaderPreset(FS_TEXTURE_COLOR_2D_RB_SWIZZLE) }, + inputLayout, depth, blendstateOff, rasterNoCull, &vsTexColBufDesc + }; + texColorRBSwizzle = draw_->CreateGraphicsPipeline(pipelineDescRBSwizzle); + inputLayout->Release(); depth->Release(); blendstateOff->Release(); @@ -122,6 +128,8 @@ void SoftGPU::DeviceRestore() { SoftGPU::~SoftGPU() { texColor->Release(); texColor = nullptr; + texColorRBSwizzle->Release(); + texColorRBSwizzle = nullptr; if (fbTex) { fbTex->Release(); @@ -179,9 +187,10 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { desc.mipLevels = 1; desc.tag = "SoftGPU"; bool hasImage = true; + + Draw::Pipeline *pipeline = texColor; if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && displayFormat_ == GE_FORMAT_5551 && g_DarkStalkerStretch) { u8 *data = Memory::GetPointer(0x04088000); - desc.swizzle = Draw::TextureSwizzle::BGRA; desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16; desc.width = displayStride_ == 0 ? srcwidth : displayStride_; desc.height = srcheight; @@ -190,6 +199,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { u1 = 448.0f / 512.0f; v1 = 16.0f / 272.0f; v0 = 240.0f / 272.0f; + pipeline = texColorRBSwizzle; g_DarkStalkerStretch = false; } else if (!Memory::IsValidAddress(displayFramebuf_) || srcwidth == 0 || srcheight == 0) { hasImage = false; @@ -307,7 +317,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { Draw::VsTexColUB ub{}; memcpy(ub.WorldViewProj, g_display_rot_matrix.m, sizeof(float) * 16); - draw_->BindPipeline(texColor); + draw_->BindPipeline(pipeline); draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub)); draw_->BindVertexBuffers(0, 1, &vdata, nullptr); draw_->BindIndexBuffer(idata, 0); diff --git a/GPU/Software/SoftGpu.h b/GPU/Software/SoftGpu.h index f92344742e..c7d4f9365e 100644 --- a/GPU/Software/SoftGpu.h +++ b/GPU/Software/SoftGpu.h @@ -108,6 +108,7 @@ private: Draw::Texture *fbTex; Draw::Pipeline *texColor; + Draw::Pipeline *texColorRBSwizzle; std::vector fbTexBuffer; Draw::SamplerState *samplerNearest = nullptr; diff --git a/ext/native/thin3d/thin3d.cpp b/ext/native/thin3d/thin3d.cpp index d142638e07..340157708d 100644 --- a/ext/native/thin3d/thin3d.cpp +++ b/ext/native/thin3d/thin3d.cpp @@ -146,6 +146,50 @@ static const std::vector fsTexCol = { } }; +static const std::vector fsTexColRBSwizzle = { + {ShaderLanguage::GLSL_ES_200, + "#ifdef GL_ES\n" + "precision lowp float;\n" + "#endif\n" + "#if __VERSION__ >= 130\n" + "#define varying in\n" + "#define texture2D texture\n" + "#define gl_FragColor fragColor0\n" + "out vec4 fragColor0;\n" + "#endif\n" + "varying vec4 oColor0;\n" + "varying vec2 oTexCoord0;\n" + "uniform sampler2D Sampler0;\n" + "void main() { gl_FragColor = texture2D(Sampler0, oTexCoord0).zyxw * oColor0; }\n" + }, + {ShaderLanguage::HLSL_D3D9, + "struct PS_INPUT { float4 color : COLOR0; float2 uv : TEXCOORD0; };\n" + "sampler2D Sampler0 : register(s0);\n" + "float4 main(PS_INPUT input) : COLOR0 {\n" + " return input.color * tex2D(Sampler0, input.uv).zyxw;\n" + "}\n" + }, + {ShaderLanguage::HLSL_D3D11, + "struct PS_INPUT { float4 color : COLOR0; float2 uv : TEXCOORD0; };\n" + "SamplerState samp : register(s0);\n" + "Texture2D tex : register(t0);\n" + "float4 main(PS_INPUT input) : SV_Target {\n" + " float4 col = input.color * tex.Sample(samp, input.uv).bgra;\n" + " return col;\n" + "}\n" + }, + {ShaderLanguage::GLSL_VULKAN, + "#version 140\n" + "#extension GL_ARB_separate_shader_objects : enable\n" + "#extension GL_ARB_shading_language_420pack : enable\n" + "layout(location = 0) in vec4 oColor0;\n" + "layout(location = 1) in vec2 oTexCoord0;\n" + "layout(location = 0) out vec4 fragColor0\n;" + "layout(set = 0, binding = 1) uniform sampler2D Sampler0;\n" + "void main() { fragColor0 = texture(Sampler0, oTexCoord0).bgra * oColor0; }\n" + } +}; + static const std::vector fsCol = { { ShaderLanguage::GLSL_ES_200, "#ifdef GL_ES\n" @@ -330,8 +374,9 @@ bool DrawContext::CreatePresets() { fsPresets_[FS_TEXTURE_COLOR_2D] = CreateShader(this, ShaderStage::FRAGMENT, fsTexCol); fsPresets_[FS_COLOR_2D] = CreateShader(this, ShaderStage::FRAGMENT, fsCol); + fsPresets_[FS_TEXTURE_COLOR_2D_RB_SWIZZLE] = CreateShader(this, ShaderStage::FRAGMENT, fsTexColRBSwizzle); - return vsPresets_[VS_TEXTURE_COLOR_2D] && vsPresets_[VS_COLOR_2D] && fsPresets_[FS_TEXTURE_COLOR_2D] && fsPresets_[FS_COLOR_2D]; + return vsPresets_[VS_TEXTURE_COLOR_2D] && vsPresets_[VS_COLOR_2D] && fsPresets_[FS_TEXTURE_COLOR_2D] && fsPresets_[FS_COLOR_2D] && fsPresets_[FS_TEXTURE_COLOR_2D_RB_SWIZZLE]; } void DrawContext::DestroyPresets() { diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 91b1847f4b..fce59694b9 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -146,6 +146,7 @@ enum VertexShaderPreset : int { enum FragmentShaderPreset : int { FS_COLOR_2D, FS_TEXTURE_COLOR_2D, + FS_TEXTURE_COLOR_2D_RB_SWIZZLE, FS_MAX_PRESET, }; diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index cdd784b5f1..e9c2a8d171 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -348,6 +348,10 @@ bool D3D9Texture::Create(const TextureDesc &desc) { format_ = desc.format; tex_ = NULL; d3dfmt_ = FormatToD3DFMT(desc.format); + + if (d3dfmt_ == D3DFMT_UNKNOWN) { + return false; + } HRESULT hr = E_FAIL; D3DPOOL pool = D3DPOOL_MANAGED; @@ -424,6 +428,7 @@ void D3D9Texture::SetImageData(int x, int y, int z, int width, int height, int d } break; case DataFormat::A4R4G4B4_UNORM_PACK16: + case DataFormat::A1R5G5B5_UNORM_PACK16: // Native memcpy(dest, source, width * sizeof(uint16_t)); break; @@ -437,6 +442,10 @@ void D3D9Texture::SetImageData(int x, int y, int z, int width, int height, int d case DataFormat::B8G8R8A8_UNORM: memcpy(dest, source, sizeof(uint32_t) * width); break; + default: + // Unhandled data format copy. + DebugBreak(); + break; } } tex_->UnlockRect(level);