mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
GS/HW: Refactor StretchRect() to have single entry to renderer/reduce duplication.
This commit is contained in:
parent
9b147cc57c
commit
35624a12d9
@ -723,6 +723,39 @@ GSTexture* GSDevice::CreateTexture(int w, int h, int mipmap_levels, GSTexture::F
|
||||
return FetchSurface(GSTexture::Type::Texture, w, h, levels, format, false, m_features.prefer_new_textures && !prefer_reuse);
|
||||
}
|
||||
|
||||
void GSDevice::DoStretchRectWithAssertions(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear)
|
||||
{
|
||||
pxAssert((dTex && dTex->IsDepthStencil()) == HasDepthOutput(shader));
|
||||
pxAssert(linear ? SupportsBilinear(shader) : SupportsNearest(shader));
|
||||
GL_INS("StretchRect(%d) {%d,%d} %dx%d -> {%d,%d) %dx%d", shader, int(sRect.left), int(sRect.top),
|
||||
int(sRect.right - sRect.left), int(sRect.bottom - sRect.top), int(dRect.left), int(dRect.top),
|
||||
int(dRect.right - dRect.left), int(dRect.bottom - dRect.top));
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, cms, shader, linear);
|
||||
}
|
||||
|
||||
void GSDevice::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
bool red, bool green, bool blue, bool alpha, ShaderConvert shader)
|
||||
{
|
||||
GSHWDrawConfig::ColorMaskSelector cms;
|
||||
|
||||
cms.wr = red;
|
||||
cms.wg = green;
|
||||
cms.wb = blue;
|
||||
cms.wa = alpha;
|
||||
|
||||
pxAssert(HasVariableWriteMask(shader));
|
||||
GL_INS("ColorCopy Red:%d Green:%d Blue:%d Alpha:%d", cms.wr, cms.wg, cms.wb, cms.wa);
|
||||
|
||||
DoStretchRectWithAssertions(sTex, sRect, dTex, dRect, cms, shader, false);
|
||||
}
|
||||
|
||||
void GSDevice::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
ShaderConvert shader, bool linear)
|
||||
{
|
||||
DoStretchRectWithAssertions(sTex, sRect, dTex, dRect, GSHWDrawConfig::ColorMaskSelector(ShaderConvertWriteMask(shader)), shader, linear);
|
||||
}
|
||||
|
||||
void GSDevice::StretchRect(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
|
||||
{
|
||||
StretchRect(sTex, GSVector4(0, 0, 1, 1), dTex, dRect, shader, linear);
|
||||
@ -734,11 +767,11 @@ void GSDevice::DrawMultiStretchRects(
|
||||
for (u32 i = 0; i < num_rects; i++)
|
||||
{
|
||||
const MultiStretchRect& sr = rects[i];
|
||||
pxAssert(shader == ShaderConvert::COPY || shader == ShaderConvert::RTA_CORRECTION || rects[0].wmask.wrgba == 0xf);
|
||||
pxAssert(HasVariableWriteMask(shader) || rects[0].wmask.wrgba == 0xf);
|
||||
if (rects[0].wmask.wrgba != 0xf)
|
||||
{
|
||||
g_gs_device->StretchRect(sr.src, sr.src_rect, dTex, sr.dst_rect, rects[0].wmask.wr,
|
||||
rects[0].wmask.wg, rects[0].wmask.wb, rects[0].wmask.wa);
|
||||
rects[0].wmask.wg, rects[0].wmask.wb, rects[0].wmask.wa, shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -69,6 +69,27 @@ enum class ShaderInterlace
|
||||
Count
|
||||
};
|
||||
|
||||
static inline bool HasVariableWriteMask(ShaderConvert shader)
|
||||
{
|
||||
switch (shader)
|
||||
{
|
||||
case ShaderConvert::COPY:
|
||||
case ShaderConvert::RTA_CORRECTION:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int GetShaderIndexForMask(ShaderConvert shader, int mask)
|
||||
{
|
||||
pxAssert(HasVariableWriteMask(shader));
|
||||
int index = mask;
|
||||
if (shader == ShaderConvert::RTA_CORRECTION)
|
||||
index |= 1 << 4;
|
||||
return index;
|
||||
}
|
||||
|
||||
static inline bool HasDepthOutput(ShaderConvert shader)
|
||||
{
|
||||
switch (shader)
|
||||
@ -549,6 +570,7 @@ struct alignas(16) GSHWDrawConfig
|
||||
constexpr ColorMaskSelector(): key(0xF) {}
|
||||
constexpr ColorMaskSelector(u8 c): key(0) { wrgba = c; }
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
struct alignas(16) VSConstantBuffer
|
||||
{
|
||||
@ -922,6 +944,12 @@ protected:
|
||||
/// Perform texture operations for ImGui
|
||||
void UpdateImGuiTextures();
|
||||
|
||||
protected:
|
||||
// Entry point to the renderer-specific StretchRect code.
|
||||
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear) = 0;
|
||||
void DoStretchRectWithAssertions(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear);
|
||||
|
||||
public:
|
||||
GSDevice();
|
||||
virtual ~GSDevice();
|
||||
@ -1037,9 +1065,9 @@ public:
|
||||
virtual std::unique_ptr<GSDownloadTexture> CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format) = 0;
|
||||
|
||||
virtual void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) = 0;
|
||||
virtual void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) = 0;
|
||||
virtual void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY) = 0;
|
||||
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY);
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true);
|
||||
void StretchRect(GSTexture* sTex, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true);
|
||||
|
||||
/// Performs a screen blit for display. If dTex is null, it assumes you are writing to the system framebuffer/swap chain.
|
||||
|
||||
@ -1274,28 +1274,18 @@ void GSDevice11::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
|
||||
dTex->SetState(GSTexture::State::Dirty);
|
||||
}
|
||||
|
||||
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
|
||||
void GSDevice11::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear)
|
||||
{
|
||||
pxAssert(dTex->IsDepthStencil() == HasDepthOutput(shader));
|
||||
pxAssert(linear ? SupportsBilinear(shader) : SupportsNearest(shader));
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), nullptr,
|
||||
m_convert.bs[ShaderConvertWriteMask(shader)].get(), linear);
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), nullptr, m_convert.bs[cms.wrgba].get(), linear);
|
||||
}
|
||||
|
||||
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear)
|
||||
void GSDevice11::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear)
|
||||
{
|
||||
StretchRect(sTex, sRect, dTex, dRect, ps, ps_cb, m_convert.bs[D3D11_COLOR_WRITE_ENABLE_ALL].get(), linear);
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, ps, ps_cb, m_convert.bs[D3D11_COLOR_WRITE_ENABLE_ALL].get(), linear);
|
||||
}
|
||||
|
||||
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader)
|
||||
{
|
||||
const u8 index = static_cast<u8>(red) | (static_cast<u8>(green) << 1) | (static_cast<u8>(blue) << 2) |
|
||||
(static_cast<u8>(alpha) << 3);
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), nullptr,
|
||||
m_convert.bs[index].get(), false);
|
||||
}
|
||||
|
||||
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear)
|
||||
void GSDevice11::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear)
|
||||
{
|
||||
CommitClear(sTex);
|
||||
|
||||
@ -1439,7 +1429,7 @@ void GSDevice11::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u
|
||||
|
||||
const GSVector4 dRect(0, 0, dSize, 1);
|
||||
const ShaderConvert shader = (dSize == 16) ? ShaderConvert::CLUT_4 : ShaderConvert::CLUT_8;
|
||||
StretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
|
||||
DoStretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
|
||||
}
|
||||
|
||||
void GSDevice11::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM)
|
||||
@ -1457,7 +1447,7 @@ void GSDevice11::ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offs
|
||||
|
||||
const GSVector4 dRect(0, 0, dTex->GetWidth(), dTex->GetHeight());
|
||||
const ShaderConvert shader = ((SPSM & 0xE) == 0) ? ShaderConvert::RGBA_TO_8I : ShaderConvert::RGB5A1_TO_8I;
|
||||
StretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
|
||||
DoStretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
|
||||
}
|
||||
|
||||
void GSDevice11::FilteredDownsampleTexture(GSTexture* sTex, GSTexture* dTex, u32 downsample_factor, const GSVector2i& clamp_min, const GSVector4& dRect)
|
||||
@ -1477,7 +1467,7 @@ void GSDevice11::FilteredDownsampleTexture(GSTexture* sTex, GSTexture* dTex, u32
|
||||
m_ctx->UpdateSubresource(m_merge.cb.get(), 0, nullptr, &cb, 0, 0);
|
||||
|
||||
const ShaderConvert shader = ShaderConvert::DOWNSAMPLE_COPY;
|
||||
StretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
|
||||
DoStretchRect(sTex, GSVector4::zero(), dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), m_merge.cb.get(), nullptr, false);
|
||||
}
|
||||
|
||||
void GSDevice11::DrawMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvert shader)
|
||||
@ -1596,7 +1586,7 @@ void GSDevice11::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
||||
// Save 2nd output
|
||||
if (feedback_write_2)
|
||||
{
|
||||
StretchRect(dTex, full_r, sTex[2], dRect[2], m_convert.ps[static_cast<int>(ShaderConvert::YUV)].get(),
|
||||
DoStretchRect(dTex, full_r, sTex[2], dRect[2], m_convert.ps[static_cast<int>(ShaderConvert::YUV)].get(),
|
||||
m_merge.cb.get(), nullptr, linear);
|
||||
}
|
||||
|
||||
@ -1607,12 +1597,12 @@ void GSDevice11::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
||||
if (sTex[0])
|
||||
{
|
||||
// 1st output is enabled. It must be blended
|
||||
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge.ps[PMODE.MMOD].get(), m_merge.cb.get(), m_merge.bs.get(), linear);
|
||||
DoStretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge.ps[PMODE.MMOD].get(), m_merge.cb.get(), m_merge.bs.get(), linear);
|
||||
}
|
||||
|
||||
if (feedback_write_1)
|
||||
{
|
||||
StretchRect(dTex, full_r, sTex[2], dRect[2], m_convert.ps[static_cast<int>(ShaderConvert::YUV)].get(),
|
||||
DoStretchRect(dTex, full_r, sTex[2], dRect[2], m_convert.ps[static_cast<int>(ShaderConvert::YUV)].get(),
|
||||
m_merge.cb.get(), nullptr, linear);
|
||||
}
|
||||
}
|
||||
@ -1621,7 +1611,7 @@ void GSDevice11::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture*
|
||||
{
|
||||
m_ctx->UpdateSubresource(m_interlace.cb.get(), 0, nullptr, &cb, 0, 0);
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[static_cast<int>(shader)].get(), m_interlace.cb.get(), linear);
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[static_cast<int>(shader)].get(), m_interlace.cb.get(), linear);
|
||||
}
|
||||
|
||||
void GSDevice11::DoFXAA(GSTexture* sTex, GSTexture* dTex)
|
||||
@ -1647,7 +1637,7 @@ void GSDevice11::DoFXAA(GSTexture* sTex, GSTexture* dTex)
|
||||
return;
|
||||
}
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_fxaa_ps.get(), nullptr, true);
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, m_fxaa_ps.get(), nullptr, true);
|
||||
}
|
||||
|
||||
void GSDevice11::DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float params[4])
|
||||
@ -1659,7 +1649,7 @@ void GSDevice11::DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float para
|
||||
|
||||
m_ctx->UpdateSubresource(m_shadeboost.cb.get(), 0, nullptr, params, 0, 0);
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_shadeboost.ps.get(), m_shadeboost.cb.get(), false);
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, m_shadeboost.ps.get(), m_shadeboost.cb.get(), false);
|
||||
}
|
||||
|
||||
void GSDevice11::SetupVS(VSSelector sel, const GSHWDrawConfig::VSConstantBuffer* cb)
|
||||
@ -2647,7 +2637,7 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
return;
|
||||
}
|
||||
|
||||
StretchRect(colclip_rt ? colclip_rt : config.rt, GSVector4(config.drawarea) / GSVector4(rtsize).xyxy(),
|
||||
DoStretchRect(colclip_rt ? colclip_rt : config.rt, GSVector4(config.drawarea) / GSVector4(rtsize).xyxy(),
|
||||
primid_texture, GSVector4(config.drawarea), m_date.primid_init_ps[static_cast<u8>(config.datm)].get(), nullptr, false);
|
||||
}
|
||||
else if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil ||
|
||||
|
||||
@ -253,6 +253,10 @@ private:
|
||||
D3D11ShaderCache m_shader_cache;
|
||||
std::string m_tfx_source;
|
||||
|
||||
protected:
|
||||
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear) override;
|
||||
|
||||
public:
|
||||
GSDevice11();
|
||||
~GSDevice11() override;
|
||||
@ -298,10 +302,8 @@ public:
|
||||
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
|
||||
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) override;
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear = true);
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY) override;
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear = true);
|
||||
void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear);
|
||||
void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear);
|
||||
void PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, PresentShader shader, float shaderTime, bool linear) override;
|
||||
void UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize) override;
|
||||
void ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM) override;
|
||||
|
||||
@ -1425,30 +1425,17 @@ void GSDevice12::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
|
||||
dTex12->SetState(GSTexture::State::Dirty);
|
||||
}
|
||||
|
||||
void GSDevice12::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
ShaderConvert shader /* = ShaderConvert::COPY */, bool linear /* = true */)
|
||||
void GSDevice12::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear)
|
||||
{
|
||||
pxAssert(HasDepthOutput(shader) == (dTex && dTex->GetType() == GSTexture::Type::DepthStencil));
|
||||
|
||||
GL_INS("StretchRect(%d) {%d,%d} %dx%d -> {%d,%d) %dx%d", shader, int(sRect.left), int(sRect.top),
|
||||
int(sRect.right - sRect.left), int(sRect.bottom - sRect.top), int(dRect.left), int(dRect.top),
|
||||
int(dRect.right - dRect.left), int(dRect.bottom - dRect.top));
|
||||
|
||||
const bool allow_discard = (cms.wrgba == 0xf);
|
||||
const ID3D12PipelineState* state;
|
||||
if (HasVariableWriteMask(shader))
|
||||
state = m_color_copy[GetShaderIndexForMask(shader, cms.wrgba)].get();
|
||||
else
|
||||
state = dTex ? m_convert[static_cast<int>(shader)].get() : m_present[static_cast<int>(shader)].get();
|
||||
DoStretchRect(static_cast<GSTexture12*>(sTex), sRect, static_cast<GSTexture12*>(dTex), dRect,
|
||||
dTex ? m_convert[static_cast<int>(shader)].get() : m_present[static_cast<int>(shader)].get(), linear,
|
||||
ShaderConvertWriteMask(shader) == 0xf);
|
||||
}
|
||||
|
||||
void GSDevice12::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red,
|
||||
bool green, bool blue, bool alpha, ShaderConvert shader)
|
||||
{
|
||||
GL_PUSH("ColorCopy Red:%d Green:%d Blue:%d Alpha:%d", red, green, blue, alpha);
|
||||
|
||||
const u32 index = (red ? 1 : 0) | (green ? 2 : 0) | (blue ? 4 : 0) | (alpha ? 8 : 0);
|
||||
int rta_offset = (shader == ShaderConvert::RTA_CORRECTION) ? 16 : 0;
|
||||
const bool allow_discard = (index == 0xf);
|
||||
DoStretchRect(static_cast<GSTexture12*>(sTex), sRect, static_cast<GSTexture12*>(dTex), dRect,
|
||||
m_color_copy[index + rta_offset].get(), false, allow_discard);
|
||||
state, linear, allow_discard);
|
||||
}
|
||||
|
||||
void GSDevice12::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
@ -1639,10 +1626,10 @@ void GSDevice12::DoMultiStretchRects(
|
||||
SetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
SetUtilityTexture(rects[0].src, rects[0].linear ? m_linear_sampler_cpu : m_point_sampler_cpu);
|
||||
|
||||
pxAssert(shader == ShaderConvert::COPY || shader == ShaderConvert::RTA_CORRECTION || rects[0].wmask.wrgba == 0xf);
|
||||
int rta_bit = (shader == ShaderConvert::RTA_CORRECTION) ? 16 : 0;
|
||||
SetPipeline((rects[0].wmask.wrgba != 0xf) ? m_color_copy[rects[0].wmask.wrgba | rta_bit].get() :
|
||||
m_convert[static_cast<int>(shader)].get());
|
||||
pxAssert(HasVariableWriteMask(shader) || rects[0].wmask.wrgba == 0xf);
|
||||
SetPipeline((rects[0].wmask.wrgba != 0xf) ?
|
||||
m_color_copy[GetShaderIndexForMask(shader, rects[0].wmask.wrgba)].get() :
|
||||
m_convert[static_cast<int>(shader)].get());
|
||||
|
||||
if (ApplyUtilityState())
|
||||
DrawIndexedPrimitive();
|
||||
|
||||
@ -390,6 +390,10 @@ private:
|
||||
|
||||
void DestroyResources();
|
||||
|
||||
protected:
|
||||
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear) override;
|
||||
|
||||
public:
|
||||
GSDevice12();
|
||||
~GSDevice12() override;
|
||||
@ -428,10 +432,6 @@ public:
|
||||
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
|
||||
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
ShaderConvert shader = ShaderConvert::COPY, bool linear = true) override;
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red,
|
||||
bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY) override;
|
||||
void PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
PresentShader shader, float shaderTime, bool linear) override;
|
||||
void UpdateCLUTTexture(
|
||||
|
||||
@ -407,8 +407,6 @@ public:
|
||||
void DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2& ds);
|
||||
/// Copy from a position in sTex to the same position in the currently active render encoder using the given fs pipeline and rect
|
||||
void RenderCopy(GSTexture* sTex, id<MTLRenderPipelineState> pipeline, const GSVector4i& rect);
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) override;
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY) override;
|
||||
void PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, PresentShader shader, float shaderTime, bool linear) override;
|
||||
void DrawMultiStretchRects(const MultiStretchRect* rects, u32 num_rects, GSTexture* dTex, ShaderConvert shader) override;
|
||||
void UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize) override;
|
||||
@ -452,6 +450,10 @@ public:
|
||||
|
||||
void RenderImGui(ImDrawData* data);
|
||||
u32 FrameNo() const { return m_frame; }
|
||||
|
||||
protected:
|
||||
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear) override;
|
||||
};
|
||||
|
||||
static constexpr bool IsCommandBufferCompleted(MTLCommandBufferStatus status)
|
||||
|
||||
@ -1600,33 +1600,21 @@ void GSDeviceMTL::RenderCopy(GSTexture* sTex, id<MTLRenderPipelineState> pipelin
|
||||
g_perfmon.Put(GSPerfMon::DrawCalls, 1);
|
||||
}
|
||||
|
||||
void GSDeviceMTL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
|
||||
void GSDeviceMTL::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear)
|
||||
{ @autoreleasepool {
|
||||
|
||||
pxAssert(linear ? SupportsBilinear(shader) : SupportsNearest(shader));
|
||||
|
||||
id<MTLRenderPipelineState> pipeline = m_convert_pipeline[static_cast<int>(shader)];
|
||||
const LoadAction load_action = (cms.wrgba == 0xf) ? LoadAction::DontCareIfFull : LoadAction::Load;
|
||||
id<MTLRenderPipelineState> pipeline;
|
||||
if (HasVariableWriteMask(shader))
|
||||
pipeline = m_convert_pipeline_copy_mask[GetShaderIndexForMask(shader, cms.wrgba)];
|
||||
else
|
||||
pipeline = m_convert_pipeline[static_cast<int>(shader)];
|
||||
pxAssertRel(pipeline, fmt::format("No pipeline for {}", shaderName(shader)).c_str());
|
||||
|
||||
const LoadAction load_action = (ShaderConvertWriteMask(shader) == 0xf) ? LoadAction::DontCareIfFull : LoadAction::Load;
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, pipeline, linear, load_action, nullptr, 0);
|
||||
}}
|
||||
|
||||
void GSDeviceMTL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader)
|
||||
{ @autoreleasepool {
|
||||
int sel = 0;
|
||||
if (red) sel |= 1;
|
||||
if (green) sel |= 2;
|
||||
if (blue) sel |= 4;
|
||||
if (alpha) sel |= 8;
|
||||
if (shader == ShaderConvert::RTA_CORRECTION) sel |= 16;
|
||||
const int color_sel = sel & 15;
|
||||
|
||||
id<MTLRenderPipelineState> pipeline = m_convert_pipeline_copy_mask[sel];
|
||||
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, pipeline, false, color_sel == 15 ? LoadAction::DontCareIfFull : LoadAction::Load, nullptr, 0);
|
||||
}}
|
||||
|
||||
static_assert(sizeof(DisplayConstantBuffer) == sizeof(GSMTLPresentPSUniform));
|
||||
static_assert(offsetof(DisplayConstantBuffer, SourceRect) == offsetof(GSMTLPresentPSUniform, source_rect));
|
||||
static_assert(offsetof(DisplayConstantBuffer, TargetRect) == offsetof(GSMTLPresentPSUniform, target_rect));
|
||||
@ -1683,9 +1671,9 @@ void GSDeviceMTL::DrawMultiStretchRects(const MultiStretchRect* rects, u32 num_r
|
||||
const u32 end = i * 4;
|
||||
const u32 vertex_count = end - start;
|
||||
const u32 index_count = vertex_count + (vertex_count >> 1); // 6 indices per 4 vertices
|
||||
const int rta_bit = shader == ShaderConvert::RTA_CORRECTION ? 16 : 0;
|
||||
pxAssert(HasVariableWriteMask(shader) || wmask == 0xf);
|
||||
id<MTLRenderPipelineState> new_pipeline = wmask == 0xf ? m_convert_pipeline[static_cast<int>(shader)]
|
||||
: m_convert_pipeline_copy_mask[wmask | rta_bit];
|
||||
: m_convert_pipeline_copy_mask[GetShaderIndexForMask(shader, wmask)];
|
||||
if (new_pipeline != pipeline)
|
||||
{
|
||||
pipeline = new_pipeline;
|
||||
|
||||
@ -1253,7 +1253,7 @@ GSTexture* GSDeviceOGL::InitPrimDateTexture(GSTexture* rt, const GSVector4i& are
|
||||
return nullptr;
|
||||
|
||||
GL_PUSH("PrimID Destination Alpha Clear");
|
||||
StretchRect(rt, GSVector4(area) / GSVector4(rtsize).xyxy(), tex, GSVector4(area), m_date.primid_ps[static_cast<u8>(datm)], false);
|
||||
DoStretchRect(rt, GSVector4(area) / GSVector4(rtsize).xyxy(), tex, GSVector4(area), m_date.primid_ps[static_cast<u8>(datm)], false);
|
||||
return tex;
|
||||
}
|
||||
|
||||
@ -1472,31 +1472,20 @@ void GSDeviceOGL::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r
|
||||
dTex->SetState(GSTexture::State::Dirty);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader, bool linear)
|
||||
void GSDeviceOGL::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
OMColorMaskSelector cms, ShaderConvert shader, bool linear)
|
||||
{
|
||||
pxAssert(dTex->IsDepthStencil() == HasDepthOutput(shader));
|
||||
pxAssert(linear ? SupportsBilinear(shader) : SupportsNearest(shader));
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[(int)shader], false, OMColorMaskSelector(ShaderConvertWriteMask(shader)), linear);
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(shader)], false, cms, linear);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool linear)
|
||||
void GSDeviceOGL::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
const GLProgram& ps, bool linear)
|
||||
{
|
||||
StretchRect(sTex, sRect, dTex, dRect, ps, false, OMColorMaskSelector(), linear);
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, ps, false, OMColorMaskSelector(), linear);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader)
|
||||
{
|
||||
OMColorMaskSelector cms;
|
||||
|
||||
cms.wr = red;
|
||||
cms.wg = green;
|
||||
cms.wb = blue;
|
||||
cms.wa = alpha;
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[(int)shader], false, cms, false);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool alpha_blend, OMColorMaskSelector cms, bool linear)
|
||||
void GSDeviceOGL::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
const GLProgram& ps, bool alpha_blend, OMColorMaskSelector cms, bool linear)
|
||||
{
|
||||
CommitClear(sTex, true);
|
||||
|
||||
@ -1816,12 +1805,12 @@ void GSDeviceOGL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
||||
// Blend with a constant alpha
|
||||
m_merge_obj.ps[1].Bind();
|
||||
m_merge_obj.ps[1].Uniform4fv(0, GSVector4::unorm8(c).v);
|
||||
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[1], true, OMColorMaskSelector(), linear);
|
||||
DoStretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[1], true, OMColorMaskSelector(), linear);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Blend with 2 * input alpha
|
||||
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[0], true, OMColorMaskSelector(), linear);
|
||||
DoStretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[0], true, OMColorMaskSelector(), linear);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1836,7 +1825,7 @@ void GSDeviceOGL::DoInterlace(GSTexture* sTex, const GSVector4& sRect, GSTexture
|
||||
m_interlace.ps[static_cast<int>(shader)].Bind();
|
||||
m_interlace.ps[static_cast<int>(shader)].Uniform4fv(0, cb.ZrH.F32);
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[static_cast<int>(shader)], linear);
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[static_cast<int>(shader)], linear);
|
||||
}
|
||||
|
||||
bool GSDeviceOGL::CompileFXAAProgram()
|
||||
@ -1875,7 +1864,7 @@ void GSDeviceOGL::DoFXAA(GSTexture* sTex, GSTexture* dTex)
|
||||
const GSVector4 sRect(0, 0, 1, 1);
|
||||
const GSVector4 dRect(0, 0, s.x, s.y);
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_fxaa.ps, true);
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, m_fxaa.ps, true);
|
||||
}
|
||||
|
||||
bool GSDeviceOGL::CompileShadeBoostProgram()
|
||||
@ -1909,7 +1898,7 @@ void GSDeviceOGL::DoShadeBoost(GSTexture* sTex, GSTexture* dTex, const float par
|
||||
const GSVector4 sRect(0, 0, 1, 1);
|
||||
const GSVector4 dRect(0, 0, s.x, s.y);
|
||||
|
||||
StretchRect(sTex, sRect, dTex, dRect, m_shadeboost.ps, false);
|
||||
DoStretchRect(sTex, sRect, dTex, dRect, m_shadeboost.ps, false);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSVector4i& bbox)
|
||||
|
||||
@ -265,6 +265,10 @@ private:
|
||||
|
||||
void DrawStretchRect(const GSVector4& sRect, const GSVector4& dRect, const GSVector2i& ds);
|
||||
|
||||
protected:
|
||||
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear) override;
|
||||
|
||||
public:
|
||||
GSDeviceOGL();
|
||||
virtual ~GSDeviceOGL();
|
||||
@ -317,10 +321,8 @@ public:
|
||||
// BlitRect *does* mess with GL state, be sure to re-bind.
|
||||
void BlitRect(GSTexture* sTex, const GSVector4i& r, const GSVector2i& dsize, bool at_origin, bool linear);
|
||||
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, ShaderConvert shader = ShaderConvert::COPY, bool linear = true) override;
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool linear = true);
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY) override;
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool alpha_blend, OMColorMaskSelector cms, bool linear = true);
|
||||
void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool linear);
|
||||
void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GLProgram& ps, bool alpha_blend, OMColorMaskSelector cms, bool linear);
|
||||
void PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, PresentShader shader, float shaderTime, bool linear) override;
|
||||
void UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize) override;
|
||||
void ConvertToIndexedTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, u32 SBW, u32 SPSM, GSTexture* dTex, u32 DBW, u32 DPSM) override;
|
||||
|
||||
@ -2821,31 +2821,16 @@ void GSDeviceVK::CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r,
|
||||
dTexVK->SetState(GSTexture::State::Dirty);
|
||||
}
|
||||
|
||||
void GSDeviceVK::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
ShaderConvert shader /* = ShaderConvert::COPY */, bool linear /* = true */)
|
||||
void GSDeviceVK::DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear)
|
||||
{
|
||||
pxAssert(HasDepthOutput(shader) == (dTex && dTex->GetType() == GSTexture::Type::DepthStencil));
|
||||
pxAssert(linear ? SupportsBilinear(shader) : SupportsNearest(shader));
|
||||
|
||||
GL_INS("StretchRect(%d) {%d,%d} %dx%d -> {%d,%d) %dx%d", shader, int(sRect.left), int(sRect.top),
|
||||
int(sRect.right - sRect.left), int(sRect.bottom - sRect.top), int(dRect.left), int(dRect.top),
|
||||
int(dRect.right - dRect.left), int(dRect.bottom - dRect.top));
|
||||
|
||||
DoStretchRect(static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect,
|
||||
dTex ? m_convert[static_cast<int>(shader)] : m_present[static_cast<int>(shader)], linear,
|
||||
ShaderConvertWriteMask(shader) == 0xf);
|
||||
}
|
||||
|
||||
void GSDeviceVK::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red,
|
||||
bool green, bool blue, bool alpha, ShaderConvert shader)
|
||||
{
|
||||
GL_PUSH("ColorCopy Red:%d Green:%d Blue:%d Alpha:%d", red, green, blue, alpha);
|
||||
|
||||
const u32 index = (red ? 1 : 0) | (green ? 2 : 0) | (blue ? 4 : 0) | (alpha ? 8 : 0);
|
||||
const bool allow_discard = (index == 0xf);
|
||||
int rta_offset = (shader == ShaderConvert::RTA_CORRECTION) ? 16 : 0;
|
||||
DoStretchRect(static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect, m_color_copy[index + rta_offset],
|
||||
false, allow_discard);
|
||||
const bool allow_discard = (cms.wrgba == 0xf);
|
||||
VkPipeline state;
|
||||
if (HasVariableWriteMask(shader))
|
||||
state = m_color_copy[GetShaderIndexForMask(shader, cms.wrgba)];
|
||||
else
|
||||
state = dTex ? m_convert[static_cast<int>(shader)] : m_present[static_cast<int>(shader)];
|
||||
DoStretchRect(static_cast<GSTextureVK*>(sTex), sRect, static_cast<GSTextureVK*>(dTex), dRect, state, linear, allow_discard);
|
||||
}
|
||||
|
||||
void GSDeviceVK::PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
@ -2967,10 +2952,10 @@ void GSDeviceVK::DoMultiStretchRects(
|
||||
BeginRenderPassForStretchRect(dTex, rc, rc, false);
|
||||
SetUtilityTexture(rects[0].src, rects[0].linear ? m_linear_sampler : m_point_sampler);
|
||||
|
||||
pxAssert(shader == ShaderConvert::COPY || shader == ShaderConvert::RTA_CORRECTION || rects[0].wmask.wrgba == 0xf);
|
||||
int rta_bit = (shader == ShaderConvert::RTA_CORRECTION) ? 16 : 0;
|
||||
SetPipeline(
|
||||
(rects[0].wmask.wrgba != 0xf) ? m_color_copy[rects[0].wmask.wrgba | rta_bit] : m_convert[static_cast<int>(shader)]);
|
||||
pxAssert(HasVariableWriteMask(shader) || rects[0].wmask.wrgba == 0xf);
|
||||
SetPipeline((rects[0].wmask.wrgba != 0xf) ?
|
||||
m_color_copy[GetShaderIndexForMask(shader, rects[0].wmask.wrgba)] :
|
||||
m_convert[static_cast<int>(shader)]);
|
||||
|
||||
if (ApplyUtilityState())
|
||||
DrawIndexedPrimitive();
|
||||
|
||||
@ -470,6 +470,10 @@ private:
|
||||
|
||||
void DestroyResources();
|
||||
|
||||
protected:
|
||||
virtual void DoStretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
GSHWDrawConfig::ColorMaskSelector cms, ShaderConvert shader, bool linear) override;
|
||||
|
||||
public:
|
||||
GSDeviceVK();
|
||||
~GSDeviceVK() override;
|
||||
@ -525,10 +529,6 @@ public:
|
||||
|
||||
void CopyRect(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, u32 destX, u32 destY) override;
|
||||
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
ShaderConvert shader = ShaderConvert::COPY, bool linear = true) override;
|
||||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red,
|
||||
bool green, bool blue, bool alpha, ShaderConvert shader = ShaderConvert::COPY) override;
|
||||
void PresentRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect,
|
||||
PresentShader shader, float shaderTime, bool linear) override;
|
||||
void DrawMultiStretchRects(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user