GPU/HW: Use GSVector instead of Rectangle
This commit is contained in:
parent
ef152c47a6
commit
9ef7e8c5d0
|
@ -21,6 +21,7 @@
|
||||||
#include "common/align.h"
|
#include "common/align.h"
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
#include "common/file_system.h"
|
#include "common/file_system.h"
|
||||||
|
#include "common/gsvector_formatter.h"
|
||||||
#include "common/heap_array.h"
|
#include "common/heap_array.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/path.h"
|
#include "common/path.h"
|
||||||
|
@ -351,6 +352,7 @@ bool GPU::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_displ
|
||||||
m_draw_mode.texture_page_changed = true;
|
m_draw_mode.texture_page_changed = true;
|
||||||
m_draw_mode.texture_window_changed = true;
|
m_draw_mode.texture_window_changed = true;
|
||||||
m_drawing_area_changed = true;
|
m_drawing_area_changed = true;
|
||||||
|
SetClampedDrawingArea();
|
||||||
UpdateDMARequest();
|
UpdateDMARequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1089,12 +1091,11 @@ void GPU::UpdateCommandTickEvent()
|
||||||
void GPU::ConvertScreenCoordinatesToDisplayCoordinates(float window_x, float window_y, float* display_x,
|
void GPU::ConvertScreenCoordinatesToDisplayCoordinates(float window_x, float window_y, float* display_x,
|
||||||
float* display_y) const
|
float* display_y) const
|
||||||
{
|
{
|
||||||
const Common::Rectangle<s32> draw_rc =
|
const GSVector4i draw_rc = CalculateDrawRect(g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight(), true);
|
||||||
CalculateDrawRect(g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight());
|
|
||||||
|
|
||||||
// convert coordinates to active display region, then to full display region
|
// convert coordinates to active display region, then to full display region
|
||||||
const float scaled_display_x = (window_x - static_cast<float>(draw_rc.left)) / static_cast<float>(draw_rc.GetWidth());
|
const float scaled_display_x = (window_x - static_cast<float>(draw_rc.left)) / static_cast<float>(draw_rc.width());
|
||||||
const float scaled_display_y = (window_y - static_cast<float>(draw_rc.top)) / static_cast<float>(draw_rc.GetHeight());
|
const float scaled_display_y = (window_y - static_cast<float>(draw_rc.top)) / static_cast<float>(draw_rc.height());
|
||||||
|
|
||||||
// scale back to internal resolution
|
// scale back to internal resolution
|
||||||
*display_x = scaled_display_x * static_cast<float>(m_crtc_state.display_width);
|
*display_x = scaled_display_x * static_cast<float>(m_crtc_state.display_width);
|
||||||
|
@ -1632,6 +1633,21 @@ void GPU::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 he
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPU::SetClampedDrawingArea()
|
||||||
|
{
|
||||||
|
if (!IsDrawingAreaIsValid()) [[unlikely]]
|
||||||
|
{
|
||||||
|
m_clamped_drawing_area = GSVector4i::zero();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 right = std::min(m_drawing_area.right + 1, static_cast<u32>(VRAM_WIDTH));
|
||||||
|
const u32 left = std::min(m_drawing_area.left, std::min(m_drawing_area.right, VRAM_WIDTH - 1));
|
||||||
|
const u32 bottom = std::min(m_drawing_area.bottom + 1, static_cast<u32>(VRAM_HEIGHT));
|
||||||
|
const u32 top = std::min(m_drawing_area.top, std::min(m_drawing_area.bottom, VRAM_HEIGHT - 1));
|
||||||
|
m_clamped_drawing_area = GSVector4i(left, top, right, bottom);
|
||||||
|
}
|
||||||
|
|
||||||
void GPU::SetDrawMode(u16 value)
|
void GPU::SetDrawMode(u16 value)
|
||||||
{
|
{
|
||||||
GPUDrawModeReg new_mode_reg{static_cast<u16>(value & GPUDrawModeReg::MASK)};
|
GPUDrawModeReg new_mode_reg{static_cast<u16>(value & GPUDrawModeReg::MASK)};
|
||||||
|
@ -1917,16 +1933,15 @@ bool GPU::PresentDisplay()
|
||||||
{
|
{
|
||||||
FlushRender();
|
FlushRender();
|
||||||
|
|
||||||
const Common::Rectangle<s32> draw_rect =
|
const GSVector4i draw_rect = m_display_texture ?
|
||||||
m_display_texture ? CalculateDrawRect(g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight()) :
|
CalculateDrawRect(g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight()) :
|
||||||
Common::Rectangle<s32>();
|
GSVector4i::zero();
|
||||||
return RenderDisplay(nullptr, draw_rect, !g_settings.debugging.show_vram);
|
return RenderDisplay(nullptr, draw_rect, !g_settings.debugging.show_vram);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_rect, bool postfx)
|
bool GPU::RenderDisplay(GPUTexture* target, const GSVector4i draw_rect, bool postfx)
|
||||||
{
|
{
|
||||||
GL_SCOPE_FMT("RenderDisplay: {}x{} at {},{}", draw_rect.GetWidth(), draw_rect.GetHeight(), draw_rect.left,
|
GL_SCOPE_FMT("RenderDisplay: {}", draw_rect);
|
||||||
draw_rect.top);
|
|
||||||
|
|
||||||
if (m_display_texture)
|
if (m_display_texture)
|
||||||
m_display_texture->MakeReadyForSampling();
|
m_display_texture->MakeReadyForSampling();
|
||||||
|
@ -1947,8 +1962,8 @@ bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_r
|
||||||
|
|
||||||
// Now we can apply the post chain.
|
// Now we can apply the post chain.
|
||||||
GPUTexture* post_output_texture = PostProcessing::InternalChain.GetOutputTexture();
|
GPUTexture* post_output_texture = PostProcessing::InternalChain.GetOutputTexture();
|
||||||
if (PostProcessing::InternalChain.Apply(display_texture, m_display_depth_buffer, post_output_texture, 0, 0,
|
if (PostProcessing::InternalChain.Apply(display_texture, m_display_depth_buffer, post_output_texture,
|
||||||
display_texture_view_width, display_texture_view_height,
|
GSVector4i(0, 0, display_texture_view_width, display_texture_view_height),
|
||||||
display_texture_view_width, display_texture_view_height,
|
display_texture_view_width, display_texture_view_height,
|
||||||
m_crtc_state.display_width, m_crtc_state.display_height))
|
m_crtc_state.display_width, m_crtc_state.display_height))
|
||||||
{
|
{
|
||||||
|
@ -1966,7 +1981,7 @@ bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_r
|
||||||
(postfx && PostProcessing::DisplayChain.IsActive() && !g_gpu_device->GetWindowInfo().IsSurfaceless() &&
|
(postfx && PostProcessing::DisplayChain.IsActive() && !g_gpu_device->GetWindowInfo().IsSurfaceless() &&
|
||||||
hdformat != GPUTexture::Format::Unknown && target_width > 0 && target_height > 0 &&
|
hdformat != GPUTexture::Format::Unknown && target_width > 0 && target_height > 0 &&
|
||||||
PostProcessing::DisplayChain.CheckTargets(hdformat, target_width, target_height));
|
PostProcessing::DisplayChain.CheckTargets(hdformat, target_width, target_height));
|
||||||
const Common::Rectangle<s32> real_draw_rect =
|
const GSVector4i real_draw_rect =
|
||||||
g_gpu_device->UsesLowerLeftOrigin() ? GPUDevice::FlipToLowerLeft(draw_rect, target_height) : draw_rect;
|
g_gpu_device->UsesLowerLeftOrigin() ? GPUDevice::FlipToLowerLeft(draw_rect, target_height) : draw_rect;
|
||||||
if (really_postfx)
|
if (really_postfx)
|
||||||
{
|
{
|
||||||
|
@ -2009,11 +2024,9 @@ bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_r
|
||||||
{
|
{
|
||||||
texture_filter_linear = true;
|
texture_filter_linear = true;
|
||||||
uniforms.params[0] = std::max(
|
uniforms.params[0] = std::max(
|
||||||
std::floor(static_cast<float>(draw_rect.GetWidth()) / static_cast<float>(m_display_texture_view_width)),
|
std::floor(static_cast<float>(draw_rect.width()) / static_cast<float>(m_display_texture_view_width)), 1.0f);
|
||||||
1.0f);
|
|
||||||
uniforms.params[1] = std::max(
|
uniforms.params[1] = std::max(
|
||||||
std::floor(static_cast<float>(draw_rect.GetHeight()) / static_cast<float>(m_display_texture_view_height)),
|
std::floor(static_cast<float>(draw_rect.height()) / static_cast<float>(m_display_texture_view_height)), 1.0f);
|
||||||
1.0f);
|
|
||||||
uniforms.params[2] = 0.5f - 0.5f / uniforms.params[0];
|
uniforms.params[2] = 0.5f - 0.5f / uniforms.params[0];
|
||||||
uniforms.params[3] = 0.5f - 0.5f / uniforms.params[1];
|
uniforms.params[3] = 0.5f - 0.5f / uniforms.params[1];
|
||||||
}
|
}
|
||||||
|
@ -2048,8 +2061,7 @@ bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_r
|
||||||
uniforms.src_size[3] = rcp_height;
|
uniforms.src_size[3] = rcp_height;
|
||||||
g_gpu_device->PushUniformBuffer(&uniforms, sizeof(uniforms));
|
g_gpu_device->PushUniformBuffer(&uniforms, sizeof(uniforms));
|
||||||
|
|
||||||
g_gpu_device->SetViewportAndScissor(real_draw_rect.left, real_draw_rect.top, real_draw_rect.GetWidth(),
|
g_gpu_device->SetViewportAndScissor(real_draw_rect);
|
||||||
real_draw_rect.GetHeight());
|
|
||||||
g_gpu_device->Draw(3, 0);
|
g_gpu_device->Draw(3, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2066,14 +2078,11 @@ bool GPU::RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_r
|
||||||
const s32 orig_height = static_cast<s32>(std::ceil(static_cast<float>(m_crtc_state.display_height) * upscale_y));
|
const s32 orig_height = static_cast<s32>(std::ceil(static_cast<float>(m_crtc_state.display_height) * upscale_y));
|
||||||
|
|
||||||
return PostProcessing::DisplayChain.Apply(PostProcessing::DisplayChain.GetInputTexture(), nullptr, target,
|
return PostProcessing::DisplayChain.Apply(PostProcessing::DisplayChain.GetInputTexture(), nullptr, target,
|
||||||
real_draw_rect.left, real_draw_rect.top, real_draw_rect.GetWidth(),
|
real_draw_rect, orig_width, orig_height, m_crtc_state.display_width,
|
||||||
real_draw_rect.GetHeight(), orig_width, orig_height,
|
m_crtc_state.display_height);
|
||||||
m_crtc_state.display_width, m_crtc_state.display_height);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU::DestroyDeinterlaceTextures()
|
void GPU::DestroyDeinterlaceTextures()
|
||||||
|
@ -2303,8 +2312,7 @@ bool GPU::ApplyChromaSmoothing()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Rectangle<s32> GPU::CalculateDrawRect(s32 window_width, s32 window_height,
|
GSVector4i GPU::CalculateDrawRect(s32 window_width, s32 window_height, bool apply_aspect_ratio /* = true */) const
|
||||||
bool apply_aspect_ratio /* = true */) const
|
|
||||||
{
|
{
|
||||||
const bool integer_scale = (g_settings.display_scaling == DisplayScalingMode::NearestInteger ||
|
const bool integer_scale = (g_settings.display_scaling == DisplayScalingMode::NearestInteger ||
|
||||||
g_settings.display_scaling == DisplayScalingMode::BlinearInteger);
|
g_settings.display_scaling == DisplayScalingMode::BlinearInteger);
|
||||||
|
@ -2401,9 +2409,11 @@ Common::Rectangle<s32> GPU::CalculateDrawRect(s32 window_width, s32 window_heigh
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This should be a float rectangle. But because GL is lame, it only has integer viewports...
|
// TODO: This should be a float rectangle. But because GL is lame, it only has integer viewports...
|
||||||
return Common::Rectangle<s32>::FromExtents(
|
const s32 left = static_cast<s32>(active_left * scale + left_padding);
|
||||||
static_cast<s32>(active_left * scale + left_padding), static_cast<s32>(active_top * scale + top_padding),
|
const s32 top = static_cast<s32>(active_top * scale + top_padding);
|
||||||
static_cast<s32>(active_width * scale), static_cast<s32>(active_height * scale));
|
const s32 right = left + static_cast<s32>(active_width * scale);
|
||||||
|
const s32 bottom = top + static_cast<s32>(active_height * scale);
|
||||||
|
return GSVector4i(left, top, right, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompressAndWriteTextureToFile(u32 width, u32 height, std::string filename, FileSystem::ManagedCFilePtr fp,
|
bool CompressAndWriteTextureToFile(u32 width, u32 height, std::string filename, FileSystem::ManagedCFilePtr fp,
|
||||||
|
@ -2575,7 +2585,7 @@ bool GPU::WriteDisplayTextureToFile(std::string filename, bool compress_on_threa
|
||||||
flip_y, std::move(texture_data), texture_data_stride, m_display_texture->GetFormat(), false, compress_on_thread);
|
flip_y, std::move(texture_data), texture_data_stride, m_display_texture->GetFormat(), false, compress_on_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU::RenderScreenshotToBuffer(u32 width, u32 height, const Common::Rectangle<s32>& draw_rect, bool postfx,
|
bool GPU::RenderScreenshotToBuffer(u32 width, u32 height, const GSVector4i draw_rect, bool postfx,
|
||||||
std::vector<u32>* out_pixels, u32* out_stride, GPUTexture::Format* out_format)
|
std::vector<u32>* out_pixels, u32* out_stride, GPUTexture::Format* out_format)
|
||||||
{
|
{
|
||||||
const GPUTexture::Format hdformat =
|
const GPUTexture::Format hdformat =
|
||||||
|
@ -2627,15 +2637,15 @@ bool GPU::RenderScreenshotToFile(std::string filename, DisplayScreenshotMode mod
|
||||||
{
|
{
|
||||||
u32 width = g_gpu_device->GetWindowWidth();
|
u32 width = g_gpu_device->GetWindowWidth();
|
||||||
u32 height = g_gpu_device->GetWindowHeight();
|
u32 height = g_gpu_device->GetWindowHeight();
|
||||||
Common::Rectangle<s32> draw_rect = CalculateDrawRect(width, height);
|
GSVector4i draw_rect = CalculateDrawRect(width, height, true);
|
||||||
|
|
||||||
const bool internal_resolution = (mode != DisplayScreenshotMode::ScreenResolution || g_settings.debugging.show_vram);
|
const bool internal_resolution = (mode != DisplayScreenshotMode::ScreenResolution || g_settings.debugging.show_vram);
|
||||||
if (internal_resolution && m_display_texture_view_width != 0 && m_display_texture_view_height != 0)
|
if (internal_resolution && m_display_texture_view_width != 0 && m_display_texture_view_height != 0)
|
||||||
{
|
{
|
||||||
if (mode == DisplayScreenshotMode::InternalResolution)
|
if (mode == DisplayScreenshotMode::InternalResolution)
|
||||||
{
|
{
|
||||||
const u32 draw_width = static_cast<u32>(draw_rect.GetWidth());
|
const u32 draw_width = static_cast<u32>(draw_rect.width());
|
||||||
const u32 draw_height = static_cast<u32>(draw_rect.GetHeight());
|
const u32 draw_height = static_cast<u32>(draw_rect.height());
|
||||||
|
|
||||||
// If internal res, scale the computed draw rectangle to the internal res.
|
// If internal res, scale the computed draw rectangle to the internal res.
|
||||||
// We re-use the draw rect because it's already been AR corrected.
|
// We re-use the draw rect because it's already been AR corrected.
|
||||||
|
@ -2679,7 +2689,7 @@ bool GPU::RenderScreenshotToFile(std::string filename, DisplayScreenshotMode mod
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove padding, it's not part of the framebuffer.
|
// Remove padding, it's not part of the framebuffer.
|
||||||
draw_rect.Set(0, 0, static_cast<s32>(width), static_cast<s32>(height));
|
draw_rect = GSVector4i(0, 0, static_cast<s32>(width), static_cast<s32>(height));
|
||||||
}
|
}
|
||||||
if (width == 0 || height == 0)
|
if (width == 0 || height == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
|
|
||||||
#include "common/bitfield.h"
|
#include "common/bitfield.h"
|
||||||
#include "common/fifo_queue.h"
|
#include "common/fifo_queue.h"
|
||||||
#include "common/rectangle.h"
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -208,13 +207,13 @@ public:
|
||||||
virtual void FlushRender() = 0;
|
virtual void FlushRender() = 0;
|
||||||
|
|
||||||
/// Helper function for computing the draw rectangle in a larger window.
|
/// Helper function for computing the draw rectangle in a larger window.
|
||||||
Common::Rectangle<s32> CalculateDrawRect(s32 window_width, s32 window_height, bool apply_aspect_ratio = true) const;
|
GSVector4i CalculateDrawRect(s32 window_width, s32 window_height, bool apply_aspect_ratio = true) const;
|
||||||
|
|
||||||
/// Helper function to save current display texture to PNG.
|
/// Helper function to save current display texture to PNG.
|
||||||
bool WriteDisplayTextureToFile(std::string filename, bool compress_on_thread = false);
|
bool WriteDisplayTextureToFile(std::string filename, bool compress_on_thread = false);
|
||||||
|
|
||||||
/// Renders the display, optionally with postprocessing to the specified image.
|
/// Renders the display, optionally with postprocessing to the specified image.
|
||||||
bool RenderScreenshotToBuffer(u32 width, u32 height, const Common::Rectangle<s32>& draw_rect, bool postfx,
|
bool RenderScreenshotToBuffer(u32 width, u32 height, const GSVector4i draw_rect, bool postfx,
|
||||||
std::vector<u32>* out_pixels, u32* out_stride, GPUTexture::Format* out_format);
|
std::vector<u32>* out_pixels, u32* out_stride, GPUTexture::Format* out_format);
|
||||||
|
|
||||||
/// Helper function to save screenshot to PNG.
|
/// Helper function to save screenshot to PNG.
|
||||||
|
@ -276,6 +275,9 @@ protected:
|
||||||
/// Returns 0 if the currently-displayed field is on an even line in VRAM, otherwise 1.
|
/// Returns 0 if the currently-displayed field is on an even line in VRAM, otherwise 1.
|
||||||
ALWAYS_INLINE u32 GetActiveLineLSB() const { return ZeroExtend32(m_crtc_state.active_line_lsb); }
|
ALWAYS_INLINE u32 GetActiveLineLSB() const { return ZeroExtend32(m_crtc_state.active_line_lsb); }
|
||||||
|
|
||||||
|
/// Updates drawing area that's suitablef or clamping.
|
||||||
|
void SetClampedDrawingArea();
|
||||||
|
|
||||||
/// Sets/decodes GP0(E1h) (set draw mode).
|
/// Sets/decodes GP0(E1h) (set draw mode).
|
||||||
void SetDrawMode(u16 bits);
|
void SetDrawMode(u16 bits);
|
||||||
|
|
||||||
|
@ -323,23 +325,21 @@ protected:
|
||||||
virtual void DrawRendererStats();
|
virtual void DrawRendererStats();
|
||||||
virtual void OnBufferSwapped();
|
virtual void OnBufferSwapped();
|
||||||
|
|
||||||
ALWAYS_INLINE_RELEASE void AddDrawTriangleTicks(s32 x1, s32 y1, s32 x2, s32 y2, s32 x3, s32 y3, bool shaded,
|
ALWAYS_INLINE_RELEASE void AddDrawTriangleTicks(GSVector4i v1, GSVector4i v2, GSVector4i v3, bool shaded,
|
||||||
bool textured, bool semitransparent)
|
bool textured, bool semitransparent)
|
||||||
{
|
{
|
||||||
// This will not produce the correct results for triangles which are partially outside the clip area.
|
// This will not produce the correct results for triangles which are partially outside the clip area.
|
||||||
// However, usually it'll undershoot not overshoot. If we wanted to make this more accurate, we'd need to intersect
|
// However, usually it'll undershoot not overshoot. If we wanted to make this more accurate, we'd need to intersect
|
||||||
// the edges with the clip rectangle.
|
// the edges with the clip rectangle.
|
||||||
// TODO: Coordinates are exclusive, so off by one here...
|
// TODO: Coordinates are exclusive, so off by one here...
|
||||||
const s32 clip_right = static_cast<s32>(m_drawing_area.right) + 1;
|
const GSVector4i clamp_min = m_clamped_drawing_area; // would be xyxy(), but zw isn't used.
|
||||||
const s32 clip_bottom = static_cast<s32>(m_drawing_area.bottom) + 1;
|
const GSVector4i clamp_max = m_clamped_drawing_area.zwzw();
|
||||||
x1 = std::clamp(x1, static_cast<s32>(m_drawing_area.left), clip_right);
|
v1 = v1.sat_i32(clamp_min, clamp_max);
|
||||||
x2 = std::clamp(x2, static_cast<s32>(m_drawing_area.left), clip_right);
|
v2 = v2.sat_i32(clamp_min, clamp_max);
|
||||||
x3 = std::clamp(x3, static_cast<s32>(m_drawing_area.left), clip_right);
|
v3 = v3.sat_i32(clamp_min, clamp_max);
|
||||||
y1 = std::clamp(y1, static_cast<s32>(m_drawing_area.top), clip_bottom);
|
|
||||||
y2 = std::clamp(y2, static_cast<s32>(m_drawing_area.top), clip_bottom);
|
|
||||||
y3 = std::clamp(y3, static_cast<s32>(m_drawing_area.top), clip_bottom);
|
|
||||||
|
|
||||||
TickCount pixels = std::abs((x1 * y2 + x2 * y3 + x3 * y1 - x1 * y3 - x2 * y1 - x3 * y2) / 2);
|
TickCount pixels =
|
||||||
|
std::abs((v1.x * v2.y + v2.x * v3.y + v3.x * v1.y - v1.x * v3.y - v2.x * v1.y - v3.x * v2.y) / 2);
|
||||||
if (textured)
|
if (textured)
|
||||||
pixels += pixels;
|
pixels += pixels;
|
||||||
if (semitransparent || m_GPUSTAT.check_mask_before_draw)
|
if (semitransparent || m_GPUSTAT.check_mask_before_draw)
|
||||||
|
@ -479,6 +479,7 @@ protected:
|
||||||
|
|
||||||
GPUDrawingArea m_drawing_area = {};
|
GPUDrawingArea m_drawing_area = {};
|
||||||
GPUDrawingOffset m_drawing_offset = {};
|
GPUDrawingOffset m_drawing_offset = {};
|
||||||
|
GSVector4i m_clamped_drawing_area = {};
|
||||||
|
|
||||||
bool m_console_is_pal = false;
|
bool m_console_is_pal = false;
|
||||||
bool m_set_texture_disable_mask = false;
|
bool m_set_texture_disable_mask = false;
|
||||||
|
@ -609,7 +610,7 @@ protected:
|
||||||
void SetDisplayTexture(GPUTexture* texture, GPUTexture* depth_texture, s32 view_x, s32 view_y, s32 view_width,
|
void SetDisplayTexture(GPUTexture* texture, GPUTexture* depth_texture, s32 view_x, s32 view_y, s32 view_width,
|
||||||
s32 view_height);
|
s32 view_height);
|
||||||
|
|
||||||
bool RenderDisplay(GPUTexture* target, const Common::Rectangle<s32>& draw_rect, bool postfx);
|
bool RenderDisplay(GPUTexture* target, const GSVector4i draw_rect, bool postfx);
|
||||||
|
|
||||||
bool Deinterlace(u32 field, u32 line_skip);
|
bool Deinterlace(u32 field, u32 line_skip);
|
||||||
bool DeinterlaceExtractField(u32 dst_bufidx, GPUTexture* src, u32 x, u32 y, u32 width, u32 height, u32 line_skip);
|
bool DeinterlaceExtractField(u32 dst_bufidx, GPUTexture* src, u32 x, u32 y, u32 width, u32 height, u32 line_skip);
|
||||||
|
|
|
@ -250,6 +250,7 @@ bool GPU::HandleSetDrawingAreaTopLeftCommand()
|
||||||
m_drawing_area.left = left;
|
m_drawing_area.left = left;
|
||||||
m_drawing_area.top = top;
|
m_drawing_area.top = top;
|
||||||
m_drawing_area_changed = true;
|
m_drawing_area_changed = true;
|
||||||
|
SetClampedDrawingArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
AddCommandTicks(1);
|
AddCommandTicks(1);
|
||||||
|
@ -271,6 +272,7 @@ bool GPU::HandleSetDrawingAreaBottomRightCommand()
|
||||||
m_drawing_area.right = right;
|
m_drawing_area.right = right;
|
||||||
m_drawing_area.bottom = bottom;
|
m_drawing_area.bottom = bottom;
|
||||||
m_drawing_area_changed = true;
|
m_drawing_area_changed = true;
|
||||||
|
SetClampedDrawingArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
AddCommandTicks(1);
|
AddCommandTicks(1);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
|
||||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -9,10 +9,10 @@
|
||||||
#include "util/gpu_device.h"
|
#include "util/gpu_device.h"
|
||||||
|
|
||||||
#include "common/dimensional_array.h"
|
#include "common/dimensional_array.h"
|
||||||
|
#include "common/gsvector.h"
|
||||||
#include "common/heap_array.h"
|
#include "common/heap_array.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <limits>
|
||||||
#include <string>
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -122,8 +122,7 @@ private:
|
||||||
|
|
||||||
struct BatchUBOData
|
struct BatchUBOData
|
||||||
{
|
{
|
||||||
u32 u_texture_window_and[2];
|
u32 u_texture_window[4]; // and_x, and_y, or_x, or_y
|
||||||
u32 u_texture_window_or[2];
|
|
||||||
float u_src_alpha_factor;
|
float u_src_alpha_factor;
|
||||||
float u_dst_alpha_factor;
|
float u_dst_alpha_factor;
|
||||||
u32 u_interlaced_displayed_field;
|
u32 u_interlaced_displayed_field;
|
||||||
|
@ -137,6 +136,11 @@ private:
|
||||||
u32 num_uniform_buffer_updates;
|
u32 num_uniform_buffer_updates;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr GSVector4i VRAM_SIZE_RECT = GSVector4i::cxpr(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
||||||
|
static constexpr GSVector4i INVALID_RECT =
|
||||||
|
GSVector4i::cxpr(std::numeric_limits<s32>::max(), std::numeric_limits<s32>::max(), std::numeric_limits<s32>::min(),
|
||||||
|
std::numeric_limits<s32>::min());
|
||||||
|
|
||||||
/// Returns true if a depth buffer should be created.
|
/// Returns true if a depth buffer should be created.
|
||||||
bool NeedsDepthBuffer() const;
|
bool NeedsDepthBuffer() const;
|
||||||
GPUTexture::Format GetDepthBufferFormat() const;
|
GPUTexture::Format GetDepthBufferFormat() const;
|
||||||
|
@ -153,7 +157,6 @@ private:
|
||||||
void PrintSettingsToLog();
|
void PrintSettingsToLog();
|
||||||
void CheckSettings();
|
void CheckSettings();
|
||||||
|
|
||||||
void SetClampedDrawingArea();
|
|
||||||
void UpdateVRAMReadTexture(bool drawn, bool written);
|
void UpdateVRAMReadTexture(bool drawn, bool written);
|
||||||
void UpdateDepthBufferFromMaskBit();
|
void UpdateDepthBufferFromMaskBit();
|
||||||
void CopyAndClearDepthBuffer();
|
void CopyAndClearDepthBuffer();
|
||||||
|
@ -172,9 +175,9 @@ private:
|
||||||
|
|
||||||
void SetFullVRAMDirtyRectangle();
|
void SetFullVRAMDirtyRectangle();
|
||||||
void ClearVRAMDirtyRectangle();
|
void ClearVRAMDirtyRectangle();
|
||||||
void IncludeVRAMDirtyRectangle(Common::Rectangle<u32>& rect, const Common::Rectangle<u32>& new_rect);
|
void IncludeVRAMDirtyRectangle(GSVector4i& rect, const GSVector4i new_rect);
|
||||||
void IncludeDrawnDirtyRectangle(s32 min_x, s32 min_y, s32 max_x, s32 max_y);
|
void IncludeDrawnDirtyRectangle(const GSVector4i rect);
|
||||||
void CheckForTexPageOverlap(u32 texpage, u32 min_u, u32 min_v, u32 max_u, u32 max_v);
|
void CheckForTexPageOverlap(GSVector4i uv_rect);
|
||||||
|
|
||||||
bool IsFlushed() const;
|
bool IsFlushed() const;
|
||||||
void EnsureVertexBufferSpace(u32 required_vertices, u32 required_indices);
|
void EnsureVertexBufferSpace(u32 required_vertices, u32 required_indices);
|
||||||
|
@ -205,7 +208,7 @@ private:
|
||||||
void OnBufferSwapped() override;
|
void OnBufferSwapped() override;
|
||||||
|
|
||||||
void UpdateVRAMOnGPU(u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_pitch, bool set_mask,
|
void UpdateVRAMOnGPU(u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_pitch, bool set_mask,
|
||||||
bool check_mask, const Common::Rectangle<u32>& bounds);
|
bool check_mask, const GSVector4i bounds);
|
||||||
bool BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
bool BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
||||||
|
|
||||||
/// Expands a line into two triangles.
|
/// Expands a line into two triangles.
|
||||||
|
@ -214,10 +217,10 @@ private:
|
||||||
/// Handles quads with flipped texture coordinate directions.
|
/// Handles quads with flipped texture coordinate directions.
|
||||||
void HandleFlippedQuadTextureCoordinates(BatchVertex* vertices);
|
void HandleFlippedQuadTextureCoordinates(BatchVertex* vertices);
|
||||||
bool IsPossibleSpritePolygon(const BatchVertex* vertices) const;
|
bool IsPossibleSpritePolygon(const BatchVertex* vertices) const;
|
||||||
void ExpandLineTriangles(BatchVertex* vertices, u32 base_vertex);
|
bool ExpandLineTriangles(BatchVertex* vertices);
|
||||||
|
|
||||||
/// Computes polygon U/V boundaries.
|
/// Computes polygon U/V boundaries, and for overlap with the current texture page.
|
||||||
void ComputePolygonUVLimits(u32 texpage, BatchVertex* vertices, u32 num_vertices);
|
void ComputePolygonUVLimits(BatchVertex* vertices, u32 num_vertices);
|
||||||
|
|
||||||
/// Sets the depth test flag for PGXP depth buffering.
|
/// Sets the depth test flag for PGXP depth buffering.
|
||||||
void SetBatchDepthBuffer(bool enabled);
|
void SetBatchDepthBuffer(bool enabled);
|
||||||
|
@ -271,9 +274,10 @@ private:
|
||||||
bool m_compute_uv_range : 1 = false;
|
bool m_compute_uv_range : 1 = false;
|
||||||
bool m_allow_sprite_mode : 1 = false;
|
bool m_allow_sprite_mode : 1 = false;
|
||||||
bool m_allow_shader_blend : 1 = false;
|
bool m_allow_shader_blend : 1 = false;
|
||||||
|
bool m_depth_was_copied : 1 = false;
|
||||||
|
bool m_texture_window_active : 1 = false;
|
||||||
|
|
||||||
u8 m_texpage_dirty = 0;
|
u8 m_texpage_dirty = 0;
|
||||||
bool m_depth_was_copied = false;
|
|
||||||
|
|
||||||
BatchConfig m_batch;
|
BatchConfig m_batch;
|
||||||
|
|
||||||
|
@ -282,10 +286,10 @@ private:
|
||||||
BatchUBOData m_batch_ubo_data = {};
|
BatchUBOData m_batch_ubo_data = {};
|
||||||
|
|
||||||
// Bounding box of VRAM area that the GPU has drawn into.
|
// Bounding box of VRAM area that the GPU has drawn into.
|
||||||
GPUDrawingArea m_clamped_drawing_area = {};
|
GSVector4i m_vram_dirty_draw_rect = INVALID_RECT;
|
||||||
Common::Rectangle<u32> m_vram_dirty_draw_rect;
|
GSVector4i m_vram_dirty_write_rect = INVALID_RECT;
|
||||||
Common::Rectangle<u32> m_vram_dirty_write_rect;
|
GSVector4i m_current_uv_range = INVALID_RECT;
|
||||||
Common::Rectangle<u32> m_current_uv_range;
|
GSVector2i m_current_texture_page_offset = {};
|
||||||
|
|
||||||
std::unique_ptr<GPUPipeline> m_wireframe_pipeline;
|
std::unique_ptr<GPUPipeline> m_wireframe_pipeline;
|
||||||
|
|
||||||
|
|
|
@ -523,6 +523,7 @@ void GPU_SW::DispatchRenderCommand()
|
||||||
GPUBackendDrawPolygonCommand* cmd = m_backend.NewDrawPolygonCommand(num_vertices);
|
GPUBackendDrawPolygonCommand* cmd = m_backend.NewDrawPolygonCommand(num_vertices);
|
||||||
FillDrawCommand(cmd, rc);
|
FillDrawCommand(cmd, rc);
|
||||||
|
|
||||||
|
std::array<GSVector4i, 4> positions;
|
||||||
const u32 first_color = rc.color_for_first_vertex;
|
const u32 first_color = rc.color_for_first_vertex;
|
||||||
const bool shaded = rc.shading_enable;
|
const bool shaded = rc.shading_enable;
|
||||||
const bool textured = rc.texture_enable;
|
const bool textured = rc.texture_enable;
|
||||||
|
@ -535,49 +536,55 @@ void GPU_SW::DispatchRenderCommand()
|
||||||
vert->x = m_drawing_offset.x + vp.x;
|
vert->x = m_drawing_offset.x + vp.x;
|
||||||
vert->y = m_drawing_offset.y + vp.y;
|
vert->y = m_drawing_offset.y + vp.y;
|
||||||
vert->texcoord = textured ? Truncate16(FifoPop()) : 0;
|
vert->texcoord = textured ? Truncate16(FifoPop()) : 0;
|
||||||
|
positions[i] = GSVector4i::loadl(&vert->x);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsDrawingAreaIsValid())
|
if (!IsDrawingAreaIsValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Cull polygons which are too large.
|
// Cull polygons which are too large.
|
||||||
const auto [min_x_12, max_x_12] = MinMax(cmd->vertices[1].x, cmd->vertices[2].x);
|
const GSVector4i min_pos_12 = positions[1].min_i32(positions[2]);
|
||||||
const auto [min_y_12, max_y_12] = MinMax(cmd->vertices[1].y, cmd->vertices[2].y);
|
const GSVector4i max_pos_12 = positions[1].max_i32(positions[2]);
|
||||||
const s32 min_x = std::min(min_x_12, cmd->vertices[0].x);
|
const GSVector4i draw_rect_012 =
|
||||||
const s32 max_x = std::max(max_x_12, cmd->vertices[0].x);
|
min_pos_12.min_i32(positions[0]).upl64(max_pos_12.max_i32(positions[0])).add32(GSVector4i::cxpr(0, 0, 1, 1));
|
||||||
const s32 min_y = std::min(min_y_12, cmd->vertices[0].y);
|
const bool first_tri_culled =
|
||||||
const s32 max_y = std::max(max_y_12, cmd->vertices[0].y);
|
(draw_rect_012.width() > MAX_PRIMITIVE_WIDTH || draw_rect_012.height() > MAX_PRIMITIVE_HEIGHT ||
|
||||||
|
!m_clamped_drawing_area.rintersects(draw_rect_012));
|
||||||
if ((max_x - min_x) >= MAX_PRIMITIVE_WIDTH || (max_y - min_y) >= MAX_PRIMITIVE_HEIGHT)
|
if (first_tri_culled)
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Culling too-large polygon: {},{} {},{} {},{}", cmd->vertices[0].x, cmd->vertices[0].y,
|
DEBUG_LOG("Culling off-screen/too-large polygon: {},{} {},{} {},{}", cmd->vertices[0].x, cmd->vertices[0].y,
|
||||||
cmd->vertices[1].x, cmd->vertices[1].y, cmd->vertices[2].x, cmd->vertices[2].y);
|
cmd->vertices[1].x, cmd->vertices[1].y, cmd->vertices[2].x, cmd->vertices[2].y);
|
||||||
|
|
||||||
|
if (!rc.quad_polygon)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddDrawTriangleTicks(cmd->vertices[0].x, cmd->vertices[0].y, cmd->vertices[1].x, cmd->vertices[1].y,
|
AddDrawTriangleTicks(positions[0], positions[1], positions[2], rc.shading_enable, rc.texture_enable,
|
||||||
cmd->vertices[2].x, cmd->vertices[2].y, rc.shading_enable, rc.texture_enable,
|
|
||||||
rc.transparency_enable);
|
rc.transparency_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// quads
|
// quads
|
||||||
if (rc.quad_polygon)
|
if (rc.quad_polygon)
|
||||||
{
|
{
|
||||||
const s32 min_x_123 = std::min(min_x_12, cmd->vertices[3].x);
|
const GSVector4i draw_rect_123 =
|
||||||
const s32 max_x_123 = std::max(max_x_12, cmd->vertices[3].x);
|
min_pos_12.min_i32(positions[3]).upl64(max_pos_12.max_i32(positions[3])).add32(GSVector4i::cxpr(0, 0, 1, 1));
|
||||||
const s32 min_y_123 = std::min(min_y_12, cmd->vertices[3].y);
|
|
||||||
const s32 max_y_123 = std::max(max_y_12, cmd->vertices[3].y);
|
|
||||||
|
|
||||||
// Cull polygons which are too large.
|
// Cull polygons which are too large.
|
||||||
if ((max_x_123 - min_x_123) >= MAX_PRIMITIVE_WIDTH || (max_y_123 - min_y_123) >= MAX_PRIMITIVE_HEIGHT)
|
const bool second_tri_culled =
|
||||||
|
(draw_rect_123.width() > MAX_PRIMITIVE_WIDTH || draw_rect_123.height() > MAX_PRIMITIVE_HEIGHT ||
|
||||||
|
!m_clamped_drawing_area.rintersects(draw_rect_123));
|
||||||
|
if (second_tri_culled)
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Culling too-large polygon (quad second half): {},{} {},{} {},{}", cmd->vertices[2].x,
|
DEBUG_LOG("Culling too-large polygon (quad second half): {},{} {},{} {},{}", cmd->vertices[2].x,
|
||||||
cmd->vertices[2].y, cmd->vertices[1].x, cmd->vertices[1].y, cmd->vertices[0].x, cmd->vertices[0].y);
|
cmd->vertices[2].y, cmd->vertices[1].x, cmd->vertices[1].y, cmd->vertices[0].x, cmd->vertices[0].y);
|
||||||
|
|
||||||
|
if (first_tri_culled)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddDrawTriangleTicks(cmd->vertices[2].x, cmd->vertices[2].y, cmd->vertices[1].x, cmd->vertices[1].y,
|
AddDrawTriangleTicks(positions[2], positions[1], positions[3], rc.shading_enable, rc.texture_enable,
|
||||||
cmd->vertices[3].x, cmd->vertices[3].y, rc.shading_enable, rc.texture_enable,
|
|
||||||
rc.transparency_enable);
|
rc.transparency_enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -627,12 +634,6 @@ void GPU_SW::DispatchRenderCommand()
|
||||||
const u32 width_and_height = FifoPop();
|
const u32 width_and_height = FifoPop();
|
||||||
cmd->width = static_cast<u16>(width_and_height & VRAM_WIDTH_MASK);
|
cmd->width = static_cast<u16>(width_and_height & VRAM_WIDTH_MASK);
|
||||||
cmd->height = static_cast<u16>((width_and_height >> 16) & VRAM_HEIGHT_MASK);
|
cmd->height = static_cast<u16>((width_and_height >> 16) & VRAM_HEIGHT_MASK);
|
||||||
|
|
||||||
if (cmd->width >= MAX_PRIMITIVE_WIDTH || cmd->height >= MAX_PRIMITIVE_HEIGHT)
|
|
||||||
{
|
|
||||||
DEBUG_LOG("Culling too-large rectangle: {},{} {}x{}", cmd->x, cmd->y, cmd->width, cmd->height);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "common/bitfield.h"
|
#include "common/bitfield.h"
|
||||||
#include "common/bitutils.h"
|
#include "common/bitutils.h"
|
||||||
#include "common/rectangle.h"
|
#include "common/gsvector.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
|
@ -189,18 +189,19 @@ union GPUDrawModeReg
|
||||||
BitField<u16, bool, 12, 1> texture_x_flip;
|
BitField<u16, bool, 12, 1> texture_x_flip;
|
||||||
BitField<u16, bool, 13, 1> texture_y_flip;
|
BitField<u16, bool, 13, 1> texture_y_flip;
|
||||||
|
|
||||||
ALWAYS_INLINE u16 GetTexturePageBaseX() const { return ZeroExtend16(texture_page_x_base.GetValue()) * 64; }
|
ALWAYS_INLINE u32 GetTexturePageBaseX() const { return ZeroExtend32(texture_page_x_base.GetValue()) * 64; }
|
||||||
ALWAYS_INLINE u16 GetTexturePageBaseY() const { return ZeroExtend16(texture_page_y_base.GetValue()) * 256; }
|
ALWAYS_INLINE u32 GetTexturePageBaseY() const { return ZeroExtend32(texture_page_y_base.GetValue()) * 256; }
|
||||||
|
|
||||||
/// Returns true if the texture mode requires a palette.
|
/// Returns true if the texture mode requires a palette.
|
||||||
ALWAYS_INLINE bool IsUsingPalette() const { return (bits & (2 << 7)) == 0; }
|
ALWAYS_INLINE bool IsUsingPalette() const { return (bits & (2 << 7)) == 0; }
|
||||||
|
|
||||||
/// Returns a rectangle comprising the texture page area.
|
/// Returns a rectangle comprising the texture page area.
|
||||||
ALWAYS_INLINE_RELEASE Common::Rectangle<u32> GetTexturePageRectangle() const
|
ALWAYS_INLINE_RELEASE GSVector4i GetTexturePageRectangle() const
|
||||||
{
|
{
|
||||||
return Common::Rectangle<u32>::FromExtents(GetTexturePageBaseX(), GetTexturePageBaseY(),
|
const u32 base_x = GetTexturePageBaseX();
|
||||||
texture_page_widths[static_cast<u8>(texture_mode.GetValue())],
|
const u32 base_y = GetTexturePageBaseY();
|
||||||
TEXTURE_PAGE_HEIGHT);
|
return GSVector4i(base_x, base_y, base_x + texture_page_widths[static_cast<u8>(texture_mode.GetValue())],
|
||||||
|
base_y + TEXTURE_PAGE_HEIGHT);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -217,10 +218,12 @@ union GPUTexturePaletteReg
|
||||||
ALWAYS_INLINE u32 GetYBase() const { return static_cast<u32>(y); }
|
ALWAYS_INLINE u32 GetYBase() const { return static_cast<u32>(y); }
|
||||||
|
|
||||||
/// Returns a rectangle comprising the texture palette area.
|
/// Returns a rectangle comprising the texture palette area.
|
||||||
ALWAYS_INLINE_RELEASE Common::Rectangle<u32> GetRectangle(GPUTextureMode mode) const
|
ALWAYS_INLINE_RELEASE GSVector4i GetRectangle(GPUTextureMode mode) const
|
||||||
{
|
{
|
||||||
static constexpr std::array<u32, 4> palette_widths = {{16, 256, 0, 0}};
|
static constexpr std::array<u32, 4> palette_widths = {{16, 256, 0, 0}};
|
||||||
return Common::Rectangle<u32>::FromExtents(GetXBase(), GetYBase(), palette_widths[static_cast<u8>(mode)], 1);
|
const u32 base_x = GetXBase();
|
||||||
|
const u32 base_y = GetYBase();
|
||||||
|
return GSVector4i(base_x, base_y, base_x + palette_widths[static_cast<u8>(mode)], base_y + 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2727,8 +2727,8 @@ bool System::SaveStateToStream(ByteStream* state, Error* error, u32 screenshot_s
|
||||||
u32 screenshot_stride;
|
u32 screenshot_stride;
|
||||||
GPUTexture::Format screenshot_format;
|
GPUTexture::Format screenshot_format;
|
||||||
if (g_gpu->RenderScreenshotToBuffer(screenshot_width, screenshot_height,
|
if (g_gpu->RenderScreenshotToBuffer(screenshot_width, screenshot_height,
|
||||||
Common::Rectangle<s32>::FromExtents(0, 0, screenshot_width, screenshot_height),
|
GSVector4i(0, 0, screenshot_width, screenshot_height), false,
|
||||||
false, &screenshot_buffer, &screenshot_stride, &screenshot_format) &&
|
&screenshot_buffer, &screenshot_stride, &screenshot_format) &&
|
||||||
GPUTexture::ConvertTextureDataToRGBA8(screenshot_width, screenshot_height, screenshot_buffer, screenshot_stride,
|
GPUTexture::ConvertTextureDataToRGBA8(screenshot_width, screenshot_height, screenshot_buffer, screenshot_stride,
|
||||||
screenshot_format))
|
screenshot_format))
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "common/file_system.h"
|
#include "common/file_system.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/path.h"
|
#include "common/path.h"
|
||||||
#include "common/rectangle.h"
|
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
@ -1086,17 +1085,18 @@ void D3D11Device::UnbindTexture(D3D11Texture* tex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11Device::SetViewport(s32 x, s32 y, s32 width, s32 height)
|
void D3D11Device::SetViewport(const GSVector4i rc)
|
||||||
{
|
{
|
||||||
const CD3D11_VIEWPORT vp(static_cast<float>(x), static_cast<float>(y), static_cast<float>(width),
|
const CD3D11_VIEWPORT vp(static_cast<float>(rc.left), static_cast<float>(rc.top), static_cast<float>(rc.width()),
|
||||||
static_cast<float>(height), 0.0f, 1.0f);
|
static_cast<float>(rc.height()), 0.0f, 1.0f);
|
||||||
m_context->RSSetViewports(1, &vp);
|
m_context->RSSetViewports(1, &vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11Device::SetScissor(s32 x, s32 y, s32 width, s32 height)
|
void D3D11Device::SetScissor(const GSVector4i rc)
|
||||||
{
|
{
|
||||||
const CD3D11_RECT rc(x, y, x + width, y + height);
|
alignas(16) D3D11_RECT drc;
|
||||||
m_context->RSSetScissorRects(1, &rc);
|
GSVector4i::store<true>(&drc, rc);
|
||||||
|
m_context->RSSetScissorRects(1, &drc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11Device::Draw(u32 vertex_count, u32 base_vertex)
|
void D3D11Device::Draw(u32 vertex_count, u32 base_vertex)
|
||||||
|
|
|
@ -92,8 +92,8 @@ public:
|
||||||
void SetPipeline(GPUPipeline* pipeline) override;
|
void SetPipeline(GPUPipeline* pipeline) override;
|
||||||
void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) override;
|
void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) override;
|
||||||
void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) override;
|
void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) override;
|
||||||
void SetViewport(s32 x, s32 y, s32 width, s32 height) override;
|
void SetViewport(const GSVector4i rc) override;
|
||||||
void SetScissor(s32 x, s32 y, s32 width, s32 height) override;
|
void SetScissor(const GSVector4i rc) override;
|
||||||
void Draw(u32 vertex_count, u32 base_vertex) override;
|
void Draw(u32 vertex_count, u32 base_vertex) override;
|
||||||
void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) override;
|
void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) override;
|
||||||
void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) override;
|
void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) override;
|
||||||
|
|
|
@ -1927,8 +1927,8 @@ void D3D12Device::SetViewport(ID3D12GraphicsCommandList4* cmdlist)
|
||||||
{
|
{
|
||||||
const D3D12_VIEWPORT vp = {static_cast<float>(m_current_viewport.left),
|
const D3D12_VIEWPORT vp = {static_cast<float>(m_current_viewport.left),
|
||||||
static_cast<float>(m_current_viewport.top),
|
static_cast<float>(m_current_viewport.top),
|
||||||
static_cast<float>(m_current_viewport.GetWidth()),
|
static_cast<float>(m_current_viewport.width()),
|
||||||
static_cast<float>(m_current_viewport.GetHeight()),
|
static_cast<float>(m_current_viewport.height()),
|
||||||
0.0f,
|
0.0f,
|
||||||
1.0f};
|
1.0f};
|
||||||
cmdlist->RSSetViewports(1, &vp);
|
cmdlist->RSSetViewports(1, &vp);
|
||||||
|
@ -1936,9 +1936,8 @@ void D3D12Device::SetViewport(ID3D12GraphicsCommandList4* cmdlist)
|
||||||
|
|
||||||
void D3D12Device::SetScissor(ID3D12GraphicsCommandList4* cmdlist)
|
void D3D12Device::SetScissor(ID3D12GraphicsCommandList4* cmdlist)
|
||||||
{
|
{
|
||||||
const D3D12_RECT rc = {static_cast<LONG>(m_current_scissor.left), static_cast<LONG>(m_current_scissor.top),
|
static_assert(sizeof(GSVector4i) == sizeof(D3D12_RECT));
|
||||||
static_cast<LONG>(m_current_scissor.right), static_cast<LONG>(m_current_scissor.bottom)};
|
cmdlist->RSSetScissorRects(1, reinterpret_cast<const D3D12_RECT*>(&m_current_scissor));
|
||||||
cmdlist->RSSetScissorRects(1, &rc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12Device::SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler)
|
void D3D12Device::SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler)
|
||||||
|
@ -2027,10 +2026,9 @@ void D3D12Device::UnbindTextureBuffer(D3D12TextureBuffer* buf)
|
||||||
m_dirty_flags |= DIRTY_FLAG_TEXTURES;
|
m_dirty_flags |= DIRTY_FLAG_TEXTURES;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12Device::SetViewport(s32 x, s32 y, s32 width, s32 height)
|
void D3D12Device::SetViewport(const GSVector4i rc)
|
||||||
{
|
{
|
||||||
const Common::Rectangle<s32> rc = Common::Rectangle<s32>::FromExtents(x, y, width, height);
|
if (m_current_viewport.eq(rc))
|
||||||
if (m_current_viewport == rc)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_current_viewport = rc;
|
m_current_viewport = rc;
|
||||||
|
@ -2041,10 +2039,9 @@ void D3D12Device::SetViewport(s32 x, s32 y, s32 width, s32 height)
|
||||||
SetViewport(GetCommandList());
|
SetViewport(GetCommandList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12Device::SetScissor(s32 x, s32 y, s32 width, s32 height)
|
void D3D12Device::SetScissor(const GSVector4i rc)
|
||||||
{
|
{
|
||||||
const Common::Rectangle<s32> rc = Common::Rectangle<s32>::FromExtents(x, y, width, height);
|
if (m_current_scissor.eq(rc))
|
||||||
if (m_current_scissor == rc)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_current_scissor = rc;
|
m_current_scissor = rc;
|
||||||
|
|
|
@ -114,8 +114,8 @@ public:
|
||||||
void SetPipeline(GPUPipeline* pipeline) override;
|
void SetPipeline(GPUPipeline* pipeline) override;
|
||||||
void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) override;
|
void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) override;
|
||||||
void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) override;
|
void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) override;
|
||||||
void SetViewport(s32 x, s32 y, s32 width, s32 height) override;
|
void SetViewport(const GSVector4i rc) override;
|
||||||
void SetScissor(s32 x, s32 y, s32 width, s32 height) override;
|
void SetScissor(const GSVector4i rc) override;
|
||||||
void Draw(u32 vertex_count, u32 base_vertex) override;
|
void Draw(u32 vertex_count, u32 base_vertex) override;
|
||||||
void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) override;
|
void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) override;
|
||||||
void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) override;
|
void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) override;
|
||||||
|
@ -344,6 +344,6 @@ private:
|
||||||
std::array<D3D12Texture*, MAX_TEXTURE_SAMPLERS> m_current_textures = {};
|
std::array<D3D12Texture*, MAX_TEXTURE_SAMPLERS> m_current_textures = {};
|
||||||
std::array<D3D12DescriptorHandle, MAX_TEXTURE_SAMPLERS> m_current_samplers = {};
|
std::array<D3D12DescriptorHandle, MAX_TEXTURE_SAMPLERS> m_current_samplers = {};
|
||||||
D3D12TextureBuffer* m_current_texture_buffer = nullptr;
|
D3D12TextureBuffer* m_current_texture_buffer = nullptr;
|
||||||
Common::Rectangle<s32> m_current_viewport{0, 0, 1, 1};
|
GSVector4i m_current_viewport = GSVector4i::cxpr(0, 0, 1, 1);
|
||||||
Common::Rectangle<s32> m_current_scissor{0, 0, 1, 1};
|
GSVector4i m_current_scissor = {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
#include "common/file_system.h"
|
#include "common/file_system.h"
|
||||||
|
#include "common/gsvector.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/rectangle.h"
|
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
@ -179,7 +179,7 @@ bool D3DCommon::GetRequestedExclusiveFullscreenModeDesc(IDXGIFactory5* factory,
|
||||||
DXGI_MODE_DESC* fullscreen_mode, IDXGIOutput** output)
|
DXGI_MODE_DESC* fullscreen_mode, IDXGIOutput** output)
|
||||||
{
|
{
|
||||||
// We need to find which monitor the window is located on.
|
// We need to find which monitor the window is located on.
|
||||||
const Common::Rectangle<s32> client_rc_vec(window_rect.left, window_rect.top, window_rect.right, window_rect.bottom);
|
const GSVector4i client_rc_vec(window_rect.left, window_rect.top, window_rect.right, window_rect.bottom);
|
||||||
|
|
||||||
// The window might be on a different adapter to which we are rendering.. so we have to enumerate them all.
|
// The window might be on a different adapter to which we are rendering.. so we have to enumerate them all.
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -204,10 +204,9 @@ bool D3DCommon::GetRequestedExclusiveFullscreenModeDesc(IDXGIFactory5* factory,
|
||||||
else if (FAILED(hr) || FAILED(this_output->GetDesc(&output_desc)))
|
else if (FAILED(hr) || FAILED(this_output->GetDesc(&output_desc)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const Common::Rectangle<s32> output_rc(output_desc.DesktopCoordinates.left, output_desc.DesktopCoordinates.top,
|
const GSVector4i output_rc(output_desc.DesktopCoordinates.left, output_desc.DesktopCoordinates.top,
|
||||||
output_desc.DesktopCoordinates.right,
|
output_desc.DesktopCoordinates.right, output_desc.DesktopCoordinates.bottom);
|
||||||
output_desc.DesktopCoordinates.bottom);
|
if (!client_rc_vec.rintersects(output_rc))
|
||||||
if (!client_rc_vec.Intersects(output_rc))
|
|
||||||
{
|
{
|
||||||
intersecting_output = std::move(this_output);
|
intersecting_output = std::move(this_output);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -643,10 +643,25 @@ void GPUDevice::SetRenderTarget(GPUTexture* rt, GPUTexture* ds, GPUPipeline::Ren
|
||||||
SetRenderTargets(rt ? &rt : nullptr, rt ? 1 : 0, ds, render_pass_flags);
|
SetRenderTargets(rt ? &rt : nullptr, rt ? 1 : 0, ds, render_pass_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPUDevice::SetViewport(s32 x, s32 y, s32 width, s32 height)
|
||||||
|
{
|
||||||
|
SetViewport(GSVector4i(x, y, x + width, y + height));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPUDevice::SetScissor(s32 x, s32 y, s32 width, s32 height)
|
||||||
|
{
|
||||||
|
SetScissor(GSVector4i(x, y, x + width, y + height));
|
||||||
|
}
|
||||||
|
|
||||||
void GPUDevice::SetViewportAndScissor(s32 x, s32 y, s32 width, s32 height)
|
void GPUDevice::SetViewportAndScissor(s32 x, s32 y, s32 width, s32 height)
|
||||||
{
|
{
|
||||||
SetViewport(x, y, width, height);
|
SetViewportAndScissor(GSVector4i(x, y, x + width, y + height));
|
||||||
SetScissor(x, y, width, height);
|
}
|
||||||
|
|
||||||
|
void GPUDevice::SetViewportAndScissor(const GSVector4i rc)
|
||||||
|
{
|
||||||
|
SetViewport(rc);
|
||||||
|
SetScissor(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUDevice::ClearRenderTarget(GPUTexture* t, u32 c)
|
void GPUDevice::ClearRenderTarget(GPUTexture* t, u32 c)
|
||||||
|
@ -818,11 +833,13 @@ bool GPUDevice::UsesLowerLeftOrigin() const
|
||||||
return (api == RenderAPI::OpenGL || api == RenderAPI::OpenGLES);
|
return (api == RenderAPI::OpenGL || api == RenderAPI::OpenGLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Rectangle<s32> GPUDevice::FlipToLowerLeft(const Common::Rectangle<s32>& rc, s32 target_height)
|
GSVector4i GPUDevice::FlipToLowerLeft(GSVector4i rc, s32 target_height)
|
||||||
{
|
{
|
||||||
const s32 height = rc.GetHeight();
|
const s32 height = rc.height();
|
||||||
const s32 flipped_y = target_height - rc.top - height;
|
const s32 flipped_y = target_height - rc.top - height;
|
||||||
return Common::Rectangle<s32>(rc.left, flipped_y, rc.right, flipped_y + height);
|
rc.top = flipped_y;
|
||||||
|
rc.bottom = flipped_y + height;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPUDevice::IsTexturePoolType(GPUTexture::Type type)
|
bool GPUDevice::IsTexturePoolType(GPUTexture::Type type)
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
#include "window_info.h"
|
#include "window_info.h"
|
||||||
|
|
||||||
#include "common/bitfield.h"
|
#include "common/bitfield.h"
|
||||||
|
#include "common/gsvector.h"
|
||||||
#include "common/heap_array.h"
|
#include "common/heap_array.h"
|
||||||
#include "common/rectangle.h"
|
|
||||||
#include "common/small_string.h"
|
#include "common/small_string.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
|
@ -676,11 +676,14 @@ public:
|
||||||
virtual void SetPipeline(GPUPipeline* pipeline) = 0;
|
virtual void SetPipeline(GPUPipeline* pipeline) = 0;
|
||||||
virtual void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) = 0;
|
virtual void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) = 0;
|
||||||
virtual void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) = 0;
|
virtual void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) = 0;
|
||||||
virtual void SetViewport(s32 x, s32 y, s32 width, s32 height) = 0; // TODO: Rectangle
|
virtual void SetViewport(const GSVector4i rc) = 0;
|
||||||
virtual void SetScissor(s32 x, s32 y, s32 width, s32 height) = 0;
|
virtual void SetScissor(const GSVector4i rc) = 0;
|
||||||
void SetRenderTarget(GPUTexture* rt, GPUTexture* ds = nullptr,
|
void SetRenderTarget(GPUTexture* rt, GPUTexture* ds = nullptr,
|
||||||
GPUPipeline::RenderPassFlag render_pass_flags = GPUPipeline::NoRenderPassFlags);
|
GPUPipeline::RenderPassFlag render_pass_flags = GPUPipeline::NoRenderPassFlags);
|
||||||
|
void SetViewport(s32 x, s32 y, s32 width, s32 height);
|
||||||
|
void SetScissor(s32 x, s32 y, s32 width, s32 height);
|
||||||
void SetViewportAndScissor(s32 x, s32 y, s32 width, s32 height);
|
void SetViewportAndScissor(s32 x, s32 y, s32 width, s32 height);
|
||||||
|
void SetViewportAndScissor(const GSVector4i rc);
|
||||||
|
|
||||||
// Drawing abstraction.
|
// Drawing abstraction.
|
||||||
virtual void Draw(u32 vertex_count, u32 base_vertex) = 0;
|
virtual void Draw(u32 vertex_count, u32 base_vertex) = 0;
|
||||||
|
@ -704,7 +707,7 @@ public:
|
||||||
|
|
||||||
bool UpdateImGuiFontTexture();
|
bool UpdateImGuiFontTexture();
|
||||||
bool UsesLowerLeftOrigin() const;
|
bool UsesLowerLeftOrigin() const;
|
||||||
static Common::Rectangle<s32> FlipToLowerLeft(const Common::Rectangle<s32>& rc, s32 target_height);
|
static GSVector4i FlipToLowerLeft(GSVector4i rc, s32 target_height);
|
||||||
bool ResizeTexture(std::unique_ptr<GPUTexture>* tex, u32 new_width, u32 new_height, GPUTexture::Type type,
|
bool ResizeTexture(std::unique_ptr<GPUTexture>* tex, u32 new_width, u32 new_height, GPUTexture::Type type,
|
||||||
GPUTexture::Format format, bool preserve = true);
|
GPUTexture::Format format, bool preserve = true);
|
||||||
bool ShouldSkipPresentingFrame();
|
bool ShouldSkipPresentingFrame();
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
|
||||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/gsvector.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -103,6 +104,10 @@ public:
|
||||||
ALWAYS_INLINE u32 GetSamples() const { return m_samples; }
|
ALWAYS_INLINE u32 GetSamples() const { return m_samples; }
|
||||||
ALWAYS_INLINE Type GetType() const { return m_type; }
|
ALWAYS_INLINE Type GetType() const { return m_type; }
|
||||||
ALWAYS_INLINE Format GetFormat() const { return m_format; }
|
ALWAYS_INLINE Format GetFormat() const { return m_format; }
|
||||||
|
ALWAYS_INLINE GSVector4i GetRect() const
|
||||||
|
{
|
||||||
|
return GSVector4i(0, 0, static_cast<s32>(m_width), static_cast<s32>(m_height));
|
||||||
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool IsTextureArray() const { return m_layers > 1; }
|
ALWAYS_INLINE bool IsTextureArray() const { return m_layers > 1; }
|
||||||
ALWAYS_INLINE bool IsMultisampled() const { return m_samples > 1; }
|
ALWAYS_INLINE bool IsMultisampled() const { return m_samples > 1; }
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "metal_stream_buffer.h"
|
#include "metal_stream_buffer.h"
|
||||||
#include "window_info.h"
|
#include "window_info.h"
|
||||||
|
|
||||||
#include "common/rectangle.h"
|
|
||||||
#include "common/timer.h"
|
#include "common/timer.h"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
@ -255,8 +254,8 @@ public:
|
||||||
void SetPipeline(GPUPipeline* pipeline) override;
|
void SetPipeline(GPUPipeline* pipeline) override;
|
||||||
void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) override;
|
void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) override;
|
||||||
void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) override;
|
void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) override;
|
||||||
void SetViewport(s32 x, s32 y, s32 width, s32 height) override;
|
void SetViewport(const GSVector4i rc) override;
|
||||||
void SetScissor(s32 x, s32 y, s32 width, s32 height) override;
|
void SetScissor(const GSVector4i rc) override;
|
||||||
void Draw(u32 vertex_count, u32 base_vertex) override;
|
void Draw(u32 vertex_count, u32 base_vertex) override;
|
||||||
void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) override;
|
void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) override;
|
||||||
void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) override;
|
void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) override;
|
||||||
|
@ -404,8 +403,8 @@ private:
|
||||||
std::array<id<MTLTexture>, MAX_TEXTURE_SAMPLERS> m_current_textures = {};
|
std::array<id<MTLTexture>, MAX_TEXTURE_SAMPLERS> m_current_textures = {};
|
||||||
std::array<id<MTLSamplerState>, MAX_TEXTURE_SAMPLERS> m_current_samplers = {};
|
std::array<id<MTLSamplerState>, MAX_TEXTURE_SAMPLERS> m_current_samplers = {};
|
||||||
id<MTLBuffer> m_current_ssbo = nil;
|
id<MTLBuffer> m_current_ssbo = nil;
|
||||||
Common::Rectangle<s32> m_current_viewport = {};
|
GSVector4i m_current_viewport = {};
|
||||||
Common::Rectangle<s32> m_current_scissor = {};
|
GSVector4i m_current_scissor = {};
|
||||||
|
|
||||||
bool m_vsync_enabled = false;
|
bool m_vsync_enabled = false;
|
||||||
|
|
||||||
|
|
|
@ -766,14 +766,12 @@ bool OpenGLDevice::BeginPresent(bool skip_present)
|
||||||
m_last_blend_state.write_a);
|
m_last_blend_state.write_a);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
const Common::Rectangle<s32> window_rc =
|
|
||||||
Common::Rectangle<s32>::FromExtents(0, 0, m_window_info.surface_width, m_window_info.surface_height);
|
|
||||||
|
|
||||||
m_current_fbo = 0;
|
m_current_fbo = 0;
|
||||||
m_num_current_render_targets = 0;
|
m_num_current_render_targets = 0;
|
||||||
std::memset(m_current_render_targets.data(), 0, sizeof(m_current_render_targets));
|
std::memset(m_current_render_targets.data(), 0, sizeof(m_current_render_targets));
|
||||||
m_current_depth_target = nullptr;
|
m_current_depth_target = nullptr;
|
||||||
|
|
||||||
|
const GSVector4i window_rc = GSVector4i(0, 0, m_window_info.surface_width, m_window_info.surface_height);
|
||||||
m_last_viewport = window_rc;
|
m_last_viewport = window_rc;
|
||||||
m_last_scissor = window_rc;
|
m_last_scissor = window_rc;
|
||||||
UpdateViewport();
|
UpdateViewport();
|
||||||
|
@ -1220,20 +1218,18 @@ void OpenGLDevice::SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDevice::SetViewport(s32 x, s32 y, s32 width, s32 height)
|
void OpenGLDevice::SetViewport(const GSVector4i rc)
|
||||||
{
|
{
|
||||||
const Common::Rectangle<s32> rc = Common::Rectangle<s32>::FromExtents(x, y, width, height);
|
if (m_last_viewport.eq(rc))
|
||||||
if (m_last_viewport == rc)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_last_viewport = rc;
|
m_last_viewport = rc;
|
||||||
UpdateViewport();
|
UpdateViewport();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDevice::SetScissor(s32 x, s32 y, s32 width, s32 height)
|
void OpenGLDevice::SetScissor(const GSVector4i rc)
|
||||||
{
|
{
|
||||||
const Common::Rectangle<s32> rc = Common::Rectangle<s32>::FromExtents(x, y, width, height);
|
if (m_last_scissor.eq(rc))
|
||||||
if (m_last_scissor == rc)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_last_scissor = rc;
|
m_last_scissor = rc;
|
||||||
|
@ -1242,10 +1238,10 @@ void OpenGLDevice::SetScissor(s32 x, s32 y, s32 width, s32 height)
|
||||||
|
|
||||||
void OpenGLDevice::UpdateViewport()
|
void OpenGLDevice::UpdateViewport()
|
||||||
{
|
{
|
||||||
glViewport(m_last_viewport.left, m_last_viewport.top, m_last_viewport.GetWidth(), m_last_viewport.GetHeight());
|
glViewport(m_last_viewport.left, m_last_viewport.top, m_last_viewport.width(), m_last_viewport.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDevice::UpdateScissor()
|
void OpenGLDevice::UpdateScissor()
|
||||||
{
|
{
|
||||||
glScissor(m_last_scissor.left, m_last_scissor.top, m_last_scissor.GetWidth(), m_last_scissor.GetHeight());
|
glScissor(m_last_scissor.left, m_last_scissor.top, m_last_scissor.width(), m_last_scissor.height());
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
#include "opengl_pipeline.h"
|
#include "opengl_pipeline.h"
|
||||||
#include "opengl_texture.h"
|
#include "opengl_texture.h"
|
||||||
|
|
||||||
#include "common/rectangle.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
@ -96,8 +94,8 @@ public:
|
||||||
void SetPipeline(GPUPipeline* pipeline) override;
|
void SetPipeline(GPUPipeline* pipeline) override;
|
||||||
void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) override;
|
void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) override;
|
||||||
void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) override;
|
void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) override;
|
||||||
void SetViewport(s32 x, s32 y, s32 width, s32 height) override;
|
void SetViewport(const GSVector4i rc) override;
|
||||||
void SetScissor(s32 x, s32 y, s32 width, s32 height) override;
|
void SetScissor(const GSVector4i rc) override;
|
||||||
void Draw(u32 vertex_count, u32 base_vertex) override;
|
void Draw(u32 vertex_count, u32 base_vertex) override;
|
||||||
void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) override;
|
void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) override;
|
||||||
void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) override;
|
void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) override;
|
||||||
|
@ -203,8 +201,8 @@ private:
|
||||||
u32 m_last_texture_unit = 0;
|
u32 m_last_texture_unit = 0;
|
||||||
std::array<std::pair<GLuint, GLuint>, MAX_TEXTURE_SAMPLERS> m_last_samplers = {};
|
std::array<std::pair<GLuint, GLuint>, MAX_TEXTURE_SAMPLERS> m_last_samplers = {};
|
||||||
GLuint m_last_ssbo = 0;
|
GLuint m_last_ssbo = 0;
|
||||||
Common::Rectangle<s32> m_last_viewport{0, 0, 1, 1};
|
GSVector4i m_last_viewport = {};
|
||||||
Common::Rectangle<s32> m_last_scissor{0, 0, 1, 1};
|
GSVector4i m_last_scissor = GSVector4i::cxpr(0, 0, 1, 1);
|
||||||
|
|
||||||
// Misc framebuffers
|
// Misc framebuffers
|
||||||
GLuint m_read_fbo = 0;
|
GLuint m_read_fbo = 0;
|
||||||
|
|
|
@ -620,8 +620,8 @@ void PostProcessing::Chain::DestroyTextures()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PostProcessing::Chain::Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target,
|
bool PostProcessing::Chain::Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target,
|
||||||
s32 final_left, s32 final_top, s32 final_width, s32 final_height, s32 orig_width,
|
GSVector4i final_rect, s32 orig_width, s32 orig_height, s32 native_width,
|
||||||
s32 orig_height, s32 native_width, s32 native_height)
|
s32 native_height)
|
||||||
{
|
{
|
||||||
GL_SCOPE_FMT("{} Apply", m_section);
|
GL_SCOPE_FMT("{} Apply", m_section);
|
||||||
|
|
||||||
|
@ -634,9 +634,8 @@ bool PostProcessing::Chain::Apply(GPUTexture* input_color, GPUTexture* input_dep
|
||||||
{
|
{
|
||||||
const bool is_final = (stage.get() == m_stages.back().get());
|
const bool is_final = (stage.get() == m_stages.back().get());
|
||||||
|
|
||||||
if (!stage->Apply(input_color, input_depth, is_final ? final_target : output, final_left, final_top, final_width,
|
if (!stage->Apply(input_color, input_depth, is_final ? final_target : output, final_rect, orig_width, orig_height,
|
||||||
final_height, orig_width, orig_height, native_width, native_height, m_target_width,
|
native_width, native_height, m_target_width, m_target_height))
|
||||||
m_target_height))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,8 +134,8 @@ public:
|
||||||
bool CheckTargets(GPUTexture::Format target_format, u32 target_width, u32 target_height,
|
bool CheckTargets(GPUTexture::Format target_format, u32 target_width, u32 target_height,
|
||||||
ProgressCallback* progress = nullptr);
|
ProgressCallback* progress = nullptr);
|
||||||
|
|
||||||
bool Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target, s32 final_left, s32 final_top,
|
bool Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target, const GSVector4i final_rect,
|
||||||
s32 final_width, s32 final_height, s32 orig_width, s32 orig_height, s32 native_width, s32 native_height);
|
s32 orig_width, s32 orig_height, s32 native_width, s32 native_height);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ClearStagesWithError(const Error& error);
|
void ClearStagesWithError(const Error& error);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include "gpu_texture.h"
|
#include "gpu_texture.h"
|
||||||
|
|
||||||
#include "common/rectangle.h"
|
#include "common/gsvector.h"
|
||||||
#include "common/settings_interface.h"
|
#include "common/settings_interface.h"
|
||||||
#include "common/timer.h"
|
#include "common/timer.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
@ -49,9 +49,9 @@ public:
|
||||||
|
|
||||||
virtual bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height, ProgressCallback* progress) = 0;
|
virtual bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height, ProgressCallback* progress) = 0;
|
||||||
|
|
||||||
virtual bool Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target, s32 final_left,
|
virtual bool Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target, GSVector4i final_rect,
|
||||||
s32 final_top, s32 final_width, s32 final_height, s32 orig_width, s32 orig_height,
|
s32 orig_width, s32 orig_height, s32 native_width, s32 native_height, u32 target_width,
|
||||||
s32 native_width, s32 native_height, u32 target_width, u32 target_height) = 0;
|
u32 target_height) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void ParseKeyValue(std::string_view line, std::string_view* key, std::string_view* value);
|
static void ParseKeyValue(std::string_view line, std::string_view* key, std::string_view* value);
|
||||||
|
|
|
@ -1490,16 +1490,15 @@ bool PostProcessing::ReShadeFXShader::ResizeOutput(GPUTexture::Format format, u3
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PostProcessing::ReShadeFXShader::Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target,
|
bool PostProcessing::ReShadeFXShader::Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target,
|
||||||
s32 final_left, s32 final_top, s32 final_width, s32 final_height,
|
GSVector4i final_rect, s32 orig_width, s32 orig_height, s32 native_width,
|
||||||
s32 orig_width, s32 orig_height, s32 native_width, s32 native_height,
|
s32 native_height, u32 target_width, u32 target_height)
|
||||||
u32 target_width, u32 target_height)
|
|
||||||
{
|
{
|
||||||
GL_PUSH_FMT("PostProcessingShaderFX {}", m_name);
|
GL_PUSH_FMT("PostProcessingShaderFX {}", m_name);
|
||||||
|
|
||||||
m_frame_count++;
|
m_frame_count++;
|
||||||
|
|
||||||
// Reshade always draws at full size.
|
// Reshade always draws at full size.
|
||||||
g_gpu_device->SetViewportAndScissor(0, 0, target_width, target_height);
|
g_gpu_device->SetViewportAndScissor(final_rect);
|
||||||
|
|
||||||
if (m_uniforms_size > 0)
|
if (m_uniforms_size > 0)
|
||||||
{
|
{
|
||||||
|
@ -1675,84 +1674,85 @@ bool PostProcessing::ReShadeFXShader::Apply(GPUTexture* input_color, GPUTexture*
|
||||||
|
|
||||||
case SourceOptionType::ViewportX:
|
case SourceOptionType::ViewportX:
|
||||||
{
|
{
|
||||||
const float value = static_cast<float>(final_left);
|
const float value = static_cast<float>(final_rect.left);
|
||||||
std::memcpy(dst, &value, sizeof(value));
|
std::memcpy(dst, &value, sizeof(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SourceOptionType::ViewportY:
|
case SourceOptionType::ViewportY:
|
||||||
{
|
{
|
||||||
const float value = static_cast<float>(final_top);
|
const float value = static_cast<float>(final_rect.top);
|
||||||
std::memcpy(dst, &value, sizeof(value));
|
std::memcpy(dst, &value, sizeof(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SourceOptionType::ViewportWidth:
|
case SourceOptionType::ViewportWidth:
|
||||||
{
|
{
|
||||||
const float value = static_cast<float>(final_width);
|
const float value = static_cast<float>(final_rect.width());
|
||||||
std::memcpy(dst, &value, sizeof(value));
|
std::memcpy(dst, &value, sizeof(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SourceOptionType::ViewportHeight:
|
case SourceOptionType::ViewportHeight:
|
||||||
{
|
{
|
||||||
const float value = static_cast<float>(final_height);
|
const float value = static_cast<float>(final_rect.height());
|
||||||
std::memcpy(dst, &value, sizeof(value));
|
std::memcpy(dst, &value, sizeof(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SourceOptionType::ViewportOffset:
|
case SourceOptionType::ViewportOffset:
|
||||||
{
|
{
|
||||||
const float value[2] = {static_cast<float>(final_left), static_cast<float>(final_top)};
|
GSVector4::storel(dst, GSVector4(final_rect));
|
||||||
std::memcpy(dst, &value, sizeof(value));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SourceOptionType::ViewportSize:
|
case SourceOptionType::ViewportSize:
|
||||||
{
|
{
|
||||||
const float value[2] = {static_cast<float>(final_width), static_cast<float>(final_height)};
|
const float value[2] = {static_cast<float>(final_rect.width()), static_cast<float>(final_rect.height())};
|
||||||
std::memcpy(dst, &value, sizeof(value));
|
std::memcpy(dst, &value, sizeof(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SourceOptionType::InternalPixelSize:
|
case SourceOptionType::InternalPixelSize:
|
||||||
{
|
{
|
||||||
const float value[2] = {static_cast<float>(final_width) / static_cast<float>(orig_width),
|
const float value[2] = {static_cast<float>(final_rect.width()) / static_cast<float>(orig_width),
|
||||||
static_cast<float>(final_height) / static_cast<float>(orig_height)};
|
static_cast<float>(final_rect.height()) / static_cast<float>(orig_height)};
|
||||||
std::memcpy(dst, value, sizeof(value));
|
std::memcpy(dst, value, sizeof(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SourceOptionType::InternalNormPixelSize:
|
case SourceOptionType::InternalNormPixelSize:
|
||||||
{
|
{
|
||||||
const float value[2] = {
|
const float value[2] = {(static_cast<float>(final_rect.width()) / static_cast<float>(orig_width)) /
|
||||||
(static_cast<float>(final_width) / static_cast<float>(orig_width)) / static_cast<float>(target_width),
|
static_cast<float>(target_width),
|
||||||
(static_cast<float>(final_height) / static_cast<float>(orig_height)) / static_cast<float>(target_height)};
|
(static_cast<float>(final_rect.height()) / static_cast<float>(orig_height)) /
|
||||||
|
static_cast<float>(target_height)};
|
||||||
std::memcpy(dst, value, sizeof(value));
|
std::memcpy(dst, value, sizeof(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SourceOptionType::NativePixelSize:
|
case SourceOptionType::NativePixelSize:
|
||||||
{
|
{
|
||||||
const float value[2] = {static_cast<float>(final_width) / static_cast<float>(native_width),
|
const float value[2] = {static_cast<float>(final_rect.width()) / static_cast<float>(native_width),
|
||||||
static_cast<float>(final_height) / static_cast<float>(native_height)};
|
static_cast<float>(final_rect.height()) / static_cast<float>(native_height)};
|
||||||
std::memcpy(dst, value, sizeof(value));
|
std::memcpy(dst, value, sizeof(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SourceOptionType::NativeNormPixelSize:
|
case SourceOptionType::NativeNormPixelSize:
|
||||||
{
|
{
|
||||||
const float value[2] = {
|
const float value[2] = {(static_cast<float>(final_rect.width()) / static_cast<float>(native_width)) /
|
||||||
(static_cast<float>(final_width) / static_cast<float>(native_width)) / static_cast<float>(target_width),
|
static_cast<float>(target_width),
|
||||||
(static_cast<float>(final_height) / static_cast<float>(native_height)) / static_cast<float>(target_height)};
|
(static_cast<float>(final_rect.height()) / static_cast<float>(native_height)) /
|
||||||
|
static_cast<float>(target_height)};
|
||||||
std::memcpy(dst, value, sizeof(value));
|
std::memcpy(dst, value, sizeof(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SourceOptionType::BufferToViewportRatio:
|
case SourceOptionType::BufferToViewportRatio:
|
||||||
{
|
{
|
||||||
const float value[2] = {static_cast<float>(target_width) / static_cast<float>(final_width),
|
const float value[2] = {static_cast<float>(target_width) / static_cast<float>(final_rect.width()),
|
||||||
static_cast<float>(target_height) / static_cast<float>(final_height)};
|
static_cast<float>(target_height) / static_cast<float>(final_rect.height())};
|
||||||
std::memcpy(dst, value, sizeof(value));
|
std::memcpy(dst, value, sizeof(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -31,9 +31,9 @@ public:
|
||||||
|
|
||||||
bool ResizeOutput(GPUTexture::Format format, u32 width, u32 height) override;
|
bool ResizeOutput(GPUTexture::Format format, u32 width, u32 height) override;
|
||||||
bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height, ProgressCallback* progress) override;
|
bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height, ProgressCallback* progress) override;
|
||||||
bool Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target, s32 final_left, s32 final_top,
|
bool Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target, GSVector4i final_rect,
|
||||||
s32 final_width, s32 final_height, s32 orig_width, s32 orig_height, s32 native_width, s32 native_height,
|
s32 orig_width, s32 orig_height, s32 native_width, s32 native_height, u32 target_width,
|
||||||
u32 target_width, u32 target_height) override;
|
u32 target_height) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using TextureID = s32;
|
using TextureID = s32;
|
||||||
|
|
|
@ -168,9 +168,8 @@ bool PostProcessing::GLSLShader::CompilePipeline(GPUTexture::Format format, u32
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PostProcessing::GLSLShader::Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target,
|
bool PostProcessing::GLSLShader::Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target,
|
||||||
s32 final_left, s32 final_top, s32 final_width, s32 final_height, s32 orig_width,
|
GSVector4i final_rect, s32 orig_width, s32 orig_height, s32 native_width,
|
||||||
s32 orig_height, s32 native_width, s32 native_height, u32 target_width,
|
s32 native_height, u32 target_width, u32 target_height)
|
||||||
u32 target_height)
|
|
||||||
{
|
{
|
||||||
GL_SCOPE_FMT("GLSL Shader {}", m_name);
|
GL_SCOPE_FMT("GLSL Shader {}", m_name);
|
||||||
|
|
||||||
|
@ -188,12 +187,12 @@ bool PostProcessing::GLSLShader::Apply(GPUTexture* input_color, GPUTexture* inpu
|
||||||
|
|
||||||
g_gpu_device->SetPipeline(m_pipeline.get());
|
g_gpu_device->SetPipeline(m_pipeline.get());
|
||||||
g_gpu_device->SetTextureSampler(0, input_color, m_sampler.get());
|
g_gpu_device->SetTextureSampler(0, input_color, m_sampler.get());
|
||||||
g_gpu_device->SetViewportAndScissor(final_left, final_top, final_width, final_height);
|
g_gpu_device->SetViewportAndScissor(final_rect);
|
||||||
|
|
||||||
const u32 uniforms_size = GetUniformsSize();
|
const u32 uniforms_size = GetUniformsSize();
|
||||||
void* uniforms = g_gpu_device->MapUniformBuffer(uniforms_size);
|
void* uniforms = g_gpu_device->MapUniformBuffer(uniforms_size);
|
||||||
FillUniformBuffer(uniforms, final_left, final_top, final_width, final_height, target_width, target_height, orig_width,
|
FillUniformBuffer(uniforms, final_rect.left, final_rect.top, final_rect.width(), final_rect.height(), target_width,
|
||||||
orig_height, native_width, native_height,
|
target_height, orig_width, orig_height, native_width, native_height,
|
||||||
static_cast<float>(PostProcessing::GetTimer().GetTimeSeconds()));
|
static_cast<float>(PostProcessing::GetTimer().GetTimeSeconds()));
|
||||||
g_gpu_device->UnmapUniformBuffer(uniforms_size);
|
g_gpu_device->UnmapUniformBuffer(uniforms_size);
|
||||||
g_gpu_device->Draw(3, 0);
|
g_gpu_device->Draw(3, 0);
|
||||||
|
|
|
@ -24,9 +24,9 @@ public:
|
||||||
|
|
||||||
bool ResizeOutput(GPUTexture::Format format, u32 width, u32 height) override;
|
bool ResizeOutput(GPUTexture::Format format, u32 width, u32 height) override;
|
||||||
bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height, ProgressCallback* progress) override;
|
bool CompilePipeline(GPUTexture::Format format, u32 width, u32 height, ProgressCallback* progress) override;
|
||||||
bool Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target, s32 final_left, s32 final_top,
|
bool Apply(GPUTexture* input_color, GPUTexture* input_depth, GPUTexture* final_target, GSVector4i final_rect,
|
||||||
s32 final_width, s32 final_height, s32 orig_width, s32 orig_height, s32 native_width, s32 native_height,
|
s32 orig_width, s32 orig_height, s32 native_width, s32 native_height, u32 target_width,
|
||||||
u32 target_width, u32 target_height) override;
|
u32 target_height) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct CommonUniforms
|
struct CommonUniforms
|
||||||
|
|
|
@ -3611,15 +3611,14 @@ void VulkanDevice::SetInitialPipelineState()
|
||||||
|
|
||||||
const VkViewport vp = {static_cast<float>(m_current_viewport.left),
|
const VkViewport vp = {static_cast<float>(m_current_viewport.left),
|
||||||
static_cast<float>(m_current_viewport.top),
|
static_cast<float>(m_current_viewport.top),
|
||||||
static_cast<float>(m_current_viewport.GetWidth()),
|
static_cast<float>(m_current_viewport.width()),
|
||||||
static_cast<float>(m_current_viewport.GetHeight()),
|
static_cast<float>(m_current_viewport.height()),
|
||||||
0.0f,
|
0.0f,
|
||||||
1.0f};
|
1.0f};
|
||||||
vkCmdSetViewport(GetCurrentCommandBuffer(), 0, 1, &vp);
|
vkCmdSetViewport(GetCurrentCommandBuffer(), 0, 1, &vp);
|
||||||
|
|
||||||
const VkRect2D vrc = {
|
const VkRect2D vrc = {{m_current_scissor.left, m_current_scissor.top},
|
||||||
{m_current_scissor.left, m_current_scissor.top},
|
{static_cast<u32>(m_current_scissor.width()), static_cast<u32>(m_current_scissor.height())}};
|
||||||
{static_cast<u32>(m_current_scissor.GetWidth()), static_cast<u32>(m_current_scissor.GetHeight())}};
|
|
||||||
vkCmdSetScissor(GetCurrentCommandBuffer(), 0, 1, &vrc);
|
vkCmdSetScissor(GetCurrentCommandBuffer(), 0, 1, &vrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3706,10 +3705,9 @@ void VulkanDevice::UnbindTextureBuffer(VulkanTextureBuffer* buf)
|
||||||
m_dirty_flags |= DIRTY_FLAG_TEXTURES_OR_SAMPLERS;
|
m_dirty_flags |= DIRTY_FLAG_TEXTURES_OR_SAMPLERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanDevice::SetViewport(s32 x, s32 y, s32 width, s32 height)
|
void VulkanDevice::SetViewport(const GSVector4i rc)
|
||||||
{
|
{
|
||||||
const Common::Rectangle<s32> rc = Common::Rectangle<s32>::FromExtents(x, y, width, height);
|
if (m_current_viewport.eq(rc))
|
||||||
if (m_current_viewport == rc)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_current_viewport = rc;
|
m_current_viewport = rc;
|
||||||
|
@ -3717,15 +3715,18 @@ void VulkanDevice::SetViewport(s32 x, s32 y, s32 width, s32 height)
|
||||||
if (m_dirty_flags & DIRTY_FLAG_INITIAL)
|
if (m_dirty_flags & DIRTY_FLAG_INITIAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const VkViewport vp = {
|
const VkViewport vp = {static_cast<float>(rc.x),
|
||||||
static_cast<float>(x), static_cast<float>(y), static_cast<float>(width), static_cast<float>(height), 0.0f, 1.0f};
|
static_cast<float>(rc.y),
|
||||||
|
static_cast<float>(rc.width()),
|
||||||
|
static_cast<float>(rc.height()),
|
||||||
|
0.0f,
|
||||||
|
1.0f};
|
||||||
vkCmdSetViewport(GetCurrentCommandBuffer(), 0, 1, &vp);
|
vkCmdSetViewport(GetCurrentCommandBuffer(), 0, 1, &vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanDevice::SetScissor(s32 x, s32 y, s32 width, s32 height)
|
void VulkanDevice::SetScissor(const GSVector4i rc)
|
||||||
{
|
{
|
||||||
const Common::Rectangle<s32> rc = Common::Rectangle<s32>::FromExtents(x, y, width, height);
|
if (m_current_scissor.eq(rc))
|
||||||
if (m_current_scissor == rc)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_current_scissor = rc;
|
m_current_scissor = rc;
|
||||||
|
@ -3733,7 +3734,7 @@ void VulkanDevice::SetScissor(s32 x, s32 y, s32 width, s32 height)
|
||||||
if (m_dirty_flags & DIRTY_FLAG_INITIAL)
|
if (m_dirty_flags & DIRTY_FLAG_INITIAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const VkRect2D vrc = {{x, y}, {static_cast<u32>(width), static_cast<u32>(height)}};
|
const VkRect2D vrc = {{rc.x, rc.y}, {static_cast<u32>(rc.width()), static_cast<u32>(rc.height())}};
|
||||||
vkCmdSetScissor(GetCurrentCommandBuffer(), 0, 1, &vrc);
|
vkCmdSetScissor(GetCurrentCommandBuffer(), 0, 1, &vrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,8 +122,8 @@ public:
|
||||||
void SetPipeline(GPUPipeline* pipeline) override;
|
void SetPipeline(GPUPipeline* pipeline) override;
|
||||||
void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) override;
|
void SetTextureSampler(u32 slot, GPUTexture* texture, GPUSampler* sampler) override;
|
||||||
void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) override;
|
void SetTextureBuffer(u32 slot, GPUTextureBuffer* buffer) override;
|
||||||
void SetViewport(s32 x, s32 y, s32 width, s32 height) override;
|
void SetViewport(const GSVector4i rc) override;
|
||||||
void SetScissor(s32 x, s32 y, s32 width, s32 height) override;
|
void SetScissor(const GSVector4i rc) override;
|
||||||
void Draw(u32 vertex_count, u32 base_vertex) override;
|
void Draw(u32 vertex_count, u32 base_vertex) override;
|
||||||
void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) override;
|
void DrawIndexed(u32 index_count, u32 base_index, u32 base_vertex) override;
|
||||||
void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) override;
|
void DrawIndexedWithBarrier(u32 index_count, u32 base_index, u32 base_vertex, DrawBarrier type) override;
|
||||||
|
@ -477,6 +477,6 @@ private:
|
||||||
std::array<VulkanTexture*, MAX_TEXTURE_SAMPLERS> m_current_textures = {};
|
std::array<VulkanTexture*, MAX_TEXTURE_SAMPLERS> m_current_textures = {};
|
||||||
std::array<VkSampler, MAX_TEXTURE_SAMPLERS> m_current_samplers = {};
|
std::array<VkSampler, MAX_TEXTURE_SAMPLERS> m_current_samplers = {};
|
||||||
VulkanTextureBuffer* m_current_texture_buffer = nullptr;
|
VulkanTextureBuffer* m_current_texture_buffer = nullptr;
|
||||||
Common::Rectangle<s32> m_current_viewport{0, 0, 1, 1};
|
GSVector4i m_current_viewport = {};
|
||||||
Common::Rectangle<s32> m_current_scissor{0, 0, 1, 1};
|
GSVector4i m_current_scissor = GSVector4i::cxpr(0, 0, 1, 1);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue