Merge pull request #1978 from CookiePLMonster/msaa-improvements
MSAA improvements basing on xdk-3911 behaviour
This commit is contained in:
commit
8a87fd8376
|
@ -173,6 +173,8 @@ static xbox::X_D3DSurface *g_pXbox_DefaultDepthStencilSurface = xbox::
|
|||
xbox::X_D3DSurface *g_pXbox_RenderTarget = xbox::zeroptr;
|
||||
static xbox::X_D3DSurface *g_pXbox_DepthStencil = xbox::zeroptr;
|
||||
xbox::X_D3DMULTISAMPLE_TYPE g_Xbox_MultiSampleType = xbox::X_D3DMULTISAMPLE_NONE;
|
||||
static float g_Xbox_MultiSampleXScale = 1.0f;
|
||||
static float g_Xbox_MultiSampleYScale = 1.0f;
|
||||
|
||||
xbox::X_VERTEXSHADERCONSTANTMODE g_Xbox_VertexShaderConstantMode = X_D3DSCM_192CONSTANTS; // Set by D3DDevice_SetShaderConstantMode, TODO : Move to XbVertexShader.cpp
|
||||
static xbox::dword_xt g_Xbox_BaseVertexIndex = 0; // Set by D3DDevice_SetIndices, read by D3DDevice_DrawIndexedVertices : a value that's effectively added to every vertex index (as stored in an index buffer) by multiplying this by vertex stride and added to the vertex buffer start (see BaseVertexIndex in CxbxDrawIndexed)
|
||||
|
@ -2995,15 +2997,10 @@ static inline void GetMultiSampleOffset(float& xOffset, float& yOffset)
|
|||
xOffset = yOffset = GetMultiSampleOffsetDelta();
|
||||
}
|
||||
|
||||
static inline void GetMultiSampleScale(float& xScale, float& yScale)
|
||||
{
|
||||
xScale = (float)CXBX_D3DMULTISAMPLE_XSCALE(g_Xbox_MultiSampleType);
|
||||
yScale = (float)CXBX_D3DMULTISAMPLE_YSCALE(g_Xbox_MultiSampleType);
|
||||
}
|
||||
|
||||
void GetMultiSampleOffsetAndScale(float& xScale, float& yScale, float& xOffset, float& yOffset)
|
||||
{
|
||||
GetMultiSampleScale(xScale, yScale);
|
||||
xScale = g_Xbox_MultiSampleXScale;
|
||||
yScale = g_Xbox_MultiSampleYScale;
|
||||
GetMultiSampleOffset(xOffset, yOffset);
|
||||
}
|
||||
|
||||
|
@ -3016,10 +3013,8 @@ static void ApplyXboxMultiSampleOffset(float& x, float& y)
|
|||
|
||||
static void ApplyXboxMultiSampleScale(float& x, float& y)
|
||||
{
|
||||
float xs, ys;
|
||||
GetMultiSampleScale(xs, ys);
|
||||
x *= xs;
|
||||
y *= ys;
|
||||
x *= g_Xbox_MultiSampleXScale;
|
||||
y *= g_Xbox_MultiSampleYScale;
|
||||
}
|
||||
|
||||
void ApplyXboxMultiSampleOffsetAndScale(float& x, float& y)
|
||||
|
@ -3028,6 +3023,30 @@ void ApplyXboxMultiSampleOffsetAndScale(float& x, float& y)
|
|||
ApplyXboxMultiSampleOffset(x, y);
|
||||
}
|
||||
|
||||
void CalculateMultiSampleScaleForRenderTarget(xbox::X_D3DSurface* renderTarget)
|
||||
{
|
||||
float xScale = 1.0f;
|
||||
float yScale = 1.0f;
|
||||
if (renderTarget == g_pXbox_BackBufferSurface && (g_Xbox_MultiSampleType & xbox::X_D3DMULTISAMPLE_SAMPLING_MASK) != 0) {
|
||||
xScale = static_cast<float>(CXBX_D3DMULTISAMPLE_XSCALE(g_Xbox_MultiSampleType));
|
||||
yScale = static_cast<float>(CXBX_D3DMULTISAMPLE_YSCALE(g_Xbox_MultiSampleType));
|
||||
if (xScale > 3.0f || yScale > 3.0f) {
|
||||
// No games known to do this, but XSCALE and YSCALE masks technically allow for it
|
||||
LOG_TEST_CASE("g_Xbox_MultiSampleXScale or g_Xbox_MultiSampleYScale over 3");
|
||||
}
|
||||
// TODO: Buffers should not be upscaled when using multisampling
|
||||
/*if ((g_Xbox_MultiSampleType & xbox::X_D3DMULTISAMPLE_SAMPLING_MULTI) != 0) {
|
||||
xScale /= 2.0f;
|
||||
if (yScale > 1.0f) {
|
||||
yScale /= 2.0f;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
g_Xbox_MultiSampleXScale = xScale;
|
||||
g_Xbox_MultiSampleYScale = yScale;
|
||||
}
|
||||
|
||||
void Direct3D_CreateDevice_Start
|
||||
(
|
||||
xbox::X_D3DPRESENT_PARAMETERS *pPresentationParameters
|
||||
|
@ -3971,8 +3990,8 @@ void GetViewPortOffsetAndScale(float (&vOffset)[4], float(&vScale)[4])
|
|||
// Since Width and Height are DWORD, subtracting MultiSampleOffset 0.0f or 0.5f makes no sense
|
||||
//ViewPort.Width -= xOffset;
|
||||
//ViewPort.Height -= yOffset;
|
||||
ViewPort.Width /= (DWORD)xScale;
|
||||
ViewPort.Height /= (DWORD)yScale;
|
||||
ViewPort.Width = static_cast<DWORD>(ViewPort.Width / xScale);
|
||||
ViewPort.Height = static_cast<DWORD>(ViewPort.Height / yScale);
|
||||
|
||||
// Calculate Width/Height scale & offset
|
||||
float scaleWidth = (2.0f / ViewPort.Width) * g_RenderScaleFactor;
|
||||
|
@ -4101,10 +4120,8 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetViewport)
|
|||
}
|
||||
|
||||
// Apply MSAA scale and offset
|
||||
float xScale, yScale;
|
||||
GetMultiSampleScale(xScale, yScale);
|
||||
HostViewPort.Width *= (DWORD)xScale;
|
||||
HostViewPort.Height *= (DWORD)yScale;
|
||||
HostViewPort.Width = static_cast<DWORD>(HostViewPort.Width * g_Xbox_MultiSampleXScale);
|
||||
HostViewPort.Height = static_cast<DWORD>(HostViewPort.Height * g_Xbox_MultiSampleYScale);
|
||||
// Since Width and Height are DWORD, adding GetMultiSampleOffset 0.0f or 0.5f makes no sense
|
||||
|
||||
HRESULT hRet = g_pD3DDevice->SetViewport(&HostViewPort);
|
||||
|
@ -4984,12 +5001,12 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_Clear)
|
|||
HRESULT hRet;
|
||||
|
||||
if (pRects != nullptr) {
|
||||
// Scale the fill based on our scale factor
|
||||
D3DRECT rect = *pRects;
|
||||
rect.x1 *= g_RenderScaleFactor;
|
||||
rect.x2 *= g_RenderScaleFactor;
|
||||
rect.y1 *= g_RenderScaleFactor;
|
||||
rect.y2 *= g_RenderScaleFactor;
|
||||
// Scale the fill based on our scale factor and MSAA scale
|
||||
D3DRECT rect;
|
||||
rect.x1 = static_cast<LONG>(pRects->x1 * g_Xbox_MultiSampleXScale * g_RenderScaleFactor);
|
||||
rect.x2 = static_cast<LONG>(pRects->x2 * g_Xbox_MultiSampleXScale * g_RenderScaleFactor);
|
||||
rect.y1 = static_cast<LONG>(pRects->y1 * g_Xbox_MultiSampleYScale * g_RenderScaleFactor);
|
||||
rect.y2 = static_cast<LONG>(pRects->y2 * g_Xbox_MultiSampleYScale * g_RenderScaleFactor);
|
||||
hRet = g_pD3DDevice->Clear(Count, &rect, HostFlags, Color, Z, Stencil);
|
||||
} else {
|
||||
hRet = g_pD3DDevice->Clear(Count, pRects, HostFlags, Color, Z, Stencil);
|
||||
|
@ -5280,8 +5297,8 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(D3DDevice_Swap)
|
|||
DWORD XboxBackBufferHeight = GetPixelContainerHeight(g_pXbox_BackBufferSurface);
|
||||
|
||||
// We also need to account for any MSAA which may have enlarged the Xbox Backbuffer
|
||||
float xScale, yScale;
|
||||
GetMultiSampleScale(xScale, yScale);
|
||||
float xScale = g_Xbox_MultiSampleXScale;
|
||||
float yScale = g_Xbox_MultiSampleYScale;
|
||||
|
||||
xScale = (float)width / ((float)XboxBackBufferWidth / xScale);
|
||||
yScale = (float)height / ((float)XboxBackBufferHeight / yScale);
|
||||
|
@ -7801,6 +7818,7 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetRenderTarget)
|
|||
}
|
||||
|
||||
UpdateViewPortOffsetAndScaleConstants();
|
||||
CalculateMultiSampleScaleForRenderTarget(pRenderTarget);
|
||||
}
|
||||
|
||||
// LTCG specific D3DDevice_SetPalette function...
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "core/hle/D3D8/Direct3D9/Direct3D9.h" // For g_pD3DDevice
|
||||
#include "core/hle/D3D8/XbConvert.h"
|
||||
|
||||
void SetXboxMultiSampleType(xbox::X_D3DMULTISAMPLE_TYPE value);
|
||||
|
||||
bool XboxRenderStateConverter::Init()
|
||||
{
|
||||
if (g_SymbolAddresses.find("D3DDeferredRenderState") != g_SymbolAddresses.end()) {
|
||||
|
@ -457,6 +459,9 @@ void XboxRenderStateConverter::ApplyComplexRenderState(uint32_t State, uint32_t
|
|||
case xbox::X_D3DRS_MULTISAMPLEANTIALIAS:
|
||||
case xbox::X_D3DRS_MULTISAMPLEMASK:
|
||||
break;
|
||||
case xbox::X_D3DRS_MULTISAMPLETYPE:
|
||||
SetXboxMultiSampleType(Value);
|
||||
break;
|
||||
default:
|
||||
// Only log missing state if it has a PC counterpart
|
||||
if (RenderStateInfo.PC != 0) {
|
||||
|
|
|
@ -480,10 +480,10 @@ const int X_D3DMULTISAMPLE_9_SAMPLES_MULTISAMPLE_GAUSSIAN = 0x1233;
|
|||
const int X_D3DMULTISAMPLE_9_SAMPLES_SUPERSAMPLE_GAUSSIAN = 0x2233;
|
||||
|
||||
// Multisample masks (Cxbx additions)
|
||||
const int X_D3DMULTISAMPLE_YSCALE_MASK = 0x0003;
|
||||
const int X_D3DMULTISAMPLE_YSCALE_MASK = 0x000F;
|
||||
const int X_D3DMULTISAMPLE_YSCALE_SHIFT = 0;
|
||||
|
||||
const int X_D3DMULTISAMPLE_XSCALE_MASK = 0x0030;
|
||||
const int X_D3DMULTISAMPLE_XSCALE_MASK = 0x00F0;
|
||||
const int X_D3DMULTISAMPLE_XSCALE_SHIFT = 4;
|
||||
|
||||
const int X_D3DMULTISAMPLE_ALGO_LINEAR = 0x0000;
|
||||
|
|
Loading…
Reference in New Issue