refactor xform matrix out of gles. use xform matrix in vulkan
This commit is contained in:
parent
2f363a7355
commit
07958f08ae
|
@ -329,7 +329,8 @@ bool rend_single_frame()
|
|||
}
|
||||
while (!_pvrrc);
|
||||
bool do_swp = rend_frame(_pvrrc);
|
||||
swap_pending = settings.rend.DelayFrameSwapping && do_swp && !_pvrrc->rend.isRenderFramebuffer;
|
||||
swap_pending = settings.rend.DelayFrameSwapping && do_swp && !_pvrrc->rend.isRenderFramebuffer
|
||||
&& settings.pvr.rend != 4; // TODO Fix vulkan
|
||||
|
||||
#if !defined(TARGET_NO_THREADS)
|
||||
if (_pvrrc->rend.isRTT)
|
||||
|
|
|
@ -40,7 +40,6 @@ struct gl4_ctx
|
|||
{
|
||||
GLuint program;
|
||||
|
||||
GLuint extra_depth_scale;
|
||||
GLuint normal_matrix;
|
||||
} modvol_shader;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "oslib/oslib.h"
|
||||
#include "rend/rend.h"
|
||||
#include "rend/gui.h"
|
||||
#include "rend/transform_matrix.h"
|
||||
|
||||
//Fragment and vertex shaders code
|
||||
|
||||
|
@ -513,7 +514,6 @@ static void create_modvol_shader()
|
|||
|
||||
gl4.modvol_shader.program=gl_CompileAndLink(vshader, ModifierVolumeShader);
|
||||
gl4.modvol_shader.normal_matrix = glGetUniformLocation(gl4.modvol_shader.program, "normal_matrix");
|
||||
gl4.modvol_shader.extra_depth_scale = glGetUniformLocation(gl4.modvol_shader.program, "extra_depth_scale");
|
||||
}
|
||||
|
||||
static bool gl_create_resources()
|
||||
|
@ -639,38 +639,29 @@ static bool RenderFrame()
|
|||
DoCleanup();
|
||||
create_modvol_shader();
|
||||
|
||||
bool is_rtt = pvrrc.isRTT;
|
||||
const bool is_rtt = pvrrc.isRTT;
|
||||
|
||||
TransformMatrix<true> matrices(pvrrc);
|
||||
gl4ShaderUniforms.normal_mat = matrices.GetNormalMatrix();
|
||||
const glm::mat4& scissor_mat = matrices.GetScissorMatrix();
|
||||
ViewportMatrix = matrices.GetViewportMatrix();
|
||||
|
||||
//these should be adjusted based on the current PVR scaling etc params
|
||||
float dc_width;
|
||||
float dc_height;
|
||||
GetFramebufferSize(dc_width, dc_height);
|
||||
|
||||
if (!is_rtt)
|
||||
gcflip = 0;
|
||||
else
|
||||
gcflip = 1;
|
||||
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
float scissoring_scale_x;
|
||||
float scissoring_scale_y;
|
||||
GetFramebufferScaling(scale_x, scale_y, scissoring_scale_x, scissoring_scale_y);
|
||||
|
||||
dc_width *= scale_x;
|
||||
dc_height *= scale_y;
|
||||
|
||||
/*
|
||||
Handle Dc to screen scaling
|
||||
*/
|
||||
float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
||||
const float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
||||
int rendering_width;
|
||||
int rendering_height;
|
||||
if (is_rtt)
|
||||
{
|
||||
int scaling = settings.rend.RenderToTextureBuffer ? 1 : settings.rend.RenderToTextureUpscale;
|
||||
rendering_width = dc_width * scaling;
|
||||
rendering_height = dc_height * scaling;
|
||||
rendering_width = matrices.GetDreamcastViewport().x * scaling;
|
||||
rendering_height = matrices.GetDreamcastViewport().y * scaling;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -679,11 +670,6 @@ static bool RenderFrame()
|
|||
}
|
||||
resize(rendering_width, rendering_height);
|
||||
|
||||
float ds2s_offs_x;
|
||||
|
||||
glm::mat4 scissor_mat;
|
||||
SetupMatrices(dc_width, dc_height, scale_x, scale_y, scissoring_scale_x, scissoring_scale_y, ds2s_offs_x, gl4ShaderUniforms.normal_mat, scissor_mat);
|
||||
|
||||
gl4ShaderUniforms.extra_depth_scale = settings.rend.ExtraDepthScale;
|
||||
|
||||
//DEBUG_LOG(RENDERER, "scale: %f, %f, %f, %f", gl4ShaderUniforms.scale_coefs[0], gl4ShaderUniforms.scale_coefs[1], gl4ShaderUniforms.scale_coefs[2], gl4ShaderUniforms.scale_coefs[3]);
|
||||
|
@ -724,7 +710,6 @@ static bool RenderFrame()
|
|||
glcache.UseProgram(gl4.modvol_shader.program);
|
||||
|
||||
glUniformMatrix4fv(gl4.modvol_shader.normal_matrix, 1, GL_FALSE, &gl4ShaderUniforms.normal_mat[0][0]);
|
||||
glUniform1f(gl4.modvol_shader.extra_depth_scale, gl4ShaderUniforms.extra_depth_scale);
|
||||
|
||||
gl4ShaderUniforms.PT_ALPHA=(PT_ALPHA_REF&0xFF)/255.0f;
|
||||
|
||||
|
@ -768,7 +753,8 @@ static bool RenderFrame()
|
|||
}
|
||||
DEBUG_LOG(RENDERER, "RTT packmode=%d stride=%d - %d,%d -> %d,%d", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8,
|
||||
FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max);
|
||||
output_fbo = gl4BindRTT(FB_W_SOF1 & VRAM_MASK, dc_width, dc_height, channels, format);
|
||||
output_fbo = gl4BindRTT(FB_W_SOF1 & VRAM_MASK, (u32)lroundf(matrices.GetDreamcastViewport().x),
|
||||
(u32)lroundf(matrices.GetDreamcastViewport().y), channels, format);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -809,23 +795,7 @@ static bool RenderFrame()
|
|||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(struct PolyParam) * pvrrc.global_param_tr.used(), pvrrc.global_param_tr.head(), GL_STATIC_DRAW);
|
||||
glCheck();
|
||||
|
||||
//not all scaling affects pixel operations, scale to adjust for that
|
||||
scale_x *= scissoring_scale_x;
|
||||
|
||||
#if 0
|
||||
//handy to debug really stupid render-not-working issues ...
|
||||
DEBUG_LOG(RENDERER, "SS: %dx%d", screen_width, screen_height);
|
||||
DEBUG_LOG(RENDERER, "SCI: %d, %f", pvrrc.fb_X_CLIP.max, dc2s_scale_h);
|
||||
DEBUG_LOG(RENDERER, "SCI: %f, %f, %f, %f", offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h);
|
||||
#endif
|
||||
|
||||
bool wide_screen_on = !is_rtt && settings.rend.WideScreen
|
||||
&& pvrrc.fb_X_CLIP.min == 0
|
||||
&& lroundf((pvrrc.fb_X_CLIP.max + 1) / scale_x) == 640L
|
||||
&& pvrrc.fb_Y_CLIP.min == 0
|
||||
&& lroundf((pvrrc.fb_Y_CLIP.max + 1) / scale_y) == 480L;
|
||||
|
||||
if (!wide_screen_on)
|
||||
if (is_rtt || !settings.rend.WideScreen || matrices.IsClipped())
|
||||
{
|
||||
float width;
|
||||
float height;
|
||||
|
@ -853,9 +823,9 @@ static bool RenderFrame()
|
|||
min_y += height;
|
||||
height = -height;
|
||||
}
|
||||
if (ds2s_offs_x > 0)
|
||||
if (matrices.GetSidebarWidth() > 0)
|
||||
{
|
||||
float scaled_offs_x = ds2s_offs_x * screen_scaling;
|
||||
float scaled_offs_x = matrices.GetSidebarWidth() * screen_scaling;
|
||||
|
||||
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glcache.Enable(GL_SCISSOR_TEST);
|
||||
|
@ -883,8 +853,6 @@ static bool RenderFrame()
|
|||
glcache.Enable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
//restore scale_x
|
||||
scale_x /= scissoring_scale_x;
|
||||
gl4DrawStrips(output_fbo, rendering_width, rendering_height);
|
||||
}
|
||||
else
|
||||
|
@ -895,7 +863,7 @@ static bool RenderFrame()
|
|||
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
gl4DrawFramebuffer(dc_width, dc_height);
|
||||
gl4DrawFramebuffer(640.f, 480.f);
|
||||
}
|
||||
|
||||
eglCheck();
|
||||
|
@ -917,7 +885,7 @@ struct gl4rend : Renderer
|
|||
{
|
||||
screen_width=w;
|
||||
screen_height=h;
|
||||
resize(lroundf(w * settings.rend.ScreenScaling / 100.f), lroundf(h * settings.rend.ScreenScaling / 100.f));
|
||||
resize((int)lroundf(w * settings.rend.ScreenScaling / 100.f), (int)lroundf(h * settings.rend.ScreenScaling / 100.f));
|
||||
}
|
||||
void Term() override
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "wsi/gl_context.h"
|
||||
#include "cfg/cfg.h"
|
||||
#include "rend/osd.h"
|
||||
#include "rend/transform_matrix.h"
|
||||
|
||||
#ifdef GLES
|
||||
#ifndef GL_RED
|
||||
|
@ -20,7 +21,6 @@
|
|||
#include "oslib/oslib.h"
|
||||
#include "rend/rend.h"
|
||||
#include "input/gamepad.h"
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
float fb_scale_x, fb_scale_y; // FIXME
|
||||
|
||||
|
@ -816,7 +816,6 @@ static void create_modvol_shader()
|
|||
gl.modvol_shader.normal_matrix = glGetUniformLocation(gl.modvol_shader.program, "normal_matrix");
|
||||
gl.modvol_shader.sp_ShaderColor = glGetUniformLocation(gl.modvol_shader.program, "sp_ShaderColor");
|
||||
gl.modvol_shader.depth_scale = glGetUniformLocation(gl.modvol_shader.program, "depth_scale");
|
||||
gl.modvol_shader.extra_depth_scale = glGetUniformLocation(gl.modvol_shader.program, "extra_depth_scale");
|
||||
}
|
||||
|
||||
bool gl_create_resources()
|
||||
|
@ -1026,161 +1025,6 @@ static void upload_vertex_indices()
|
|||
glCheck();
|
||||
}
|
||||
|
||||
void GetFramebufferScaling(float& scale_x, float& scale_y, float& scissoring_scale_x, float& scissoring_scale_y)
|
||||
{
|
||||
scale_x = 1;
|
||||
scale_y = 1;
|
||||
scissoring_scale_x = 1;
|
||||
scissoring_scale_y = 1;
|
||||
|
||||
if (!pvrrc.isRTT && !pvrrc.isRenderFramebuffer)
|
||||
{
|
||||
scale_x = fb_scale_x;
|
||||
scale_y = fb_scale_y;
|
||||
if (SCALER_CTL.vscalefactor >= 0x400)
|
||||
{
|
||||
// Interlace mode A (single framebuffer)
|
||||
if (SCALER_CTL.interlace == 0)
|
||||
scale_y *= (float)SCALER_CTL.vscalefactor / 0x400;
|
||||
else
|
||||
// Interlace mode B (alternating framebuffers)
|
||||
scissoring_scale_y /= (float)SCALER_CTL.vscalefactor / 0x400;
|
||||
}
|
||||
|
||||
// VO pixel doubling is done after fb rendering/clipping
|
||||
// so it should be used for scissoring as well
|
||||
if (VO_CONTROL.pixel_double)
|
||||
scale_x *= 0.5f;
|
||||
|
||||
// the X Scaler halves the horizontal resolution but
|
||||
// before clipping/scissoring
|
||||
if (SCALER_CTL.hscale)
|
||||
{
|
||||
scissoring_scale_x /= 2.f;
|
||||
scale_x *= 2.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GetFramebufferSize(float& dc_width, float& dc_height)
|
||||
{
|
||||
if (pvrrc.isRTT)
|
||||
{
|
||||
dc_width = pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1;
|
||||
dc_height = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dc_width = 640;
|
||||
dc_height = 480;
|
||||
}
|
||||
}
|
||||
|
||||
void SetupMatrices(float dc_width, float dc_height,
|
||||
float scale_x, float scale_y, float scissoring_scale_x, float scissoring_scale_y,
|
||||
float &ds2s_offs_x, glm::mat4& normal_mat, glm::mat4& scissor_mat)
|
||||
{
|
||||
float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
||||
|
||||
if (pvrrc.isRTT)
|
||||
{
|
||||
ShaderUniforms.normal_mat = glm::translate(glm::vec3(-1, -1, 0))
|
||||
* glm::scale(glm::vec3(2.0f / dc_width, 2.0f / dc_height, 1.f));
|
||||
scissor_mat = ShaderUniforms.normal_mat;
|
||||
}
|
||||
else
|
||||
{
|
||||
float startx = 0;
|
||||
float starty = 0;
|
||||
bool vga = FB_R_CTRL.vclk_div == 1;
|
||||
switch (SPG_LOAD.hcount)
|
||||
{
|
||||
case 857: // NTSC, VGA
|
||||
startx = VO_STARTX.HStart - (vga ? 0xa8 : 0xa4);
|
||||
break;
|
||||
case 863: // PAL
|
||||
startx = VO_STARTX.HStart - 0xae;
|
||||
break;
|
||||
default:
|
||||
INFO_LOG(PVR, "unknown video mode: hcount %d", SPG_LOAD.hcount);
|
||||
break;
|
||||
}
|
||||
switch (SPG_LOAD.vcount)
|
||||
{
|
||||
case 524: // NTSC, VGA
|
||||
starty = VO_STARTY.VStart_field1 - (vga ? 0x28 : 0x12);
|
||||
break;
|
||||
case 262: // NTSC 240p
|
||||
starty = VO_STARTY.VStart_field1 - 0x11;
|
||||
break;
|
||||
case 624: // PAL
|
||||
starty = VO_STARTY.VStart_field1 - 0x2d;
|
||||
break;
|
||||
case 312: // PAL 240p
|
||||
starty = VO_STARTY.VStart_field1 - 0x2e;
|
||||
break;
|
||||
default:
|
||||
INFO_LOG(PVR, "unknown video mode: vcount %d", SPG_LOAD.vcount);
|
||||
break;
|
||||
}
|
||||
// some heuristic...
|
||||
startx *= 0.8;
|
||||
starty *= 1.1;
|
||||
normal_mat = glm::translate(glm::vec3(startx, starty, 0));
|
||||
scissor_mat = normal_mat;
|
||||
|
||||
float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
||||
float dc2s_scale_h;
|
||||
|
||||
if (settings.rend.Rotate90)
|
||||
{
|
||||
dc2s_scale_h = screen_height / 640.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
||||
float y_coef = 2.0f / (screen_width / dc2s_scale_h * scale_y) * screen_stretching;
|
||||
float x_coef = -2.0f / dc_width;
|
||||
glm::mat4 trans_rot = glm::rotate((float)M_PI_2, glm::vec3(0, 0, 1))
|
||||
* glm::translate(glm::vec3(1, -1 + 2 * ds2s_offs_x / screen_width, 0));
|
||||
normal_mat = trans_rot
|
||||
* glm::scale(glm::vec3(x_coef, y_coef, 1.f))
|
||||
* normal_mat;
|
||||
scissor_mat = trans_rot
|
||||
* glm::scale(glm::vec3(x_coef / scissoring_scale_x,
|
||||
y_coef/ scissoring_scale_y, 1.f))
|
||||
* scissor_mat; // FIXME scale_x not used, except in dc_width???
|
||||
}
|
||||
else
|
||||
{
|
||||
dc2s_scale_h = screen_height / 480.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
||||
float x_coef = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching;
|
||||
float y_coef = -2.0f / dc_height;
|
||||
normal_mat = glm::translate(glm::vec3(-1 + 2 * ds2s_offs_x / screen_width, 1, 0))
|
||||
* glm::scale(glm::vec3(x_coef, y_coef, 1.f))
|
||||
* normal_mat;
|
||||
scissor_mat = glm::translate(glm::vec3(-1 + 2 * ds2s_offs_x / screen_width, 1, 0))
|
||||
* glm::scale(glm::vec3(x_coef / scissoring_scale_x,
|
||||
y_coef / scissoring_scale_y, 1.f))
|
||||
* scissor_mat;
|
||||
}
|
||||
}
|
||||
normal_mat = glm::scale(glm::vec3(1, 1, 1 / settings.rend.ExtraDepthScale))
|
||||
* normal_mat;
|
||||
|
||||
glm::mat4 vp_trans = glm::translate(glm::vec3(1, 1, 0));
|
||||
if (pvrrc.isRTT)
|
||||
{
|
||||
vp_trans = glm::scale(glm::vec3(dc_width / 2, dc_height / 2, 1.f))
|
||||
* vp_trans;
|
||||
}
|
||||
else
|
||||
{
|
||||
vp_trans = glm::scale(glm::vec3(screen_width * screen_scaling / 2, screen_height * screen_scaling / 2, 1.f))
|
||||
* vp_trans;
|
||||
}
|
||||
ViewportMatrix = vp_trans * normal_mat;
|
||||
scissor_mat = vp_trans * scissor_mat;
|
||||
}
|
||||
|
||||
bool RenderFrame()
|
||||
{
|
||||
DoCleanup();
|
||||
|
@ -1200,39 +1044,16 @@ bool RenderFrame()
|
|||
vtx_min_fZ *= 0.98f;
|
||||
vtx_max_fZ *= 1.001f;
|
||||
|
||||
//calculate a projection so that it matches the pvr x,y setup, and
|
||||
//a) Z is linearly scaled between 0 ... 1
|
||||
//b) W is passed though for proper perspective calculations
|
||||
|
||||
//these should be adjusted based on the current PVR scaling etc params
|
||||
float dc_width;
|
||||
float dc_height;
|
||||
GetFramebufferSize(dc_width, dc_height);
|
||||
TransformMatrix<true> matrices(pvrrc);
|
||||
ShaderUniforms.normal_mat = matrices.GetNormalMatrix();
|
||||
const glm::mat4& scissor_mat = matrices.GetScissorMatrix();
|
||||
ViewportMatrix = matrices.GetViewportMatrix();
|
||||
|
||||
if (!is_rtt)
|
||||
gcflip = 0;
|
||||
else
|
||||
gcflip = 1;
|
||||
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
float scissoring_scale_x;
|
||||
float scissoring_scale_y;
|
||||
GetFramebufferScaling(scale_x, scale_y, scissoring_scale_x, scissoring_scale_y);
|
||||
|
||||
dc_width *= scale_x;
|
||||
dc_height *= scale_y;
|
||||
|
||||
/*
|
||||
Handle Dc to screen scaling
|
||||
*/
|
||||
float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
||||
|
||||
float ds2s_offs_x;
|
||||
|
||||
glm::mat4 scissor_mat;
|
||||
SetupMatrices(dc_width, dc_height, scale_x, scale_y, scissoring_scale_x, scissoring_scale_y, ds2s_offs_x, ShaderUniforms.normal_mat, scissor_mat);
|
||||
|
||||
ShaderUniforms.depth_coefs[0] = 2 / (vtx_max_fZ - vtx_min_fZ);
|
||||
ShaderUniforms.depth_coefs[1] = -vtx_min_fZ - 1;
|
||||
ShaderUniforms.depth_coefs[2] = 0;
|
||||
|
@ -1276,7 +1097,6 @@ bool RenderFrame()
|
|||
glcache.UseProgram(gl.modvol_shader.program);
|
||||
|
||||
glUniform4fv( gl.modvol_shader.depth_scale, 1, ShaderUniforms.depth_coefs);
|
||||
glUniform1f(gl.modvol_shader.extra_depth_scale, ShaderUniforms.extra_depth_scale);
|
||||
glUniformMatrix4fv(gl.modvol_shader.normal_matrix, 1, GL_FALSE, &ShaderUniforms.normal_mat[0][0]);
|
||||
|
||||
ShaderUniforms.PT_ALPHA=(PT_ALPHA_REF&0xFF)/255.0f;
|
||||
|
@ -1287,6 +1107,8 @@ bool RenderFrame()
|
|||
ShaderUniforms.Set(&it.second);
|
||||
}
|
||||
|
||||
const float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
||||
|
||||
//setup render target first
|
||||
if (is_rtt)
|
||||
{
|
||||
|
@ -1325,7 +1147,7 @@ bool RenderFrame()
|
|||
}
|
||||
DEBUG_LOG(RENDERER, "RTT packmode=%d stride=%d - %d,%d -> %d,%d", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8,
|
||||
FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max);
|
||||
BindRTT(FB_W_SOF1 & VRAM_MASK, dc_width, dc_height, channels, format);
|
||||
BindRTT(FB_W_SOF1 & VRAM_MASK, FB_X_CLIP.max - FB_X_CLIP.min + 1, FB_Y_CLIP.max - FB_Y_CLIP.min + 1, channels, format);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1343,11 +1165,7 @@ bool RenderFrame()
|
|||
}
|
||||
}
|
||||
|
||||
bool wide_screen_on = !is_rtt && settings.rend.WideScreen
|
||||
&& pvrrc.fb_X_CLIP.min == 0
|
||||
&& lroundf((pvrrc.fb_X_CLIP.max + 1) / scale_x) == 640L
|
||||
&& pvrrc.fb_Y_CLIP.min == 0
|
||||
&& lroundf((pvrrc.fb_Y_CLIP.max + 1) / scale_y) == 480L;
|
||||
bool wide_screen_on = !is_rtt && settings.rend.WideScreen && !matrices.IsClipped();
|
||||
|
||||
//Color is cleared by the background plane
|
||||
|
||||
|
@ -1406,9 +1224,9 @@ bool RenderFrame()
|
|||
min_y += height;
|
||||
height = -height;
|
||||
}
|
||||
if (ds2s_offs_x > 0)
|
||||
if (matrices.GetSidebarWidth() > 0)
|
||||
{
|
||||
float scaled_offs_x = ds2s_offs_x * screen_scaling;
|
||||
float scaled_offs_x = matrices.GetSidebarWidth() * screen_scaling;
|
||||
|
||||
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glcache.Enable(GL_SCISSOR_TEST);
|
||||
|
|
|
@ -53,7 +53,6 @@ struct gl_ctx
|
|||
GLuint program;
|
||||
|
||||
GLuint depth_scale;
|
||||
GLuint extra_depth_scale;
|
||||
GLuint sp_ShaderColor;
|
||||
GLuint normal_matrix;
|
||||
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
// Personal message to whoever wrote this code originally: please quit programming. Stop making other people's life miserable
|
||||
/*
|
||||
This file is part of reicast.
|
||||
|
||||
reicast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
reicast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with reicast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "osd.h"
|
||||
#include "types.h"
|
||||
#include "input/gamepad.h"
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
This file is part of reicast.
|
||||
|
||||
reicast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
reicast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with reicast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <vector>
|
||||
#include "types.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
Created on: Oct 22, 2019
|
||||
|
||||
Copyright 2019 flyinghead
|
||||
|
||||
This file is part of Flycast.
|
||||
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/transform.hpp>
|
||||
#include "hw/pvr/ta_ctx.h"
|
||||
|
||||
extern float fb_scale_x, fb_scale_y;
|
||||
extern int screen_width, screen_height;
|
||||
|
||||
template<bool invertY>
|
||||
class TransformMatrix
|
||||
{
|
||||
public:
|
||||
TransformMatrix() = default;
|
||||
TransformMatrix(const rend_context& renderingContext)
|
||||
{
|
||||
CalcMatrices(&renderingContext);
|
||||
}
|
||||
|
||||
bool IsClipped() const
|
||||
{
|
||||
return renderingContext->fb_X_CLIP.min != 0
|
||||
|| lroundf((renderingContext->fb_X_CLIP.max + 1) / scale_x) != 640L
|
||||
|| renderingContext->fb_Y_CLIP.min != 0
|
||||
|| lroundf((renderingContext->fb_Y_CLIP.max + 1) / scale_y) != 480L;
|
||||
}
|
||||
|
||||
const glm::mat4& GetNormalMatrix() const {
|
||||
return normalMatrix;
|
||||
}
|
||||
const glm::mat4& GetScissorMatrix() const {
|
||||
return scissorMatrix;
|
||||
}
|
||||
const glm::mat4& GetViewportMatrix() const {
|
||||
return viewportMatrix;
|
||||
}
|
||||
|
||||
float GetSidebarWidth() const {
|
||||
return sidebarWidth;
|
||||
}
|
||||
|
||||
glm::vec2 GetDreamcastViewport() const {
|
||||
return dcViewport;
|
||||
}
|
||||
|
||||
void CalcMatrices(const rend_context *renderingContext)
|
||||
{
|
||||
this->renderingContext = renderingContext;
|
||||
|
||||
GetFramebufferScaling(false, scale_x, scale_y);
|
||||
|
||||
if (renderingContext->isRTT)
|
||||
{
|
||||
dcViewport.x = renderingContext->fb_X_CLIP.max - renderingContext->fb_X_CLIP.min + 1;
|
||||
dcViewport.y = renderingContext->fb_Y_CLIP.max - renderingContext->fb_Y_CLIP.min + 1;
|
||||
normalMatrix = glm::translate(glm::vec3(-1, -1, 0))
|
||||
* glm::scale(glm::vec3(2.0f / dcViewport.x, 2.0f / dcViewport.y, 1.f));
|
||||
scissorMatrix = normalMatrix;
|
||||
sidebarWidth = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dcViewport.x = 640.f * scale_x;
|
||||
dcViewport.y = 480.f * scale_y;
|
||||
|
||||
float startx = 0;
|
||||
float starty = 0;
|
||||
const bool vga = FB_R_CTRL.vclk_div == 1;
|
||||
switch (SPG_LOAD.hcount)
|
||||
{
|
||||
case 857: // NTSC, VGA
|
||||
startx = VO_STARTX.HStart - (vga ? 0xa8 : 0xa4);
|
||||
break;
|
||||
case 863: // PAL
|
||||
startx = VO_STARTX.HStart - 0xae;
|
||||
break;
|
||||
default:
|
||||
INFO_LOG(PVR, "unknown video mode: hcount %d", SPG_LOAD.hcount);
|
||||
break;
|
||||
}
|
||||
switch (SPG_LOAD.vcount)
|
||||
{
|
||||
case 524: // NTSC, VGA
|
||||
starty = VO_STARTY.VStart_field1 - (vga ? 0x28 : 0x12);
|
||||
break;
|
||||
case 262: // NTSC 240p
|
||||
starty = VO_STARTY.VStart_field1 - 0x11;
|
||||
break;
|
||||
case 624: // PAL
|
||||
starty = VO_STARTY.VStart_field1 - 0x2d;
|
||||
break;
|
||||
case 312: // PAL 240p
|
||||
starty = VO_STARTY.VStart_field1 - 0x2e;
|
||||
break;
|
||||
default:
|
||||
INFO_LOG(PVR, "unknown video mode: vcount %d", SPG_LOAD.vcount);
|
||||
break;
|
||||
}
|
||||
// some heuristic...
|
||||
startx *= 0.8;
|
||||
starty *= 1.1;
|
||||
normalMatrix = glm::translate(glm::vec3(startx, starty, 0));
|
||||
scissorMatrix = normalMatrix;
|
||||
|
||||
const float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
||||
float scissoring_scale_x, scissoring_scale_y;
|
||||
GetFramebufferScaling(true, scissoring_scale_x, scissoring_scale_y);
|
||||
|
||||
if (settings.rend.Rotate90)
|
||||
{
|
||||
float dc2s_scale_h = screen_height / 640.0f;
|
||||
sidebarWidth = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
||||
float y_coef = -2.0f / (screen_width / dc2s_scale_h * scale_y) * screen_stretching;
|
||||
float x_coef = -2.0f / dcViewport.x * (invertY ? -1 : 1);
|
||||
glm::mat4 trans_rot = glm::rotate((float)M_PI_2, glm::vec3(0, 0, 1))
|
||||
* glm::translate(glm::vec3(invertY ? -1.f : 1.f, 1 - 2 * sidebarWidth / screen_width, 0));
|
||||
normalMatrix = trans_rot
|
||||
* glm::scale(glm::vec3(x_coef, y_coef, 1.f))
|
||||
* normalMatrix;
|
||||
scissorMatrix = trans_rot
|
||||
* glm::scale(glm::vec3(x_coef / scale_x * scissoring_scale_x, y_coef / scale_y * scissoring_scale_y, 1.f))
|
||||
* scissorMatrix;
|
||||
}
|
||||
else
|
||||
{
|
||||
float dc2s_scale_h = screen_height / 480.0f;
|
||||
sidebarWidth = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
||||
float x_coef = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching;
|
||||
float y_coef = 2.0f / dcViewport.y * (invertY ? -1 : 1);
|
||||
normalMatrix = glm::translate(glm::vec3(-1 + 2 * sidebarWidth / screen_width, invertY ? 1 : -1, 0))
|
||||
* glm::scale(glm::vec3(x_coef, y_coef, 1.f))
|
||||
* normalMatrix;
|
||||
scissorMatrix = glm::translate(glm::vec3(-1 + 2 * sidebarWidth / screen_width, invertY ? 1 : -1, 0))
|
||||
* glm::scale(glm::vec3(x_coef / scale_x * scissoring_scale_x, y_coef / scale_y * scissoring_scale_y, 1.f))
|
||||
* scissorMatrix;
|
||||
}
|
||||
}
|
||||
normalMatrix = glm::scale(glm::vec3(1, 1, 1 / settings.rend.ExtraDepthScale))
|
||||
* normalMatrix;
|
||||
|
||||
glm::mat4 vp_trans = glm::translate(glm::vec3(1, 1, 0));
|
||||
if (renderingContext->isRTT)
|
||||
{
|
||||
vp_trans = glm::scale(glm::vec3(dcViewport.x / 2, dcViewport.y / 2, 1.f))
|
||||
* vp_trans;
|
||||
}
|
||||
else
|
||||
{
|
||||
float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
||||
vp_trans = glm::scale(glm::vec3(screen_width * screen_scaling / 2, screen_height * screen_scaling / 2, 1.f))
|
||||
* vp_trans;
|
||||
}
|
||||
viewportMatrix = vp_trans * normalMatrix;
|
||||
scissorMatrix = vp_trans * scissorMatrix;
|
||||
}
|
||||
|
||||
private:
|
||||
void GetFramebufferScaling(bool scissor, float& scale_x, float& scale_y)
|
||||
{
|
||||
scale_x = 1.f;
|
||||
scale_y = 1.f;
|
||||
|
||||
if (!renderingContext->isRTT && !renderingContext->isRenderFramebuffer)
|
||||
{
|
||||
scale_x = fb_scale_x;
|
||||
scale_y = fb_scale_y;
|
||||
if (SCALER_CTL.vscalefactor > 0x400)
|
||||
{
|
||||
// Interlace mode A (single framebuffer)
|
||||
if (SCALER_CTL.interlace == 0 && !scissor)
|
||||
scale_y *= roundf((float)SCALER_CTL.vscalefactor / 0x400);
|
||||
else if (SCALER_CTL.interlace == 1 && scissor)
|
||||
// Interlace mode B (alternating framebuffers)
|
||||
scale_y *= roundf((float)SCALER_CTL.vscalefactor / 0x400);
|
||||
}
|
||||
|
||||
// VO pixel doubling is done after fb rendering/clipping
|
||||
// so it should be used for scissoring as well
|
||||
if (VO_CONTROL.pixel_double)
|
||||
scale_x *= 0.5f;
|
||||
|
||||
// the X Scaler halves the horizontal resolution but
|
||||
// before clipping/scissoring
|
||||
if (SCALER_CTL.hscale && !scissor)
|
||||
scale_x *= 2.f;
|
||||
}
|
||||
}
|
||||
|
||||
const rend_context *renderingContext = nullptr;
|
||||
|
||||
glm::mat4 normalMatrix;
|
||||
glm::mat4 scissorMatrix;
|
||||
glm::mat4 viewportMatrix;
|
||||
glm::vec2 dcViewport;
|
||||
float scale_x = 0;
|
||||
float scale_y = 0;
|
||||
float sidebarWidth = 0;
|
||||
};
|
|
@ -20,11 +20,8 @@
|
|||
*/
|
||||
#include <math.h>
|
||||
#include "drawer.h"
|
||||
#include "../gui.h"
|
||||
#include "hw/pvr/pvr_mem.h"
|
||||
|
||||
extern float fb_scale_x, fb_scale_y;
|
||||
|
||||
void Drawer::SortTriangles()
|
||||
{
|
||||
sortedPolys.resize(pvrrc.render_passes.used());
|
||||
|
@ -84,33 +81,15 @@ TileClipping Drawer::SetTileClip(u32 val, vk::Rect2D& clipRect)
|
|||
{
|
||||
if (!pvrrc.isRTT)
|
||||
{
|
||||
csx /= scale_x;
|
||||
csy /= scale_y;
|
||||
cex /= scale_x;
|
||||
cey /= scale_y;
|
||||
float dc2s_scale_h;
|
||||
float ds2s_offs_x;
|
||||
float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
||||
glm::vec4 clip_start(csx, csy, 0, 1);
|
||||
glm::vec4 clip_end(cex, cey, 0, 1);
|
||||
clip_start = matrices.GetViewportMatrix() * clip_start;
|
||||
clip_end = matrices.GetViewportMatrix() * clip_end;
|
||||
|
||||
if (settings.rend.Rotate90)
|
||||
{
|
||||
float t = cex;
|
||||
cex = cey;
|
||||
cey = 640 - csx;
|
||||
csx = csy;
|
||||
csy = 640 - t;
|
||||
dc2s_scale_h = screen_height / 640.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0 * screen_stretching) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
dc2s_scale_h = screen_height / 480.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0 * screen_stretching) / 2;
|
||||
}
|
||||
csx = csx * dc2s_scale_h * screen_stretching + ds2s_offs_x;
|
||||
cex = cex * dc2s_scale_h * screen_stretching + ds2s_offs_x;
|
||||
csy = csy * dc2s_scale_h;
|
||||
cey = cey * dc2s_scale_h;
|
||||
csx = clip_start[0];
|
||||
csy = clip_start[1];
|
||||
cey = clip_end[1];
|
||||
cex = clip_end[0];
|
||||
}
|
||||
else if (!settings.rend.RenderToTextureBuffer)
|
||||
{
|
||||
|
@ -290,79 +269,8 @@ bool Drawer::Draw(const Texture *fogTexture)
|
|||
{
|
||||
extern bool fog_needs_update;
|
||||
|
||||
bool is_rtt = pvrrc.isRTT;
|
||||
float dc_width = 640;
|
||||
float dc_height = 480;
|
||||
|
||||
if (is_rtt)
|
||||
{
|
||||
dc_width = pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1;
|
||||
dc_height = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
|
||||
}
|
||||
|
||||
scale_x = 1;
|
||||
scissor_scale_x = 1;
|
||||
scale_y = 1;
|
||||
|
||||
if (!is_rtt && !pvrrc.isRenderFramebuffer)
|
||||
{
|
||||
scale_x = fb_scale_x;
|
||||
scissor_scale_x = fb_scale_x;
|
||||
scale_y = fb_scale_y;
|
||||
if (SCALER_CTL.interlace == 0 && SCALER_CTL.vscalefactor > 0x400)
|
||||
scale_y *= roundf((float)SCALER_CTL.vscalefactor / 0x400);
|
||||
|
||||
//Pixel doubling is on VO, so it does not affect any pixel operations
|
||||
if (VO_CONTROL.pixel_double)
|
||||
{
|
||||
scissor_scale_x *= 0.5f;
|
||||
scale_x *= 0.5f;
|
||||
}
|
||||
|
||||
if (SCALER_CTL.hscale)
|
||||
scale_x *= 2;
|
||||
}
|
||||
|
||||
dc_width *= scale_x;
|
||||
dc_height *= scale_y;
|
||||
|
||||
float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
||||
float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
||||
|
||||
float dc2s_scale_h;
|
||||
float ds2s_offs_x;
|
||||
|
||||
VertexShaderUniforms vtxUniforms;
|
||||
if (is_rtt)
|
||||
{
|
||||
vtxUniforms.scale[0] = 2.0f / dc_width;
|
||||
vtxUniforms.scale[1] = 2.0f / dc_height;
|
||||
vtxUniforms.scale[2] = 1;
|
||||
vtxUniforms.scale[3] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (settings.rend.Rotate90)
|
||||
{
|
||||
dc2s_scale_h = screen_height / 640.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
||||
vtxUniforms.scale[0] = -2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching;
|
||||
vtxUniforms.scale[1] = 2.0f / dc_width;
|
||||
vtxUniforms.scale[2] = 1 - 2 * ds2s_offs_x / screen_width;
|
||||
vtxUniforms.scale[3] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dc2s_scale_h = screen_height / 480.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
||||
vtxUniforms.scale[0] = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching;
|
||||
vtxUniforms.scale[1] = 2.0f / dc_height;
|
||||
vtxUniforms.scale[2] = 1 - 2 * ds2s_offs_x / screen_width;
|
||||
vtxUniforms.scale[3] = 1;
|
||||
}
|
||||
//-1 -> too much to left
|
||||
}
|
||||
vtxUniforms.extra_depth_scale = settings.rend.ExtraDepthScale;
|
||||
vtxUniforms.normal_matrix = matrices.GetNormalMatrix();
|
||||
|
||||
FragmentShaderUniforms fragUniforms;
|
||||
fragUniforms.extra_depth_scale = settings.rend.ExtraDepthScale;
|
||||
|
@ -445,16 +353,16 @@ bool Drawer::Draw(const Texture *fogTexture)
|
|||
DrawList(cmdBuffer, ListType_Translucent, false, pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);
|
||||
previous_pass = current_pass;
|
||||
}
|
||||
if (!is_rtt)
|
||||
gui_display_osd();
|
||||
|
||||
return !is_rtt;
|
||||
return !pvrrc.isRTT;
|
||||
}
|
||||
|
||||
vk::CommandBuffer TextureDrawer::BeginRenderPass()
|
||||
{
|
||||
DEBUG_LOG(RENDERER, "RenderToTexture packmode=%d stride=%d - %d,%d -> %d,%d", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8,
|
||||
FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max);
|
||||
matrices.CalcMatrices(&pvrrc);
|
||||
|
||||
textureAddr = FB_W_SOF1 & VRAM_MASK;
|
||||
u32 origWidth = pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1;
|
||||
u32 origHeight = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
|
||||
|
@ -631,12 +539,12 @@ vk::CommandBuffer ScreenDrawer::BeginRenderPass()
|
|||
GetContext()->NewFrame();
|
||||
GetContext()->BeginRenderPass();
|
||||
vk::CommandBuffer commandBuffer = GetContext()->GetCurrentCommandBuffer();
|
||||
commandBuffer.setViewport(0, vk::Viewport(0.0f, 0.0f, (float) ((screen_width)), (float) ((screen_height)), 1.0f, 0.0f));
|
||||
bool wide_screen_on = settings.rend.WideScreen && !pvrrc.isRenderFramebuffer
|
||||
&& pvrrc.fb_X_CLIP.min == 0
|
||||
&& lroundf((pvrrc.fb_X_CLIP.max + 1) / scissor_scale_x) == 640L
|
||||
&& pvrrc.fb_Y_CLIP.min == 0
|
||||
&& lroundf((pvrrc.fb_Y_CLIP.max + 1) / scale_y) == 480L;
|
||||
commandBuffer.setViewport(0, vk::Viewport(0.0f, 0.0f, (float)screen_width, (float)screen_height, 1.0f, 0.0f));
|
||||
|
||||
matrices.CalcMatrices(&pvrrc);
|
||||
|
||||
bool wide_screen_on = settings.rend.WideScreen && !pvrrc.isRenderFramebuffer && !matrices.IsClipped();
|
||||
|
||||
if (!wide_screen_on)
|
||||
{
|
||||
float width;
|
||||
|
@ -653,45 +561,27 @@ vk::CommandBuffer ScreenDrawer::BeginRenderPass()
|
|||
}
|
||||
else
|
||||
{
|
||||
width = (pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1) / scissor_scale_x;
|
||||
height = (pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1) / scale_y;
|
||||
min_x = pvrrc.fb_X_CLIP.min / scissor_scale_x;
|
||||
min_y = pvrrc.fb_Y_CLIP.min / scale_y;
|
||||
glm::vec4 clip_min(pvrrc.fb_X_CLIP.min, pvrrc.fb_Y_CLIP.min, 0, 1);
|
||||
glm::vec4 clip_dim(pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1,
|
||||
pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1, 0, 0);
|
||||
clip_min = matrices.GetScissorMatrix() * clip_min;
|
||||
clip_dim = matrices.GetScissorMatrix() * clip_dim;
|
||||
|
||||
if (SCALER_CTL.interlace && SCALER_CTL.vscalefactor > 0x400)
|
||||
min_x = clip_min[0];
|
||||
min_y = clip_min[1];
|
||||
width = clip_dim[0];
|
||||
height = clip_dim[1];
|
||||
if (width < 0)
|
||||
{
|
||||
// Clipping is done after scaling/filtering so account for that if enabled
|
||||
height *= (float) SCALER_CTL.vscalefactor / 0x400;
|
||||
min_y *= (float) SCALER_CTL.vscalefactor / 0x400;
|
||||
min_x += width;
|
||||
width = -width;
|
||||
}
|
||||
if (height < 0)
|
||||
{
|
||||
min_y += height;
|
||||
height = -height;
|
||||
}
|
||||
}
|
||||
if (settings.rend.Rotate90)
|
||||
{
|
||||
float t = width;
|
||||
width = height;
|
||||
height = t;
|
||||
t = min_x;
|
||||
min_x = min_y;
|
||||
min_y = 640 - t - height;
|
||||
}
|
||||
const float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
||||
const float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
||||
float dc2s_scale_h, ds2s_offs_x;
|
||||
if (settings.rend.Rotate90)
|
||||
{
|
||||
dc2s_scale_h = screen_height / 640.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
dc2s_scale_h = screen_height / 480.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
||||
}
|
||||
// Add x offset for aspect ratio > 4/3
|
||||
min_x = (min_x * dc2s_scale_h * screen_stretching + ds2s_offs_x) * screen_scaling;
|
||||
min_y = min_y * dc2s_scale_h * screen_scaling;
|
||||
width *= dc2s_scale_h * screen_stretching * screen_scaling;
|
||||
height *= dc2s_scale_h * screen_scaling;
|
||||
|
||||
baseScissor = vk::Rect2D(
|
||||
vk::Offset2D((u32)std::max(lroundf(min_x), 0L), (u32)std::max(lroundf(min_y), 0L)),
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#pragma once
|
||||
#include <memory>
|
||||
#include "rend/sorter.h"
|
||||
#include "rend/transform_matrix.h"
|
||||
#include "vulkan.h"
|
||||
#include "buffer.h"
|
||||
#include "commandpool.h"
|
||||
|
@ -68,10 +69,7 @@ protected:
|
|||
|
||||
PipelineManager *pipelineManager = nullptr;
|
||||
vk::Rect2D baseScissor;
|
||||
// temp stuff
|
||||
float scale_x = 1.f;
|
||||
float scissor_scale_x = 1.f;
|
||||
float scale_y = 1.f;
|
||||
TransformMatrix<false> matrices;
|
||||
|
||||
private:
|
||||
TileClipping SetTileClip(u32 val, vk::Rect2D& clipRect);
|
||||
|
|
|
@ -319,7 +319,7 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol
|
|||
vk::DynamicState dynamicStates[2] = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
|
||||
vk::PipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo(vk::PipelineDynamicStateCreateFlags(), 2, dynamicStates);
|
||||
|
||||
vk::ShaderModule vertex_module = shaderManager->GetVertexShader(VertexShaderParams{ pp.pcw.Gouraud == 1, false }); // TODO rotate90
|
||||
vk::ShaderModule vertex_module = shaderManager->GetVertexShader(VertexShaderParams{ pp.pcw.Gouraud == 1 });
|
||||
FragmentShaderParams params = {};
|
||||
params.alphaTest = listType == ListType_Punch_Through;
|
||||
params.bumpmap = pp.tcw.PixelFmt == PixelBumpMap;
|
||||
|
|
|
@ -195,7 +195,6 @@ private:
|
|||
| (pp->tsp.DstInstr << 17);
|
||||
hash |= (pp->isp.ZWriteDis << 20) | (pp->isp.CullMode << 21) | (pp->isp.DepthMode << 23);
|
||||
hash |= (u32)sortTriangles << 26;
|
||||
// TODO hash |= (u32)rotate90 << 27;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ static const char VertexShaderSource[] = R"(
|
|||
#extension GL_ARB_shading_language_420pack : enable
|
||||
|
||||
#define pp_Gouraud %d
|
||||
#define ROTATE_90 %d
|
||||
|
||||
#if pp_Gouraud == 0
|
||||
#define INTERPOLATION flat
|
||||
|
@ -38,8 +37,7 @@ static const char VertexShaderSource[] = R"(
|
|||
|
||||
layout (std140, set = 0, binding = 0) uniform VertexShaderUniforms
|
||||
{
|
||||
vec4 scale;
|
||||
float extra_depth_scale;
|
||||
mat4 normal_matrix;
|
||||
} uniformBuffer;
|
||||
|
||||
layout (location = 0) in vec4 in_pos;
|
||||
|
@ -62,13 +60,9 @@ void main()
|
|||
gl_Position = vec4(0.0, 0.0, 1.0, 1.0 / vpos.z);
|
||||
return;
|
||||
}
|
||||
|
||||
vpos.w = uniformBuffer.extra_depth_scale / vpos.z;
|
||||
vpos = uniformBuffer.normal_matrix * vpos;
|
||||
vpos.w = 1.0 / vpos.z;
|
||||
vpos.z = vpos.w;
|
||||
#if ROTATE_90 == 1
|
||||
vpos.xy = vec2(vpos.y, -vpos.x);
|
||||
#endif
|
||||
vpos.xy = vpos.xy * uniformBuffer.scale.xy - uniformBuffer.scale.zw;
|
||||
vpos.xy *= vpos.w;
|
||||
gl_Position = vpos;
|
||||
}
|
||||
|
@ -252,8 +246,7 @@ static const char ModVolVertexShaderSource[] = R"(
|
|||
|
||||
layout (std140, set = 0, binding = 0) uniform VertexShaderUniforms
|
||||
{
|
||||
vec4 scale;
|
||||
float extra_depth_scale;
|
||||
mat4 normal_matrix;
|
||||
} uniformBuffer;
|
||||
|
||||
layout (location = 0) in vec4 in_pos;
|
||||
|
@ -267,9 +260,9 @@ void main()
|
|||
return;
|
||||
}
|
||||
|
||||
vpos.w = uniformBuffer.extra_depth_scale / vpos.z;
|
||||
vpos = uniformBuffer.normal_matrix * vpos;
|
||||
vpos.w = 1.0 / vpos.z;
|
||||
vpos.z = vpos.w;
|
||||
vpos.xy = vpos.xy * uniformBuffer.scale.xy - uniformBuffer.scale.zw;
|
||||
vpos.xy *= vpos.w;
|
||||
gl_Position = vpos;
|
||||
}
|
||||
|
@ -542,7 +535,7 @@ vk::UniqueShaderModule ShaderManager::compileShader(const VertexShaderParams& pa
|
|||
{
|
||||
char buf[sizeof(VertexShaderSource) * 2];
|
||||
|
||||
sprintf(buf, VertexShaderSource, (int)params.gouraud, (int)params.rotate90);
|
||||
sprintf(buf, VertexShaderSource, (int)params.gouraud);
|
||||
return createShaderModule(VulkanContext::Instance()->GetDevice(), vk::ShaderStageFlagBits::eVertex, buf);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,15 +19,15 @@
|
|||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <glm/glm.hpp>
|
||||
#include "vulkan.h"
|
||||
#include "SPIRV/GlslangToSpv.h"
|
||||
|
||||
struct VertexShaderParams
|
||||
{
|
||||
bool gouraud;
|
||||
bool rotate90;
|
||||
|
||||
u32 hash() { return (((u32)gouraud) << 1) | rotate90; }
|
||||
u32 hash() { return (u32)gouraud; }
|
||||
};
|
||||
|
||||
// alpha test, clip test, use alpha, texture, ignore alpha, shader instr, offset, fog, gouraud, bump, clamp, trilinear
|
||||
|
@ -58,8 +58,7 @@ struct FragmentShaderParams
|
|||
// std140 alignment required
|
||||
struct VertexShaderUniforms
|
||||
{
|
||||
float scale[4];
|
||||
float extra_depth_scale;
|
||||
glm::mat4 normal_matrix;
|
||||
};
|
||||
|
||||
// std140 alignment required
|
||||
|
|
|
@ -142,17 +142,23 @@ public:
|
|||
curTexture->SetCommandBuffer(nullptr);
|
||||
texCommandPool.EndFrame();
|
||||
|
||||
float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
||||
float dc2s_scale_h, ds2s_offs_x;
|
||||
if (settings.rend.Rotate90)
|
||||
TransformMatrix<false> matrices(pvrrc);
|
||||
glm::vec4 viewport_min = matrices.GetViewportMatrix() * glm::vec4(0, 0, 0, 1.f);
|
||||
glm::vec4 viewport_dim = matrices.GetViewportMatrix() * glm::vec4(640.f, 480.f, 0, 0);
|
||||
|
||||
float min_x = viewport_min[0];
|
||||
float min_y = viewport_min[1];
|
||||
width = viewport_dim[0];
|
||||
height = viewport_dim[1];
|
||||
if (width < 0)
|
||||
{
|
||||
dc2s_scale_h = screen_height / 640.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
||||
min_x += width;
|
||||
width = -width;
|
||||
}
|
||||
else
|
||||
if (height < 0)
|
||||
{
|
||||
dc2s_scale_h = screen_height / 480.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
||||
min_y += height;
|
||||
height = -height;
|
||||
}
|
||||
|
||||
vk::CommandBuffer cmdBuffer = screenDrawer.BeginRenderPass();
|
||||
|
@ -165,9 +171,10 @@ public:
|
|||
|
||||
float blendConstants[4] = { 1.0, 1.0, 1.0, 1.0 };
|
||||
cmdBuffer.setBlendConstants(blendConstants);
|
||||
// FIXME scaling, stretching...
|
||||
vk::Viewport viewport(ds2s_offs_x, 0.f, screen_width - ds2s_offs_x * 2, (float)screen_height);
|
||||
|
||||
vk::Viewport viewport(min_x, min_y, width, height);
|
||||
cmdBuffer.setViewport(0, 1, &viewport);
|
||||
cmdBuffer.setScissor(0, vk::Rect2D(vk::Offset2D(min_x, min_y), vk::Extent2D(width, height)));
|
||||
cmdBuffer.draw(3, 1, 0, 0);
|
||||
|
||||
gui_display_osd();
|
||||
|
@ -211,6 +218,7 @@ public:
|
|||
|
||||
void DrawOSD(bool clear_screen) override
|
||||
{
|
||||
gui_display_osd();
|
||||
if (!vjoyTexture)
|
||||
return;
|
||||
if (clear_screen)
|
||||
|
@ -218,22 +226,13 @@ public:
|
|||
GetContext()->NewFrame();
|
||||
GetContext()->BeginRenderPass();
|
||||
}
|
||||
const float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
||||
float dc2s_scale_h, ds2s_offs_x;
|
||||
if (settings.rend.Rotate90)
|
||||
{
|
||||
dc2s_scale_h = screen_height / 640.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
dc2s_scale_h = screen_height / 480.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
||||
}
|
||||
const float dc2s_scale_h = screen_height / 480.0f;
|
||||
const float sidebarWidth = (screen_width - dc2s_scale_h * 640.0f) / 2;
|
||||
|
||||
std::vector<OSDVertex> osdVertices = GetOSDVertices();
|
||||
const float x1 = 2.0f / (screen_width / dc2s_scale_h /* FIXME * scale_x */) * screen_stretching;
|
||||
const float y1 = 2.0f / 480 /* FIXME dc_height */;
|
||||
const float x2 = 1 - 2 * ds2s_offs_x / screen_width;
|
||||
const float x1 = 2.0f / (screen_width / dc2s_scale_h);
|
||||
const float y1 = 2.0f / 480;
|
||||
const float x2 = 1 - 2 * sidebarWidth / screen_width;
|
||||
const float y2 = 1;
|
||||
for (OSDVertex& vtx : osdVertices)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue