diff --git a/src/core/gpu_hw.h b/src/core/gpu_hw.h index 096a200b2..06c52b76e 100644 --- a/src/core/gpu_hw.h +++ b/src/core/gpu_hw.h @@ -46,7 +46,11 @@ protected: UNIFORM_BUFFER_SIZE = 512 * 1024, MAX_BATCH_VERTEX_COUNTER_IDS = 65536 - 2, MAX_VERTICES_FOR_RECTANGLE = 6 * (((MAX_PRIMITIVE_WIDTH + (TEXTURE_PAGE_WIDTH - 1)) / TEXTURE_PAGE_WIDTH) + 1u) * - (((MAX_PRIMITIVE_HEIGHT + (TEXTURE_PAGE_HEIGHT - 1)) / TEXTURE_PAGE_HEIGHT) + 1u) + (((MAX_PRIMITIVE_HEIGHT + (TEXTURE_PAGE_HEIGHT - 1)) / TEXTURE_PAGE_HEIGHT) + 1u), + + // In interlaced modes, we can exceed the 512 height of VRAM, up to 576 in PAL games. + BASE_DISPLAY_TEXTURE_WIDTH = 720, + BASE_DISPLAY_TEXTURE_HEIGHT = 576, }; struct BatchVertex diff --git a/src/core/gpu_hw_d3d11.cpp b/src/core/gpu_hw_d3d11.cpp index 283e59301..9d10982b4 100644 --- a/src/core/gpu_hw_d3d11.cpp +++ b/src/core/gpu_hw_d3d11.cpp @@ -256,7 +256,8 @@ bool GPU_HW_D3D11::CreateFramebuffer() D3D11_BIND_DEPTH_STENCIL) || !m_vram_read_texture.Create(m_device.Get(), texture_width, texture_height, 1, 1, texture_format, D3D11_BIND_SHADER_RESOURCE) || - !m_display_texture.Create(m_device.Get(), texture_width, texture_height, 1, 1, texture_format, + !m_display_texture.Create(m_device.Get(), BASE_DISPLAY_TEXTURE_WIDTH * m_resolution_scale, + BASE_DISPLAY_TEXTURE_HEIGHT * m_resolution_scale, 1, 1, texture_format, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET) || !m_vram_encoding_texture.Create(m_device.Get(), VRAM_WIDTH, VRAM_HEIGHT, 1, 1, texture_format, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET) || @@ -905,6 +906,9 @@ void GPU_HW_D3D11::UpdateDisplay() ID3D11PixelShader* display_pixel_shader = m_display_pixel_shaders[BoolToUInt8(m_GPUSTAT.display_area_color_depth_24)][static_cast(interlaced)].Get(); + Assert(scaled_display_width <= m_display_texture.GetWidth() && + scaled_display_height <= m_display_texture.GetHeight()); + SetViewportAndScissor(0, 0, scaled_display_width, scaled_display_height); DrawUtilityShader(display_pixel_shader, uniforms, sizeof(uniforms)); diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index d7e59e2ca..5f1327aa2 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -399,8 +399,9 @@ bool GPU_HW_OpenGL::CreateFramebuffer() !m_vram_encoding_texture.Create(VRAM_WIDTH, VRAM_HEIGHT, 1, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false) || !m_vram_encoding_texture.CreateFramebuffer() || - !m_display_texture.Create(texture_width, texture_height, 1, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, - false) || + !m_display_texture.Create(BASE_DISPLAY_TEXTURE_WIDTH * m_resolution_scale, + BASE_DISPLAY_TEXTURE_HEIGHT * m_resolution_scale, 1, GL_RGBA8, GL_RGBA, + GL_UNSIGNED_BYTE, nullptr, false) || !m_display_texture.CreateFramebuffer()) { return false; @@ -926,6 +927,9 @@ void GPU_HW_OpenGL::UpdateDisplay() UploadUniformBuffer(uniforms, sizeof(uniforms)); m_batch_ubo_dirty = true; + Assert(scaled_display_width <= m_display_texture.GetWidth() && + scaled_display_height <= m_display_texture.GetHeight()); + glViewport(0, 0, scaled_display_width, scaled_display_height); glBindVertexArray(m_attributeless_vao_id); glDrawArrays(GL_TRIANGLES, 0, 3); diff --git a/src/core/gpu_hw_vulkan.cpp b/src/core/gpu_hw_vulkan.cpp index e8d675391..8265fce66 100644 --- a/src/core/gpu_hw_vulkan.cpp +++ b/src/core/gpu_hw_vulkan.cpp @@ -519,8 +519,9 @@ bool GPU_HW_Vulkan::CreateFramebuffer() !m_vram_read_texture.Create(texture_width, texture_height, 1, 1, texture_format, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT) || - !m_display_texture.Create(texture_width, texture_height, 1, 1, texture_format, VK_SAMPLE_COUNT_1_BIT, - VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, + !m_display_texture.Create(BASE_DISPLAY_TEXTURE_WIDTH * m_resolution_scale, + BASE_DISPLAY_TEXTURE_HEIGHT * m_resolution_scale, 1, 1, texture_format, + VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT) || !m_vram_readback_texture.Create(VRAM_WIDTH, VRAM_HEIGHT, 1, 1, texture_format, VK_SAMPLE_COUNT_1_BIT, @@ -1357,6 +1358,9 @@ void GPU_HW_Vulkan::UpdateDisplay() m_display_texture.TransitionToLayout(cmdbuf, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); m_vram_texture.TransitionToLayout(cmdbuf, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + Assert(scaled_display_width <= m_display_texture.GetWidth() && + scaled_display_height <= m_display_texture.GetHeight()); + BeginRenderPass(m_display_render_pass, m_display_framebuffer, 0, 0, scaled_display_width, scaled_display_height); vkCmdBindPipeline(