Add pre-rotation for Android

This commit is contained in:
SSimco
2023-06-13 11:25:22 +03:00
parent 785a37e503
commit b1fef19a63
10 changed files with 56 additions and 21 deletions
+2 -2
View File
@@ -338,7 +338,7 @@ void LatteShaderCache_load()
if (g_renderer->GetType() == RendererAPI::Vulkan)
LatteShaderCache_loadVulkanPipelineCache(cacheTitleId);
#if !__ANDROID__
g_renderer->BeginFrame(true);
if (g_renderer->ImguiBegin(true))
{
@@ -351,7 +351,7 @@ void LatteShaderCache_load()
LatteShaderCache_drawBackgroundImage(g_shaderCacheLoaderState.textureDRCId, 854, 480);
g_renderer->ImguiEnd();
}
#endif // __ANDROID__
g_renderer->SwapBuffers(true, true);
if (g_shaderCacheLoaderState.textureTVId)
@@ -302,16 +302,16 @@ std::string RendererOutputShader::GetVulkanVertexSource(bool render_upside_down)
{
// vertex shader
std::ostringstream vertex_source;
vertex_source <<
R"(#version 450
vertex_source << R"(#version 450
layout(location = 0) out vec2 passUV;
out gl_PerVertex
{
vec4 gl_Position;
};
void main(){
};)";
#if __ANDROID__
vertex_source << "layout (push_constant) uniform PushConstants { mat2 preRotate; } pushConstants;\n";
#endif // __ANDROID__
vertex_source << R"(void main(){
vec2 vPos;
vec2 vUV;
int vID = gl_VertexIndex;
@@ -340,12 +340,13 @@ void main(){
)";
}
vertex_source <<
R"( passUV = vUV;
gl_Position = vec4(vPos, 0.0, 1.0);
}
)";
return vertex_source.str();
vertex_source << "passUV = vUV;\n";
#if __ANDROID__
vertex_source << "gl_Position = vec4(pushConstants.preRotate * vPos, 0.0, 1.0);}";
#else
vertex_source << "gl_Position = vec4(vPos, 0.0, 1.0);}";
#endif // __ANDROID__
return vertex_source.str();
}
void RendererOutputShader::InitializeStatic()
{
@@ -12,6 +12,9 @@ void SwapchainInfoVk::Create(VkPhysicalDevice physicalDevice, VkDevice logicalDe
const auto details = QuerySwapchainSupport(surface, physicalDevice);
m_surfaceFormat = ChooseSurfaceFormat(details.formats);
m_actualExtent = ChooseSwapExtent(details.capabilities);
#if __ANDROID__
m_preTransform = details.capabilities.currentTransform;
#endif // __ANDROID__
// use at least two swapchain images. fewer than that causes problems on some drivers
uint32_t image_count = std::max(2u, details.capabilities.minImageCount);
@@ -76,7 +76,9 @@ struct SwapchainInfoVk
bool m_usesSRGB = false;
VSync m_vsyncState = VSync::Immediate;
bool hasDefinedSwapchainImage{}; // indicates if the swapchain image is in a defined state
#if __ANDROID__
VkSurfaceTransformFlagBitsKHR m_preTransform{};
#endif // __ANDROID__
VkPhysicalDevice m_physicalDevice{};
VkDevice m_logicalDevice{};
VkSurfaceKHR surface{};
@@ -2923,7 +2923,25 @@ void VulkanRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
auto descriptSet = backbufferBlit_createDescriptorSet(m_swapchainDescriptorSetLayout, texViewVk, useLinearTexFilter);
vkCmdBeginRenderPass(m_state.currentCommandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
#if __ANDROID__
float radians = 0.0f;
switch (chainInfo.m_preTransform)
{
case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
radians = glm::radians(90.0f);
break;
case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
radians = glm::radians(180.0f);
break;
case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
radians = glm::radians(270.0f);
break;
default:
break;
}
const glm::mat2 preRotate = glm::rotate(glm::mat4(1.0), radians, glm::vec3(0.0F, 0.0F, 1.0F));
vkCmdPushConstants(m_state.currentCommandBuffer, m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(preRotate), &preRotate);
#endif // __ANDROID__
vkCmdBindPipeline(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
m_state.currentPipeline = pipeline;
+8 -2
View File
@@ -113,6 +113,7 @@ public:
reinterpret_cast<const jint *>(iconData.m_image));
env->CallVoidMethod(*m_gameTitleLoadedCallbackObj, m_onGameIconLoadedMID, jTitleId,
jIconData, iconData.m_width, iconData.m_height);
env->DeleteLocalRef(jIconData);
}
};
@@ -179,5 +180,10 @@ Java_info_cemu_Cemu_NativeLibrary_initializeRendererSurface(JNIEnv *env, jclass
VulkanRenderer::GetInstance()->InitializeSurface(
{width, height},
is_main_canvas);
}
}
extern "C"
JNIEXPORT void JNICALL
Java_info_cemu_Cemu_NativeLibrary_setDPI(JNIEnv *env, jclass clazz, jfloat dpi) {
auto& windowInfo = gui_getWindowInfo();
windowInfo.dpi_scale = windowInfo.pad_dpi_scale = dpi;
}
@@ -1,11 +1,14 @@
package info.cemu.Cemu;
import android.app.Application;
import android.util.DisplayMetrics;
public class CemuApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
NativeLibrary.setDPI(displayMetrics.density);
NativeLibrary.initializeActiveSettings(getExternalFilesDir(null).getAbsoluteFile().toString(), getCacheDir().toString());
NativeLibrary.initializeEmulation();
}
@@ -7,6 +7,8 @@ public class NativeLibrary {
System.loadLibrary("CemuAndroid");
}
public static native void setDPI(float dpi);
public static native void setSurface(Surface surface, boolean isMainCanvas);
public static native void setSurfaceSize(int width, int height, boolean isMainCanvas);
+1 -1
View File
@@ -65,7 +65,7 @@ bool ActiveSettings::FullscreenEnabled()
CPUMode ActiveSettings::GetCPUMode()
{
#if !ARCH_X86_64
#ifndef ARCH_X86_64
return CPUMode::SinglecoreInterpreter;
#else
auto mode = g_current_game_profile->GetCPUMode().value_or(CPUMode::Auto);
+2 -2
View File
@@ -72,11 +72,11 @@ void gui_getPadWindowPhysSize(int& w, int& h)
}
double gui_getWindowDPIScale()
{
return 1.0;
return gui_getWindowInfo().dpi_scale;
}
double gui_getPadDPIScale()
{
return 1.0;
return gui_getWindowInfo().pad_dpi_scale;
}
bool gui_isPadWindowOpen()
{