rsx/gl/vk: Enable use of native PCF shadows

This commit is contained in:
kd-11 2017-06-12 12:42:30 +03:00
parent 5f66d0b996
commit 6a9eef0382
9 changed files with 51 additions and 16 deletions

View File

@ -106,7 +106,8 @@ bool fragment_program_compare::operator()(const RSXFragmentProgram& binary1, con
if (binary1.texture_dimensions != binary2.texture_dimensions || binary1.unnormalized_coords != binary2.unnormalized_coords ||
binary1.height != binary2.height || binary1.origin_mode != binary2.origin_mode || binary1.pixel_center_mode != binary2.pixel_center_mode ||
binary1.back_color_diffuse_output != binary2.back_color_diffuse_output || binary1.back_color_specular_output != binary2.back_color_specular_output ||
binary1.front_back_color_enabled != binary2.front_back_color_enabled || binary1.alpha_func != binary2.alpha_func || binary1.redirected_textures != binary2.redirected_textures)
binary1.front_back_color_enabled != binary2.front_back_color_enabled || binary1.alpha_func != binary2.alpha_func ||
binary1.shadow_textures != binary2.shadow_textures || binary1.redirected_textures != binary2.redirected_textures)
return false;
const qword *instBuffer1 = (const qword*)binary1.addr;
const qword *instBuffer2 = (const qword*)binary2.addr;

View File

@ -123,9 +123,9 @@ void insert_glsl_legacy_function(std::ostream& OS)
//NOTE: We lose precision if we just store depth value into 8-bit textures i.e (depth, 0, 0)
//NOTE2: After testing with GOW, the w component is either the original depth or wraps around to the x component
//Since component.r == depth_value with some precision loss, just use the precise depth value for now (further testing needed)
OS << "vec4 texture2DReconstruct(sampler2D tex, vec2 coord)\n";
OS << "highp vec4 texture2DReconstruct(sampler2D tex, vec2 coord)\n";
OS << "{\n";
OS << " float depth_value = texture(tex, coord.xy).r;\n";
OS << " highp float depth_value = texture(tex, coord.xy).r;\n";
OS << " uint value = uint(depth_value * 16777215);\n";
OS << " uint b = (value & 0xff);\n";
OS << " uint g = (value >> 8) & 0xff;\n";

View File

@ -107,6 +107,9 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS)
std::string samplerType = PT.type;
int index = atoi(&PI.name.data()[3]);
if ((m_prog.shadow_textures & (1 << index)) > 0)
samplerType = "sampler2DShadow";
OS << "uniform " << samplerType << " " << PI.name << ";" << std::endl;
}
}

View File

@ -176,6 +176,26 @@ namespace gl
glSamplerParameteri(samplerHandle, GL_TEXTURE_MAG_FILTER, tex_mag_filter(tex.mag_filter()));
glSamplerParameteri(samplerHandle, GL_TEXTURE_MAX_ANISOTROPY_EXT, ::gl::max_aniso(tex.max_aniso()));
const u32 texture_format = tex.format() & ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN);
if (texture_format == CELL_GCM_TEXTURE_DEPTH16 || texture_format == CELL_GCM_TEXTURE_DEPTH24_D8)
{
//NOTE: The stored texture function is reversed wrt the textureProj compare function
GLenum compare_mode = (GLenum)tex.zfunc() | GL_NEVER;
switch (compare_mode)
{
case GL_GREATER: compare_mode = GL_LESS; break;
case GL_GEQUAL: compare_mode = GL_LEQUAL; break;
case GL_LESS: compare_mode = GL_GREATER; break;
case GL_LEQUAL: compare_mode = GL_GEQUAL; break;
}
glSamplerParameteri(samplerHandle, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glSamplerParameteri(samplerHandle, GL_TEXTURE_COMPARE_FUNC, compare_mode);
}
else
glSamplerParameteri(samplerHandle, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
}

View File

@ -222,6 +222,7 @@ struct RSXFragmentProgram
u32 ctrl;
u16 unnormalized_coords;
u16 redirected_textures;
u16 shadow_textures;
rsx::comparison_function alpha_func;
bool front_back_color_enabled : 1;
bool back_color_diffuse_output : 1;

View File

@ -946,7 +946,7 @@ namespace rsx
result.pixel_center_mode = rsx::method_registers.shader_window_pixel();
result.height = rsx::method_registers.shader_window_height();
result.redirected_textures = 0;
result.shadow_textures = 0;
std::array<texture_dimension_extended, 16> texture_dimensions;
for (u32 i = 0; i < rsx::limits::fragment_textures_count; ++i)
@ -989,9 +989,11 @@ namespace rsx
{
u32 format = raw_format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
if (format == CELL_GCM_TEXTURE_A8R8G8B8 || format == CELL_GCM_TEXTURE_D8R8G8B8)
{
result.redirected_textures |= (1 << i);
}
else if (format == CELL_GCM_TEXTURE_DEPTH16 || format == CELL_GCM_TEXTURE_DEPTH24_D8)
result.shadow_textures |= (1 << i);
else
LOG_ERROR(RSX, "Depth texture bound to pipeline with unexpected format 0x%X", format);
}
}
}

View File

@ -125,6 +125,8 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
if (m_prog.unnormalized_coords & (1 << index))
samplerType = "sampler2DRect";
else if (m_prog.shadow_textures & (1 << index))
samplerType = "sampler2DShadow";
vk::glsl::program_input in;
in.location = location;

View File

@ -32,15 +32,15 @@ namespace
namespace vk
{
VkCompareOp get_compare_func(rsx::comparison_function op)
VkCompareOp get_compare_func(rsx::comparison_function op, bool reverse_direction = false)
{
switch (op)
{
case rsx::comparison_function::never: return VK_COMPARE_OP_NEVER;
case rsx::comparison_function::greater: return VK_COMPARE_OP_GREATER;
case rsx::comparison_function::less: return VK_COMPARE_OP_LESS;
case rsx::comparison_function::less_or_equal: return VK_COMPARE_OP_LESS_OR_EQUAL;
case rsx::comparison_function::greater_or_equal: return VK_COMPARE_OP_GREATER_OR_EQUAL;
case rsx::comparison_function::greater: return reverse_direction ? VK_COMPARE_OP_LESS: VK_COMPARE_OP_GREATER;
case rsx::comparison_function::less: return reverse_direction ? VK_COMPARE_OP_GREATER: VK_COMPARE_OP_LESS;
case rsx::comparison_function::less_or_equal: return reverse_direction ? VK_COMPARE_OP_GREATER_OR_EQUAL: VK_COMPARE_OP_LESS_OR_EQUAL;
case rsx::comparison_function::greater_or_equal: return reverse_direction ? VK_COMPARE_OP_LESS_OR_EQUAL: VK_COMPARE_OP_GREATER_OR_EQUAL;
case rsx::comparison_function::equal: return VK_COMPARE_OP_EQUAL;
case rsx::comparison_function::not_equal: return VK_COMPARE_OP_NOT_EQUAL;
case rsx::comparison_function::always: return VK_COMPARE_OP_ALWAYS;
@ -863,6 +863,11 @@ void VKGSRender::end()
continue;
}
const u32 texture_format = rsx::method_registers.fragment_textures[i].format() & ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN);
VkBool32 is_depth_texture = (texture_format == CELL_GCM_TEXTURE_DEPTH16 || texture_format == CELL_GCM_TEXTURE_DEPTH24_D8);
VkCompareOp depth_compare = is_depth_texture? vk::get_compare_func((rsx::comparison_function)rsx::method_registers.fragment_textures[i].zfunc(), true): VK_COMPARE_OP_NEVER;
VkFilter min_filter;
VkSamplerMipmapMode mip_mode;
float min_lod = 0.f, max_lod = 0.f;
@ -886,8 +891,8 @@ void VKGSRender::end()
vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_s()), vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_t()), vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_r()),
!!(rsx::method_registers.fragment_textures[i].format() & CELL_GCM_TEXTURE_UN),
lod_bias, vk::max_aniso(rsx::method_registers.fragment_textures[i].max_aniso()), min_lod, max_lod,
min_filter, vk::get_mag_filter(rsx::method_registers.fragment_textures[i].mag_filter()), mip_mode, vk::get_border_color(rsx::method_registers.fragment_textures[i].border_color())
));
min_filter, vk::get_mag_filter(rsx::method_registers.fragment_textures[i].mag_filter()), mip_mode, vk::get_border_color(rsx::method_registers.fragment_textures[i].border_color()),
is_depth_texture, depth_compare));
m_program->bind_uniform({ m_sampler_to_clean.back()->value, texture0->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, "tex" + std::to_string(i), descriptor_sets);
}

View File

@ -592,7 +592,8 @@ namespace vk
sampler(VkDevice dev, VkSamplerAddressMode clamp_u, VkSamplerAddressMode clamp_v, VkSamplerAddressMode clamp_w,
bool unnormalized_coordinates, float mipLodBias, float max_anisotropy, float min_lod, float max_lod,
VkFilter min_filter, VkFilter mag_filter, VkSamplerMipmapMode mipmap_mode, VkBorderColor border_color)
VkFilter min_filter, VkFilter mag_filter, VkSamplerMipmapMode mipmap_mode, VkBorderColor border_color,
VkBool32 depth_compare = false, VkCompareOp depth_compare_mode = VK_COMPARE_OP_NEVER)
: m_device(dev)
{
VkSamplerCreateInfo info = {};
@ -601,7 +602,7 @@ namespace vk
info.addressModeV = clamp_v;
info.addressModeW = clamp_w;
info.anisotropyEnable = VK_TRUE;
info.compareEnable = VK_FALSE;
info.compareEnable = depth_compare;
info.unnormalizedCoordinates = unnormalized_coordinates;
info.mipLodBias = mipLodBias;
info.maxAnisotropy = max_anisotropy;
@ -610,7 +611,7 @@ namespace vk
info.magFilter = mag_filter;
info.minFilter = min_filter;
info.mipmapMode = mipmap_mode;
info.compareOp = VK_COMPARE_OP_NEVER;
info.compareOp = depth_compare_mode;
info.borderColor = border_color;
CHECK_RESULT(vkCreateSampler(m_device, &info, nullptr, &value));