mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
rsx: Implement delayed swizzle remap for blit engine resources
- Fixes remap vectors for memory copied via blit engine as it has no context
This commit is contained in:
parent
17bfb3beaf
commit
ac0022483a
@ -25,6 +25,12 @@ namespace rsx
|
||||
framebuffer_storage = 3
|
||||
};
|
||||
|
||||
enum texture_sampler_status
|
||||
{
|
||||
status_uninitialized = 0,
|
||||
status_ready = 1
|
||||
};
|
||||
|
||||
//Sampled image descriptor
|
||||
struct sampled_image_descriptor_base
|
||||
{
|
||||
@ -52,6 +58,7 @@ namespace rsx
|
||||
rsx::texture_create_flags view_flags = rsx::texture_create_flags::default_component_order;
|
||||
rsx::texture_upload_context context = rsx::texture_upload_context::shader_read;
|
||||
rsx::texture_dimension_extended image_type = rsx::texture_dimension_extended::texture_dimension_2d;
|
||||
rsx::texture_sampler_status sampler_status = rsx::texture_sampler_status::status_uninitialized;
|
||||
|
||||
bool matches(const u32 rsx_address, const u32 rsx_size)
|
||||
{
|
||||
@ -98,6 +105,11 @@ namespace rsx
|
||||
image_type = type;
|
||||
}
|
||||
|
||||
void set_sampler_status(const rsx::texture_sampler_status status)
|
||||
{
|
||||
sampler_status = status;
|
||||
}
|
||||
|
||||
void set_gcm_format(u32 format)
|
||||
{
|
||||
gcm_format = format;
|
||||
@ -132,6 +144,11 @@ namespace rsx
|
||||
{
|
||||
return gcm_format;
|
||||
}
|
||||
|
||||
rsx::texture_sampler_status get_sampler_status() const
|
||||
{
|
||||
return sampler_status;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename commandbuffer_type, typename section_storage_type, typename image_resource_type, typename image_view_type, typename image_storage_type, typename texture_format>
|
||||
@ -288,6 +305,7 @@ namespace rsx
|
||||
virtual section_storage_type* upload_image_from_cpu(commandbuffer_type&, u32 rsx_address, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, const u32 gcm_format, const texture_upload_context context,
|
||||
std::vector<rsx_subresource_layout>& subresource_layout, const rsx::texture_dimension_extended type, const bool swizzled, std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) = 0;
|
||||
virtual void enforce_surface_creation_type(section_storage_type& section, const texture_create_flags expected) = 0;
|
||||
virtual void set_up_remap_vector(section_storage_type& section, std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) = 0;
|
||||
virtual void insert_texture_barrier() = 0;
|
||||
virtual image_view_type generate_cubemap_from_images(commandbuffer_type&, const u32 gcm_format, u16 size, std::array<image_resource_type, 6>& sources) = 0;
|
||||
|
||||
@ -795,6 +813,7 @@ namespace rsx
|
||||
region.protect(utils::protection::no);
|
||||
region.create(width, height, 1, 1, nullptr, image, pitch, false, std::forward<Args>(extras)...);
|
||||
region.set_context(texture_upload_context::framebuffer_storage);
|
||||
region.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
region.set_image_type(rsx::texture_dimension_extended::texture_dimension_2d);
|
||||
update_cache_tag();
|
||||
}
|
||||
@ -1432,6 +1451,9 @@ namespace rsx
|
||||
if (cached_texture->get_image_type() == rsx::texture_dimension_extended::texture_dimension_1d)
|
||||
scale_y = 0.f;
|
||||
|
||||
if (cached_texture->get_sampler_status() != rsx::texture_sampler_status::status_ready)
|
||||
set_up_remap_vector(*cached_texture, tex.decoded_remap());
|
||||
|
||||
return{ cached_texture->get_raw_view(), cached_texture->get_context(), cached_texture->is_depth_texture(), scale_x, scale_y, cached_texture->get_image_type() };
|
||||
}
|
||||
}
|
||||
@ -1475,6 +1497,9 @@ namespace rsx
|
||||
break;
|
||||
}
|
||||
|
||||
if (surface->get_sampler_status() != rsx::texture_sampler_status::status_ready)
|
||||
set_up_remap_vector(*surface, tex.decoded_remap());
|
||||
|
||||
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,
|
||||
surface->is_depth_texture(), scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d };
|
||||
|
@ -442,6 +442,41 @@ namespace gl
|
||||
}
|
||||
}
|
||||
|
||||
void apply_swizzle_remap(const GLenum target, const std::array<GLenum, 4>& swizzle_remap, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& decoded_remap)
|
||||
{
|
||||
//Remapping tables; format is A-R-G-B
|
||||
//Remap input table. Contains channel index to read color from
|
||||
const auto remap_inputs = decoded_remap.first;
|
||||
|
||||
//Remap control table. Controls whether the remap value is used, or force either 0 or 1
|
||||
const auto remap_lookup = decoded_remap.second;
|
||||
|
||||
GLenum remap_values[4];
|
||||
|
||||
for (u8 channel = 0; channel < 4; ++channel)
|
||||
{
|
||||
switch (remap_lookup[channel])
|
||||
{
|
||||
default:
|
||||
LOG_ERROR(RSX, "Unknown remap function 0x%X", remap_lookup[channel]);
|
||||
case CELL_GCM_TEXTURE_REMAP_REMAP:
|
||||
remap_values[channel] = swizzle_remap[remap_inputs[channel]];
|
||||
break;
|
||||
case CELL_GCM_TEXTURE_REMAP_ZERO:
|
||||
remap_values[channel] = GL_ZERO;
|
||||
break;
|
||||
case CELL_GCM_TEXTURE_REMAP_ONE:
|
||||
remap_values[channel] = GL_ONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, remap_values[0]);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, remap_values[1]);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, remap_values[2]);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, remap_values[3]);
|
||||
}
|
||||
|
||||
void upload_texture(const GLuint id, const u32 texaddr, const u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, bool is_swizzled, rsx::texture_dimension_extended type,
|
||||
std::vector<rsx_subresource_layout>& subresources_layout, std::pair<std::array<u8, 4>, std::array<u8, 4>>& decoded_remap, bool static_state)
|
||||
{
|
||||
@ -453,7 +488,6 @@ namespace gl
|
||||
const std::array<GLenum, 4>& glRemap = get_swizzle_remap(gcm_format);
|
||||
|
||||
GLenum target;
|
||||
GLenum remap_values[4];
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@ -496,35 +530,7 @@ namespace gl
|
||||
}
|
||||
else
|
||||
{
|
||||
//Remapping tables; format is A-R-G-B
|
||||
//Remap input table. Contains channel index to read color from
|
||||
const auto remap_inputs = decoded_remap.first;
|
||||
|
||||
//Remap control table. Controls whether the remap value is used, or force either 0 or 1
|
||||
const auto remap_lookup = decoded_remap.second;
|
||||
|
||||
for (u8 channel = 0; channel < 4; ++channel)
|
||||
{
|
||||
switch (remap_lookup[channel])
|
||||
{
|
||||
default:
|
||||
LOG_ERROR(RSX, "Unknown remap function 0x%X", remap_lookup[channel]);
|
||||
case CELL_GCM_TEXTURE_REMAP_REMAP:
|
||||
remap_values[channel] = glRemap[remap_inputs[channel]];
|
||||
break;
|
||||
case CELL_GCM_TEXTURE_REMAP_ZERO:
|
||||
remap_values[channel] = GL_ZERO;
|
||||
break;
|
||||
case CELL_GCM_TEXTURE_REMAP_ONE:
|
||||
remap_values[channel] = GL_ONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, remap_values[0]);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, remap_values[1]);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, remap_values[2]);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, remap_values[3]);
|
||||
apply_swizzle_remap(target, glRemap, decoded_remap);
|
||||
}
|
||||
|
||||
//The rest of sampler state is now handled by sampler state objects
|
||||
|
@ -28,6 +28,8 @@ namespace gl
|
||||
void upload_texture(const GLuint id, const u32 texaddr, const u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, bool is_swizzled, rsx::texture_dimension_extended type,
|
||||
std::vector<rsx_subresource_layout>& subresources_layout, std::pair<std::array<u8, 4>, std::array<u8, 4>>& decoded_remap, bool static_state);
|
||||
|
||||
void apply_swizzle_remap(const GLenum target, const std::array<GLenum, 4>& swizzle_remap, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& decoded_remap);
|
||||
|
||||
class sampler_state
|
||||
{
|
||||
GLuint samplerHandle = 0;
|
||||
|
@ -758,6 +758,7 @@ namespace gl
|
||||
cached.set_depth_flag(depth_flag);
|
||||
cached.set_view_flags(flags);
|
||||
cached.set_context(context);
|
||||
cached.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
cached.set_image_type(type);
|
||||
|
||||
//Its not necessary to lock blit dst textures as they are just reused as necessary
|
||||
@ -778,8 +779,18 @@ namespace gl
|
||||
auto section = create_new_texture(unused, rsx_address, pitch * height, width, height, depth, mipmaps, gcm_format, context, type,
|
||||
rsx::texture_create_flags::default_component_order, remap_vector);
|
||||
|
||||
//Swizzling is ignored for blit engine copy and emulated using remapping
|
||||
bool input_swizzled = (context == rsx::texture_upload_context::blit_engine_src)? false : swizzled;
|
||||
bool input_swizzled = swizzled;
|
||||
if (context == rsx::texture_upload_context::blit_engine_src)
|
||||
{
|
||||
//Swizzling is ignored for blit engine copy and emulated using remapping
|
||||
input_swizzled = false;
|
||||
section->set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Generic upload - sampler status will be set on upload
|
||||
section->set_sampler_status(rsx::texture_sampler_status::status_ready);
|
||||
}
|
||||
|
||||
gl::upload_texture(section->get_raw_texture(), rsx_address, gcm_format, width, height, depth, mipmaps, input_swizzled, type, subresource_layout, remap_vector, false);
|
||||
return section;
|
||||
@ -802,6 +813,19 @@ namespace gl
|
||||
section.set_view_flags(flags);
|
||||
}
|
||||
|
||||
void set_up_remap_vector(cached_texture_section& section, std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) override
|
||||
{
|
||||
std::array<GLenum, 4> swizzle_remap;
|
||||
glBindTexture(GL_TEXTURE_2D, section.get_raw_texture());
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, (GLint*)&swizzle_remap[0]);
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, (GLint*)&swizzle_remap[1]);
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, (GLint*)&swizzle_remap[2]);
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, (GLint*)&swizzle_remap[3]);
|
||||
|
||||
apply_swizzle_remap(GL_TEXTURE_2D, swizzle_remap, remap_vector);
|
||||
section.set_sampler_status(rsx::texture_sampler_status::status_ready);
|
||||
}
|
||||
|
||||
void insert_texture_barrier() override
|
||||
{
|
||||
auto &caps = gl::get_driver_caps();
|
||||
|
@ -457,6 +457,31 @@ namespace vk
|
||||
m_texture_memory_in_use = 0;
|
||||
m_discarded_memory_size = 0;
|
||||
}
|
||||
|
||||
VkComponentMapping apply_swizzle_remap(const std::array<VkComponentSwizzle, 4>& base_remap, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector)
|
||||
{
|
||||
VkComponentSwizzle final_mapping[4] = {};
|
||||
|
||||
for (u8 channel = 0; channel < 4; ++channel)
|
||||
{
|
||||
switch (remap_vector.second[channel])
|
||||
{
|
||||
case CELL_GCM_TEXTURE_REMAP_ONE:
|
||||
final_mapping[channel] = VK_COMPONENT_SWIZZLE_ONE;
|
||||
break;
|
||||
case CELL_GCM_TEXTURE_REMAP_ZERO:
|
||||
final_mapping[channel] = VK_COMPONENT_SWIZZLE_ZERO;
|
||||
break;
|
||||
case CELL_GCM_TEXTURE_REMAP_REMAP:
|
||||
final_mapping[channel] = base_remap[remap_vector.first[channel]];
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(RSX, "Unknown remap lookup value %d", remap_vector.second[channel]);
|
||||
}
|
||||
}
|
||||
|
||||
return { final_mapping[1], final_mapping[2], final_mapping[3], final_mapping[0] };
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@ -677,28 +702,7 @@ namespace vk
|
||||
{
|
||||
case rsx::texture_create_flags::default_component_order:
|
||||
{
|
||||
auto native_mapping = vk::get_component_mapping(gcm_format);
|
||||
VkComponentSwizzle final_mapping[4] = {};
|
||||
|
||||
for (u8 channel = 0; channel < 4; ++channel)
|
||||
{
|
||||
switch (remap_vector.second[channel])
|
||||
{
|
||||
case CELL_GCM_TEXTURE_REMAP_ONE:
|
||||
final_mapping[channel] = VK_COMPONENT_SWIZZLE_ONE;
|
||||
break;
|
||||
case CELL_GCM_TEXTURE_REMAP_ZERO:
|
||||
final_mapping[channel] = VK_COMPONENT_SWIZZLE_ZERO;
|
||||
break;
|
||||
case CELL_GCM_TEXTURE_REMAP_REMAP:
|
||||
final_mapping[channel] = native_mapping[remap_vector.first[channel]];
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(RSX, "Unknown remap lookup value %d", remap_vector.second[channel]);
|
||||
}
|
||||
}
|
||||
|
||||
mapping = { final_mapping[1], final_mapping[2], final_mapping[3], final_mapping[0] };
|
||||
mapping = apply_swizzle_remap(vk::get_component_mapping(gcm_format), remap_vector);
|
||||
break;
|
||||
}
|
||||
case rsx::texture_create_flags::native_component_order:
|
||||
@ -721,6 +725,7 @@ namespace vk
|
||||
region.create(width, height, section_depth, mipmaps, view, image, 0, true, gcm_format);
|
||||
region.set_dirty(false);
|
||||
region.set_context(context);
|
||||
region.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
region.set_image_type(type);
|
||||
|
||||
//Its not necessary to lock blit dst textures as they are just reused as necessary
|
||||
@ -756,8 +761,18 @@ namespace vk
|
||||
|
||||
vk::enter_uninterruptible();
|
||||
|
||||
//Swizzling is ignored for blit engine copy and emulated using a swapped order image view
|
||||
bool input_swizzled = (context == rsx::texture_upload_context::blit_engine_src) ? false : swizzled;
|
||||
bool input_swizzled = swizzled;
|
||||
if (context == rsx::texture_upload_context::blit_engine_src)
|
||||
{
|
||||
//Swizzling is ignored for blit engine copy and emulated using remapping
|
||||
input_swizzled = false;
|
||||
section->set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Generic upload - sampler status will be set on upload
|
||||
section->set_sampler_status(rsx::texture_sampler_status::status_ready);
|
||||
}
|
||||
|
||||
vk::copy_mipmaped_image_using_buffer(cmd, image->value, subresource_layout, gcm_format, input_swizzled, mipmaps, subres_range.aspectMask,
|
||||
*m_texture_upload_heap, m_texture_upload_buffer);
|
||||
@ -802,6 +817,20 @@ namespace vk
|
||||
section.set_view_flags(expected_flags);
|
||||
}
|
||||
|
||||
void set_up_remap_vector(cached_texture_section& section, std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) override
|
||||
{
|
||||
auto& view = section.get_view();
|
||||
auto& original_remap = section.get_view()->info.components;
|
||||
std::array<VkComponentSwizzle, 4> base_remap = {original_remap.a, original_remap.r, original_remap.g, original_remap.b};
|
||||
|
||||
auto final_remap = apply_swizzle_remap(base_remap, remap_vector);
|
||||
vk::image_view *new_view = new vk::image_view(*m_device, view->info.image, view->info.viewType, view->info.format,
|
||||
final_remap, view->info.subresourceRange);
|
||||
|
||||
view.reset(new_view);
|
||||
section.set_sampler_status(rsx::texture_sampler_status::status_ready);
|
||||
}
|
||||
|
||||
void insert_texture_barrier() override
|
||||
{}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user