diff --git a/Common/GPU/D3D9/thin3d_d3d9.cpp b/Common/GPU/D3D9/thin3d_d3d9.cpp index ff14902417e4..3773a4e28817 100644 --- a/Common/GPU/D3D9/thin3d_d3d9.cpp +++ b/Common/GPU/D3D9/thin3d_d3d9.cpp @@ -775,6 +775,7 @@ D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, ID caps_.framebufferSeparateDepthCopySupported = false; caps_.texture3DSupported = true; caps_.fragmentShaderDepthWriteSupported = true; + caps_.requiresHalfPixelOffset = true; caps_.fragmentShaderStencilWriteSupported = false; caps_.blendMinMaxSupported = true; caps_.isTilingGPU = false; diff --git a/Common/GPU/ShaderWriter.h b/Common/GPU/ShaderWriter.h index b10c3169b001..937de6a9f2df 100644 --- a/Common/GPU/ShaderWriter.h +++ b/Common/GPU/ShaderWriter.h @@ -84,6 +84,7 @@ class ShaderWriter { void ConstFloat(const char *name, float value); void SetFlags(ShaderWriterFlags flags) { flags_ |= flags; } + ShaderWriterFlags Flags() const { return flags_; } void SetTexBindingBase(int base) { texBindingBase_ = base; } ShaderWriter &SampleTexture2D(const char *texName, const char *uv); diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index fb6f402e49c4..5f66db4a0382 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -608,6 +608,7 @@ struct DeviceCaps { bool sampleRateShadingSupported; bool setMaxFrameLatencySupported; bool textureSwizzleSupported; + bool requiresHalfPixelOffset; bool verySlowShaderCompiler; diff --git a/GPU/Common/Draw2D.cpp b/GPU/Common/Draw2D.cpp index ebf9dec6838a..927660252ddc 100644 --- a/GPU/Common/Draw2D.cpp +++ b/GPU/Common/Draw2D.cpp @@ -317,11 +317,17 @@ void Draw2D::Blit(Draw2DPipeline *pipeline, float srcX1, float srcY1, float srcX float dY = 1.0f / (float)dstHeight; float sX = 1.0f / (float)srcWidth; float sY = 1.0f / (float)srcHeight; + float xOffset = 0.0f; + float yOffset = 0.0f; + if (draw_->GetDeviceCaps().requiresHalfPixelOffset) { + xOffset = -dX * 0.5f; + yOffset = -dY * 0.5f; + } Draw2DVertex vtx[4] = { - { -1.0f + 2.0f * dX * dstX1, -(1.0f - 2.0f * dY * dstY1), sX * srcX1, sY * srcY1 }, - { -1.0f + 2.0f * dX * dstX2, -(1.0f - 2.0f * dY * dstY1), sX * srcX2, sY * srcY1 }, - { -1.0f + 2.0f * dX * dstX1, -(1.0f - 2.0f * dY * dstY2), sX * srcX1, sY * srcY2 }, - { -1.0f + 2.0f * dX * dstX2, -(1.0f - 2.0f * dY * dstY2), sX * srcX2, sY * srcY2 }, + { -1.0f + 2.0f * dX * dstX1 + xOffset, -(1.0f - 2.0f * dY * dstY1) + yOffset, sX * srcX1, sY * srcY1 }, + { -1.0f + 2.0f * dX * dstX2 + xOffset, -(1.0f - 2.0f * dY * dstY1) + yOffset, sX * srcX2, sY * srcY1 }, + { -1.0f + 2.0f * dX * dstX1 + xOffset, -(1.0f - 2.0f * dY * dstY2) + yOffset, sX * srcX1, sY * srcY2 }, + { -1.0f + 2.0f * dX * dstX2 + xOffset, -(1.0f - 2.0f * dY * dstY2) + yOffset, sX * srcX2, sY * srcY2 }, }; DrawStrip2D(nullptr, vtx, 4, linear, pipeline, srcWidth, srcHeight, scaleFactor);