Skip to content

Commit

Permalink
Integer overscale GPU screenshot crash fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
sonninnos committed Oct 23, 2024
1 parent 192c992 commit 2065956
Show file tree
Hide file tree
Showing 12 changed files with 138 additions and 55 deletions.
41 changes: 33 additions & 8 deletions gfx/common/d3d9_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,10 @@ bool d3d9_initialize_symbols(enum gfx_ctx_api api)
return false;
#endif
#if defined(DEBUG) || defined(_DEBUG)
if (!(g_d3d9_dll = dylib_load("d3d9d.dll")))
if (!(g_d3d9_dll = dylib_load("d3d9d.dll")))
#endif
if (!(g_d3d9_dll = dylib_load("d3d9.dll")))
return false;
if (!(g_d3d9_dll = dylib_load("d3d9.dll")))
return false;
D3D9Create = (D3D9Create_t)dylib_proc(g_d3d9_dll, "Direct3DCreate9");
#ifdef HAVE_D3DX
D3D9CompileShaderFromFile = (D3D9CompileShaderFromFile_t)dylib_proc(g_d3d9x_dll, "D3DXCompileShaderFromFile");
Expand Down Expand Up @@ -872,18 +872,39 @@ void d3d9_set_viewport(void *data,
bool force_full,
bool allow_rotate)
{
d3d9_video_t *d3d = (d3d9_video_t*)data;
float translate_x = d3d->translate_x;
float translate_y = d3d->translate_y;
int x = 0;
int y = 0;
d3d9_video_t *d3d = (d3d9_video_t*)data;

d3d9_calculate_rect(d3d, &width, &height, &x, &y,
force_full, allow_rotate);

/* D3D doesn't support negative X/Y viewports ... */
if (x < 0)
{
if (!force_full)
d3d->translate_x = x * 2;
x = 0;
}
else if (!force_full)
d3d->translate_x = 0;

if (y < 0)
{
if (!force_full)
d3d->translate_y = y * 2;
y = 0;
}
else if (!force_full)
d3d->translate_y = 0;

if (!force_full)
{
if (translate_x != d3d->translate_x || translate_y != d3d->translate_y)
d3d->needs_restore = true;
}

d3d->final_viewport.X = x;
d3d->final_viewport.Y = y;
Expand Down Expand Up @@ -1073,7 +1094,8 @@ void d3d9_set_menu_texture_frame(void *data,
|| (d3d->menu->tex_w != width)
|| (d3d->menu->tex_h != height))
{
IDirect3DTexture9_Release((LPDIRECT3DTEXTURE9)d3d->menu->tex);
if (d3d->menu->tex)
IDirect3DTexture9_Release((LPDIRECT3DTEXTURE9)d3d->menu->tex);

d3d->menu->tex = d3d9_texture_new(d3d->dev,
width, height, 1,
Expand All @@ -1096,6 +1118,7 @@ void d3d9_set_menu_texture_frame(void *data,
0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK);
{
unsigned h, w;

if (rgb32)
{
uint8_t *dst = (uint8_t*)d3dlr.pBits;
Expand Down Expand Up @@ -1281,16 +1304,18 @@ bool d3d9_read_viewport(void *data, uint8_t *buffer, bool is_idle)

{
unsigned x, y;
unsigned vp_width = (d3d->final_viewport.Width > width) ? width : d3d->final_viewport.Width;
unsigned vp_height = (d3d->final_viewport.Height > height) ? height : d3d->final_viewport.Height;
unsigned pitchpix = rect.Pitch / 4;
const uint32_t *pixels = (const uint32_t*)rect.pBits;

pixels += d3d->final_viewport.X;
pixels += (d3d->final_viewport.Height - 1) * pitchpix;
pixels += (vp_height - 1) * pitchpix;
pixels -= d3d->final_viewport.Y * pitchpix;

for (y = 0; y < d3d->final_viewport.Height; y++, pixels -= pitchpix)
for (y = 0; y < vp_height; y++, pixels -= pitchpix)
{
for (x = 0; x < d3d->final_viewport.Width; x++)
for (x = 0; x < vp_width; x++)
{
*buffer++ = (pixels[x] >> 0) & 0xff;
*buffer++ = (pixels[x] >> 8) & 0xff;
Expand Down
2 changes: 2 additions & 0 deletions gfx/common/d3d9_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ typedef struct d3d9_video
#endif
LPDIRECT3DDEVICE9 dev;
D3DVIEWPORT9 final_viewport;
float translate_x;
float translate_y;

char *shader_path;

Expand Down
4 changes: 2 additions & 2 deletions gfx/common/d3d_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ void d3d_matrix_ortho_off_center_lh(void *_pout,
pout->m[0][0] = 2.0f / (r - l);
pout->m[1][1] = 2.0f / (t - b);
pout->m[2][2] = 1.0f / (zf -zn);
pout->m[3][0] = -1.0f -2.0f *l / (r - l);
pout->m[3][1] = 1.0f + 2.0f * t / (b - t);
pout->m[3][0] = -1.0f - 2.0f * l / (r - l);
pout->m[3][1] = 1.0f + 2.0f * t / (b - t);
pout->m[3][2] = zn / (zn -zf);
}

Expand Down
2 changes: 1 addition & 1 deletion gfx/common/vulkan_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1264,7 +1264,7 @@ static void vulkan_acquire_clear_fences(gfx_ctx_vulkan_data_t *vk)

if (vk->context.swapchain_wait_semaphores[i])
{
struct vulkan_context *ctx = &vk->context;
struct vulkan_context *ctx = &vk->context;
VkSemaphore sem = vk->context.swapchain_wait_semaphores[i];
assert(ctx->num_recycled_acquire_semaphores < VULKAN_MAX_SWAPCHAIN_IMAGES);
ctx->swapchain_recycled_semaphores[ctx->num_recycled_acquire_semaphores++] = sem;
Expand Down
15 changes: 10 additions & 5 deletions gfx/drivers/d3d11.c
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ static void d3d11_font_render_message(
d3d11_font_render_line(d3d11,
font, glyph_q, msg, msg_len, scale, color, pos_x,
pos_y - (float)lines * line_height,
x,
x,
width, height, text_align);

if (!delim)
Expand Down Expand Up @@ -3694,12 +3694,17 @@ static bool d3d11_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle)
/* Assuming format is DXGI_FORMAT_R8G8B8A8_UNORM */
if (StagingDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM)
{
BackBufferData += Map.RowPitch * d3d11->vp.y;
for (y = 0; y < d3d11->vp.height; y++, BackBufferData += Map.RowPitch)
unsigned vp_y = (d3d11->vp.y > 0) ? d3d11->vp.y : 0;
unsigned vp_width = (d3d11->vp.width > d3d11->vp.full_width) ? d3d11->vp.full_width : d3d11->vp.width;
unsigned vp_height = (d3d11->vp.height > d3d11->vp.full_height) ? d3d11->vp.full_height : d3d11->vp.height;

BackBufferData += Map.RowPitch * vp_y;

for (y = 0; y < vp_height; y++, BackBufferData += Map.RowPitch)
{
bufferRow = buffer + 3 * (d3d11->vp.height - y - 1) * d3d11->vp.width;
bufferRow = buffer + 3 * (vp_height - y - 1) * vp_width;

for (x = 0; x < d3d11->vp.width; x++)
for (x = 0; x < vp_width; x++)
{
bufferRow[3 * x + 2] = BackBufferData[4 * (x + d3d11->vp.x) + 0];
bufferRow[3 * x + 1] = BackBufferData[4 * (x + d3d11->vp.x) + 1];
Expand Down
21 changes: 17 additions & 4 deletions gfx/drivers/d3d9cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1755,7 +1755,21 @@ static bool d3d9_cg_initialize(d3d9_video_t *d3d, const video_info_t *info)

d3d_matrix_identity(&d3d->mvp_transposed);
d3d_matrix_ortho_off_center_lh(&d3d->mvp_transposed, 0, 1, 0, 1, 0, 1);
d3d_matrix_transpose(&d3d->mvp, &d3d->mvp_transposed);
d3d->mvp = d3d->mvp_transposed;

if (d3d->translate_x)
{
struct d3d_matrix *pout = (struct d3d_matrix*)&d3d->mvp;
float vp_x = -(d3d->translate_x/(float)d3d->final_viewport.Width);
pout->m[3][0] = -1.0f + vp_x - 2.0f * 1 / (0 - 1);
}

if (d3d->translate_y)
{
struct d3d_matrix *pout = (struct d3d_matrix*)&d3d->mvp;
float vp_y = -(d3d->translate_y/(float)d3d->final_viewport.Height);
pout->m[3][1] = 1.0f + vp_y + 2.0f * 1 / (0 - 1);
}

IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_CULLMODE, D3DCULL_NONE);
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_SCISSORTESTENABLE, TRUE);
Expand Down Expand Up @@ -2103,7 +2117,7 @@ static bool d3d9_cg_frame(void *data, const void *frame,
if (d3d->overlays_enabled && overlay_behind_menu)
{
IDirect3DDevice9_SetVertexShaderConstantF(d3d->dev,
0, (const float*)&d3d->mvp, 4);
0, (const float*)&d3d->mvp_transposed, 4);
for (i = 0; i < d3d->overlays_size; i++)
d3d9_overlay_render(d3d, width, height, &d3d->overlays[i], true);
}
Expand All @@ -2121,7 +2135,6 @@ static bool d3d9_cg_frame(void *data, const void *frame,
IDirect3DDevice9_SetStreamSource(d3d->dev, 0,
(LPDIRECT3DVERTEXBUFFER9)d3d->menu_display.buffer,
0, sizeof(Vertex));

IDirect3DDevice9_SetViewport(d3d->dev, (D3DVIEWPORT9*)&screen_vp);
menu_driver_frame(menu_is_alive, video_info);
}
Expand All @@ -2142,7 +2155,7 @@ static bool d3d9_cg_frame(void *data, const void *frame,
if (d3d->overlays_enabled && !overlay_behind_menu)
{
IDirect3DDevice9_SetVertexShaderConstantF(d3d->dev,
0, (const float*)&d3d->mvp, 4);
0, (const float*)&d3d->mvp_transposed, 4);
for (i = 0; i < d3d->overlays_size; i++)
d3d9_overlay_render(d3d, width, height, &d3d->overlays[i], true);
}
Expand Down
20 changes: 17 additions & 3 deletions gfx/drivers/d3d9hlsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1343,7 +1343,21 @@ static bool d3d9_hlsl_initialize(

d3d_matrix_identity(&d3d->mvp_transposed);
d3d_matrix_ortho_off_center_lh(&d3d->mvp_transposed, 0, 1, 0, 1, 0, 1);
d3d_matrix_transpose(&d3d->mvp, &d3d->mvp_transposed);
d3d->mvp = d3d->mvp_transposed;

if (d3d->translate_x)
{
struct d3d_matrix *pout = (struct d3d_matrix*)&d3d->mvp;
float vp_x = -(d3d->translate_x/(float)d3d->final_viewport.Width);
pout->m[3][0] = -1.0f + vp_x - 2.0f * 1 / (0 - 1);
}

if (d3d->translate_y)
{
struct d3d_matrix *pout = (struct d3d_matrix*)&d3d->mvp;
float vp_y = -(d3d->translate_y/(float)d3d->final_viewport.Height);
pout->m[3][1] = 1.0f + vp_y + 2.0f * 1 / (0 - 1);
}

IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_CULLMODE, D3DCULL_NONE);
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_SCISSORTESTENABLE, TRUE);
Expand Down Expand Up @@ -1675,7 +1689,7 @@ static bool d3d9_hlsl_frame(void *data, const void *frame,
0, 1, 0);

IDirect3DDevice9_SetVertexShaderConstantF(d3d->dev, 0,
(const float*)&d3d->mvp_transposed, 4);
(const float*)&d3d->mvp, 4);
hlsl_d3d9_renderchain_render(
d3d, frame, frame_width, frame_height,
pitch, d3d->dev_rotation);
Expand Down Expand Up @@ -1713,7 +1727,7 @@ static bool d3d9_hlsl_frame(void *data, const void *frame,
if (d3d->menu && d3d->menu->enabled)
{
IDirect3DDevice9_SetVertexShaderConstantF(d3d->dev, 0,
(const float*)&d3d->mvp_transposed, 4);
(const float*)&d3d->mvp, 4);
d3d9_overlay_render(d3d, width, height, d3d->menu, false);

d3d->menu_display.offset = 0;
Expand Down
18 changes: 12 additions & 6 deletions gfx/drivers/gl1.c
Original file line number Diff line number Diff line change
Expand Up @@ -1270,10 +1270,10 @@ static void gl1_draw_tex(gl1_t *gl1, int pot_width, int pot_height, int width, i
GLenum type = GL_UNSIGNED_BYTE;
#endif
float vertices[] = {
-1.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
};

float colors[] = {
Expand Down Expand Up @@ -1408,15 +1408,20 @@ static void gl1_draw_tex(gl1_t *gl1, int pot_width, int pot_height, int width, i

static void gl1_readback(gl1_t *gl1,
unsigned alignment, unsigned fmt, unsigned type,
unsigned video_width, unsigned video_height,
void *src)
{
#ifndef VITA
glPixelStorei(GL_PACK_ALIGNMENT, alignment);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glReadBuffer(GL_BACK);
#endif
glReadPixels(gl1->vp.x, gl1->vp.y,
gl1->vp.width, gl1->vp.height,

glReadPixels(
(gl1->vp.x > 0) ? gl1->vp.x : 0,
(gl1->vp.y > 0) ? gl1->vp.y : 0,
(gl1->vp.width > video_width) ? video_width : gl1->vp.width,
(gl1->vp.height > video_height) ? video_height : gl1->vp.height,
(GLenum)fmt, (GLenum)type, (GLvoid*)src);
}

Expand Down Expand Up @@ -1656,6 +1661,7 @@ static bool gl1_frame(void *data, const void *frame,
#else
GL_UNSIGNED_BYTE,
#endif
video_width, video_height,
gl1->readback_buffer_screenshot);


Expand Down
11 changes: 7 additions & 4 deletions gfx/drivers/gl2.c
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,7 @@ static void gl2_raster_font_render_line(gl2_t *gl,

if (font->block)
video_coord_array_append(&font->block->carr,
&coords, coords.vertices);
&coords, coords.vertices);
else
gl2_raster_font_draw_vertices(gl, font, &coords);
}
Expand Down Expand Up @@ -1580,7 +1580,7 @@ static unsigned gl2_wrap_type_to_enum(enum gfx_wrap_type type)
case RARCH_WRAP_MIRRORED_REPEAT:
return GL_MIRRORED_REPEAT;
default:
break;
break;
}

return 0;
Expand Down Expand Up @@ -2391,8 +2391,11 @@ static void gl2_renderchain_readback(
glReadBuffer(GL_BACK);
#endif

glReadPixels(gl->vp.x, gl->vp.y,
gl->vp.width, gl->vp.height,
glReadPixels(
(gl->vp.x > 0) ? gl->vp.x : 0,
(gl->vp.y > 0) ? gl->vp.y : 0,
(gl->vp.width > gl->video_width) ? gl->video_width : gl->vp.width,
(gl->vp.height > gl->video_height) ? gl->video_height : gl->vp.height,
(GLenum)fmt, (GLenum)type, (GLvoid*)src);
}

Expand Down
22 changes: 12 additions & 10 deletions gfx/drivers/gl3.c
Original file line number Diff line number Diff line change
Expand Up @@ -2183,7 +2183,7 @@ static void video_texture_load_gl3(
break;

case TEXTURE_FILTER_MIPMAP_LINEAR:
default:
default:
mag_filter = GL_LINEAR;
min_filter = GL_LINEAR_MIPMAP_LINEAR;
break;
Expand Down Expand Up @@ -2465,11 +2465,10 @@ static void gl3_set_rotation(void *data, unsigned rotation)
static void gl3_viewport_info(void *data, struct video_viewport *vp)
{
unsigned top_y, top_dist;
gl3_t *gl = (gl3_t*)data;
gl3_t *gl = (gl3_t*)data;
unsigned width = gl->video_width;
unsigned height = gl->video_height;


*vp = gl->vp;
vp->full_width = width;
vp->full_height = height;
Expand All @@ -2490,6 +2489,7 @@ static bool gl3_read_viewport(void *data, uint8_t *buffer, bool is_idle)

if (gl->flags & GL3_FLAG_USE_SHARED_CONTEXT)
gl->ctx_driver->bind_hw_render(gl->ctx_data, false);

num_pixels = gl->vp.width * gl->vp.height;

if (gl->flags & GL3_FLAG_PBO_READBACK_ENABLE)
Expand Down Expand Up @@ -2724,10 +2724,10 @@ static bool gl3_frame(void *data, const void *frame,
texture.padded_width = gl->hw_render_max_width;
texture.padded_height = gl->hw_render_max_height;

if (texture.width == 0)
texture.width = 1;
if (texture.height == 0)
texture.height = 1;
if (texture.width == 0)
texture.width = 1;
if (texture.height == 0)
texture.height = 1;
}
else
{
Expand Down Expand Up @@ -2843,8 +2843,11 @@ static bool gl3_frame(void *data, const void *frame,
#ifndef HAVE_OPENGLES
glReadBuffer(GL_BACK);
#endif
glReadPixels(gl->vp.x, gl->vp.y,
gl->vp.width, gl->vp.height,
glReadPixels(
(gl->vp.x > 0) ? gl->vp.x : 0,
(gl->vp.y > 0) ? gl->vp.y : 0,
(gl->vp.width > gl->video_width) ? gl->video_width : gl->vp.width,
(gl->vp.height > gl->video_height) ? gl->video_height : gl->vp.height,
GL_RGBA, GL_UNSIGNED_BYTE,
gl->readback_buffer_screenshot);
}
Expand All @@ -2857,7 +2860,6 @@ static bool gl3_frame(void *data, const void *frame,
gl3_pbo_async_readback(gl);
}


if (gl->ctx_driver->swap_buffers)
gl->ctx_driver->swap_buffers(gl->ctx_data);

Expand Down
Loading

0 comments on commit 2065956

Please sign in to comment.