mirror of
https://github.com/azahar-emu/azahar
synced 2025-11-15 19:39:58 +01:00
Implement framebuffer vertical flip flag (#699)
* Implement framebuffer vertical flip flag * Make VerticalMirror const
This commit is contained in:
parent
007b809ad7
commit
0eb4a71720
@ -1,4 +1,8 @@
|
|||||||
// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
// Copyright 2013 Dolphin Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -23,6 +27,12 @@ struct Rectangle {
|
|||||||
constexpr Rectangle(T left, T top, T right, T bottom)
|
constexpr Rectangle(T left, T top, T right, T bottom)
|
||||||
: left(left), top(top), right(right), bottom(bottom) {}
|
: left(left), top(top), right(right), bottom(bottom) {}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
operator Rectangle<U>() const {
|
||||||
|
return Rectangle<U>{static_cast<U>(left), static_cast<U>(top), static_cast<U>(right),
|
||||||
|
static_cast<U>(bottom)};
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr bool operator==(const Rectangle<T>& rhs) const {
|
[[nodiscard]] constexpr bool operator==(const Rectangle<T>& rhs) const {
|
||||||
return (left == rhs.left) && (top == rhs.top) && (right == rhs.right) &&
|
return (left == rhs.left) && (top == rhs.top) && (right == rhs.right) &&
|
||||||
(bottom == rhs.bottom);
|
(bottom == rhs.bottom);
|
||||||
@ -55,6 +65,9 @@ struct Rectangle {
|
|||||||
return Rectangle{left, top, static_cast<T>(left + GetWidth() * s),
|
return Rectangle{left, top, static_cast<T>(left + GetWidth() * s),
|
||||||
static_cast<T>(top + GetHeight() * s)};
|
static_cast<T>(top + GetHeight() * s)};
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] Rectangle<T> VerticalMirror(T ref_height) const {
|
||||||
|
return Rectangle{left, ref_height - bottom, right, ref_height - top};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2017 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -233,6 +233,7 @@ struct FramebufferRegs {
|
|||||||
// GetWidth() and GetHeight() instead.
|
// GetWidth() and GetHeight() instead.
|
||||||
BitField<0, 11, u32> width;
|
BitField<0, 11, u32> width;
|
||||||
BitField<12, 10, u32> height;
|
BitField<12, 10, u32> height;
|
||||||
|
BitField<24, 1, u32> flip;
|
||||||
};
|
};
|
||||||
|
|
||||||
INSERT_PADDING_WORDS(0x1);
|
INSERT_PADDING_WORDS(0x1);
|
||||||
@ -251,6 +252,10 @@ struct FramebufferRegs {
|
|||||||
inline u32 GetHeight() const {
|
inline u32 GetHeight() const {
|
||||||
return height + 1;
|
return height + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool IsFlipped() const {
|
||||||
|
return !flip.Value();
|
||||||
|
}
|
||||||
} framebuffer;
|
} framebuffer;
|
||||||
|
|
||||||
// Returns the number of bytes in the specified depth format
|
// Returns the number of bytes in the specified depth format
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2017 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -29,11 +29,13 @@ struct RasterizerRegs {
|
|||||||
|
|
||||||
BitField<0, 24, u32> viewport_size_x;
|
BitField<0, 24, u32> viewport_size_x;
|
||||||
|
|
||||||
INSERT_PADDING_WORDS(0x1);
|
BitField<1, 31, u32> viewport_size_x_inv;
|
||||||
|
|
||||||
BitField<0, 24, u32> viewport_size_y;
|
BitField<0, 24, u32> viewport_size_y;
|
||||||
|
|
||||||
INSERT_PADDING_WORDS(0x3);
|
BitField<1, 31, u32> viewport_size_y_inv;
|
||||||
|
|
||||||
|
INSERT_PADDING_WORDS(0x2);
|
||||||
|
|
||||||
BitField<0, 1, u32> clip_enable;
|
BitField<0, 1, u32> clip_enable;
|
||||||
BitField<0, 24, u32> clip_coef[4]; // float24
|
BitField<0, 24, u32> clip_coef[4]; // float24
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr u32 MASK = (1 << (M + E + 1)) - 1;
|
static constexpr u32 MASK = static_cast<u32>(1 << (M + E + 1)) - 1;
|
||||||
static constexpr u32 MANTISSA_MASK = (1 << M) - 1;
|
static constexpr u32 MANTISSA_MASK = (1 << M) - 1;
|
||||||
static constexpr u32 EXPONENT_MASK = (1 << E) - 1;
|
static constexpr u32 EXPONENT_MASK = (1 << E) - 1;
|
||||||
|
|
||||||
@ -153,6 +153,7 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using f31 = Pica::Float<23, 7>;
|
||||||
using f24 = Pica::Float<16, 7>;
|
using f24 = Pica::Float<16, 7>;
|
||||||
using f20 = Pica::Float<12, 7>;
|
using f20 = Pica::Float<12, 7>;
|
||||||
using f16 = Pica::Float<10, 5>;
|
using f16 = Pica::Float<10, 5>;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2023 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -846,7 +846,7 @@ void RasterizerAccelerated::SyncTextureBorderColor(int tex_index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerAccelerated::SyncClipPlane() {
|
void RasterizerAccelerated::SyncClipPlane() {
|
||||||
const u32 enable_clip1 = regs.rasterizer.clip_enable != 0;
|
const bool enable_clip1 = regs.rasterizer.clip_enable != 0;
|
||||||
const auto raw_clip_coef = regs.rasterizer.GetClipCoef();
|
const auto raw_clip_coef = regs.rasterizer.GetClipCoef();
|
||||||
const Common::Vec4f new_clip_coef = {raw_clip_coef.x.ToFloat32(), raw_clip_coef.y.ToFloat32(),
|
const Common::Vec4f new_clip_coef = {raw_clip_coef.x.ToFloat32(), raw_clip_coef.y.ToFloat32(),
|
||||||
raw_clip_coef.z.ToFloat32(), raw_clip_coef.w.ToFloat32()};
|
raw_clip_coef.z.ToFloat32(), raw_clip_coef.w.ToFloat32()};
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2023 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -65,13 +65,18 @@ template <class T>
|
|||||||
class FramebufferHelper {
|
class FramebufferHelper {
|
||||||
public:
|
public:
|
||||||
explicit FramebufferHelper(RasterizerCache<T>* res_cache_, typename T::Framebuffer* fb_,
|
explicit FramebufferHelper(RasterizerCache<T>* res_cache_, typename T::Framebuffer* fb_,
|
||||||
const Pica::RasterizerRegs& regs,
|
bool flip_rect, const Pica::RasterizerRegs& regs,
|
||||||
Common::Rectangle<u32> surfaces_rect)
|
Common::Rectangle<u32> surfaces_rect)
|
||||||
: res_cache{res_cache_}, fb{fb_} {
|
: res_cache{res_cache_}, fb{fb_} {
|
||||||
const u32 res_scale = fb->Scale();
|
const u32 res_scale = fb->Scale();
|
||||||
|
const u32 height = surfaces_rect.GetHeight() / res_scale;
|
||||||
|
|
||||||
// Determine the draw rectangle (render area + scissor)
|
// Determine the draw rectangle (render area + scissor)
|
||||||
const Common::Rectangle viewport_rect = regs.GetViewportRect();
|
Common::Rectangle viewport_rect = regs.GetViewportRect();
|
||||||
|
if (flip_rect) {
|
||||||
|
viewport_rect = viewport_rect.VerticalMirror(height);
|
||||||
|
}
|
||||||
|
|
||||||
draw_rect.left =
|
draw_rect.left =
|
||||||
std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.left * res_scale,
|
std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.left * res_scale,
|
||||||
surfaces_rect.left, surfaces_rect.right);
|
surfaces_rect.left, surfaces_rect.right);
|
||||||
@ -103,6 +108,10 @@ public:
|
|||||||
static_cast<s32>(surfaces_rect.left + (regs.scissor_test.x2 + 1) * res_scale);
|
static_cast<s32>(surfaces_rect.left + (regs.scissor_test.x2 + 1) * res_scale);
|
||||||
scissor_rect.top =
|
scissor_rect.top =
|
||||||
static_cast<s32>(surfaces_rect.bottom + (regs.scissor_test.y2 + 1) * res_scale);
|
static_cast<s32>(surfaces_rect.bottom + (regs.scissor_test.y2 + 1) * res_scale);
|
||||||
|
|
||||||
|
if (flip_rect) {
|
||||||
|
scissor_rect = scissor_rect.VerticalMirror(height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~FramebufferHelper() {
|
~FramebufferHelper() {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright Citra Emulator Project / Lime3DS Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -765,7 +765,8 @@ FramebufferHelper<T> RasterizerCache<T>::GetFramebufferSurfaces(bool using_color
|
|||||||
it->second = slot_framebuffers.insert(runtime, fb_params, color_surface, depth_surface);
|
it->second = slot_framebuffers.insert(runtime, fb_params, color_surface, depth_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FramebufferHelper<T>{this, &slot_framebuffers[it->second], regs.rasterizer, fb_rect};
|
return FramebufferHelper<T>{this, &slot_framebuffers[it->second],
|
||||||
|
regs.framebuffer.framebuffer.IsFlipped(), regs.rasterizer, fb_rect};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -409,6 +409,12 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) {
|
|||||||
state.viewport.width = static_cast<GLsizei>(viewport.width);
|
state.viewport.width = static_cast<GLsizei>(viewport.width);
|
||||||
state.viewport.height = static_cast<GLsizei>(viewport.height);
|
state.viewport.height = static_cast<GLsizei>(viewport.height);
|
||||||
|
|
||||||
|
// If the framebuffer is flipped, request vertex shader to flip vertex y
|
||||||
|
const bool is_flipped = regs.framebuffer.framebuffer.IsFlipped();
|
||||||
|
vs_uniform_block_data.dirty |= vs_uniform_block_data.data.flip_viewport != is_flipped;
|
||||||
|
vs_uniform_block_data.data.flip_viewport = is_flipped;
|
||||||
|
state.cull.mode = is_flipped && state.cull.enabled ? GL_FRONT : GL_BACK;
|
||||||
|
|
||||||
// Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect.
|
// Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect.
|
||||||
// Enable scissor test to prevent drawing outside of the framebuffer region
|
// Enable scissor test to prevent drawing outside of the framebuffer region
|
||||||
const auto draw_rect = fb_helper.DrawRect();
|
const auto draw_rect = fb_helper.DrawRect();
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2023 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -177,13 +177,13 @@ inline vk::PrimitiveTopology PrimitiveTopology(Pica::PipelineRegs::TriangleTopol
|
|||||||
return vk::PrimitiveTopology::eTriangleList;
|
return vk::PrimitiveTopology::eTriangleList;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline vk::CullModeFlags CullMode(Pica::RasterizerRegs::CullMode mode) {
|
inline vk::CullModeFlags CullMode(Pica::RasterizerRegs::CullMode mode, bool flip_viewport) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case Pica::RasterizerRegs::CullMode::KeepAll:
|
case Pica::RasterizerRegs::CullMode::KeepAll:
|
||||||
return vk::CullModeFlagBits::eNone;
|
return vk::CullModeFlagBits::eNone;
|
||||||
case Pica::RasterizerRegs::CullMode::KeepClockWise:
|
case Pica::RasterizerRegs::CullMode::KeepClockWise:
|
||||||
case Pica::RasterizerRegs::CullMode::KeepCounterClockWise:
|
case Pica::RasterizerRegs::CullMode::KeepCounterClockWise:
|
||||||
return vk::CullModeFlagBits::eBack;
|
return flip_viewport ? vk::CullModeFlagBits::eFront : vk::CullModeFlagBits::eBack;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE_MSG("Unknown cull mode {}", mode);
|
UNREACHABLE_MSG("Unknown cull mode {}", mode);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2023 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -147,7 +147,8 @@ bool GraphicsPipeline::Build(bool fail_on_compile_required) {
|
|||||||
const vk::PipelineRasterizationStateCreateInfo raster_state = {
|
const vk::PipelineRasterizationStateCreateInfo raster_state = {
|
||||||
.depthClampEnable = false,
|
.depthClampEnable = false,
|
||||||
.rasterizerDiscardEnable = false,
|
.rasterizerDiscardEnable = false,
|
||||||
.cullMode = PicaToVK::CullMode(info.rasterization.cull_mode),
|
.cullMode =
|
||||||
|
PicaToVK::CullMode(info.rasterization.cull_mode, info.rasterization.flip_viewport),
|
||||||
.frontFace = PicaToVK::FrontFace(info.rasterization.cull_mode),
|
.frontFace = PicaToVK::FrontFace(info.rasterization.cull_mode),
|
||||||
.depthBiasEnable = false,
|
.depthBiasEnable = false,
|
||||||
.lineWidth = 1.0f,
|
.lineWidth = 1.0f,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2023 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -54,6 +54,7 @@ union RasterizationState {
|
|||||||
u8 value = 0;
|
u8 value = 0;
|
||||||
BitField<0, 2, Pica::PipelineRegs::TriangleTopology> topology;
|
BitField<0, 2, Pica::PipelineRegs::TriangleTopology> topology;
|
||||||
BitField<4, 2, Pica::RasterizerRegs::CullMode> cull_mode;
|
BitField<4, 2, Pica::RasterizerRegs::CullMode> cull_mode;
|
||||||
|
BitField<6, 1, u8> flip_viewport;
|
||||||
};
|
};
|
||||||
|
|
||||||
union DepthStencilState {
|
union DepthStencilState {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2023 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -271,8 +271,12 @@ bool PipelineCache::BindPipeline(const PipelineInfo& info, bool wait_built) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (instance.IsExtendedDynamicStateSupported()) {
|
if (instance.IsExtendedDynamicStateSupported()) {
|
||||||
if (rasterization.cull_mode != current_rasterization.cull_mode || is_dirty) {
|
const bool needs_flip =
|
||||||
cmdbuf.setCullModeEXT(PicaToVK::CullMode(rasterization.cull_mode));
|
rasterization.flip_viewport != current_rasterization.flip_viewport;
|
||||||
|
if (rasterization.cull_mode != current_rasterization.cull_mode || needs_flip ||
|
||||||
|
is_dirty) {
|
||||||
|
cmdbuf.setCullModeEXT(
|
||||||
|
PicaToVK::CullMode(rasterization.cull_mode, rasterization.flip_viewport));
|
||||||
cmdbuf.setFrontFaceEXT(PicaToVK::FrontFace(rasterization.cull_mode));
|
cmdbuf.setFrontFaceEXT(PicaToVK::FrontFace(rasterization.cull_mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2023 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -509,6 +509,12 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
|
|||||||
shader_dirty = false;
|
shader_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the framebuffer is flipped, request to also flip vulkan viewport
|
||||||
|
const bool is_flipped = regs.framebuffer.framebuffer.IsFlipped();
|
||||||
|
vs_uniform_block_data.dirty |= vs_uniform_block_data.data.flip_viewport != is_flipped;
|
||||||
|
vs_uniform_block_data.data.flip_viewport = is_flipped;
|
||||||
|
pipeline_info.rasterization.flip_viewport.Assign(is_flipped);
|
||||||
|
|
||||||
// Sync the LUTs within the texture buffer
|
// Sync the LUTs within the texture buffer
|
||||||
SyncAndUploadLUTs();
|
SyncAndUploadLUTs();
|
||||||
SyncAndUploadLUTsLF();
|
SyncAndUploadLUTsLF();
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2023 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -37,6 +37,7 @@ layout (set = 0, binding = 1, std140) uniform vs_data {
|
|||||||
layout (binding = 1, std140) uniform vs_data {
|
layout (binding = 1, std140) uniform vs_data {
|
||||||
#endif
|
#endif
|
||||||
bool enable_clip1;
|
bool enable_clip1;
|
||||||
|
bool flip_viewport;
|
||||||
vec4 clip_coef;
|
vec4 clip_coef;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -123,6 +124,9 @@ void main() {
|
|||||||
normquat = vert_normquat;
|
normquat = vert_normquat;
|
||||||
view = vert_view;
|
view = vert_view;
|
||||||
vec4 vtx_pos = SanitizeVertex(vert_position);
|
vec4 vtx_pos = SanitizeVertex(vert_position);
|
||||||
|
if (flip_viewport) {
|
||||||
|
vtx_pos.y = -vtx_pos.y;
|
||||||
|
}
|
||||||
gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);
|
gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);
|
||||||
)";
|
)";
|
||||||
if (use_clip_planes) {
|
if (use_clip_planes) {
|
||||||
@ -238,6 +242,9 @@ std::string GenerateVertexShader(const ShaderSetup& setup, const PicaVSConfig& c
|
|||||||
semantic(VSOutputAttributes::POSITION_Z) + ", " +
|
semantic(VSOutputAttributes::POSITION_Z) + ", " +
|
||||||
semantic(VSOutputAttributes::POSITION_W) + ");\n";
|
semantic(VSOutputAttributes::POSITION_W) + ");\n";
|
||||||
out += " vtx_pos = SanitizeVertex(vtx_pos);\n";
|
out += " vtx_pos = SanitizeVertex(vtx_pos);\n";
|
||||||
|
out += " if (flip_viewport) {\n";
|
||||||
|
out += " vtx_pos.y = -vtx_pos.y;\n";
|
||||||
|
out += " }\n";
|
||||||
out += " gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);\n";
|
out += " gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);\n";
|
||||||
if (config.state.use_clip_planes) {
|
if (config.state.use_clip_planes) {
|
||||||
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
|
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
|
||||||
@ -332,6 +339,9 @@ struct Vertex {
|
|||||||
semantic(VSOutputAttributes::POSITION_Z) + ", " +
|
semantic(VSOutputAttributes::POSITION_Z) + ", " +
|
||||||
semantic(VSOutputAttributes::POSITION_W) + ");\n";
|
semantic(VSOutputAttributes::POSITION_W) + ");\n";
|
||||||
out += " vtx_pos = SanitizeVertex(vtx_pos);\n";
|
out += " vtx_pos = SanitizeVertex(vtx_pos);\n";
|
||||||
|
out += " if (flip_viewport) {\n";
|
||||||
|
out += " vtx_pos.y = -vtx_pos.y;\n";
|
||||||
|
out += " }\n";
|
||||||
out += " gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);\n";
|
out += " gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);\n";
|
||||||
if (state.use_clip_planes) {
|
if (state.use_clip_planes) {
|
||||||
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
|
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2023 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -86,7 +86,8 @@ struct PicaUniformsData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct VSUniformData {
|
struct VSUniformData {
|
||||||
u32 enable_clip1;
|
alignas(4) bool enable_clip1;
|
||||||
|
alignas(4) bool flip_viewport;
|
||||||
alignas(16) Common::Vec4f clip_coef;
|
alignas(16) Common::Vec4f clip_coef;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(VSUniformData) == 32,
|
static_assert(sizeof(VSUniformData) == 32,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user