DarkStalkers: Fix display in the D3D backends. Still broken in OpenGL.

This commit is contained in:
Henrik Rydgård 2019-10-24 00:51:55 +02:00
parent 9099441973
commit 796539ad7f
5 changed files with 71 additions and 5 deletions

View file

@ -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); vdata = draw_->CreateBuffer(sizeof(Vertex) * 4, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA);
idata = draw_->CreateBuffer(sizeof(int) * 6, BufferUsageFlag::DYNAMIC | BufferUsageFlag::INDEXDATA); 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 inputLayout, depth, blendstateOff, rasterNoCull, &vsTexColBufDesc
}; };
texColor = draw_->CreateGraphicsPipeline(pipelineDesc); 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(); inputLayout->Release();
depth->Release(); depth->Release();
blendstateOff->Release(); blendstateOff->Release();
@ -122,6 +128,8 @@ void SoftGPU::DeviceRestore() {
SoftGPU::~SoftGPU() { SoftGPU::~SoftGPU() {
texColor->Release(); texColor->Release();
texColor = nullptr; texColor = nullptr;
texColorRBSwizzle->Release();
texColorRBSwizzle = nullptr;
if (fbTex) { if (fbTex) {
fbTex->Release(); fbTex->Release();
@ -179,9 +187,10 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
desc.mipLevels = 1; desc.mipLevels = 1;
desc.tag = "SoftGPU"; desc.tag = "SoftGPU";
bool hasImage = true; bool hasImage = true;
Draw::Pipeline *pipeline = texColor;
if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && displayFormat_ == GE_FORMAT_5551 && g_DarkStalkerStretch) { if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && displayFormat_ == GE_FORMAT_5551 && g_DarkStalkerStretch) {
u8 *data = Memory::GetPointer(0x04088000); u8 *data = Memory::GetPointer(0x04088000);
desc.swizzle = Draw::TextureSwizzle::BGRA;
desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16; desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16;
desc.width = displayStride_ == 0 ? srcwidth : displayStride_; desc.width = displayStride_ == 0 ? srcwidth : displayStride_;
desc.height = srcheight; desc.height = srcheight;
@ -190,6 +199,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
u1 = 448.0f / 512.0f; u1 = 448.0f / 512.0f;
v1 = 16.0f / 272.0f; v1 = 16.0f / 272.0f;
v0 = 240.0f / 272.0f; v0 = 240.0f / 272.0f;
pipeline = texColorRBSwizzle;
g_DarkStalkerStretch = false; g_DarkStalkerStretch = false;
} else if (!Memory::IsValidAddress(displayFramebuf_) || srcwidth == 0 || srcheight == 0) { } else if (!Memory::IsValidAddress(displayFramebuf_) || srcwidth == 0 || srcheight == 0) {
hasImage = false; hasImage = false;
@ -307,7 +317,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
Draw::VsTexColUB ub{}; Draw::VsTexColUB ub{};
memcpy(ub.WorldViewProj, g_display_rot_matrix.m, sizeof(float) * 16); memcpy(ub.WorldViewProj, g_display_rot_matrix.m, sizeof(float) * 16);
draw_->BindPipeline(texColor); draw_->BindPipeline(pipeline);
draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub)); draw_->UpdateDynamicUniformBuffer(&ub, sizeof(ub));
draw_->BindVertexBuffers(0, 1, &vdata, nullptr); draw_->BindVertexBuffers(0, 1, &vdata, nullptr);
draw_->BindIndexBuffer(idata, 0); draw_->BindIndexBuffer(idata, 0);

View file

@ -108,6 +108,7 @@ private:
Draw::Texture *fbTex; Draw::Texture *fbTex;
Draw::Pipeline *texColor; Draw::Pipeline *texColor;
Draw::Pipeline *texColorRBSwizzle;
std::vector<u32> fbTexBuffer; std::vector<u32> fbTexBuffer;
Draw::SamplerState *samplerNearest = nullptr; Draw::SamplerState *samplerNearest = nullptr;

View file

@ -146,6 +146,50 @@ static const std::vector<ShaderSource> fsTexCol = {
} }
}; };
static const std::vector<ShaderSource> 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<float4> 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<ShaderSource> fsCol = { static const std::vector<ShaderSource> fsCol = {
{ ShaderLanguage::GLSL_ES_200, { ShaderLanguage::GLSL_ES_200,
"#ifdef GL_ES\n" "#ifdef GL_ES\n"
@ -330,8 +374,9 @@ bool DrawContext::CreatePresets() {
fsPresets_[FS_TEXTURE_COLOR_2D] = CreateShader(this, ShaderStage::FRAGMENT, fsTexCol); fsPresets_[FS_TEXTURE_COLOR_2D] = CreateShader(this, ShaderStage::FRAGMENT, fsTexCol);
fsPresets_[FS_COLOR_2D] = CreateShader(this, ShaderStage::FRAGMENT, fsCol); 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() { void DrawContext::DestroyPresets() {

View file

@ -146,6 +146,7 @@ enum VertexShaderPreset : int {
enum FragmentShaderPreset : int { enum FragmentShaderPreset : int {
FS_COLOR_2D, FS_COLOR_2D,
FS_TEXTURE_COLOR_2D, FS_TEXTURE_COLOR_2D,
FS_TEXTURE_COLOR_2D_RB_SWIZZLE,
FS_MAX_PRESET, FS_MAX_PRESET,
}; };

View file

@ -348,6 +348,10 @@ bool D3D9Texture::Create(const TextureDesc &desc) {
format_ = desc.format; format_ = desc.format;
tex_ = NULL; tex_ = NULL;
d3dfmt_ = FormatToD3DFMT(desc.format); d3dfmt_ = FormatToD3DFMT(desc.format);
if (d3dfmt_ == D3DFMT_UNKNOWN) {
return false;
}
HRESULT hr = E_FAIL; HRESULT hr = E_FAIL;
D3DPOOL pool = D3DPOOL_MANAGED; D3DPOOL pool = D3DPOOL_MANAGED;
@ -424,6 +428,7 @@ void D3D9Texture::SetImageData(int x, int y, int z, int width, int height, int d
} }
break; break;
case DataFormat::A4R4G4B4_UNORM_PACK16: case DataFormat::A4R4G4B4_UNORM_PACK16:
case DataFormat::A1R5G5B5_UNORM_PACK16:
// Native // Native
memcpy(dest, source, width * sizeof(uint16_t)); memcpy(dest, source, width * sizeof(uint16_t));
break; break;
@ -437,6 +442,10 @@ void D3D9Texture::SetImageData(int x, int y, int z, int width, int height, int d
case DataFormat::B8G8R8A8_UNORM: case DataFormat::B8G8R8A8_UNORM:
memcpy(dest, source, sizeof(uint32_t) * width); memcpy(dest, source, sizeof(uint32_t) * width);
break; break;
default:
// Unhandled data format copy.
DebugBreak();
break;
} }
} }
tex_->UnlockRect(level); tex_->UnlockRect(level);