android: Fix build
This commit is contained in:
@ -114,7 +114,10 @@ void Config::ReadValues() {
|
||||
sdl2_config->GetString("Premium", "texture_filter_name", "none");
|
||||
|
||||
// Renderer
|
||||
Settings::values.use_gles = sdl2_config->GetBoolean("Renderer", "use_gles", true);
|
||||
Settings::values.graphics_api =
|
||||
static_cast<Settings::GraphicsAPI>(sdl2_config->GetInteger("Renderer", "graphics_api", 2));
|
||||
Settings::values.async_command_recording =
|
||||
sdl2_config->GetBoolean("Renderer", "async_command_recording", true);
|
||||
Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true);
|
||||
Settings::values.use_hw_shader = sdl2_config->GetBoolean("Renderer", "use_hw_shader", true);
|
||||
Settings::values.shaders_accurate_mul =
|
||||
|
@ -76,24 +76,24 @@ constexpr u32 GetFormatBpp(PixelFormat format) {
|
||||
}
|
||||
|
||||
constexpr std::array<SurfaceType, PIXEL_FORMAT_COUNT> FORMAT_TYPE_TABLE = {{
|
||||
SurfaceType::Color, // RGBA8
|
||||
SurfaceType::Color, // RGB8
|
||||
SurfaceType::Color, // RGB5A1
|
||||
SurfaceType::Color, // RGB565
|
||||
SurfaceType::Color, // RGBA4
|
||||
SurfaceType::Texture, // IA8
|
||||
SurfaceType::Texture, // RG8
|
||||
SurfaceType::Texture, // I8
|
||||
SurfaceType::Texture, // A8
|
||||
SurfaceType::Texture, // IA4
|
||||
SurfaceType::Texture, // I4
|
||||
SurfaceType::Texture, // A4
|
||||
SurfaceType::Texture, // ETC1
|
||||
SurfaceType::Texture, // ETC1A4
|
||||
SurfaceType::Depth, // D16
|
||||
SurfaceType::Color, // RGBA8
|
||||
SurfaceType::Color, // RGB8
|
||||
SurfaceType::Color, // RGB5A1
|
||||
SurfaceType::Color, // RGB565
|
||||
SurfaceType::Color, // RGBA4
|
||||
SurfaceType::Texture, // IA8
|
||||
SurfaceType::Texture, // RG8
|
||||
SurfaceType::Texture, // I8
|
||||
SurfaceType::Texture, // A8
|
||||
SurfaceType::Texture, // IA4
|
||||
SurfaceType::Texture, // I4
|
||||
SurfaceType::Texture, // A4
|
||||
SurfaceType::Texture, // ETC1
|
||||
SurfaceType::Texture, // ETC1A4
|
||||
SurfaceType::Depth, // D16
|
||||
SurfaceType::Invalid,
|
||||
SurfaceType::Depth, // D24
|
||||
SurfaceType::DepthStencil, // D24S8
|
||||
SurfaceType::Depth, // D24
|
||||
SurfaceType::DepthStencil, // D24S8
|
||||
}};
|
||||
|
||||
constexpr SurfaceType GetFormatType(PixelFormat format) {
|
||||
|
@ -59,8 +59,9 @@ constexpr u32 DOWNLOAD_BUFFER_SIZE = 32 * 1024 * 1024;
|
||||
TextureRuntime::TextureRuntime(Driver& driver)
|
||||
: driver{driver}, filterer{Settings::values.texture_filter_name.GetValue(),
|
||||
VideoCore::GetResolutionScaleFactor()},
|
||||
upload_buffer{GL_PIXEL_UNPACK_BUFFER, UPLOAD_BUFFER_SIZE},
|
||||
download_buffer{GL_PIXEL_PACK_BUFFER, DOWNLOAD_BUFFER_SIZE, true} {
|
||||
upload_buffer{GL_PIXEL_UNPACK_BUFFER, UPLOAD_BUFFER_SIZE}, download_buffer{
|
||||
GL_PIXEL_PACK_BUFFER,
|
||||
DOWNLOAD_BUFFER_SIZE, true} {
|
||||
|
||||
read_fbo.Create();
|
||||
draw_fbo.Create();
|
||||
@ -466,7 +467,8 @@ void Surface::ScaledDownload(const VideoCore::BufferTextureCopy& download,
|
||||
|
||||
const auto& tuple = runtime.GetFormatTuple(pixel_format);
|
||||
if (driver.IsOpenGLES()) {
|
||||
runtime.BindFramebuffer(GL_READ_FRAMEBUFFER, 0, GL_TEXTURE_2D, type, unscaled_surface.texture);
|
||||
runtime.BindFramebuffer(GL_READ_FRAMEBUFFER, 0, GL_TEXTURE_2D, type,
|
||||
unscaled_surface.texture);
|
||||
glReadPixels(0, 0, rect_width, rect_height, tuple.format, tuple.type,
|
||||
reinterpret_cast<void*>(staging.buffer_offset));
|
||||
} else {
|
||||
|
@ -23,10 +23,10 @@
|
||||
#include "video_core/renderer_opengl/renderer_opengl.h"
|
||||
#include "video_core/video_core.h"
|
||||
|
||||
#include "video_core/host_shaders/opengl_present_vert.h"
|
||||
#include "video_core/host_shaders/opengl_present_frag.h"
|
||||
#include "video_core/host_shaders/opengl_present_anaglyph_frag.h"
|
||||
#include "video_core/host_shaders/opengl_present_frag.h"
|
||||
#include "video_core/host_shaders/opengl_present_interlaced_frag.h"
|
||||
#include "video_core/host_shaders/opengl_present_vert.h"
|
||||
|
||||
MICROPROFILE_DEFINE(OpenGL_RenderFrame, "OpenGL", "Render Frame", MP_RGB(128, 128, 64));
|
||||
MICROPROFILE_DEFINE(OpenGL_WaitPresent, "OpenGL", "Wait For Present", MP_RGB(128, 128, 128));
|
||||
|
@ -19,10 +19,10 @@
|
||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||
#include "video_core/video_core.h"
|
||||
|
||||
#include "video_core/host_shaders/vulkan_present_vert_spv.h"
|
||||
#include "video_core/host_shaders/vulkan_present_frag_spv.h"
|
||||
#include "video_core/host_shaders/vulkan_present_anaglyph_frag_spv.h"
|
||||
#include "video_core/host_shaders/vulkan_present_frag_spv.h"
|
||||
#include "video_core/host_shaders/vulkan_present_interlaced_frag_spv.h"
|
||||
#include "video_core/host_shaders/vulkan_present_vert_spv.h"
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
@ -832,8 +832,7 @@ void RendererVulkan::SwapBuffers() {
|
||||
|
||||
const auto RecreateSwapchain = [&] {
|
||||
scheduler.Finish();
|
||||
const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout();
|
||||
swapchain.Create(layout.width, layout.height);
|
||||
swapchain.Create();
|
||||
};
|
||||
|
||||
do {
|
||||
|
@ -116,8 +116,13 @@ Instance::Instance(bool validation, bool dump_command_buffers)
|
||||
.engineVersion = VK_MAKE_VERSION(1, 0, 0),
|
||||
.apiVersion = VK_API_VERSION_1_0};
|
||||
|
||||
std::array<const char*, 3> layers;
|
||||
#ifdef ANDROID
|
||||
u32 layer_count = 1;
|
||||
layers[0] = "VK_LAYER_KHRONOS_timeline_semaphore";
|
||||
#else
|
||||
u32 layer_count = 0;
|
||||
std::array<const char*, 2> layers;
|
||||
#endif
|
||||
|
||||
if (enable_validation) {
|
||||
layers[layer_count++] = "VK_LAYER_KHRONOS_validation";
|
||||
@ -159,7 +164,7 @@ Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index)
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);
|
||||
|
||||
// Enable the instance extensions the backend uses
|
||||
auto extensions = GetInstanceExtensions(window_info.type, true);
|
||||
auto extensions = GetInstanceExtensions(window_info.type, enable_validation);
|
||||
|
||||
// Use required platform-specific flags
|
||||
auto flags = GetInstanceFlags();
|
||||
|
@ -680,28 +680,13 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
|
||||
pipeline_cache.SetScissor(draw_rect.left, draw_rect.bottom, draw_rect.GetWidth(),
|
||||
draw_rect.GetHeight());
|
||||
|
||||
// Sometimes the dimentions of the color and depth framebuffers might not be the same
|
||||
// In that case select the minimum one to abide by the spec
|
||||
u32 width = 0;
|
||||
u32 height = 0;
|
||||
if (color_surface && depth_surface) {
|
||||
width = std::min(color_surface->GetScaledWidth(), depth_surface->GetScaledWidth());
|
||||
height = std::min(color_surface->GetScaledHeight(), depth_surface->GetScaledHeight());
|
||||
} else if (color_surface) {
|
||||
width = color_surface->GetScaledWidth();
|
||||
height = color_surface->GetScaledHeight();
|
||||
} else if (depth_surface) {
|
||||
width = depth_surface->GetScaledWidth();
|
||||
height = depth_surface->GetScaledHeight();
|
||||
}
|
||||
|
||||
const FramebufferInfo framebuffer_info = {
|
||||
.color = color_surface ? color_surface->GetFramebufferView() : VK_NULL_HANDLE,
|
||||
.depth = depth_surface ? depth_surface->GetFramebufferView() : VK_NULL_HANDLE,
|
||||
.renderpass = renderpass_cache.GetRenderpass(pipeline_info.color_attachment,
|
||||
pipeline_info.depth_attachment, false),
|
||||
.width = width,
|
||||
.height = height};
|
||||
.width = surfaces_rect.GetWidth(),
|
||||
.height = surfaces_rect.GetHeight()};
|
||||
|
||||
auto [it, new_framebuffer] = framebuffers.try_emplace(framebuffer_info, vk::Framebuffer{});
|
||||
if (new_framebuffer) {
|
||||
|
@ -172,7 +172,7 @@ void Scheduler::SubmitExecution(vk::Semaphore signal_semaphore, vk::Semaphore wa
|
||||
.waitSemaphoreCount = num_wait_semaphores,
|
||||
.pWaitSemaphores = wait_semaphores.data(),
|
||||
.pWaitDstStageMask = wait_stage_masks.data(),
|
||||
.commandBufferCount = 2,
|
||||
.commandBufferCount = static_cast<u32>(cmdbuffers.size()),
|
||||
.pCommandBuffers = cmdbuffers.data(),
|
||||
.signalSemaphoreCount = num_signal_semaphores,
|
||||
.pSignalSemaphores = signal_semaphores.data(),
|
||||
|
@ -92,8 +92,7 @@ constexpr TBuiltInResource DefaultTBuiltInResource = {
|
||||
.maxCombinedAtomicCounterBuffers = 1,
|
||||
.maxAtomicCounterBufferSize = 16384,
|
||||
.maxTransformFeedbackBuffers = 4,
|
||||
.maxTransformFeedbackInterleavedComponents =
|
||||
64,
|
||||
.maxTransformFeedbackInterleavedComponents = 64,
|
||||
.maxCullDistances = 8,
|
||||
.maxCombinedClipAndCullDistances = 8,
|
||||
.maxSamples = 4,
|
||||
@ -107,17 +106,18 @@ constexpr TBuiltInResource DefaultTBuiltInResource = {
|
||||
.maxTaskWorkGroupSizeZ_NV = 1,
|
||||
.maxMeshViewCountNV = 4,
|
||||
.maxDualSourceDrawBuffersEXT = 1,
|
||||
.limits = TLimits{
|
||||
.nonInductiveForLoops = 1,
|
||||
.whileLoops = 1,
|
||||
.doWhileLoops = 1,
|
||||
.generalUniformIndexing = 1,
|
||||
.generalAttributeMatrixVectorIndexing = 1,
|
||||
.generalVaryingIndexing = 1,
|
||||
.generalSamplerIndexing = 1,
|
||||
.generalVariableIndexing = 1,
|
||||
.generalConstantMatrixVectorIndexing = 1,
|
||||
},
|
||||
.limits =
|
||||
TLimits{
|
||||
.nonInductiveForLoops = 1,
|
||||
.whileLoops = 1,
|
||||
.doWhileLoops = 1,
|
||||
.generalUniformIndexing = 1,
|
||||
.generalAttributeMatrixVectorIndexing = 1,
|
||||
.generalVaryingIndexing = 1,
|
||||
.generalSamplerIndexing = 1,
|
||||
.generalVariableIndexing = 1,
|
||||
.generalConstantMatrixVectorIndexing = 1,
|
||||
},
|
||||
};
|
||||
|
||||
EShLanguage ToEshShaderStage(vk::ShaderStageFlagBits stage) {
|
||||
|
@ -80,16 +80,15 @@ StagingBuffer::~StagingBuffer() {
|
||||
vmaDestroyBuffer(instance.GetAllocator(), static_cast<VkBuffer>(buffer), allocation);
|
||||
}
|
||||
|
||||
StreamBuffer::StreamBuffer(const Instance& instance, Scheduler& scheduler, u32 size,
|
||||
bool readback)
|
||||
: instance{instance}, scheduler{scheduler}, staging{instance, size, readback},
|
||||
total_size{size}, bucket_size{size / BUCKET_COUNT}, readback{readback} {}
|
||||
StreamBuffer::StreamBuffer(const Instance& instance, Scheduler& scheduler, u32 size, bool readback)
|
||||
: instance{instance}, scheduler{scheduler}, staging{instance, size, readback}, total_size{size},
|
||||
bucket_size{size / BUCKET_COUNT}, readback{readback} {}
|
||||
|
||||
StreamBuffer::StreamBuffer(const Instance& instance, Scheduler& scheduler, u32 size,
|
||||
vk::BufferUsageFlagBits usage, std::span<const vk::Format> view_formats,
|
||||
bool readback)
|
||||
: instance{instance}, scheduler{scheduler}, staging{instance, size, readback},
|
||||
usage{usage}, total_size{size}, bucket_size{size / BUCKET_COUNT}, readback{readback} {
|
||||
: instance{instance}, scheduler{scheduler}, staging{instance, size, readback}, usage{usage},
|
||||
total_size{size}, bucket_size{size / BUCKET_COUNT}, readback{readback} {
|
||||
const vk::BufferCreateInfo buffer_info = {
|
||||
.size = total_size, .usage = usage | vk::BufferUsageFlagBits::eTransferDst};
|
||||
|
||||
@ -171,7 +170,8 @@ void StreamBuffer::Flush() {
|
||||
VmaAllocator allocator = instance.GetAllocator();
|
||||
vmaFlushAllocation(allocator, staging.allocation, flush_start, flush_size);
|
||||
if (gpu_buffer) {
|
||||
scheduler.Record([this, flush_start, flush_size](vk::CommandBuffer, vk::CommandBuffer upload_cmdbuf) {
|
||||
scheduler.Record([this, flush_start, flush_size](vk::CommandBuffer,
|
||||
vk::CommandBuffer upload_cmdbuf) {
|
||||
const vk::BufferCopy copy_region = {
|
||||
.srcOffset = flush_start, .dstOffset = flush_start, .size = flush_size};
|
||||
|
||||
@ -186,9 +186,9 @@ void StreamBuffer::Flush() {
|
||||
.offset = flush_start,
|
||||
.size = flush_size};
|
||||
|
||||
upload_cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, MakePipelineStage(usage),
|
||||
vk::DependencyFlagBits::eByRegion, {}, buffer_barrier,
|
||||
{});
|
||||
upload_cmdbuf.pipelineBarrier(
|
||||
vk::PipelineStageFlagBits::eTransfer, MakePipelineStage(usage),
|
||||
vk::DependencyFlagBits::eByRegion, {}, buffer_barrier, {});
|
||||
});
|
||||
}
|
||||
bucket.flush_cursor += flush_size;
|
||||
|
@ -30,10 +30,10 @@ struct StagingBuffer {
|
||||
class StreamBuffer {
|
||||
static constexpr u32 MAX_BUFFER_VIEWS = 3;
|
||||
static constexpr u32 BUCKET_COUNT = 4;
|
||||
|
||||
public:
|
||||
/// Staging only constructor
|
||||
StreamBuffer(const Instance& instance, Scheduler& scheduler, u32 size,
|
||||
bool readback = false);
|
||||
StreamBuffer(const Instance& instance, Scheduler& scheduler, u32 size, bool readback = false);
|
||||
/// Staging + GPU streaming constructor
|
||||
StreamBuffer(const Instance& instance, Scheduler& scheduler, u32 size,
|
||||
vk::BufferUsageFlagBits usage, std::span<const vk::Format> views,
|
||||
|
@ -40,10 +40,10 @@ Swapchain::~Swapchain() {
|
||||
}
|
||||
}
|
||||
|
||||
void Swapchain::Create(u32 width, u32 height) {
|
||||
void Swapchain::Create() {
|
||||
is_outdated = false;
|
||||
is_suboptimal = false;
|
||||
SetSurfaceProperties(width, height);
|
||||
SetSurfaceProperties();
|
||||
|
||||
const std::array queue_family_indices = {
|
||||
instance.GetGraphicsQueueFamilyIndex(),
|
||||
@ -134,23 +134,28 @@ void Swapchain::FindPresentFormat() {
|
||||
const std::vector<vk::SurfaceFormatKHR> formats =
|
||||
instance.GetPhysicalDevice().getSurfaceFormatsKHR(surface);
|
||||
|
||||
surface_format = formats[0];
|
||||
if (formats.size() == 1 && formats[0].format == vk::Format::eUndefined) {
|
||||
surface_format.format = vk::Format::eB8G8R8A8Unorm;
|
||||
} else {
|
||||
auto it =
|
||||
std::find_if(formats.begin(), formats.end(), [](vk::SurfaceFormatKHR format) -> bool {
|
||||
return format.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear &&
|
||||
format.format == vk::Format::eB8G8R8A8Unorm;
|
||||
});
|
||||
|
||||
if (it == formats.end()) {
|
||||
LOG_CRITICAL(Render_Vulkan, "Unable to find required swapchain format!");
|
||||
UNREACHABLE();
|
||||
} else {
|
||||
surface_format = *it;
|
||||
}
|
||||
// If there is a single undefined surface format, the device doesn't care, so we'll just use
|
||||
// RGBA
|
||||
if (formats[0].format == vk::Format::eUndefined) {
|
||||
surface_format.format = vk::Format::eR8G8B8A8Unorm;
|
||||
surface_format.colorSpace = vk::ColorSpaceKHR::eSrgbNonlinear;
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to find a suitable format.
|
||||
for (const vk::SurfaceFormatKHR& sformat : formats) {
|
||||
vk::Format format = sformat.format;
|
||||
if (format != vk::Format::eR8G8B8A8Unorm && format != vk::Format::eB8G8R8A8Unorm) {
|
||||
continue;
|
||||
}
|
||||
|
||||
surface_format.format = format;
|
||||
surface_format.colorSpace = sformat.colorSpace;
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_CRITICAL(Render_Vulkan, "Unable to find required swapchain format!");
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void Swapchain::SetPresentMode() {
|
||||
@ -176,18 +181,18 @@ void Swapchain::SetPresentMode() {
|
||||
}
|
||||
}
|
||||
|
||||
void Swapchain::SetSurfaceProperties(u32 width, u32 height) {
|
||||
void Swapchain::SetSurfaceProperties() {
|
||||
const vk::SurfaceCapabilitiesKHR capabilities =
|
||||
instance.GetPhysicalDevice().getSurfaceCapabilitiesKHR(surface);
|
||||
|
||||
extent = capabilities.currentExtent;
|
||||
if (capabilities.currentExtent.width == std::numeric_limits<u32>::max()) {
|
||||
extent.width =
|
||||
std::clamp(width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
|
||||
extent.height = std::clamp(height, capabilities.minImageExtent.height,
|
||||
capabilities.maxImageExtent.height);
|
||||
LOG_CRITICAL(Render_Vulkan, "Device reported no surface extent");
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
LOG_INFO(Render_Vulkan, "Creating {}x{} surface", extent.width, extent.height);
|
||||
|
||||
// Select number of images in swap chain, we prefer one buffer in the background to work on
|
||||
image_count = PREFERRED_IMAGE_COUNT;
|
||||
if (capabilities.maxImageCount > 0) {
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
~Swapchain();
|
||||
|
||||
/// Creates (or recreates) the swapchain with a given size.
|
||||
void Create(u32 width, u32 height);
|
||||
void Create();
|
||||
|
||||
/// Acquires the next image in the swapchain.
|
||||
void AcquireNextImage();
|
||||
@ -76,7 +76,7 @@ private:
|
||||
void SetPresentMode();
|
||||
|
||||
/// Sets the surface properties according to device capabilities
|
||||
void SetSurfaceProperties(u32 width, u32 height);
|
||||
void SetSurfaceProperties();
|
||||
|
||||
/// Destroys current swapchain resources
|
||||
void Destroy();
|
||||
|
Reference in New Issue
Block a user