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);
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);

View File

@ -108,6 +108,7 @@ private:
Draw::Texture *fbTex;
Draw::Pipeline *texColor;
Draw::Pipeline *texColorRBSwizzle;
std::vector<u32> fbTexBuffer;
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 = {
{ 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() {

View File

@ -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,
};

View File

@ -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);