diff --git a/src/xenia/gpu/registers.h b/src/xenia/gpu/registers.h index 21666568f..0d7b9a1b0 100644 --- a/src/xenia/gpu/registers.h +++ b/src/xenia/gpu/registers.h @@ -179,6 +179,28 @@ union PA_CL_VTE_CNTL { uint32_t value; }; +union PA_SC_WINDOW_OFFSET { + xe::bf window_x_offset; + xe::bf window_y_offset; + + uint32_t value; +}; + +union PA_SC_WINDOW_SCISSOR_TL { + xe::bf tl_x; + xe::bf tl_y; + xe::bf window_offset_disable; + + uint32_t value; +}; + +union PA_SC_WINDOW_SCISSOR_BR { + xe::bf br_x; + xe::bf br_y; + + uint32_t value; +}; + /************************************************** ___ ___ | _ \ _ ) diff --git a/src/xenia/gpu/vulkan/vulkan_command_processor.cc b/src/xenia/gpu/vulkan/vulkan_command_processor.cc index 924b80caf..5727ab634 100644 --- a/src/xenia/gpu/vulkan/vulkan_command_processor.cc +++ b/src/xenia/gpu/vulkan/vulkan_command_processor.cc @@ -472,17 +472,26 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier); + // Part of the source image that we want to blit from. VkRect2D src_rect = { {0, 0}, - {frontbuffer_width, frontbuffer_height}, + {texture->texture_info.width + 1, texture->texture_info.height + 1}, }; + VkRect2D dst_rect = {{0, 0}, {frontbuffer_width, frontbuffer_height}}; + + VkViewport viewport = { + 0.f, 0.f, float(frontbuffer_width), float(frontbuffer_height), + 0.f, 1.f}; + + VkRect2D scissor = {{0, 0}, {frontbuffer_width, frontbuffer_height}}; + blitter_->BlitTexture2D( copy_commands, current_batch_fence_, texture_cache_->DemandView(texture, 0x688)->view, src_rect, {texture->texture_info.width + 1, texture->texture_info.height + 1}, - VK_FORMAT_R8G8B8A8_UNORM, {0, 0}, - {frontbuffer_width, frontbuffer_height}, fb_framebuffer_, - VK_FILTER_LINEAR, true, true); + VK_FORMAT_R8G8B8A8_UNORM, dst_rect, + {frontbuffer_width, frontbuffer_height}, fb_framebuffer_, viewport, + scissor, VK_FILTER_LINEAR, true, true); std::swap(barrier.oldLayout, barrier.newLayout); barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; @@ -923,7 +932,15 @@ bool VulkanCommandProcessor::IssueCopy() { uint32_t copy_ref; uint32_t copy_mask; uint32_t copy_surface_slice; - }* copy_regs = (decltype(copy_regs)) & regs[XE_GPU_REG_RB_COPY_CONTROL].u32; + }* copy_regs = reinterpret_cast( + ®s[XE_GPU_REG_RB_COPY_CONTROL].u32); + + struct { + reg::PA_SC_WINDOW_OFFSET window_offset; + reg::PA_SC_WINDOW_SCISSOR_TL window_scissor_tl; + reg::PA_SC_WINDOW_SCISSOR_BR window_scissor_br; + }* window_regs = reinterpret_cast( + ®s[XE_GPU_REG_PA_SC_WINDOW_OFFSET].u32); // True if the source tile is a color target bool is_color_source = copy_regs->copy_control.copy_src_select <= 3; @@ -963,6 +980,8 @@ bool VulkanCommandProcessor::IssueCopy() { uint32_t dest_logical_width = copy_dest_pitch; uint32_t dest_logical_height = copy_dest_height; + // vtx_window_offset_enable + assert_true(regs[XE_GPU_REG_PA_SU_SC_MODE_CNTL].u32 & 0x00010000); uint32_t window_offset = regs[XE_GPU_REG_PA_SC_WINDOW_OFFSET].u32; int16_t window_offset_x = window_offset & 0x7FFF; int16_t window_offset_y = (window_offset >> 16) & 0x7FFF; @@ -1029,6 +1048,10 @@ bool VulkanCommandProcessor::IssueCopy() { int32_t dest_max_y = int32_t( (std::max(std::max(dest_points[1], dest_points[3]), dest_points[5]))); + VkOffset2D resolve_offset = {dest_min_x, dest_min_y}; + VkExtent2D resolve_extent = {uint32_t(dest_max_x - dest_min_x), + uint32_t(dest_max_y - dest_min_y)}; + uint32_t color_edram_base = 0; uint32_t depth_edram_base = 0; ColorRenderTargetFormat color_format; @@ -1136,10 +1159,6 @@ bool VulkanCommandProcessor::IssueCopy() { VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_barrier); - VkOffset2D resolve_offset = {dest_min_x, dest_min_y}; - VkExtent2D resolve_extent = {uint32_t(dest_max_x - dest_min_x), - uint32_t(dest_max_y - dest_min_y)}; - // Ask the render cache to copy to the resolve texture. auto edram_base = is_color_source ? color_edram_base : depth_edram_base; uint32_t src_format = is_color_source ? static_cast(color_format) @@ -1223,12 +1242,44 @@ bool VulkanCommandProcessor::IssueCopy() { CheckResult(res, "vkCreateFramebuffer"); } + VkRect2D src_rect = { + {0, 0}, + resolve_extent, + }; + + VkRect2D dst_rect = { + resolve_offset, + resolve_extent, + }; + + VkViewport viewport = { + 0.f, + 0.f, // Ignored because this offset is applied earlier. + float(copy_dest_pitch), + float(copy_dest_height), + 0.f, + 1.f, + }; + + VkRect2D scissor = { + { + int32_t(window_regs->window_scissor_tl.tl_x.value()), + int32_t(window_regs->window_scissor_tl.tl_y.value()), + }, + { + window_regs->window_scissor_br.br_x.value() - + window_regs->window_scissor_tl.tl_x.value(), + window_regs->window_scissor_br.br_y.value() - + window_regs->window_scissor_tl.tl_y.value(), + }, + }; + blitter_->BlitTexture2D( command_buffer, current_batch_fence_, - is_color_source ? view->image_view : view->image_view_depth, - {{0, 0}, {resolve_extent.width, resolve_extent.height}}, - view->GetSize(), texture->format, resolve_offset, resolve_extent, - texture->framebuffer, filter, is_color_source, + is_color_source ? view->image_view : view->image_view_depth, src_rect, + view->GetSize(), texture->format, dst_rect, + {copy_dest_pitch, copy_dest_height}, texture->framebuffer, viewport, + scissor, filter, is_color_source, copy_regs->copy_dest_info.copy_dest_swap != 0); // Pull the tile view back to a color/depth attachment. diff --git a/src/xenia/ui/vulkan/blitter.cc b/src/xenia/ui/vulkan/blitter.cc index c5ca6778b..37c336f71 100644 --- a/src/xenia/ui/vulkan/blitter.cc +++ b/src/xenia/ui/vulkan/blitter.cc @@ -100,15 +100,12 @@ VkResult Blitter::Initialize(VulkanDevice* device) { pipeline_layout_info.pSetLayouts = set_layouts; VkPushConstantRange push_constant_ranges[2]; - // vec4 src_uv push_constant_ranges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; push_constant_ranges[0].offset = 0; - push_constant_ranges[0].size = sizeof(float) * 4; - - // bool swap_channels + push_constant_ranges[0].size = sizeof(VtxPushConstants); push_constant_ranges[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - push_constant_ranges[1].offset = sizeof(float) * 4; - push_constant_ranges[1].size = sizeof(int) * 4; + push_constant_ranges[1].offset = sizeof(VtxPushConstants); + push_constant_ranges[1].size = sizeof(PixPushConstants); pipeline_layout_info.pushConstantRangeCount = static_cast(xe::countof(push_constant_ranges)); @@ -220,8 +217,9 @@ void Blitter::Scavenge() { void Blitter::BlitTexture2D(VkCommandBuffer command_buffer, VkFence fence, VkImageView src_image_view, VkRect2D src_rect, VkExtent2D src_extents, VkFormat dst_image_format, - VkOffset2D dst_offset, VkExtent2D dst_extents, - VkFramebuffer dst_framebuffer, VkFilter filter, + VkRect2D dst_rect, VkExtent2D dst_extents, + VkFramebuffer dst_framebuffer, VkViewport viewport, + VkRect2D scissor, VkFilter filter, bool color_or_depth, bool swap_channels) { // Do we need a full draw, or can we cheap out with a blit command? bool full_draw = swap_channels || true; @@ -237,7 +235,7 @@ void Blitter::BlitTexture2D(VkCommandBuffer command_buffer, VkFence fence, nullptr, render_pass, dst_framebuffer, - {{dst_offset.x, dst_offset.y}, {dst_extents.width, dst_extents.height}}, + {{0, 0}, dst_extents}, 0, nullptr, }; @@ -245,22 +243,7 @@ void Blitter::BlitTexture2D(VkCommandBuffer command_buffer, VkFence fence, vkCmdBeginRenderPass(command_buffer, &render_pass_info, VK_SUBPASS_CONTENTS_INLINE); - VkViewport viewport = { - float(dst_offset.x), - float(dst_offset.y), - float(dst_extents.width), - float(dst_extents.height), - 0.f, - 1.f, - }; vkCmdSetViewport(command_buffer, 0, 1, &viewport); - - VkRect2D scissor = { - dst_offset.x, - dst_offset.y, - dst_extents.width, - dst_extents.height, - }; vkCmdSetScissor(command_buffer, 0, 1, &scissor); // Acquire a pipeline. @@ -307,6 +290,12 @@ void Blitter::BlitTexture2D(VkCommandBuffer command_buffer, VkFence fence, float(src_rect.extent.width) / src_extents.width, float(src_rect.extent.height) / src_extents.height, }, + { + float(dst_rect.offset.x) / dst_extents.width, + float(dst_rect.offset.y) / dst_extents.height, + float(dst_rect.extent.width) / dst_extents.width, + float(dst_rect.extent.height) / dst_extents.height, + }, }; vkCmdPushConstants(command_buffer, pipeline_layout_, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VtxPushConstants), diff --git a/src/xenia/ui/vulkan/blitter.h b/src/xenia/ui/vulkan/blitter.h index a3ab19126..2de0997d1 100644 --- a/src/xenia/ui/vulkan/blitter.h +++ b/src/xenia/ui/vulkan/blitter.h @@ -32,13 +32,21 @@ class Blitter { void Shutdown(); // Queues commands to blit a texture to another texture. + // + // src_rect is the rectangle of pixels to copy from the source + // src_extents is the actual size of the source image + // dst_rect is the rectangle of pixels that are replaced with the source + // dst_extents is the actual size of the destination image // dst_framebuffer must only have one attachment, the target texture. + // viewport is the viewport rect (set to {0, 0, dst_w, dst_h} if unsure) + // scissor is the scissor rect for the dest (set to dst size if unsure) void BlitTexture2D(VkCommandBuffer command_buffer, VkFence fence, VkImageView src_image_view, VkRect2D src_rect, VkExtent2D src_extents, VkFormat dst_image_format, - VkOffset2D dst_offset, VkExtent2D dst_extents, - VkFramebuffer dst_framebuffer, VkFilter filter, - bool color_or_depth, bool swap_channels); + VkRect2D dst_rect, VkExtent2D dst_extents, + VkFramebuffer dst_framebuffer, VkViewport viewport, + VkRect2D scissor, VkFilter filter, bool color_or_depth, + bool swap_channels); void CopyColorTexture2D(VkCommandBuffer command_buffer, VkFence fence, VkImage src_image, VkImageView src_image_view, @@ -56,11 +64,12 @@ class Blitter { private: struct VtxPushConstants { float src_uv[4]; // 0x00 + float dst_uv[4]; // 0x10 }; struct PixPushConstants { - int _pad[3]; // 0x10 - int swap; // 0x1C + int _pad[3]; // 0x20 + int swap; // 0x2C }; VkPipeline GetPipeline(VkRenderPass render_pass, VkShaderModule frag_shader, diff --git a/src/xenia/ui/vulkan/shaders/bin/blit_color_frag.h b/src/xenia/ui/vulkan/shaders/bin/blit_color_frag.h index d1a735f3b..3f558165f 100644 --- a/src/xenia/ui/vulkan/shaders/bin/blit_color_frag.h +++ b/src/xenia/ui/vulkan/shaders/bin/blit_color_frag.h @@ -1,7 +1,7 @@ // generated from `xb genspirv` // source: blit_color.frag const uint8_t blit_color_frag[] = { - 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x08, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, @@ -30,8 +30,8 @@ const uint8_t blit_color_frag[] = { 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, diff --git a/src/xenia/ui/vulkan/shaders/bin/blit_color_frag.spv b/src/xenia/ui/vulkan/shaders/bin/blit_color_frag.spv index fa5feae3f..a7aa8961e 100644 Binary files a/src/xenia/ui/vulkan/shaders/bin/blit_color_frag.spv and b/src/xenia/ui/vulkan/shaders/bin/blit_color_frag.spv differ diff --git a/src/xenia/ui/vulkan/shaders/bin/blit_color_frag.txt b/src/xenia/ui/vulkan/shaders/bin/blit_color_frag.txt index 0eeeed778..afb470980 100644 --- a/src/xenia/ui/vulkan/shaders/bin/blit_color_frag.txt +++ b/src/xenia/ui/vulkan/shaders/bin/blit_color_frag.txt @@ -1,6 +1,6 @@ ; SPIR-V ; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 1 +; Generator: Khronos Glslang Reference Front End; 2 ; Bound: 36 ; Schema: 0 OpCapability Shader @@ -21,8 +21,8 @@ OpDecorate %src_texture DescriptorSet 0 OpDecorate %src_texture Binding 0 OpDecorate %vtx_uv Location 0 - OpMemberDecorate %PushConstants 0 Offset 16 - OpMemberDecorate %PushConstants 1 Offset 28 + OpMemberDecorate %PushConstants 0 Offset 32 + OpMemberDecorate %PushConstants 1 Offset 44 OpDecorate %PushConstants Block %void = OpTypeVoid %3 = OpTypeFunction %void diff --git a/src/xenia/ui/vulkan/shaders/bin/blit_depth_frag.h b/src/xenia/ui/vulkan/shaders/bin/blit_depth_frag.h index 77c1426c8..b92bfb75d 100644 --- a/src/xenia/ui/vulkan/shaders/bin/blit_depth_frag.h +++ b/src/xenia/ui/vulkan/shaders/bin/blit_depth_frag.h @@ -1,7 +1,7 @@ // generated from `xb genspirv` // source: blit_depth.frag const uint8_t blit_depth_frag[] = { - 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x08, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, @@ -33,9 +33,9 @@ const uint8_t blit_depth_frag[] = { 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x1C, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x2C, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, diff --git a/src/xenia/ui/vulkan/shaders/bin/blit_depth_frag.spv b/src/xenia/ui/vulkan/shaders/bin/blit_depth_frag.spv index 92660a07f..22ad38b07 100644 Binary files a/src/xenia/ui/vulkan/shaders/bin/blit_depth_frag.spv and b/src/xenia/ui/vulkan/shaders/bin/blit_depth_frag.spv differ diff --git a/src/xenia/ui/vulkan/shaders/bin/blit_depth_frag.txt b/src/xenia/ui/vulkan/shaders/bin/blit_depth_frag.txt index 87e1cb326..faad8f145 100644 --- a/src/xenia/ui/vulkan/shaders/bin/blit_depth_frag.txt +++ b/src/xenia/ui/vulkan/shaders/bin/blit_depth_frag.txt @@ -1,6 +1,6 @@ ; SPIR-V ; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 1 +; Generator: Khronos Glslang Reference Front End; 2 ; Bound: 30 ; Schema: 0 OpCapability Shader @@ -23,8 +23,8 @@ OpDecorate %src_texture DescriptorSet 0 OpDecorate %src_texture Binding 0 OpDecorate %vtx_uv Location 0 - OpMemberDecorate %PushConstants 0 Offset 16 - OpMemberDecorate %PushConstants 1 Offset 28 + OpMemberDecorate %PushConstants 0 Offset 32 + OpMemberDecorate %PushConstants 1 Offset 44 OpDecorate %PushConstants Block OpDecorate %oC Location 0 %void = OpTypeVoid diff --git a/src/xenia/ui/vulkan/shaders/bin/blit_vert.h b/src/xenia/ui/vulkan/shaders/bin/blit_vert.h index 582bc80a4..271ae099e 100644 --- a/src/xenia/ui/vulkan/shaders/bin/blit_vert.h +++ b/src/xenia/ui/vulkan/shaders/bin/blit_vert.h @@ -1,14 +1,14 @@ // generated from `xb genspirv` // source: blit.vert const uint8_t blit_vert[] = { - 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x08, 0x00, + 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, @@ -16,39 +16,46 @@ const uint8_t blit_vert[] = { 0x05, 0x00, 0x06, 0x00, 0x16, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x64, 0x65, - 0x78, 0x61, 0x62, 0x6C, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x65, 0x72, 0x56, 0x65, + 0x78, 0x61, 0x62, 0x6C, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x1C, 0x00, 0x00, 0x00, 0x73, 0x63, 0x61, 0x6C, 0x65, 0x64, 0x5F, 0x70, + 0x6F, 0x73, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x73, 0x63, 0x61, 0x6C, 0x65, 0x64, 0x5F, 0x64, 0x73, 0x74, 0x5F, 0x75, + 0x76, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x50, 0x75, 0x73, 0x68, 0x43, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74, + 0x73, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x73, 0x72, 0x63, 0x5F, 0x75, 0x76, 0x00, 0x00, + 0x06, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x64, 0x73, 0x74, 0x5F, 0x75, 0x76, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x27, 0x00, 0x00, 0x00, 0x70, 0x75, 0x73, 0x68, 0x5F, 0x63, 0x6F, 0x6E, + 0x73, 0x74, 0x61, 0x6E, 0x74, 0x73, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x06, 0x00, 0x07, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, + 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x53, 0x69, 0x7A, 0x65, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x07, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x43, 0x6C, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, - 0x6E, 0x63, 0x65, 0x00, 0x06, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x00, 0x00, + 0x6E, 0x63, 0x65, 0x00, 0x06, 0x00, 0x07, 0x00, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x43, 0x75, 0x6C, 0x6C, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x00, 0x05, 0x00, 0x03, 0x00, - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, - 0x2E, 0x00, 0x00, 0x00, 0x76, 0x74, 0x78, 0x5F, 0x75, 0x76, 0x00, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x30, 0x00, 0x00, 0x00, 0x50, 0x75, 0x73, 0x68, - 0x43, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74, 0x73, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x05, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x73, 0x72, 0x63, 0x5F, 0x75, 0x76, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, - 0x32, 0x00, 0x00, 0x00, 0x70, 0x75, 0x73, 0x68, 0x5F, 0x63, 0x6F, 0x6E, - 0x73, 0x74, 0x61, 0x6E, 0x74, 0x73, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, - 0x2E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x05, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x42, 0x00, 0x00, 0x00, 0x76, 0x74, 0x78, 0x5F, 0x75, 0x76, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x2A, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x42, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, @@ -75,33 +82,41 @@ const uint8_t blit_vert[] = { 0x14, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, - 0x1E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x1E, 0x00, 0x06, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x21, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2C, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x04, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x1C, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x2D, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x1E, 0x00, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x04, 0x00, 0x31, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x31, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x04, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x07, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x2C, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1C, 0x00, 0x04, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x2E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x06, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, + 0x2F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x31, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, + 0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x2B, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x3F, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x41, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3B, 0x00, 0x04, 0x00, 0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3B, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x19, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, @@ -109,34 +124,54 @@ const uint8_t blit_vert[] = { 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x23, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x1C, 0x00, 0x00, 0x00, - 0x2A, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, - 0x2B, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x2A, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x2F, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, - 0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x07, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, - 0x35, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x85, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, - 0x2F, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, - 0x39, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x07, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, - 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x81, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, - 0x37, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, - 0x2E, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, - 0x38, 0x00, 0x01, 0x00, + 0x1D, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, + 0x1F, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x3E, 0x00, 0x03, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, + 0x2B, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x4F, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x07, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x3A, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x3C, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, + 0x3B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x4F, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, + 0x45, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, + 0x4F, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, + 0x49, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x4B, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, + 0x3E, 0x00, 0x03, 0x00, 0x42, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00, + 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, }; diff --git a/src/xenia/ui/vulkan/shaders/bin/blit_vert.spv b/src/xenia/ui/vulkan/shaders/bin/blit_vert.spv index 404ac61ea..27380e97b 100644 Binary files a/src/xenia/ui/vulkan/shaders/bin/blit_vert.spv and b/src/xenia/ui/vulkan/shaders/bin/blit_vert.spv differ diff --git a/src/xenia/ui/vulkan/shaders/bin/blit_vert.txt b/src/xenia/ui/vulkan/shaders/bin/blit_vert.txt index 599ae76c6..735fad360 100644 --- a/src/xenia/ui/vulkan/shaders/bin/blit_vert.txt +++ b/src/xenia/ui/vulkan/shaders/bin/blit_vert.txt @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 1 -; Bound: 60 +; Generator: Khronos Glslang Reference Front End; 2 +; Bound: 76 ; Schema: 0 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" @@ -12,6 +12,12 @@ OpName %vfetch_pos "vfetch_pos" OpName %gl_VertexIndex "gl_VertexIndex" OpName %indexable "indexable" + OpName %scaled_pos "scaled_pos" + OpName %scaled_dst_uv "scaled_dst_uv" + OpName %PushConstants "PushConstants" + OpMemberName %PushConstants 0 "src_uv" + OpMemberName %PushConstants 1 "dst_uv" + OpName %push_constants "push_constants" OpName %gl_PerVertex "gl_PerVertex" OpMemberName %gl_PerVertex 0 "gl_Position" OpMemberName %gl_PerVertex 1 "gl_PointSize" @@ -19,18 +25,16 @@ OpMemberName %gl_PerVertex 3 "gl_CullDistance" OpName %_ "" OpName %vtx_uv "vtx_uv" - OpName %PushConstants "PushConstants" - OpMemberName %PushConstants 0 "src_uv" - OpName %push_constants "push_constants" OpDecorate %gl_VertexIndex BuiltIn VertexIndex + OpMemberDecorate %PushConstants 0 Offset 0 + OpMemberDecorate %PushConstants 1 Offset 16 + OpDecorate %PushConstants Block OpMemberDecorate %gl_PerVertex 0 BuiltIn Position OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance OpDecorate %gl_PerVertex Block OpDecorate %vtx_uv Location 0 - OpMemberDecorate %PushConstants 0 Offset 0 - OpDecorate %PushConstants Block %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 @@ -50,48 +54,66 @@ %_ptr_Input_int = OpTypePointer Input %int %gl_VertexIndex = OpVariable %_ptr_Input_int Input %_ptr_Function__arr_v2float_uint_4 = OpTypePointer Function %_arr_v2float_uint_4 + %float_2 = OpConstant %float 2 + %31 = OpConstantComposite %v2float %float_2 %float_2 %v4float = OpTypeVector %float 4 +%_ptr_Function_v4float = OpTypePointer Function %v4float +%PushConstants = OpTypeStruct %v4float %v4float +%_ptr_PushConstant_PushConstants = OpTypePointer PushConstant %PushConstants +%push_constants = OpVariable %_ptr_PushConstant_PushConstants PushConstant + %int_1 = OpConstant %int 1 +%_ptr_PushConstant_v4float = OpTypePointer PushConstant %v4float + %44 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 %uint_1 = OpConstant %uint 1 %_arr_float_uint_1 = OpTypeArray %float %uint_1 %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex %_ = OpVariable %_ptr_Output_gl_PerVertex Output %int_0 = OpConstant %int 0 - %float_2 = OpConstant %float 2 - %37 = OpConstantComposite %v2float %float_2 %float_2 %_ptr_Output_v4float = OpTypePointer Output %v4float %_ptr_Output_v2float = OpTypePointer Output %v2float %vtx_uv = OpVariable %_ptr_Output_v2float Output -%PushConstants = OpTypeStruct %v4float -%_ptr_PushConstant_PushConstants = OpTypePointer PushConstant %PushConstants -%push_constants = OpVariable %_ptr_PushConstant_PushConstants PushConstant -%_ptr_PushConstant_v4float = OpTypePointer PushConstant %v4float %main = OpFunction %void None %3 %5 = OpLabel %vfetch_pos = OpVariable %_ptr_Function_v2float Function %indexable = OpVariable %_ptr_Function__arr_v2float_uint_4 Function + %scaled_pos = OpVariable %_ptr_Function_v2float Function +%scaled_dst_uv = OpVariable %_ptr_Function_v4float Function %23 = OpLoad %int %gl_VertexIndex OpStore %indexable %19 %26 = OpAccessChain %_ptr_Function_v2float %indexable %23 %27 = OpLoad %v2float %26 OpStore %vfetch_pos %27 - %35 = OpLoad %v2float %vfetch_pos - %38 = OpFMul %v2float %35 %37 - %39 = OpFSub %v2float %38 %18 - %40 = OpCompositeExtract %float %39 0 - %41 = OpCompositeExtract %float %39 1 - %42 = OpCompositeConstruct %v4float %40 %41 %float_0 %float_1 - %44 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %44 %42 - %47 = OpLoad %v2float %vfetch_pos - %52 = OpAccessChain %_ptr_PushConstant_v4float %push_constants %int_0 - %53 = OpLoad %v4float %52 - %54 = OpVectorShuffle %v2float %53 %53 2 3 - %55 = OpFMul %v2float %47 %54 - %56 = OpAccessChain %_ptr_PushConstant_v4float %push_constants %int_0 - %57 = OpLoad %v4float %56 - %58 = OpVectorShuffle %v2float %57 %57 0 1 - %59 = OpFAdd %v2float %55 %58 - OpStore %vtx_uv %59 + %29 = OpLoad %v2float %vfetch_pos + %32 = OpFMul %v2float %29 %31 + %33 = OpFSub %v2float %32 %18 + OpStore %scaled_pos %33 + %42 = OpAccessChain %_ptr_PushConstant_v4float %push_constants %int_1 + %43 = OpLoad %v4float %42 + %45 = OpFMul %v4float %43 %44 + OpStore %scaled_dst_uv %45 + %52 = OpLoad %v4float %scaled_dst_uv + %53 = OpVectorShuffle %v2float %52 %52 0 1 + %54 = OpFSub %v2float %53 %18 + %55 = OpLoad %v2float %vfetch_pos + %56 = OpLoad %v4float %scaled_dst_uv + %57 = OpVectorShuffle %v2float %56 %56 2 3 + %58 = OpFMul %v2float %55 %57 + %59 = OpFAdd %v2float %54 %58 + %60 = OpCompositeExtract %float %59 0 + %61 = OpCompositeExtract %float %59 1 + %62 = OpCompositeConstruct %v4float %60 %61 %float_0 %float_1 + %64 = OpAccessChain %_ptr_Output_v4float %_ %int_0 + OpStore %64 %62 + %67 = OpLoad %v2float %vfetch_pos + %68 = OpAccessChain %_ptr_PushConstant_v4float %push_constants %int_0 + %69 = OpLoad %v4float %68 + %70 = OpVectorShuffle %v2float %69 %69 2 3 + %71 = OpFMul %v2float %67 %70 + %72 = OpAccessChain %_ptr_PushConstant_v4float %push_constants %int_0 + %73 = OpLoad %v4float %72 + %74 = OpVectorShuffle %v2float %73 %73 0 1 + %75 = OpFAdd %v2float %71 %74 + OpStore %vtx_uv %75 OpReturn OpFunctionEnd diff --git a/src/xenia/ui/vulkan/shaders/bin/immediate_frag.h b/src/xenia/ui/vulkan/shaders/bin/immediate_frag.h index 2acddaf24..4d4582676 100644 --- a/src/xenia/ui/vulkan/shaders/bin/immediate_frag.h +++ b/src/xenia/ui/vulkan/shaders/bin/immediate_frag.h @@ -1,7 +1,7 @@ // generated from `xb genspirv` // source: immediate.frag const uint8_t immediate_frag[] = { - 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x08, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, diff --git a/src/xenia/ui/vulkan/shaders/bin/immediate_frag.spv b/src/xenia/ui/vulkan/shaders/bin/immediate_frag.spv index 2498fcd39..788bd7827 100644 Binary files a/src/xenia/ui/vulkan/shaders/bin/immediate_frag.spv and b/src/xenia/ui/vulkan/shaders/bin/immediate_frag.spv differ diff --git a/src/xenia/ui/vulkan/shaders/bin/immediate_frag.txt b/src/xenia/ui/vulkan/shaders/bin/immediate_frag.txt index af0d930ba..f422e3e43 100644 --- a/src/xenia/ui/vulkan/shaders/bin/immediate_frag.txt +++ b/src/xenia/ui/vulkan/shaders/bin/immediate_frag.txt @@ -1,6 +1,6 @@ ; SPIR-V ; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 1 +; Generator: Khronos Glslang Reference Front End; 2 ; Bound: 56 ; Schema: 0 OpCapability Shader diff --git a/src/xenia/ui/vulkan/shaders/bin/immediate_vert.h b/src/xenia/ui/vulkan/shaders/bin/immediate_vert.h index d6b96912b..ea73f3393 100644 --- a/src/xenia/ui/vulkan/shaders/bin/immediate_vert.h +++ b/src/xenia/ui/vulkan/shaders/bin/immediate_vert.h @@ -1,7 +1,7 @@ // generated from `xb genspirv` // source: immediate.vert const uint8_t immediate_vert[] = { - 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x08, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, diff --git a/src/xenia/ui/vulkan/shaders/bin/immediate_vert.spv b/src/xenia/ui/vulkan/shaders/bin/immediate_vert.spv index 44b8b315c..6ba569eb5 100644 Binary files a/src/xenia/ui/vulkan/shaders/bin/immediate_vert.spv and b/src/xenia/ui/vulkan/shaders/bin/immediate_vert.spv differ diff --git a/src/xenia/ui/vulkan/shaders/bin/immediate_vert.txt b/src/xenia/ui/vulkan/shaders/bin/immediate_vert.txt index 9022adb11..a961fc4ac 100644 --- a/src/xenia/ui/vulkan/shaders/bin/immediate_vert.txt +++ b/src/xenia/ui/vulkan/shaders/bin/immediate_vert.txt @@ -1,6 +1,6 @@ ; SPIR-V ; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 1 +; Generator: Khronos Glslang Reference Front End; 2 ; Bound: 48 ; Schema: 0 OpCapability Shader diff --git a/src/xenia/ui/vulkan/shaders/blit.vert b/src/xenia/ui/vulkan/shaders/blit.vert index 6f5f572d5..f7758b57d 100644 --- a/src/xenia/ui/vulkan/shaders/blit.vert +++ b/src/xenia/ui/vulkan/shaders/blit.vert @@ -6,7 +6,8 @@ precision highp float; layout(push_constant) uniform PushConstants { // normalized [x, y, w, h] - layout(offset = 0) vec4 src_uv; + layout(offset = 0x00) vec4 src_uv; + layout(offset = 0x10) vec4 dst_uv; } push_constants; layout(location = 0) out vec2 vtx_uv; @@ -20,8 +21,19 @@ void main() { ); vec2 vfetch_pos = vtx_arr[gl_VertexIndex]; - gl_Position = vec4(vfetch_pos.xy * vec2(2.0, 2.0) - - vec2(1.0, 1.0), 0.0, 1.0); - vtx_uv = vfetch_pos.xy * push_constants.src_uv.zw + - push_constants.src_uv.xy; + // gl_Position = vec4(vfetch_pos.xy * vec2(2.0, 2.0) - + // vec2(1.0, 1.0), 0.0, 1.0); + vec2 scaled_pos = vfetch_pos.xy * vec2(2.0, 2.0) - vec2(1.0, 1.0); + + // (-1, -1) * (1, 0.35556) + (0, 0) = (-1, -0.35556) + // should be (-1, -1) for ref + // dst xy is top left + // dst zw is size + // dst = (0, 0, 1, 0.35556) + vec4 scaled_dst_uv = push_constants.dst_uv * vec4(2.0); + gl_Position = + vec4(scaled_dst_uv.xy - vec2(1.0) + vfetch_pos.xy * scaled_dst_uv.zw, 0.0, + 1.0); + + vtx_uv = vfetch_pos.xy * push_constants.src_uv.zw + push_constants.src_uv.xy; } \ No newline at end of file diff --git a/src/xenia/ui/vulkan/shaders/blit_color.frag b/src/xenia/ui/vulkan/shaders/blit_color.frag index bfa602b7e..682ae6af4 100644 --- a/src/xenia/ui/vulkan/shaders/blit_color.frag +++ b/src/xenia/ui/vulkan/shaders/blit_color.frag @@ -5,8 +5,8 @@ precision highp float; layout(push_constant) uniform PushConstants { - layout(offset = 16) vec3 _pad; - layout(offset = 28) int swap; + layout(offset = 0x20) vec3 _pad; + layout(offset = 0x2C) int swap; } push_constants; layout(set = 0, binding = 0) uniform sampler2D src_texture; diff --git a/src/xenia/ui/vulkan/shaders/blit_depth.frag b/src/xenia/ui/vulkan/shaders/blit_depth.frag index 9e08f7217..a22f1e5a6 100644 --- a/src/xenia/ui/vulkan/shaders/blit_depth.frag +++ b/src/xenia/ui/vulkan/shaders/blit_depth.frag @@ -5,8 +5,8 @@ precision highp float; layout(push_constant) uniform PushConstants { - layout(offset = 16) vec3 _pad; - layout(offset = 28) int swap; + layout(offset = 0x20) vec3 _pad; + layout(offset = 0x2C) int swap; } push_constants; layout(set = 0, binding = 0) uniform sampler2D src_texture;