rsx: Overhaul rendertarget sampling/shuffles

- Reimplements render target views used for sampling
- Optimizes access using an encoded control token
- Adds proper encoding for 24-bit textures (DRGB8 -> ORGB/OBGR)
- Adds proper encoding for ABGR textures (ABGR8 -> ARGB8)
- Silence some compiler warnings as well
- TODO: Real texture views for OGL current method is a hack
This commit is contained in:
kd-11 2018-03-23 18:05:56 +03:00
parent 9bb1ed78f9
commit 321c360dcb
16 changed files with 131 additions and 80 deletions

View file

@ -338,11 +338,6 @@ namespace rsx
}; };
protected: protected:
texture_channel_remap_t default_remap_vector =
{
{ CELL_GCM_TEXTURE_REMAP_FROM_A, CELL_GCM_TEXTURE_REMAP_FROM_R, CELL_GCM_TEXTURE_REMAP_FROM_G, CELL_GCM_TEXTURE_REMAP_FROM_B },
{ CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP }
};
shared_mutex m_cache_mutex; shared_mutex m_cache_mutex;
std::unordered_map<u32, ranged_storage> m_cache; std::unordered_map<u32, ranged_storage> m_cache;
@ -1290,7 +1285,7 @@ namespace rsx
template <typename render_target_type, typename surface_store_type> template <typename render_target_type, typename surface_store_type>
sampled_image_descriptor process_framebuffer_resource(commandbuffer_type& cmd, render_target_type texptr, u32 texaddr, u32 gcm_format, surface_store_type& m_rtts, sampled_image_descriptor process_framebuffer_resource(commandbuffer_type& cmd, render_target_type texptr, u32 texaddr, u32 gcm_format, surface_store_type& m_rtts,
u16 tex_width, u16 tex_height, u16 tex_pitch, rsx::texture_dimension_extended extended_dimension, bool is_depth, const texture_channel_remap_t& remap) u16 tex_width, u16 tex_height, u16 tex_pitch, rsx::texture_dimension_extended extended_dimension, bool is_depth, u32 encoded_remap, const texture_channel_remap_t& decoded_remap)
{ {
const u32 format = gcm_format & ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN); const u32 format = gcm_format & ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN);
const auto surface_width = texptr->get_surface_width(); const auto surface_width = texptr->get_surface_width();
@ -1350,7 +1345,7 @@ namespace rsx
sampled_image_descriptor desc = { texptr->get_surface(), texaddr, format, 0, 0, rsx::apply_resolution_scale(surface_width, true), sampled_image_descriptor desc = { texptr->get_surface(), texaddr, format, 0, 0, rsx::apply_resolution_scale(surface_width, true),
rsx::apply_resolution_scale(surface_height, true), texture_upload_context::framebuffer_storage, is_depth, 1.f, 1.f, rsx::apply_resolution_scale(surface_height, true), texture_upload_context::framebuffer_storage, is_depth, 1.f, 1.f,
rsx::texture_dimension_extended::texture_dimension_cubemap, remap }; rsx::texture_dimension_extended::texture_dimension_cubemap, decoded_remap };
desc.set_external_cubemap_resources(image_array); desc.set_external_cubemap_resources(image_array);
return desc; return desc;
@ -1385,7 +1380,7 @@ namespace rsx
sampled_image_descriptor result = { texptr->get_surface(), texaddr, format, 0, 0, w, h, sampled_image_descriptor result = { texptr->get_surface(), texaddr, format, 0, 0, w, h,
texture_upload_context::framebuffer_storage, is_depth, scale_x, scale_y, texture_upload_context::framebuffer_storage, is_depth, scale_x, scale_y,
rsx::texture_dimension_extended::texture_dimension_2d, remap }; rsx::texture_dimension_extended::texture_dimension_2d, decoded_remap };
result.external_subresource_desc.is_copy_cmd = true; result.external_subresource_desc.is_copy_cmd = true;
result.external_subresource_desc.sections_to_copy.reserve(overlapping.size()); result.external_subresource_desc.sections_to_copy.reserve(overlapping.size());
@ -1474,13 +1469,13 @@ namespace rsx
const auto h = rsx::apply_resolution_scale(internal_height, true); const auto h = rsx::apply_resolution_scale(internal_height, true);
sampled_image_descriptor result = { texptr->get_surface(), texaddr, format, 0, 0, w, h, texture_upload_context::framebuffer_storage, sampled_image_descriptor result = { texptr->get_surface(), texaddr, format, 0, 0, w, h, texture_upload_context::framebuffer_storage,
is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d, remap }; is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d, decoded_remap };
result.external_subresource_desc.update_cached = update_subresource_cache; result.external_subresource_desc.update_cached = update_subresource_cache;
return result; return result;
} }
return{ texptr->get_view(remap), texture_upload_context::framebuffer_storage, is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d }; return{ texptr->get_view(encoded_remap, decoded_remap), texture_upload_context::framebuffer_storage, is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d };
} }
template <typename RsxTextureType, typename surface_store_type, typename ...Args> template <typename RsxTextureType, typename surface_store_type, typename ...Args>
@ -1530,7 +1525,8 @@ namespace rsx
if (test_framebuffer(texaddr)) if (test_framebuffer(texaddr))
{ {
return process_framebuffer_resource(cmd, texptr, texaddr, tex.format(), m_rtts, return process_framebuffer_resource(cmd, texptr, texaddr, tex.format(), m_rtts,
tex_width, tex_height, tex_pitch, extended_dimension, false, tex.decoded_remap()); tex_width, tex_height, tex_pitch, extended_dimension, false, tex.remap(),
tex.decoded_remap());
} }
else else
{ {
@ -1544,7 +1540,8 @@ namespace rsx
if (test_framebuffer(texaddr)) if (test_framebuffer(texaddr))
{ {
return process_framebuffer_resource(cmd, texptr, texaddr, tex.format(), m_rtts, return process_framebuffer_resource(cmd, texptr, texaddr, tex.format(), m_rtts,
tex_width, tex_height, tex_pitch, extended_dimension, true, tex.decoded_remap()); tex_width, tex_height, tex_pitch, extended_dimension, true, tex.remap(),
tex.decoded_remap());
} }
else else
{ {
@ -1665,7 +1662,7 @@ namespace rsx
auto src_image = surface->get_raw_texture(); auto src_image = surface->get_raw_texture();
return{ src_image, surface->get_section_base(), format, offset_x, offset_y, tex_width, tex_height, texture_upload_context::blit_engine_dst, return{ src_image, surface->get_section_base(), format, offset_x, offset_y, tex_width, tex_height, texture_upload_context::blit_engine_dst,
surface->is_depth_texture(), scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d, default_remap_vector }; surface->is_depth_texture(), scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d, rsx::default_remap_vector };
} }
} }
} }
@ -1926,7 +1923,7 @@ namespace rsx
const u32 gcm_format = src_is_argb8 ? CELL_GCM_TEXTURE_A8R8G8B8 : CELL_GCM_TEXTURE_R5G6B5; const u32 gcm_format = src_is_argb8 ? CELL_GCM_TEXTURE_A8R8G8B8 : CELL_GCM_TEXTURE_R5G6B5;
vram_texture = upload_image_from_cpu(cmd, src_address, src.width, src.slice_h, 1, 1, src.pitch, gcm_format, texture_upload_context::blit_engine_src, vram_texture = upload_image_from_cpu(cmd, src_address, src.width, src.slice_h, 1, 1, src.pitch, gcm_format, texture_upload_context::blit_engine_src,
subresource_layout, rsx::texture_dimension_extended::texture_dimension_2d, rsx::texture_colorspace::rgb_linear, dst.swizzled, default_remap_vector)->get_raw_texture(); subresource_layout, rsx::texture_dimension_extended::texture_dimension_2d, rsx::texture_colorspace::rgb_linear, dst.swizzled, rsx::default_remap_vector)->get_raw_texture();
m_texture_memory_in_use += src.pitch * src.slice_h; m_texture_memory_in_use += src.pitch * src.slice_h;
} }
@ -2040,7 +2037,7 @@ namespace rsx
dest_texture = create_new_texture(cmd, dst.rsx_address, dst.pitch * dst_dimensions.height, dest_texture = create_new_texture(cmd, dst.rsx_address, dst.pitch * dst_dimensions.height,
dst_dimensions.width, dst_dimensions.height, 1, 1, dst_dimensions.width, dst_dimensions.height, 1, 1,
gcm_format, rsx::texture_upload_context::blit_engine_dst, rsx::texture_dimension_extended::texture_dimension_2d, gcm_format, rsx::texture_upload_context::blit_engine_dst, rsx::texture_dimension_extended::texture_dimension_2d,
channel_order, rsx::texture_colorspace::rgb_linear, default_remap_vector)->get_raw_texture(); channel_order, rsx::texture_colorspace::rgb_linear, rsx::default_remap_vector)->get_raw_texture();
m_texture_memory_in_use += dst.pitch * dst_dimensions.height; m_texture_memory_in_use += dst.pitch * dst_dimensions.height;
} }

View file

@ -302,7 +302,7 @@ void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS)
OS << "\n" << " fs_main(" + parameters + ");\n\n"; OS << "\n" << " fs_main(" + parameters + ");\n\n";
glsl::insert_rop(OS, m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS); glsl::insert_rop(OS, !!(m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS));
if (m_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) if (m_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT)
{ {

View file

@ -1344,13 +1344,19 @@ void GLGSRender::flip(int buffer)
buffer_width = render_target_texture->width(); buffer_width = render_target_texture->width();
buffer_height = render_target_texture->height(); buffer_height = render_target_texture->height();
image = render_target_texture->id(); image = render_target_texture->get_view();
} }
else if (auto surface = m_gl_texture_cache.find_texture_from_dimensions(absolute_address)) else if (auto surface = m_gl_texture_cache.find_texture_from_dimensions(absolute_address))
{ {
//Hack - this should be the first location to check for output //Hack - this should be the first location to check for output
//The render might have been done offscreen or in software and a blit used to display //The render might have been done offscreen or in software and a blit used to display
image = surface->get_raw_view(); image = surface->get_raw_view();
//Reset color swizzle
glBindTexture(GL_TEXTURE_2D, image);
const GLenum rgba_shuffle[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, (GLint*)rgba_shuffle);
surface->set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
} }
else else
{ {

View file

@ -627,6 +627,7 @@ namespace gl
program_handle.uniforms["x_offset"] = x_offset; program_handle.uniforms["x_offset"] = x_offset;
program_handle.uniforms["y_offset"] = y_offset; program_handle.uniforms["y_offset"] = y_offset;
program_handle.uniforms["gamma"] = gamma; program_handle.uniforms["gamma"] = gamma;
program_handle.uniforms["limit_range"] = (int)limited_rgb;
glActiveTexture(GL_TEXTURE31); glActiveTexture(GL_TEXTURE31);
glBindTexture(GL_TEXTURE_2D, source); glBindTexture(GL_TEXTURE_2D, source);

View file

@ -14,12 +14,29 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma
case rsx::surface_color_format::a8r8g8b8: case rsx::surface_color_format::a8r8g8b8:
return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1 }; return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1 };
//These formats discard their alpha component (always 1) //These formats discard their alpha component, forced to 0 or 1
//All XBGR formats will have remapping before they can be read back in shaders as DRGB8
//Prefix o = 1, z = 0
case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: case rsx::surface_color_format::x1r5g5b5_o1r5g5b5:
return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1,
{ ::gl::texture::channel::one, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } };
case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: case rsx::surface_color_format::x1r5g5b5_z1r5g5b5:
return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1,
{ ::gl::texture::channel::zero, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } };
case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: case rsx::surface_color_format::x8r8g8b8_z8r8g8b8:
return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1,
{ ::gl::texture::channel::zero, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } };
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1,
{ ::gl::texture::channel::one, ::gl::texture::channel::b, ::gl::texture::channel::g, ::gl::texture::channel::r } };
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1,
{ ::gl::texture::channel::zero, ::gl::texture::channel::b, ::gl::texture::channel::g, ::gl::texture::channel::r } };
case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: case rsx::surface_color_format::x8r8g8b8_o8r8g8b8:
return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1, return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1,
{ ::gl::texture::channel::one, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } }; { ::gl::texture::channel::one, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } };
@ -40,10 +57,13 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma
case rsx::surface_color_format::x32: case rsx::surface_color_format::x32:
return{ ::gl::texture::type::f32, ::gl::texture::format::r, true, 1, 4 }; return{ ::gl::texture::type::f32, ::gl::texture::format::r, true, 1, 4 };
case rsx::surface_color_format::a8b8g8r8:
//NOTE: To sample this surface as ARGB8 (ABGR8 does not exist), swizzle will be applied by the application
return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1,
{ ::gl::texture::channel::a, ::gl::texture::channel::b, ::gl::texture::channel::g, ::gl::texture::channel::r } };
default: default:
LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", (u32)color_format); LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", (u32)color_format);
case rsx::surface_color_format::a8b8g8r8:
return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1 }; return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1 };
} }
} }

View file

@ -64,6 +64,8 @@ namespace gl
texture::internal_format compatible_internal_format = texture::internal_format::rgba8; texture::internal_format compatible_internal_format = texture::internal_format::rgba8;
std::array<GLenum, 4> native_component_mapping; std::array<GLenum, 4> native_component_mapping;
u32 current_remap_encoding = 0;
public: public:
render_target *old_contents = nullptr; render_target *old_contents = nullptr;
@ -116,10 +118,29 @@ namespace gl
return id(); return id();
} }
u32 get_view(const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap) const u32 get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap)
{ {
if (remap_encoding != current_remap_encoding)
{
current_remap_encoding = remap_encoding;
bind(); bind();
apply_swizzle_remap(GL_TEXTURE_2D, native_component_mapping, remap); apply_swizzle_remap(GL_TEXTURE_2D, native_component_mapping, remap);
}
return id();
}
u32 get_view()
{
//Get view with components in true native layout
//TODO: Implement real image views
const GLenum rgba_remap[4] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
glBindTexture(GL_TEXTURE_2D, id());
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, (GLint*)rgba_remap);
//Reset view encoding
current_remap_encoding = 0;
return id(); return id();
} }

View file

@ -713,8 +713,8 @@ namespace gl
apply_component_mapping_flags(dst_type, gcm_format, rsx::texture_create_flags::default_component_order); apply_component_mapping_flags(dst_type, gcm_format, rsx::texture_create_flags::default_component_order);
} }
if (memcmp(remap.first.data(), default_remap_vector.first.data(), 4) || if (memcmp(remap.first.data(), rsx::default_remap_vector.first.data(), 4) ||
memcmp(remap.second.data(), default_remap_vector.second.data(), 4)) memcmp(remap.second.data(), rsx::default_remap_vector.second.data(), 4))
set_up_remap_vector(dst_id, dst_type, remap); set_up_remap_vector(dst_id, dst_type, remap);
return dst_id; return dst_id;
@ -810,7 +810,7 @@ namespace gl
} }
} }
u32 generate_cubemap_from_images(void*&, u32 gcm_format, u16 size, const std::array<u32, 6>& sources, const texture_channel_remap_t& remap_vector) override u32 generate_cubemap_from_images(void*&, u32 gcm_format, u16 size, const std::array<u32, 6>& sources, const texture_channel_remap_t& /*remap_vector*/) override
{ {
const GLenum ifmt = gl::get_sized_internal_format(gcm_format); const GLenum ifmt = gl::get_sized_internal_format(gcm_format);
GLuint dst_id = 0; GLuint dst_id = 0;

View file

@ -398,6 +398,12 @@ namespace rsx
}; };
} }
u32 vertex_texture::remap() const
{
//disabled
return 0xAAE4;
}
u8 vertex_texture::zfunc() const u8 vertex_texture::zfunc() const
{ {
return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 28) & 0xf); return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 28) & 0xf);

View file

@ -130,6 +130,7 @@ namespace rsx
u8 signed_remap() const; u8 signed_remap() const;
std::pair<std::array<u8, 4>, std::array<u8, 4>> decoded_remap() const; std::pair<std::array<u8, 4>, std::array<u8, 4>> decoded_remap() const;
u32 remap() const;
// Control0 // Control0
bool enabled() const; bool enabled() const;

View file

@ -2246,9 +2246,9 @@ namespace rsx
const auto elapsed = timestamp - performance_counters.last_update_timestamp; const auto elapsed = timestamp - performance_counters.last_update_timestamp;
if (elapsed > idle) if (elapsed > idle)
performance_counters.approximate_load = (elapsed - idle) * 100 / elapsed; performance_counters.approximate_load = (u32)((elapsed - idle) * 100 / elapsed);
else else
performance_counters.approximate_load = 0; performance_counters.approximate_load = 0u;
performance_counters.idle_time = 0; performance_counters.idle_time = 0;
performance_counters.sampled_frames = 0; performance_counters.sampled_frames = 0;
@ -2423,7 +2423,7 @@ namespace rsx
int retries = 0; int retries = 0;
while (!Emu.IsStopped()) while (!Emu.IsStopped())
{ {
for (int n = 0; n < occlusion_query_count; ++n) for (u32 n = 0; n < occlusion_query_count; ++n)
{ {
if (m_occlusion_query_data[n].pending || m_occlusion_query_data[n].active) if (m_occlusion_query_data[n].pending || m_occlusion_query_data[n].active)
continue; continue;
@ -2571,7 +2571,7 @@ namespace rsx
if (!writer.forwarder) if (!writer.forwarder)
//No other queries in the chain, write result //No other queries in the chain, write result
write(writer.sink, ptimer->timestamp(), writer.type, result); write(writer.sink, (u32)ptimer->timestamp(), writer.type, result);
processed++; processed++;
} }
@ -2698,7 +2698,7 @@ namespace rsx
//only zpass supported right now //only zpass supported right now
if (!writer.forwarder) if (!writer.forwarder)
//No other queries in the chain, write result //No other queries in the chain, write result
write(writer.sink, ptimer->timestamp(), writer.type, result); write(writer.sink, (u32)ptimer->timestamp(), writer.type, result);
processed++; processed++;
} }

View file

@ -324,7 +324,7 @@ void VKFragmentDecompilerThread::insertMainEnd(std::stringstream & OS)
OS << "\n" << " fs_main(" + parameters + ");\n\n"; OS << "\n" << " fs_main(" + parameters + ");\n\n";
glsl::insert_rop(OS, m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS); glsl::insert_rop(OS, !!(m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS));
if (m_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) if (m_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT)
{ {

View file

@ -52,23 +52,34 @@ namespace vk
std::pair<VkFormat, VkComponentMapping> get_compatible_surface_format(rsx::surface_color_format color_format) std::pair<VkFormat, VkComponentMapping> get_compatible_surface_format(rsx::surface_color_format color_format)
{ {
const VkComponentMapping abgr = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A };
const VkComponentMapping o_rgb = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE };
const VkComponentMapping z_rgb = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ZERO };
const VkComponentMapping o_bgr = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ONE };
const VkComponentMapping z_bgr = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO };
switch (color_format) switch (color_format)
{ {
case rsx::surface_color_format::r5g6b5: case rsx::surface_color_format::r5g6b5:
return std::make_pair(VK_FORMAT_R5G6B5_UNORM_PACK16, vk::default_component_map()); return std::make_pair(VK_FORMAT_R5G6B5_UNORM_PACK16, vk::default_component_map());
case rsx::surface_color_format::a8r8g8b8: case rsx::surface_color_format::a8r8g8b8:
case rsx::surface_color_format::a8b8g8r8:
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, vk::default_component_map()); return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, vk::default_component_map());
case rsx::surface_color_format::a8b8g8r8:
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, abgr);
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, o_bgr);
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, z_bgr);
case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: case rsx::surface_color_format::x8r8g8b8_z8r8g8b8:
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, z_rgb);
case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: case rsx::surface_color_format::x8r8g8b8_o8r8g8b8:
{ return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, o_rgb);
VkComponentMapping no_alpha = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE };
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, no_alpha);
}
case rsx::surface_color_format::w16z16y16x16: case rsx::surface_color_format::w16z16y16x16:
return std::make_pair(VK_FORMAT_R16G16B16A16_SFLOAT, vk::default_component_map()); return std::make_pair(VK_FORMAT_R16G16B16A16_SFLOAT, vk::default_component_map());
@ -77,11 +88,10 @@ namespace vk
return std::make_pair(VK_FORMAT_R32G32B32A32_SFLOAT, vk::default_component_map()); return std::make_pair(VK_FORMAT_R32G32B32A32_SFLOAT, vk::default_component_map());
case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: case rsx::surface_color_format::x1r5g5b5_o1r5g5b5:
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, o_rgb);
case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: case rsx::surface_color_format::x1r5g5b5_z1r5g5b5:
{ return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, z_rgb);
VkComponentMapping no_alpha = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE };
return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, no_alpha);
}
case rsx::surface_color_format::b8: case rsx::surface_color_format::b8:
{ {
@ -1287,7 +1297,7 @@ void VKGSRender::end()
{ {
auto rp = vk::get_render_pass_location(VK_FORMAT_UNDEFINED, ds->info.format, 0); auto rp = vk::get_render_pass_location(VK_FORMAT_UNDEFINED, ds->info.format, 0);
auto render_pass = m_render_passes[rp]; auto render_pass = m_render_passes[rp];
m_depth_converter->run(*m_current_command_buffer, ds->width(), ds->height(), ds, ds->old_contents->get_view(), render_pass, m_framebuffers_to_clean); m_depth_converter->run(*m_current_command_buffer, ds->width(), ds->height(), ds, ds->old_contents->get_view(0xAAE4, rsx::default_remap_vector), render_pass, m_framebuffers_to_clean);
ds->old_contents = nullptr; ds->old_contents = nullptr;
ds->dirty = false; ds->dirty = false;

View file

@ -20,7 +20,7 @@ namespace vk
u16 surface_height = 0; u16 surface_height = 0;
VkImageAspectFlags attachment_aspect_flag = VK_IMAGE_ASPECT_COLOR_BIT; VkImageAspectFlags attachment_aspect_flag = VK_IMAGE_ASPECT_COLOR_BIT;
std::vector<std::unique_ptr<vk::image_view>> views; std::unordered_map<u32, std::unique_ptr<vk::image_view>> views;
render_target *old_contents = nullptr; //Data occupying the memory location that this surface is replacing render_target *old_contents = nullptr; //Data occupying the memory location that this surface is replacing
u64 frame_tag = 0; //frame id when invalidated, 0 if not invalid u64 frame_tag = 0; //frame id when invalidated, 0 if not invalid
@ -42,43 +42,26 @@ namespace vk
mipmaps, layers, samples, initial_layout, tiling, usage, image_flags) mipmaps, layers, samples, initial_layout, tiling, usage, image_flags)
{} {}
vk::image_view* get_view(const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap) vk::image_view* get_view(u32 remap_encoding, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap)
{ {
auto found = views.find(remap_encoding);
if (found != views.end())
{
return found->second.get();
}
VkComponentMapping real_mapping = vk::apply_swizzle_remap VkComponentMapping real_mapping = vk::apply_swizzle_remap
( (
{native_component_map.a, native_component_map.r, native_component_map.g, native_component_map.b }, {native_component_map.a, native_component_map.r, native_component_map.g, native_component_map.b },
remap remap
); );
for (const auto& view : views)
{
if (view->info.components.a == real_mapping.a &&
view->info.components.r == real_mapping.r &&
view->info.components.g == real_mapping.g &&
view->info.components.b == real_mapping.b)
{
return view.get();
}
}
auto view = std::make_unique<vk::image_view>(*vk::get_current_renderer(), value, VK_IMAGE_VIEW_TYPE_2D, info.format, auto view = std::make_unique<vk::image_view>(*vk::get_current_renderer(), value, VK_IMAGE_VIEW_TYPE_2D, info.format,
real_mapping, vk::get_image_subresource_range(0, 0, 1, 1, attachment_aspect_flag & ~(VK_IMAGE_ASPECT_STENCIL_BIT))); real_mapping, vk::get_image_subresource_range(0, 0, 1, 1, attachment_aspect_flag & ~(VK_IMAGE_ASPECT_STENCIL_BIT)));
views.push_back(std::move(view)); auto result = view.get();
return views.back().get(); views[remap_encoding] = std::move(view);
} return result;
vk::image_view* get_view()
{
if (views.empty())
{
auto view = std::make_unique<vk::image_view>(*vk::get_current_renderer(), value, VK_IMAGE_VIEW_TYPE_2D, info.format,
native_component_map, vk::get_image_subresource_range(0, 0, 1, 1, attachment_aspect_flag & ~(VK_IMAGE_ASPECT_STENCIL_BIT)));
views.push_back(std::move(view));
}
return views.back().get();
} }
vk::image* get_surface() const override vk::image* get_surface() const override

View file

@ -116,7 +116,7 @@ namespace vk
if (context != rsx::texture_upload_context::framebuffer_storage) if (context != rsx::texture_upload_context::framebuffer_storage)
return uploaded_image_view.get(); return uploaded_image_view.get();
else else
return static_cast<vk::render_target*>(vram_texture)->get_view(); return static_cast<vk::render_target*>(vram_texture)->get_view(0xAAE4, rsx::default_remap_vector);
} }
vk::image* get_raw_texture() vk::image* get_raw_texture()
@ -585,8 +585,8 @@ namespace vk
view_swizzle = { remap[1], remap[2], remap[3], remap[0] }; view_swizzle = { remap[1], remap[2], remap[3], remap[0] };
} }
if (memcmp(remap_vector.first.data(), default_remap_vector.first.data(), 4) || if (memcmp(remap_vector.first.data(), rsx::default_remap_vector.first.data(), 4) ||
memcmp(remap_vector.second.data(), default_remap_vector.second.data(), 4)) memcmp(remap_vector.second.data(), rsx::default_remap_vector.second.data(), 4))
view_swizzle = vk::apply_swizzle_remap({view_swizzle.a, view_swizzle.r, view_swizzle.g, view_swizzle.b}, remap_vector); view_swizzle = vk::apply_swizzle_remap({view_swizzle.a, view_swizzle.r, view_swizzle.g, view_swizzle.b}, remap_vector);
VkImageSubresourceRange view_range = { aspect & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 1, 0, 1 }; VkImageSubresourceRange view_range = { aspect & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 1, 0, 1 };
@ -633,7 +633,7 @@ namespace vk
} }
vk::image_view* generate_cubemap_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 size, vk::image_view* generate_cubemap_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 size,
const std::array<vk::image*, 6>& sources, const texture_channel_remap_t& remap_vector) override const std::array<vk::image*, 6>& sources, const texture_channel_remap_t& /*remap_vector*/) override
{ {
std::unique_ptr<vk::image> image; std::unique_ptr<vk::image> image;
std::unique_ptr<vk::image_view> view; std::unique_ptr<vk::image_view> view;
@ -706,10 +706,10 @@ namespace vk
} }
vk::image_view* generate_atlas_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 width, u16 height, vk::image_view* generate_atlas_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 width, u16 height,
const std::vector<copy_region_descriptor>& sections_to_copy, const texture_channel_remap_t& remap_vector) override const std::vector<copy_region_descriptor>& sections_to_copy, const texture_channel_remap_t& /*remap_vector*/) override
{ {
auto result = create_temporary_subresource_view_impl(cmd, sections_to_copy.front().src, VK_IMAGE_TYPE_2D, auto result = create_temporary_subresource_view_impl(cmd, sections_to_copy.front().src, VK_IMAGE_TYPE_2D,
VK_IMAGE_VIEW_TYPE_2D, gcm_format, 0, 0, width, height, default_remap_vector, false); VK_IMAGE_VIEW_TYPE_2D, gcm_format, 0, 0, width, height, rsx::default_remap_vector, false);
VkImage dst = result->info.image; VkImage dst = result->info.image;
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT; VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
@ -940,7 +940,7 @@ namespace vk
vk::image* image = section.get_raw_texture(); vk::image* image = section.get_raw_texture();
auto& view = section.get_view(); auto& view = section.get_view();
VkComponentMapping mapping = apply_component_mapping_flags(gcm_format, expected_flags, default_remap_vector); VkComponentMapping mapping = apply_component_mapping_flags(gcm_format, expected_flags, rsx::default_remap_vector);
if (mapping.a != view->info.components.a || if (mapping.a != view->info.components.a ||
mapping.b != view->info.components.b || mapping.b != view->info.components.b ||
@ -1110,7 +1110,7 @@ namespace vk
return upload_texture(cmd, tex, m_rtts, cmd, m_memory_types, const_cast<const VkQueue>(m_submit_queue)); return upload_texture(cmd, tex, m_rtts, cmd, m_memory_types, const_cast<const VkQueue>(m_submit_queue));
} }
vk::image *upload_image_simple(vk::command_buffer& cmd, u32 address, u32 width, u32 height) vk::image *upload_image_simple(vk::command_buffer& /*cmd*/, u32 address, u32 width, u32 height)
{ {
//Uploads a linear memory range as a BGRA8 texture //Uploads a linear memory range as a BGRA8 texture
auto image = std::make_unique<vk::image>(*m_device, m_memory_types.host_visible_coherent, auto image = std::make_unique<vk::image>(*m_device, m_memory_types.host_visible_coherent,
@ -1139,7 +1139,7 @@ namespace vk
be_t<u32>* casted_src = (be_t<u32>*)src; be_t<u32>* casted_src = (be_t<u32>*)src;
u32* casted_dst = (u32*)dst; u32* casted_dst = (u32*)dst;
for (int col = 0; col < width; ++col) for (u32 col = 0; col < width; ++col)
casted_dst[col] = casted_src[col]; casted_dst[col] = casted_src[col];
src += row_pitch; src += row_pitch;

View file

@ -1919,7 +1919,7 @@ struct registers_decoder<NV4097_SET_SHADER_PACKER>
bool srgb_output_enabled() const bool srgb_output_enabled() const
{ {
return bool(m_data.raw_value); return !!m_data.raw_value;
} }
}; };

View file

@ -60,6 +60,12 @@ namespace rsx
f32 gamma = 1.f; //NO GAMMA CORRECTION f32 gamma = 1.f; //NO GAMMA CORRECTION
}; };
static const std::pair<std::array<u8, 4>, std::array<u8, 4>> default_remap_vector =
{
{ CELL_GCM_TEXTURE_REMAP_FROM_A, CELL_GCM_TEXTURE_REMAP_FROM_R, CELL_GCM_TEXTURE_REMAP_FROM_G, CELL_GCM_TEXTURE_REMAP_FROM_B },
{ CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP }
};
template<typename T> template<typename T>
void pad_texture(void* input_pixels, void* output_pixels, u16 input_width, u16 input_height, u16 output_width, u16 output_height) void pad_texture(void* input_pixels, void* output_pixels, u16 input_width, u16 input_height, u16 output_width, u16 output_height)
{ {