mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Implement shader blending for D3D9
This was easy, dunno why I never got around to it before.. I guess I didn't know about VPOS. This does raise our minimum shader model requirement to ps_3_0.
This commit is contained in:
@@ -54,7 +54,7 @@ LPD3DBLOB CompileShaderToByteCodeD3D9(const char *code, const char *target, std:
|
||||
}
|
||||
|
||||
bool CompilePixelShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPIXELSHADER9 *pShader, std::string *errorMessage) {
|
||||
LPD3DBLOB pShaderCode = CompileShaderToByteCodeD3D9(code, "ps_2_0", errorMessage);
|
||||
LPD3DBLOB pShaderCode = CompileShaderToByteCodeD3D9(code, "ps_3_0", errorMessage);
|
||||
if (pShaderCode) {
|
||||
// Create pixel shader.
|
||||
device->CreatePixelShader((DWORD*)pShaderCode->GetBufferPointer(), pShader);
|
||||
@@ -66,7 +66,7 @@ bool CompilePixelShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT
|
||||
}
|
||||
|
||||
bool CompileVertexShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, std::string *errorMessage) {
|
||||
LPD3DBLOB pShaderCode = CompileShaderToByteCodeD3D9(code, "vs_2_0", errorMessage);
|
||||
LPD3DBLOB pShaderCode = CompileShaderToByteCodeD3D9(code, "vs_3_0", errorMessage);
|
||||
if (pShaderCode) {
|
||||
// Create vertex shader.
|
||||
device->CreateVertexShader((DWORD*)pShaderCode->GetBufferPointer(), pShader);
|
||||
|
||||
@@ -1069,11 +1069,7 @@ bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, si
|
||||
auto compile = [&](const char *profile) -> HRESULT {
|
||||
return dyn_D3DCompile(source, (UINT)strlen(source), nullptr, defines, includes, "main", profile, 0, 0, &codeBuffer, &errorBuffer);
|
||||
};
|
||||
HRESULT hr = compile(stage_ == ShaderStage::Fragment ? "ps_2_0" : "vs_2_0");
|
||||
if (FAILED(hr) && hr == D3DXERR_INVALIDDATA) {
|
||||
// Might be a post shader. Let's try using shader model 3.
|
||||
hr = compile(stage_ == ShaderStage::Fragment ? "ps_3_0" : "vs_3_0");
|
||||
}
|
||||
HRESULT hr = compile(stage_ == ShaderStage::Fragment ? "ps_3_0" : "vs_3_0");
|
||||
if (FAILED(hr)) {
|
||||
const char *error = errorBuffer ? (const char *)errorBuffer->GetBufferPointer() : "(no errorbuffer returned)";
|
||||
if (hr == ERROR_MOD_NOT_FOUND) {
|
||||
|
||||
@@ -132,11 +132,6 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
return false;
|
||||
}
|
||||
|
||||
if (readFramebuffer && compat.shaderLanguage == HLSL_D3D9) {
|
||||
*errorString = "Framebuffer read not yet supported in HLSL D3D9";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (compat.shaderLanguage == ShaderLanguage::GLSL_VULKAN) {
|
||||
if (useDiscardStencilBugWorkaround && !gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, "layout (depth_unchanged) out float gl_FragDepth;\n");
|
||||
@@ -227,7 +222,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
}
|
||||
if (readFramebufferTex) {
|
||||
// No sampler required, we Load
|
||||
WRITE(p, "Texture2D<vec4> fboTex : register(t1);\n");
|
||||
WRITE(p, "Texture2D<vec4> fbotex : register(t1);\n");
|
||||
}
|
||||
WRITE(p, "cbuffer base : register(b0) {\n%s};\n", ub_baseStr);
|
||||
|
||||
@@ -264,8 +259,12 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
if (enableFog) {
|
||||
WRITE(p, " float v_fogdepth: TEXCOORD1;\n");
|
||||
}
|
||||
if (compat.shaderLanguage == HLSL_D3D11 && needFragCoord) {
|
||||
WRITE(p, " vec4 pixelPos : SV_POSITION;\n");
|
||||
if (needFragCoord) {
|
||||
if (compat.shaderLanguage == HLSL_D3D11) {
|
||||
WRITE(p, " vec4 pixelPos : SV_POSITION;\n");
|
||||
} else if (compat.shaderLanguage == HLSL_D3D9) {
|
||||
WRITE(p, " vec4 pixelPos : VPOS;\n"); // VPOS is only supported for Shader Model 3.0, but we can probably forget about D3D9 SM2.0 at this point...
|
||||
}
|
||||
}
|
||||
WRITE(p, "};\n");
|
||||
|
||||
@@ -457,7 +456,9 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
} else if (compat.shaderLanguage == HLSL_D3D9) {
|
||||
WRITE(p, "PS_OUT main( PS_IN In ) {\n");
|
||||
WRITE(p, " PS_OUT outfragment;\n");
|
||||
WRITE(p, " vec4 target;\n");
|
||||
if (needFragCoord) {
|
||||
WRITE(p, " vec4 gl_FragCoord = In.pixelPos;\n");
|
||||
}
|
||||
} else {
|
||||
WRITE(p, "void main() {\n");
|
||||
}
|
||||
@@ -477,7 +478,9 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
// Two things read from the old framebuffer - shader replacement blending and bit-level masking.
|
||||
if (readFramebuffer) {
|
||||
if (compat.shaderLanguage == HLSL_D3D11) {
|
||||
WRITE(p, " vec4 destColor = fboTex.Load(int3((int)gl_FragCoord.x, (int)gl_FragCoord.y, 0));\n");
|
||||
WRITE(p, " vec4 destColor = fbotex.Load(int3((int)gl_FragCoord.x, (int)gl_FragCoord.y, 0));\n");
|
||||
} else if (compat.shaderLanguage == HLSL_D3D9) {
|
||||
WRITE(p, " vec4 destColor = tex2D(fbotex, gl_FragCoord.xy * u_fbotexSize.xy);\n", compat.texture);
|
||||
} else if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) {
|
||||
// If we have EXT_shader_framebuffer_fetch / ARM_shader_framebuffer_fetch, we skip the blit.
|
||||
// We can just read the prev value more directly.
|
||||
|
||||
@@ -119,8 +119,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
|
||||
bool useBufferedRendering = framebufferManager_->UseBufferedRendering();
|
||||
|
||||
if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
|
||||
// Unfortunately, this isn't implemented on DX9 yet.
|
||||
gstate_c.SetAllowFramebufferRead(false);
|
||||
gstate_c.SetAllowFramebufferRead(!g_Config.bDisableSlowFramebufEffects);
|
||||
if (gstate.isModeClear()) {
|
||||
dxstate.blend.disable();
|
||||
// Color Mask
|
||||
|
||||
@@ -102,7 +102,7 @@ bool TestCompileShader(const char *buffer, ShaderLanguage lang, ShaderStage stag
|
||||
}
|
||||
case ShaderLanguage::HLSL_D3D9:
|
||||
{
|
||||
LPD3DBLOB blob = CompileShaderToByteCodeD3D9(buffer, stage == ShaderStage::Vertex ? "vs_2_0" : "ps_2_0", errorMessage);
|
||||
LPD3DBLOB blob = CompileShaderToByteCodeD3D9(buffer, stage == ShaderStage::Vertex ? "vs_3_0" : "ps_3_0", errorMessage);
|
||||
if (blob) {
|
||||
blob->Release();
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user