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;
|
xbox::X_D3DSurface *g_pXbox_RenderTarget = xbox::zeroptr;
|
||||||
static xbox::X_D3DSurface *g_pXbox_DepthStencil = xbox::zeroptr;
|
static xbox::X_D3DSurface *g_pXbox_DepthStencil = xbox::zeroptr;
|
||||||
xbox::X_D3DMULTISAMPLE_TYPE g_Xbox_MultiSampleType = xbox::X_D3DMULTISAMPLE_NONE;
|
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
|
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)
|
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();
|
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)
|
void GetMultiSampleOffsetAndScale(float& xScale, float& yScale, float& xOffset, float& yOffset)
|
||||||
{
|
{
|
||||||
GetMultiSampleScale(xScale, yScale);
|
xScale = g_Xbox_MultiSampleXScale;
|
||||||
|
yScale = g_Xbox_MultiSampleYScale;
|
||||||
GetMultiSampleOffset(xOffset, yOffset);
|
GetMultiSampleOffset(xOffset, yOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3016,10 +3013,8 @@ static void ApplyXboxMultiSampleOffset(float& x, float& y)
|
||||||
|
|
||||||
static void ApplyXboxMultiSampleScale(float& x, float& y)
|
static void ApplyXboxMultiSampleScale(float& x, float& y)
|
||||||
{
|
{
|
||||||
float xs, ys;
|
x *= g_Xbox_MultiSampleXScale;
|
||||||
GetMultiSampleScale(xs, ys);
|
y *= g_Xbox_MultiSampleYScale;
|
||||||
x *= xs;
|
|
||||||
y *= ys;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyXboxMultiSampleOffsetAndScale(float& x, float& y)
|
void ApplyXboxMultiSampleOffsetAndScale(float& x, float& y)
|
||||||
|
@ -3028,6 +3023,30 @@ void ApplyXboxMultiSampleOffsetAndScale(float& x, float& y)
|
||||||
ApplyXboxMultiSampleOffset(x, 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
|
void Direct3D_CreateDevice_Start
|
||||||
(
|
(
|
||||||
xbox::X_D3DPRESENT_PARAMETERS *pPresentationParameters
|
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
|
// Since Width and Height are DWORD, subtracting MultiSampleOffset 0.0f or 0.5f makes no sense
|
||||||
//ViewPort.Width -= xOffset;
|
//ViewPort.Width -= xOffset;
|
||||||
//ViewPort.Height -= yOffset;
|
//ViewPort.Height -= yOffset;
|
||||||
ViewPort.Width /= (DWORD)xScale;
|
ViewPort.Width = static_cast<DWORD>(ViewPort.Width / xScale);
|
||||||
ViewPort.Height /= (DWORD)yScale;
|
ViewPort.Height = static_cast<DWORD>(ViewPort.Height / yScale);
|
||||||
|
|
||||||
// Calculate Width/Height scale & offset
|
// Calculate Width/Height scale & offset
|
||||||
float scaleWidth = (2.0f / ViewPort.Width) * g_RenderScaleFactor;
|
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
|
// Apply MSAA scale and offset
|
||||||
float xScale, yScale;
|
HostViewPort.Width = static_cast<DWORD>(HostViewPort.Width * g_Xbox_MultiSampleXScale);
|
||||||
GetMultiSampleScale(xScale, yScale);
|
HostViewPort.Height = static_cast<DWORD>(HostViewPort.Height * g_Xbox_MultiSampleYScale);
|
||||||
HostViewPort.Width *= (DWORD)xScale;
|
|
||||||
HostViewPort.Height *= (DWORD)yScale;
|
|
||||||
// Since Width and Height are DWORD, adding GetMultiSampleOffset 0.0f or 0.5f makes no sense
|
// Since Width and Height are DWORD, adding GetMultiSampleOffset 0.0f or 0.5f makes no sense
|
||||||
|
|
||||||
HRESULT hRet = g_pD3DDevice->SetViewport(&HostViewPort);
|
HRESULT hRet = g_pD3DDevice->SetViewport(&HostViewPort);
|
||||||
|
@ -4984,12 +5001,12 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_Clear)
|
||||||
HRESULT hRet;
|
HRESULT hRet;
|
||||||
|
|
||||||
if (pRects != nullptr) {
|
if (pRects != nullptr) {
|
||||||
// Scale the fill based on our scale factor
|
// Scale the fill based on our scale factor and MSAA scale
|
||||||
D3DRECT rect = *pRects;
|
D3DRECT rect;
|
||||||
rect.x1 *= g_RenderScaleFactor;
|
rect.x1 = static_cast<LONG>(pRects->x1 * g_Xbox_MultiSampleXScale * g_RenderScaleFactor);
|
||||||
rect.x2 *= g_RenderScaleFactor;
|
rect.x2 = static_cast<LONG>(pRects->x2 * g_Xbox_MultiSampleXScale * g_RenderScaleFactor);
|
||||||
rect.y1 *= g_RenderScaleFactor;
|
rect.y1 = static_cast<LONG>(pRects->y1 * g_Xbox_MultiSampleYScale * g_RenderScaleFactor);
|
||||||
rect.y2 *= g_RenderScaleFactor;
|
rect.y2 = static_cast<LONG>(pRects->y2 * g_Xbox_MultiSampleYScale * g_RenderScaleFactor);
|
||||||
hRet = g_pD3DDevice->Clear(Count, &rect, HostFlags, Color, Z, Stencil);
|
hRet = g_pD3DDevice->Clear(Count, &rect, HostFlags, Color, Z, Stencil);
|
||||||
} else {
|
} else {
|
||||||
hRet = g_pD3DDevice->Clear(Count, pRects, HostFlags, Color, Z, Stencil);
|
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);
|
DWORD XboxBackBufferHeight = GetPixelContainerHeight(g_pXbox_BackBufferSurface);
|
||||||
|
|
||||||
// We also need to account for any MSAA which may have enlarged the Xbox Backbuffer
|
// We also need to account for any MSAA which may have enlarged the Xbox Backbuffer
|
||||||
float xScale, yScale;
|
float xScale = g_Xbox_MultiSampleXScale;
|
||||||
GetMultiSampleScale(xScale, yScale);
|
float yScale = g_Xbox_MultiSampleYScale;
|
||||||
|
|
||||||
xScale = (float)width / ((float)XboxBackBufferWidth / xScale);
|
xScale = (float)width / ((float)XboxBackBufferWidth / xScale);
|
||||||
yScale = (float)height / ((float)XboxBackBufferHeight / yScale);
|
yScale = (float)height / ((float)XboxBackBufferHeight / yScale);
|
||||||
|
@ -7801,6 +7818,7 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetRenderTarget)
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateViewPortOffsetAndScaleConstants();
|
UpdateViewPortOffsetAndScaleConstants();
|
||||||
|
CalculateMultiSampleScaleForRenderTarget(pRenderTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LTCG specific D3DDevice_SetPalette function...
|
// LTCG specific D3DDevice_SetPalette function...
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include "core/hle/D3D8/Direct3D9/Direct3D9.h" // For g_pD3DDevice
|
#include "core/hle/D3D8/Direct3D9/Direct3D9.h" // For g_pD3DDevice
|
||||||
#include "core/hle/D3D8/XbConvert.h"
|
#include "core/hle/D3D8/XbConvert.h"
|
||||||
|
|
||||||
|
void SetXboxMultiSampleType(xbox::X_D3DMULTISAMPLE_TYPE value);
|
||||||
|
|
||||||
bool XboxRenderStateConverter::Init()
|
bool XboxRenderStateConverter::Init()
|
||||||
{
|
{
|
||||||
if (g_SymbolAddresses.find("D3DDeferredRenderState") != g_SymbolAddresses.end()) {
|
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_MULTISAMPLEANTIALIAS:
|
||||||
case xbox::X_D3DRS_MULTISAMPLEMASK:
|
case xbox::X_D3DRS_MULTISAMPLEMASK:
|
||||||
break;
|
break;
|
||||||
|
case xbox::X_D3DRS_MULTISAMPLETYPE:
|
||||||
|
SetXboxMultiSampleType(Value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Only log missing state if it has a PC counterpart
|
// Only log missing state if it has a PC counterpart
|
||||||
if (RenderStateInfo.PC != 0) {
|
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;
|
const int X_D3DMULTISAMPLE_9_SAMPLES_SUPERSAMPLE_GAUSSIAN = 0x2233;
|
||||||
|
|
||||||
// Multisample masks (Cxbx additions)
|
// 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_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_XSCALE_SHIFT = 4;
|
||||||
|
|
||||||
const int X_D3DMULTISAMPLE_ALGO_LINEAR = 0x0000;
|
const int X_D3DMULTISAMPLE_ALGO_LINEAR = 0x0000;
|
||||||
|
|
Loading…
Reference in New Issue