diff --git a/rpcs3/Emu/RSX/Common/GLSLCommon.h b/rpcs3/Emu/RSX/Common/GLSLCommon.h index 3683d1c25e..f93202431f 100644 --- a/rpcs3/Emu/RSX/Common/GLSLCommon.h +++ b/rpcs3/Emu/RSX/Common/GLSLCommon.h @@ -472,10 +472,27 @@ namespace glsl OS << " return pow((cs + 0.055) / 1.055, 2.4);\n"; OS << "}\n\n"; +#ifdef __APPLE__ + OS << "vec4 remap_vector(vec4 rgba, uint remap_bits)\n"; + OS << "{\n"; + OS << " uvec4 selector = (uvec4(remap_bits) >> uvec4(3, 6, 9, 0)) & 0x7;\n"; + OS << " bvec4 choice = greaterThan(selector, uvec4(1));\n"; + OS << "\n"; + OS << " vec4 direct = vec4(selector);\n"; + OS << " selector = min(selector - 2, selector);\n"; + OS << " vec4 indexed = vec4(rgba[selector.r], rgba[selector.g], rgba[selector.b], rgba[selector.a]);\n"; + OS << " return mix(direct, indexed, choice);\n"; + OS << "}\n\n"; +#endif + //TODO: Move all the texture read control operations here OS << "vec4 process_texel(vec4 rgba, uint control_bits)\n"; OS << "{\n"; - OS << " if (control_bits == 0) return rgba;\n\n"; +#ifdef __APPLE__ + OS << " uint remap_bits = (control_bits >> 16) & 0xFFFF;\n"; + OS << " if (remap_bits != 0x8D5) rgba = remap_vector(rgba, remap_bits);\n\n"; +#endif + OS << " if ((control_bits & 0xFFFF) == 0) return rgba;\n\n"; OS << " if ((control_bits & 0x10) > 0)\n"; OS << " {\n"; OS << " //Alphakill\n"; @@ -494,27 +511,27 @@ namespace glsl OS << " return rgba;\n"; OS << "}\n\n"; - OS << "#define TEX1D(index, tex, coord1) process_texel(texture(tex, coord1 * texture_parameters[index].x), uint(texture_parameters[index].w))\n"; - OS << "#define TEX1D_BIAS(index, tex, coord1, bias) process_texel(texture(tex, coord1 * texture_parameters[index].x, bias), uint(texture_parameters[index].w))\n"; - OS << "#define TEX1D_LOD(index, tex, coord1, lod) process_texel(textureLod(tex, coord1 * texture_parameters[index].x, lod), uint(texture_parameters[index].w))\n"; - OS << "#define TEX1D_GRAD(index, tex, coord1, dpdx, dpdy) process_texel(textureGrad(tex, coord1 * texture_parameters[index].x, dpdx, dpdy), uint(texture_parameters[index].w))\n"; - OS << "#define TEX1D_PROJ(index, tex, coord2) process_texel(textureProj(tex, coord2 * vec2(texture_parameters[index].x, 1.)), uint(texture_parameters[index].w))\n"; + OS << "#define TEX1D(index, tex, coord1) process_texel(texture(tex, coord1 * texture_parameters[index].x), floatBitsToUint(texture_parameters[index].w))\n"; + OS << "#define TEX1D_BIAS(index, tex, coord1, bias) process_texel(texture(tex, coord1 * texture_parameters[index].x, bias), floatBitsToUint(texture_parameters[index].w))\n"; + OS << "#define TEX1D_LOD(index, tex, coord1, lod) process_texel(textureLod(tex, coord1 * texture_parameters[index].x, lod), floatBitsToUint(texture_parameters[index].w))\n"; + OS << "#define TEX1D_GRAD(index, tex, coord1, dpdx, dpdy) process_texel(textureGrad(tex, coord1 * texture_parameters[index].x, dpdx, dpdy), floatBitsToUint(texture_parameters[index].w))\n"; + OS << "#define TEX1D_PROJ(index, tex, coord2) process_texel(textureProj(tex, coord2 * vec2(texture_parameters[index].x, 1.)), floatBitsToUint(texture_parameters[index].w))\n"; - OS << "#define TEX2D(index, tex, coord2) process_texel(texture(tex, coord2 * texture_parameters[index].xy), uint(texture_parameters[index].w))\n"; - OS << "#define TEX2D_BIAS(index, tex, coord2, bias) process_texel(texture(tex, coord2 * texture_parameters[index].xy, bias), uint(texture_parameters[index].w))\n"; - OS << "#define TEX2D_LOD(index, tex, coord2, lod) process_texel(textureLod(tex, coord2 * texture_parameters[index].xy, lod), uint(texture_parameters[index].w))\n"; - OS << "#define TEX2D_GRAD(index, tex, coord2, dpdx, dpdy) process_texel(textureGrad(tex, coord2 * texture_parameters[index].xy, dpdx, dpdy), uint(texture_parameters[index].w))\n"; - OS << "#define TEX2D_PROJ(index, tex, coord4) process_texel(textureProj(tex, coord4 * vec4(texture_parameters[index].xy, 1., 1.)), uint(texture_parameters[index].w))\n"; + OS << "#define TEX2D(index, tex, coord2) process_texel(texture(tex, coord2 * texture_parameters[index].xy), floatBitsToUint(texture_parameters[index].w))\n"; + OS << "#define TEX2D_BIAS(index, tex, coord2, bias) process_texel(texture(tex, coord2 * texture_parameters[index].xy, bias), floatBitsToUint(texture_parameters[index].w))\n"; + OS << "#define TEX2D_LOD(index, tex, coord2, lod) process_texel(textureLod(tex, coord2 * texture_parameters[index].xy, lod), floatBitsToUint(texture_parameters[index].w))\n"; + OS << "#define TEX2D_GRAD(index, tex, coord2, dpdx, dpdy) process_texel(textureGrad(tex, coord2 * texture_parameters[index].xy, dpdx, dpdy), floatBitsToUint(texture_parameters[index].w))\n"; + OS << "#define TEX2D_PROJ(index, tex, coord4) process_texel(textureProj(tex, coord4 * vec4(texture_parameters[index].xy, 1., 1.)), floatBitsToUint(texture_parameters[index].w))\n"; - OS << "#define TEX2D_DEPTH_RGBA8(index, tex, coord2) process_texel(texture2DReconstruct(tex, coord2 * texture_parameters[index].xy, texture_parameters[index].z), uint(texture_parameters[index].w))\n"; + OS << "#define TEX2D_DEPTH_RGBA8(index, tex, coord2) process_texel(texture2DReconstruct(tex, coord2 * texture_parameters[index].xy, texture_parameters[index].z), floatBitsToUint(texture_parameters[index].w))\n"; OS << "#define TEX2D_SHADOW(index, tex, coord3) texture(tex, coord3 * vec3(texture_parameters[index].xy, 1.))\n"; OS << "#define TEX2D_SHADOWPROJ(index, tex, coord4) textureProj(tex, coord4 * vec4(texture_parameters[index].xy, 1., 1.))\n"; - OS << "#define TEX3D(index, tex, coord3) process_texel(texture(tex, coord3), uint(texture_parameters[index].w))\n"; - OS << "#define TEX3D_BIAS(index, tex, coord3, bias) process_texel(texture(tex, coord3, bias), uint(texture_parameters[index].w))\n"; - OS << "#define TEX3D_LOD(index, tex, coord3, lod) process_texel(textureLod(tex, coord3, lod), uint(texture_parameters[index].w))\n"; - OS << "#define TEX3D_GRAD(index, tex, coord3, dpdx, dpdy) process_texel(textureGrad(tex, coord3, dpdx, dpdy), uint(texture_parameters[index].w))\n"; - OS << "#define TEX3D_PROJ(index, tex, coord4) process_texel(textureProj(tex, coord4), uint(texture_parameters[index].w))\n\n"; + OS << "#define TEX3D(index, tex, coord3) process_texel(texture(tex, coord3), floatBitsToUint(texture_parameters[index].w))\n"; + OS << "#define TEX3D_BIAS(index, tex, coord3, bias) process_texel(texture(tex, coord3, bias), floatBitsToUint(texture_parameters[index].w))\n"; + OS << "#define TEX3D_LOD(index, tex, coord3, lod) process_texel(textureLod(tex, coord3, lod), floatBitsToUint(texture_parameters[index].w))\n"; + OS << "#define TEX3D_GRAD(index, tex, coord3, dpdx, dpdy) process_texel(textureGrad(tex, coord3, dpdx, dpdy), floatBitsToUint(texture_parameters[index].w))\n"; + OS << "#define TEX3D_PROJ(index, tex, coord4) process_texel(textureProj(tex, coord4), floatBitsToUint(texture_parameters[index].w))\n\n"; } if (require_wpos) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.h b/rpcs3/Emu/RSX/Common/TextureUtils.h index b5bd608eec..9714ec084b 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.h +++ b/rpcs3/Emu/RSX/Common/TextureUtils.h @@ -29,6 +29,8 @@ namespace rsx bool is_depth_texture = false; f32 scale_x = 1.f; f32 scale_y = 1.f; + + virtual u32 encoded_component_map() const = 0; }; } diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 49d41f16b5..bb7419941d 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -423,6 +423,16 @@ namespace rsx scale_y = y_scale; image_type = type; } + + u32 encoded_component_map() const override + { + if (image_handle) + { + return image_handle->encoded_component_map(); + } + + return 0; + } }; protected: diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.h b/rpcs3/Emu/RSX/GL/GLHelpers.h index dcd5b859b2..d0a6467635 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.h +++ b/rpcs3/Emu/RSX/GL/GLHelpers.h @@ -1890,6 +1890,12 @@ namespace gl { return{ component_swizzle[3], component_swizzle[0], component_swizzle[1], component_swizzle[2] }; } + + u32 encoded_component_map() const + { + // Unused, OGL supports proper component swizzles + return 0u; + } }; class viewable_image : public texture diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index bcd21f4323..f91247d0ac 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2060,7 +2060,10 @@ namespace rsx } } - result.texture_scale[i][3] = (f32)texture_control; +#ifdef __APPLE__ + texture_control |= (sampler_descriptors[i]->encoded_component_map() << 16); +#endif + result.texture_scale[i][3] = (f32&)texture_control; } } diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index e5161f9460..a949266831 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -25,6 +25,12 @@ #include #endif +#ifdef __APPLE__ +#define VK_DISABLE_COMPONENT_SWIZZLE 1 +#else +#define VK_DISABLE_COMPONENT_SWIZZLE 0 +#endif + #define DESCRIPTOR_MAX_DRAW_CALLS 4096 #define VERTEX_BUFFERS_FIRST_BIND_SLOT 3 @@ -658,17 +664,17 @@ namespace vk info.format = format; info.image = image; info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - info.viewType = view_type; info.components = mapping; + info.viewType = view_type; info.subresourceRange = range; - CHECK_RESULT(vkCreateImageView(m_device, &info, nullptr, &value)); + create_impl(); } image_view(VkDevice dev, VkImageViewCreateInfo create_info) : m_device(dev), info(create_info) { - CHECK_RESULT(vkCreateImageView(m_device, &info, nullptr, &value)); + create_impl(); } image_view(VkDevice dev, vk::image* resource, @@ -698,7 +704,7 @@ namespace vk break; } - CHECK_RESULT(vkCreateImageView(m_device, &info, nullptr, &value)); + create_impl(); } ~image_view() @@ -706,10 +712,41 @@ namespace vk vkDestroyImageView(m_device, value, nullptr); } + u32 encoded_component_map() const + { +#if (VK_DISABLE_COMPONENT_SWIZZLE) + u32 result = (u32)info.components.a - 1; + result |= ((u32)info.components.r - 1) << 3; + result |= ((u32)info.components.g - 1) << 6; + result |= ((u32)info.components.b - 1) << 9; + + return result; +#else + return 0; +#endif + } + image_view(const image_view&) = delete; image_view(image_view&&) = delete; + private: VkDevice m_device; + + void create_impl() + { +#if (VK_DISABLE_COMPONENT_SWIZZLE) + // Force identity + const auto mapping = info.components; + info.components = { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }; +#endif + + CHECK_RESULT(vkCreateImageView(m_device, &info, nullptr, &value)); + +#if (VK_DISABLE_COMPONENT_SWIZZLE) + // Restore requested mapping + info.components = mapping; +#endif + } }; struct viewable_image : public image diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.h b/rpcs3/Emu/RSX/VK/VKOverlays.h index a99dd31f30..27acc00814 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.h +++ b/rpcs3/Emu/RSX/VK/VKOverlays.h @@ -447,6 +447,7 @@ namespace vk bool m_pulse_glow = false; bool m_skip_texture_read = false; bool m_clip_enabled; + int m_texture_type; areaf m_clip_region; std::vector> resources; @@ -506,10 +507,12 @@ namespace vk " if (parameters.y != 0)\n" " diff_color.a *= (sin(parameters.x) + 1.f) * 0.5f;\n" "\n" - " if (parameters.z != 0)\n" - " ocol = texture(fs0, tc0) * diff_color;\n" - " else\n" + " if (parameters.z < 1.)\n" " ocol = diff_color;\n" + " else if (parameters.z > 1.)\n" + " ocol = texture(fs0, tc0).rrrr * diff_color;\n" + " else\n" + " ocol = texture(fs0, tc0).bgra * diff_color;\n" "}\n" }; @@ -531,10 +534,6 @@ namespace vk const auto offset = upload_heap.alloc<512>(data_size); const auto addr = upload_heap.map(offset, data_size); - const VkComponentMapping bgra = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A }; - const VkComponentMapping rrrr = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R }; - const VkComponentMapping mapping = (font) ? rrrr : bgra; - const VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; auto tex = std::make_unique(dev, dev.get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, @@ -561,7 +560,7 @@ namespace vk vkCmdCopyBufferToImage(cmd, upload_heap.heap->value, tex->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); change_image_layout(cmd, tex.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range); - auto view = std::make_unique(dev, tex.get(), mapping, range); + auto view = std::make_unique(dev, tex.get()); auto result = view.get(); @@ -664,7 +663,7 @@ namespace vk dst[7] = m_color.a; dst[8] = m_time; dst[9] = m_pulse_glow? 1.f : 0.f; - dst[10] = m_skip_texture_read? 0.f : 1.f; + dst[10] = m_skip_texture_read? 0.f : (f32)m_texture_type; dst[11] = m_clip_enabled ? 1.f : 0.f; dst[12] = m_clip_region.x1; dst[13] = m_clip_region.y1; @@ -704,6 +703,7 @@ namespace vk m_pulse_glow = command.config.pulse_glow; m_clip_enabled = command.config.clip_region; m_clip_region = command.config.clip_rect; + m_texture_type = 1; auto src = vk::null_image_view(cmd); switch (command.config.texture_ref) @@ -715,6 +715,7 @@ namespace vk m_skip_texture_read = true; break; case rsx::overlays::image_resource_id::font_file: + m_texture_type = 2; src = find_font(command.config.font_ref, cmd, upload_heap)->value; break; case rsx::overlays::image_resource_id::raw_image: diff --git a/rpcs3/Emu/RSX/VK/VKTexture.cpp b/rpcs3/Emu/RSX/VK/VKTexture.cpp index bc5426dc9c..9a04f2e820 100644 --- a/rpcs3/Emu/RSX/VK/VKTexture.cpp +++ b/rpcs3/Emu/RSX/VK/VKTexture.cpp @@ -480,7 +480,7 @@ namespace vk insert_buffer_memory_barrier(cmd, scratch_buf->value, 0, image_linear_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT); - vk::get_compute_task()->run(cmd, upload_heap.heap.get(), image_linear_size, offset_in_buffer); + vk::get_compute_task()->run(cmd, upload_heap.heap.get(), image_linear_size, (u32)offset_in_buffer); insert_buffer_memory_barrier(cmd, scratch_buf->value, 0, image_linear_size, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);