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:
kd-11 2017-12-07 12:09:07 +03:00
parent 17bfb3beaf
commit ac0022483a
5 changed files with 142 additions and 56 deletions

View File

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

View File

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

View File

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

View File

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

View File

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