mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-16 07:50:28 +02:00
The GE's blend terms are floor((2c+1)(2f+1)/1024), which truncates, while the hardware multiplies by f/255 and rounds, so every pass of a fixed color blend chain came out up to a level brighter. God Eater Burst's bloom is many such passes and ended up far too bright. For additive FIXA/FIXB blends that aren't just 0 and 0xFFFFFF, the shader now computes the src term exactly and lowers it by 0.5 - (2B+1)/1024, and the blend constant is the GE's dst factor (2B+1)/512, so the hardware's rounding of the sum lands on the GE's floor (except where the src term would go below zero). Blend constants are passed as floats to make that possible. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
74 lines
1.8 KiB
C++
74 lines
1.8 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
|
|
#include "Common/CommonWindows.h"
|
|
#include <d3d11.h>
|
|
|
|
#include "Common/GPU/thin3d.h"
|
|
|
|
struct D3D11BlendKey {
|
|
union {
|
|
uint64_t value;
|
|
struct {
|
|
// Blend
|
|
unsigned int blendEnable : 1;
|
|
unsigned int srcColor : 5; // D3D11_BLEND
|
|
unsigned int destColor : 5; // D3D11_BLEND
|
|
unsigned int srcAlpha : 5; // D3D11_BLEND
|
|
unsigned int destAlpha : 5; // D3D11_BLEND
|
|
unsigned int blendOpColor : 3; // D3D11_BLEND_OP
|
|
unsigned int blendOpAlpha : 3; // D3D11_BLEND_OP
|
|
unsigned int logicOpEnable : 1;
|
|
unsigned int logicOp : 4; // D3D11_LOGIC_OP
|
|
unsigned int colorWriteMask : 4;
|
|
};
|
|
};
|
|
};
|
|
|
|
struct D3D11DepthStencilKey {
|
|
union {
|
|
uint64_t value;
|
|
struct {
|
|
// Depth/Stencil
|
|
unsigned int depthTestEnable : 1;
|
|
unsigned int depthWriteEnable : 1;
|
|
unsigned int depthCompareOp : 4; // D3D11_COMPARISON (-1 and we could fit it in 3 bits)
|
|
unsigned int stencilTestEnable : 1;
|
|
unsigned int stencilCompareFunc : 4; // D3D11_COMPARISON
|
|
unsigned int stencilPassOp : 4; // D3D11_STENCIL_OP
|
|
unsigned int stencilFailOp : 4; // D3D11_STENCIL_OP
|
|
unsigned int stencilDepthFailOp : 4; // D3D11_STENCIL_OP
|
|
unsigned int stencilWriteMask : 8; // Unfortunately these are baked into the state on D3D11
|
|
unsigned int stencilCompareMask : 8;
|
|
};
|
|
};
|
|
};
|
|
|
|
struct D3D11RasterKey {
|
|
union {
|
|
uint32_t value;
|
|
struct {
|
|
unsigned int cullMode : 2; // D3D11_CULL_MODE
|
|
unsigned int depthClipEnable : 1;
|
|
};
|
|
};
|
|
};
|
|
|
|
// In D3D11 we cache blend state objects etc, and we simply emit keys, which are then also used to create these objects.
|
|
struct D3D11StateKeys {
|
|
D3D11BlendKey blend;
|
|
D3D11DepthStencilKey depthStencil;
|
|
D3D11RasterKey raster;
|
|
};
|
|
|
|
struct D3D11DynamicState {
|
|
int topology;
|
|
bool useBlendColor;
|
|
float blendColor[4];
|
|
bool useStencil;
|
|
uint8_t stencilRef;
|
|
Draw::Viewport viewport;
|
|
D3D11_RECT scissor;
|
|
};
|