Skip to content

Commit

Permalink
Merge branch 'master' into morellvmmem
Browse files Browse the repository at this point in the history
  • Loading branch information
rajkosto committed Oct 28, 2019
2 parents 2a6831b + 479d92d commit e547327
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 54 deletions.
37 changes: 31 additions & 6 deletions Utilities/File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,21 @@ static std::unique_ptr<wchar_t[]> to_wchar(const std::string& source)
const int size = narrow<int>(buf_size, "to_wchar" HERE);

// Buffer for max possible output length
std::unique_ptr<wchar_t[]> buffer(new wchar_t[buf_size + 4 + 32768]);
std::unique_ptr<wchar_t[]> buffer(new wchar_t[buf_size + 8 + 32768]);

// Prepend wide path prefix (4 characters)
std::memcpy(buffer.get() + 32768, L"\\\\\?\\", 4 * sizeof(wchar_t));

verify("to_wchar" HERE), MultiByteToWideChar(CP_UTF8, 0, source.c_str(), size, buffer.get() + 32768 + 4, size);
// Test whether additional UNC prefix is required
const bool unc = source.size() > 2 && (source[0] == '\\' || source[0] == '/') && source[1] == source[0];

if (unc)
{
// Use \\?\UNC\ prefix
std::memcpy(buffer.get() + 32768 + 4, L"UNC\\", 4 * sizeof(wchar_t));
}

verify("to_wchar" HERE), MultiByteToWideChar(CP_UTF8, 0, source.c_str(), size, buffer.get() + 32768 + (unc ? 8 : 4), size);

// Canonicalize wide path (replace '/', ".", "..", \\ repetitions, etc)
verify("to_wchar" HERE), GetFullPathNameW(buffer.get() + 32768, 32768, buffer.get(), nullptr) - 1 < 32768 - 1;
Expand Down Expand Up @@ -492,11 +501,27 @@ bool fs::statfs(const std::string& path, fs::device_stat& info)
ULARGE_INTEGER total_size;
ULARGE_INTEGER total_free;

// Get disk letter from path (TODO)
std::wstring disk(L"C:");
disk[0] = path[0];
// Convert path and return it back to the "short" format
const bool unc = path.size() > 2 && (path[0] == '\\' || path[0] == '/') && path[1] == path[0];

std::wstring str = to_wchar(path).get() + (unc ? 6 : 4);

if (unc)
{
str[0] = '\\';
str[1] = '\\';
}

// Keep cutting path from right until it's short enough
while (str.size() > 256)
{
if (std::size_t x = str.find_last_of('\\') + 1)
str.resize(x - 1);
else
break;
}

if (!GetDiskFreeSpaceExW(disk.c_str(), &avail_free, &total_size, &total_free))
if (!GetDiskFreeSpaceExW(str.c_str(), &avail_free, &total_size, &total_free))
{
g_tls_error = to_error(GetLastError());
return false;
Expand Down
4 changes: 1 addition & 3 deletions rpcs3/Emu/RSX/Common/texture_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1756,9 +1756,7 @@ namespace rsx

if (options.is_compressed_format)
{
attributes.width = align(attributes.width, 4);
attributes.height = align(attributes.height, 4);

// Compressed textures cannot be 1D in some APIs
extended_dimension = std::max(extended_dimension, rsx::texture_dimension_extended::texture_dimension_2d);
}

Expand Down
7 changes: 2 additions & 5 deletions rpcs3/Emu/RSX/GL/GLTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,12 +466,9 @@ namespace gl

if (LIKELY(is_compressed_format(format)))
{
//Compressed formats have a 4-byte alignment
//TODO: Verify that samplers are not affected by the padding
width = align(width, 4);
height = align(height, 4);

caps.supports_vtc_decoding = gl::get_driver_caps().vendor_NVIDIA;

unpack_settings.row_length(align(width, 4));
unpack_settings.apply();

for (const rsx_subresource_layout& layout : input_layouts)
Expand Down
21 changes: 14 additions & 7 deletions rpcs3/Emu/RSX/VK/VKGSRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1355,10 +1355,6 @@ void VKGSRender::end()

if (min_filter.sample_mipmaps && mipmap_count > 1)
{
min_lod = rsx::method_registers.fragment_textures[i].min_lod();
max_lod = rsx::method_registers.fragment_textures[i].max_lod();
lod_bias = rsx::method_registers.fragment_textures[i].bias();

f32 actual_mipmaps;
if (sampler_state->upload_context == rsx::texture_upload_context::shader_read)
{
Expand All @@ -1376,8 +1372,19 @@ void VKGSRender::end()

if (actual_mipmaps > 1.f)
{
min_lod = rsx::method_registers.fragment_textures[i].min_lod();
max_lod = rsx::method_registers.fragment_textures[i].max_lod();
lod_bias = rsx::method_registers.fragment_textures[i].bias();

min_lod = std::min(min_lod, actual_mipmaps - 1.f);
max_lod = std::min(max_lod, actual_mipmaps - 1.f);

if (min_filter.mipmap_mode == VK_SAMPLER_MIPMAP_MODE_NEAREST)
{
// Round to nearest 0.5 to work around some broken games
// Unlike openGL, sampler parameters cannot be dynamically changed on vulkan, leading to many permutations
lod_bias = std::floor(lod_bias * 2.f + 0.5f) * 0.5f;
}
}
else
{
Expand Down Expand Up @@ -2750,9 +2757,9 @@ void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_
if (m_vertex_layout_storage)
m_current_frame->buffer_views_to_clean.push_back(std::move(m_vertex_layout_storage));

// View 64M blocks at a time (different drivers will only allow a fixed viewable heap size, 64M should be safe)
const size_t view_size = (base_offset + m_texbuffer_view_size) > m_vertex_layout_ring_info.size() ? m_vertex_layout_ring_info.size() - base_offset : m_texbuffer_view_size;
m_vertex_layout_storage = std::make_unique<vk::buffer_view>(*m_device, m_vertex_layout_ring_info.heap->value, VK_FORMAT_R32G32_UINT, base_offset, view_size);
const size_t alloc_addr = m_vertex_layout_stream_info.offset;
const size_t view_size = (alloc_addr + m_texbuffer_view_size) > m_vertex_layout_ring_info.size() ? m_vertex_layout_ring_info.size() - alloc_addr : m_texbuffer_view_size;
m_vertex_layout_storage = std::make_unique<vk::buffer_view>(*m_device, m_vertex_layout_ring_info.heap->value, VK_FORMAT_R32G32_UINT, alloc_addr, view_size);
base_offset = 0;
}

Expand Down
5 changes: 3 additions & 2 deletions rpcs3/Emu/RSX/VK/VKHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -1558,8 +1558,9 @@ namespace vk
if (info.magFilter != mag_filter || info.minFilter != min_filter || info.mipmapMode != mipmap_mode ||
info.addressModeU != clamp_u || info.addressModeV != clamp_v || info.addressModeW != clamp_w ||
info.compareEnable != depth_compare || info.unnormalizedCoordinates != unnormalized_coordinates ||
info.mipLodBias != mipLodBias || info.maxAnisotropy != max_anisotropy || info.maxLod != max_lod ||
info.minLod != min_lod || info.compareOp != depth_compare_mode || info.borderColor != border_color)
!rsx::fcmp(info.maxLod, max_lod) || !rsx::fcmp(info.mipLodBias, mipLodBias) || !rsx::fcmp(info.minLod, min_lod) ||
!rsx::fcmp(info.maxAnisotropy, max_anisotropy) ||
info.compareOp != depth_compare_mode || info.borderColor != border_color)
return false;

return true;
Expand Down
60 changes: 36 additions & 24 deletions rpcs3/Emu/RSX/VK/VKResourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,9 @@ namespace vk
class resource_manager
{
private:
std::unordered_multimap<u64, std::unique_ptr<vk::sampler>> m_sampler_pool;
std::unordered_map<u64, std::unique_ptr<vk::sampler>> m_sampler_pool;
std::deque<eid_scope_t> m_eid_map;

bool value_compare(const f32& a, const f32& b)
{
return fabsf(a - b) < 0.0000001f;
}

eid_scope_t& get_current_eid_scope()
{
const auto eid = current_event_id();
Expand All @@ -66,6 +61,28 @@ namespace vk
return m_eid_map.back();
}

template<bool _signed = false>
u16 encode_fxp(f32 value)
{
u16 raw = u16(std::abs(value) * 256.);

if constexpr (!_signed)
{
return raw;
}
else
{
if (LIKELY(value >= 0.f))
{
return raw;
}
else
{
return u16(0 - raw) & 0x1fff;
}
}
}

public:

resource_manager() = default;
Expand All @@ -83,26 +100,21 @@ namespace vk
VkBool32 depth_compare = VK_FALSE, VkCompareOp depth_compare_mode = VK_COMPARE_OP_NEVER)
{
u64 key = u16(clamp_u) | u64(clamp_v) << 3 | u64(clamp_w) << 6;
key |= u64(unnormalized_coordinates) << 9; // 1 bit
key |= u64(unnormalized_coordinates) << 9; // 1 bit
key |= u64(min_filter) << 10 | u64(mag_filter) << 11; // 1 bit each
key |= u64(mipmap_mode) << 12; // 1 bit
key |= u64(border_color) << 13; // 3 bits
key |= u64(mipmap_mode) << 12; // 1 bit
key |= u64(border_color) << 13; // 3 bits
key |= u64(depth_compare) << 16; // 1 bit
key |= u64(depth_compare_mode) << 17; // 3 bits

const auto found = m_sampler_pool.equal_range(key);
for (auto It = found.first; It != found.second; ++It)
key |= u64(depth_compare_mode) << 17; // 3 bits
key |= u64(encode_fxp(min_lod)) << 20; // 12 bits
key |= u64(encode_fxp(max_lod)) << 32; // 12 bits
key |= u64(encode_fxp<true>(mipLodBias)) << 44; // 13 bits
key |= u64(max_anisotropy) << 57; // 4 bits

if (const auto found = m_sampler_pool.find(key);
found != m_sampler_pool.end())
{
const auto& info = It->second->info;
if (!value_compare(info.mipLodBias, mipLodBias) ||
!value_compare(info.maxAnisotropy, max_anisotropy) ||
!value_compare(info.minLod, min_lod) ||
!value_compare(info.maxLod, max_lod))
{
continue;
}

return It->second.get();
return found->second.get();
}

auto result = std::make_unique<vk::sampler>(
Expand All @@ -112,7 +124,7 @@ namespace vk
depth_compare, depth_compare_mode);

auto It = m_sampler_pool.emplace(key, std::move(result));
return It->second.get();
return It.first->second.get();
}

void dispose(std::unique_ptr<vk::buffer>& buf)
Expand Down
6 changes: 3 additions & 3 deletions rpcs3/Emu/RSX/rsx_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1263,13 +1263,13 @@ namespace rsx
switch (out_bpp)
{
case 1:
convert_linear_swizzle<u8>(linear_pixels, swizzled_pixels, sw_width, sw_height, in_pitch, false);
convert_linear_swizzle<u8, false>(linear_pixels, swizzled_pixels, sw_width, sw_height, in_pitch);
break;
case 2:
convert_linear_swizzle<u16>(linear_pixels, swizzled_pixels, sw_width, sw_height, in_pitch, false);
convert_linear_swizzle<u16, false>(linear_pixels, swizzled_pixels, sw_width, sw_height, in_pitch);
break;
case 4:
convert_linear_swizzle<u32>(linear_pixels, swizzled_pixels, sw_width, sw_height, in_pitch, false);
convert_linear_swizzle<u32, false>(linear_pixels, swizzled_pixels, sw_width, sw_height, in_pitch);
break;
}
}
Expand Down
8 changes: 4 additions & 4 deletions rpcs3/Emu/RSX/rsx_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,8 @@ namespace rsx
* Restriction: It has mixed results if the height or width is not a power of 2
* Restriction: Only works with 2D surfaces
*/
template<typename T>
void convert_linear_swizzle(void* input_pixels, void* output_pixels, u16 width, u16 height, u32 pitch, bool input_is_swizzled)
template<typename T, bool input_is_swizzled>
void convert_linear_swizzle(void* input_pixels, void* output_pixels, u16 width, u16 height, u32 pitch)
{
u32 log2width = ceil_log2(width);
u32 log2height = ceil_log2(height);
Expand All @@ -357,7 +357,7 @@ namespace rsx

u32 adv = pitch / sizeof(T);

if (!input_is_swizzled)
if constexpr (!input_is_swizzled)
{
for (int y = 0; y < height; ++y)
{
Expand Down Expand Up @@ -414,7 +414,7 @@ namespace rsx
{
if (depth == 1)
{
convert_linear_swizzle<T>(input_pixels, output_pixels, width, height, width * sizeof(T), true);
convert_linear_swizzle<T, true>(input_pixels, output_pixels, width, height, width * sizeof(T));
return;
}

Expand Down

0 comments on commit e547327

Please sign in to comment.