vk: Support sw component swizzle decode because metal sucks

This commit is contained in:
kd-11 2018-08-22 14:18:45 +03:00 committed by kd-11
parent f3d3a1a4a5
commit c6e35706a3
8 changed files with 108 additions and 32 deletions

View File

@ -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)

View File

@ -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;
};
}

View File

@ -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:

View File

@ -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

View File

@ -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;
}
}

View File

@ -25,6 +25,12 @@
#include <X11/Xutil.h>
#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

View File

@ -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<std::unique_ptr<vk::image>> 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<vk::image>(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, &region);
change_image_layout(cmd, tex.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range);
auto view = std::make_unique<vk::image_view>(dev, tex.get(), mapping, range);
auto view = std::make_unique<vk::image_view>(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:

View File

@ -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<vk::cs_shuffle_d24x8_f32>()->run(cmd, upload_heap.heap.get(), image_linear_size, offset_in_buffer);
vk::get_compute_task<vk::cs_shuffle_d24x8_f32>()->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);