GS:MTL: Implement region rect

This commit is contained in:
From: TellowKrinkle 2023-04-01 08:54:40 -05:00 committed by refractionpcsx2
parent 82971d3ef7
commit f6523f34d8
3 changed files with 47 additions and 4 deletions

View File

@ -1413,6 +1413,7 @@ void GSDeviceMTL::MRESetHWPipelineState(GSHWDrawConfig::VSSelector vssel, GSHWDr
setFnConstantB(m_fn_constants, pssel.automatic_lod, GSMTLConstantIndex_PS_AUTOMATIC_LOD); setFnConstantB(m_fn_constants, pssel.automatic_lod, GSMTLConstantIndex_PS_AUTOMATIC_LOD);
setFnConstantB(m_fn_constants, pssel.manual_lod, GSMTLConstantIndex_PS_MANUAL_LOD); setFnConstantB(m_fn_constants, pssel.manual_lod, GSMTLConstantIndex_PS_MANUAL_LOD);
setFnConstantB(m_fn_constants, pssel.point_sampler, GSMTLConstantIndex_PS_POINT_SAMPLER); setFnConstantB(m_fn_constants, pssel.point_sampler, GSMTLConstantIndex_PS_POINT_SAMPLER);
setFnConstantB(m_fn_constants, pssel.region_rect, GSMTLConstantIndex_PS_REGION_RECT);
setFnConstantI(m_fn_constants, pssel.scanmsk, GSMTLConstantIndex_PS_SCANMSK); setFnConstantI(m_fn_constants, pssel.scanmsk, GSMTLConstantIndex_PS_SCANMSK);
auto newps = LoadShader(@"ps_main"); auto newps = LoadShader(@"ps_main");
ps = newps; ps = newps;

View File

@ -211,5 +211,6 @@ enum GSMTLFnConstants
GSMTLConstantIndex_PS_AUTOMATIC_LOD, GSMTLConstantIndex_PS_AUTOMATIC_LOD,
GSMTLConstantIndex_PS_MANUAL_LOD, GSMTLConstantIndex_PS_MANUAL_LOD,
GSMTLConstantIndex_PS_POINT_SAMPLER, GSMTLConstantIndex_PS_POINT_SAMPLER,
GSMTLConstantIndex_PS_REGION_RECT,
GSMTLConstantIndex_PS_SCANMSK, GSMTLConstantIndex_PS_SCANMSK,
}; };

View File

@ -70,6 +70,7 @@ constant bool PS_TEX_IS_FB [[function_constant(GSMTLConstantIndex_PS_TE
constant bool PS_AUTOMATIC_LOD [[function_constant(GSMTLConstantIndex_PS_AUTOMATIC_LOD)]]; constant bool PS_AUTOMATIC_LOD [[function_constant(GSMTLConstantIndex_PS_AUTOMATIC_LOD)]];
constant bool PS_MANUAL_LOD [[function_constant(GSMTLConstantIndex_PS_MANUAL_LOD)]]; constant bool PS_MANUAL_LOD [[function_constant(GSMTLConstantIndex_PS_MANUAL_LOD)]];
constant bool PS_POINT_SAMPLER [[function_constant(GSMTLConstantIndex_PS_POINT_SAMPLER)]]; constant bool PS_POINT_SAMPLER [[function_constant(GSMTLConstantIndex_PS_POINT_SAMPLER)]];
constant bool PS_REGION_RECT [[function_constant(GSMTLConstantIndex_PS_REGION_RECT)]];
constant uint PS_SCANMSK [[function_constant(GSMTLConstantIndex_PS_SCANMSK)]]; constant uint PS_SCANMSK [[function_constant(GSMTLConstantIndex_PS_SCANMSK)]];
constant GSMTLExpandType VS_EXPAND_TYPE = static_cast<GSMTLExpandType>(VS_EXPAND_TYPE_RAW); constant GSMTLExpandType VS_EXPAND_TYPE = static_cast<GSMTLExpandType>(VS_EXPAND_TYPE_RAW);
@ -310,10 +311,20 @@ struct PSMain
return tex.sample(args...); return tex.sample(args...);
} }
float4 read_tex(uint2 pos, uint lod = 0)
{
if (PS_TEX_IS_DEPTH)
return float4(tex_depth.read(pos, lod));
else
return tex.read(pos, lod);
}
float4 sample_c(float2 uv) float4 sample_c(float2 uv)
{ {
if (PS_TEX_IS_FB) if (PS_TEX_IS_FB)
return current_color; return current_color;
if (PS_REGION_RECT)
return read_tex(uint2(uv));
if (PS_POINT_SAMPLER) if (PS_POINT_SAMPLER)
{ {
@ -382,7 +393,15 @@ struct PSMain
if (PS_WMS == PS_WMT) if (PS_WMS == PS_WMT)
{ {
if (PS_WMS == 2) if (PS_REGION_RECT && PS_WMS == 0)
{
uv_out = fract(uv);
}
else if (PS_REGION_RECT && PS_WMS == 1)
{
uv_out = saturate(uv);
}
else if (PS_WMS == 2)
{ {
uv_out = clamp(uv, cb.uv_min_max.xyxy, cb.uv_min_max.zwzw); uv_out = clamp(uv, cb.uv_min_max.xyxy, cb.uv_min_max.zwzw);
} }
@ -398,7 +417,15 @@ struct PSMain
} }
else else
{ {
if (PS_WMS == 2) if (PS_REGION_RECT && PS_WMS == 0)
{
uv_out.xz = fract(uv.xz);
}
else if (PS_REGION_RECT && PS_WMS == 1)
{
uv_out.xz = saturate(uv.xz);
}
else if (PS_WMS == 2)
{ {
uv_out.xz = clamp(uv.xz, cb.uv_min_max.xx, cb.uv_min_max.zz); uv_out.xz = clamp(uv.xz, cb.uv_min_max.xx, cb.uv_min_max.zz);
} }
@ -410,7 +437,15 @@ struct PSMain
uv_out.xz = float2((ushort2(uv.xz * tex_size.xx) & ushort2(cb.uv_msk_fix.xx)) | ushort2(cb.uv_msk_fix.zz)) / tex_size.xx; uv_out.xz = float2((ushort2(uv.xz * tex_size.xx) & ushort2(cb.uv_msk_fix.xx)) | ushort2(cb.uv_msk_fix.zz)) / tex_size.xx;
} }
if (PS_WMT == 2) if (PS_REGION_RECT && PS_WMT == 0)
{
uv_out.yw = fract(uv.yw);
}
else if (PS_REGION_RECT && PS_WMT == 1)
{
uv_out.yw = saturate(uv.yw);
}
else if (PS_WMT == 2)
{ {
uv_out.yw = clamp(uv.yw, cb.uv_min_max.yy, cb.uv_min_max.ww); uv_out.yw = clamp(uv.yw, cb.uv_min_max.yy, cb.uv_min_max.ww);
} }
@ -423,6 +458,12 @@ struct PSMain
} }
} }
if (PS_REGION_RECT)
{
// Normalized -> Integer Coordinates.
uv_out = clamp(uv_out * cb.wh.zwzw + cb.st_range.xyxy, cb.st_range.xyxy, cb.st_range.zwzw);
}
return uv_out; return uv_out;
} }
@ -631,7 +672,7 @@ struct PSMain
float4x4 c; float4x4 c;
float2 dd; float2 dd;
if (!PS_LTF && PS_AEM_FMT == FMT_32 && PS_PAL_FMT == 0 && PS_WMS < 2 && PS_WMT < 2) if (!PS_LTF && PS_AEM_FMT == FMT_32 && PS_PAL_FMT == 0 && !PS_REGION_RECT && PS_WMS < 2 && PS_WMT < 2)
{ {
c[0] = sample_c(st); c[0] = sample_c(st);
} }