rsx: Strictness cleanups

- Also account for variable pitch textures (swizzled scan)
This commit is contained in:
kd-11 2018-12-18 20:04:03 +03:00 committed by kd-11
parent 474d0f61a2
commit a95a44cf66
4 changed files with 50 additions and 31 deletions

View file

@ -587,22 +587,44 @@ size_t get_placed_texture_storage_size(const rsx::vertex_texture &texture, size_
static size_t get_texture_size(u32 format, u16 width, u16 height, u16 depth, u32 pitch, u16 mipmaps, u16 layers) static size_t get_texture_size(u32 format, u16 width, u16 height, u16 depth, u32 pitch, u16 mipmaps, u16 layers)
{ {
const auto gcm_format = format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); const auto gcm_format = format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
const bool packed = !(format & CELL_GCM_TEXTURE_LN);
const auto texel_rows_per_line = get_format_texel_rows_per_line(gcm_format); const auto texel_rows_per_line = get_format_texel_rows_per_line(gcm_format);
if (pitch == 0) verify(HERE), packed || pitch;
{
pitch = get_format_packed_pitch(gcm_format, width);
}
u32 size = 0; u32 size = 0;
for (u32 layer = 0; layer < layers; ++layer) if (!packed)
{ {
u32 mip_height = (height + texel_rows_per_line - 1) / texel_rows_per_line; // Convert texels to blocks // Constant pitch layout, simple scanning
const u32 internal_height = (height + texel_rows_per_line - 1) / texel_rows_per_line; // Convert texels to blocks
for (u32 mipmap = 0; mipmap < mipmaps; ++mipmap) for (u32 layer = 0; layer < layers; ++layer)
{ {
size += pitch * mip_height; u32 mip_height = internal_height;
mip_height = std::max(mip_height / 2u, 1u); for (u32 mipmap = 0; mipmap < mipmaps && mip_height > 0; ++mipmap)
{
size += pitch * mip_height * depth;
mip_height = std::max(mip_height / 2u, 1u);
}
}
}
else
{
// Variable pitch per mipmap level
const auto texels_per_block = get_format_block_size_in_texel(gcm_format);
const auto bytes_per_block = get_format_block_size_in_bytes(gcm_format);
const u32 internal_height = (height + texel_rows_per_line - 1) / texel_rows_per_line; // Convert texels to blocks
const u32 internal_width = (width + texels_per_block - 1) / texels_per_block; // Convert texels to blocks
for (u32 layer = 0; layer < layers; ++layer)
{
u32 mip_height = internal_height;
u32 mip_width = internal_width;
for (u32 mipmap = 0; mipmap < mipmaps && mip_height > 0; ++mipmap)
{
size += (mip_width * bytes_per_block * mip_height * depth);
mip_height = std::max(mip_height / 2u, 1u);
mip_width = std::max(mip_width / 2u, 1u);
}
} }
} }

View file

@ -286,7 +286,7 @@ namespace rsx
*/ */
virtual image_view_type create_temporary_subresource_view(commandbuffer_type&, image_resource_type* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const texture_channel_remap_t& remap_vector) = 0; virtual image_view_type create_temporary_subresource_view(commandbuffer_type&, image_resource_type* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const texture_channel_remap_t& remap_vector) = 0;
virtual image_view_type create_temporary_subresource_view(commandbuffer_type&, image_storage_type* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const texture_channel_remap_t& remap_vector) = 0; virtual image_view_type create_temporary_subresource_view(commandbuffer_type&, image_storage_type* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const texture_channel_remap_t& remap_vector) = 0;
virtual section_storage_type* create_new_texture(commandbuffer_type&, const address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u32 gcm_format, virtual section_storage_type* create_new_texture(commandbuffer_type&, const address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format,
rsx::texture_upload_context context, rsx::texture_dimension_extended type, texture_create_flags flags) = 0; rsx::texture_upload_context context, rsx::texture_dimension_extended type, texture_create_flags flags) = 0;
virtual section_storage_type* upload_image_from_cpu(commandbuffer_type&, const address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format, texture_upload_context context, virtual section_storage_type* upload_image_from_cpu(commandbuffer_type&, const address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format, texture_upload_context context,
const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, bool swizzled) = 0; const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, bool swizzled) = 0;

View file

@ -182,11 +182,9 @@ namespace gl
synchronized = false; synchronized = false;
sync_timestamp = 0ull; sync_timestamp = 0ull;
if (rsx_pitch > 0) verify(HERE), rsx_pitch;
this->rsx_pitch = rsx_pitch;
else
this->rsx_pitch = get_section_size() / height;
this->rsx_pitch = rsx_pitch;
this->width = w; this->width = w;
this->height = h; this->height = h;
this->real_pitch = 0; this->real_pitch = 0;
@ -199,10 +197,12 @@ namespace gl
baseclass::on_section_resources_created(); baseclass::on_section_resources_created();
} }
void create_read_only(gl::viewable_image* image, u32 width, u32 height, u32 depth, u32 mipmaps) void create_read_only(gl::viewable_image* image, u32 width, u32 height, u32 depth, u32 mipmaps, u16 pitch)
{ {
ASSERT(!exists() || !is_managed() || vram_texture == image); ASSERT(!exists() || !is_managed() || vram_texture == image);
verify(HERE), pitch;
//Only to be used for ro memory, we dont care about most members, just dimensions and the vram texture handle //Only to be used for ro memory, we dont care about most members, just dimensions and the vram texture handle
this->width = width; this->width = width;
this->height = height; this->height = height;
@ -212,7 +212,7 @@ namespace gl
managed_texture.reset(image); managed_texture.reset(image);
vram_texture = image; vram_texture = image;
rsx_pitch = 0; rsx_pitch = pitch;
real_pitch = 0; real_pitch = 0;
// Notify baseclass // Notify baseclass
@ -818,8 +818,8 @@ namespace gl
dst->image()->id(), GL_TEXTURE_2D, 0, 0, 0, 0, width, height, 1); dst->image()->id(), GL_TEXTURE_2D, 0, 0, 0, 0, width, height, 1);
} }
cached_texture_section* create_new_texture(void*&, const utils::address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u32 gcm_format, cached_texture_section* create_new_texture(void*&, const utils::address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch,
rsx::texture_upload_context context, rsx::texture_dimension_extended type, rsx::texture_create_flags flags) override u32 gcm_format, rsx::texture_upload_context context, rsx::texture_dimension_extended type, rsx::texture_create_flags flags) override
{ {
auto image = gl::create_texture(gcm_format, width, height, depth, mipmaps, type); auto image = gl::create_texture(gcm_format, width, height, depth, mipmaps, type);
@ -836,7 +836,7 @@ namespace gl
cached.set_image_type(type); cached.set_image_type(type);
cached.set_gcm_format(gcm_format); cached.set_gcm_format(gcm_format);
cached.create_read_only(image, width, height, depth, mipmaps); cached.create_read_only(image, width, height, depth, mipmaps, pitch);
cached.set_dirty(false); cached.set_dirty(false);
if (context != rsx::texture_upload_context::blit_engine_dst) if (context != rsx::texture_upload_context::blit_engine_dst)
@ -890,7 +890,7 @@ namespace gl
rsx::texture_upload_context context, const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, bool input_swizzled) override rsx::texture_upload_context context, const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, bool input_swizzled) override
{ {
void* unused = nullptr; void* unused = nullptr;
auto section = create_new_texture(unused, rsx_range, width, height, depth, mipmaps, gcm_format, context, type, auto section = create_new_texture(unused, rsx_range, width, height, depth, mipmaps, pitch, gcm_format, context, type,
rsx::texture_create_flags::default_component_order); rsx::texture_create_flags::default_component_order);
gl::upload_texture(section->get_raw_texture()->id(), gcm_format, width, height, depth, mipmaps, gl::upload_texture(section->get_raw_texture()->id(), gcm_format, width, height, depth, mipmaps,

View file

@ -50,10 +50,13 @@ namespace vk
ASSERT(!exists() || !is_managed() || vram_texture == new_texture); ASSERT(!exists() || !is_managed() || vram_texture == new_texture);
vram_texture = new_texture; vram_texture = new_texture;
verify(HERE), rsx_pitch;
width = w; width = w;
height = h; height = h;
this->depth = depth; this->depth = depth;
this->mipmaps = mipmaps; this->mipmaps = mipmaps;
this->rsx_pitch = rsx_pitch;
this->gcm_format = gcm_format; this->gcm_format = gcm_format;
this->pack_unpack_swap_bytes = pack_swap_bytes; this->pack_unpack_swap_bytes = pack_swap_bytes;
@ -63,12 +66,6 @@ namespace vk
managed_texture.reset(vram_texture); managed_texture.reset(vram_texture);
} }
//TODO: Properly compute these values
if (rsx_pitch > 0)
this->rsx_pitch = rsx_pitch;
else
this->rsx_pitch = get_section_size() / height;
//Even if we are managing the same vram section, we cannot guarantee contents are static //Even if we are managing the same vram section, we cannot guarantee contents are static
//The create method is only invoked when a new managed session is required //The create method is only invoked when a new managed session is required
synchronized = false; synchronized = false;
@ -770,8 +767,8 @@ namespace vk
vk::change_image_layout(cmd, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresource_range); vk::change_image_layout(cmd, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresource_range);
} }
cached_texture_section* create_new_texture(vk::command_buffer& cmd, const utils::address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u32 gcm_format, cached_texture_section* create_new_texture(vk::command_buffer& cmd, const utils::address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch,
rsx::texture_upload_context context, rsx::texture_dimension_extended type, rsx::texture_create_flags flags) override u32 gcm_format, rsx::texture_upload_context context, rsx::texture_dimension_extended type, rsx::texture_create_flags flags) override
{ {
const u16 section_depth = depth; const u16 section_depth = depth;
const bool is_cubemap = type == rsx::texture_dimension_extended::texture_dimension_cubemap; const bool is_cubemap = type == rsx::texture_dimension_extended::texture_dimension_cubemap;
@ -849,7 +846,7 @@ namespace vk
region.set_gcm_format(gcm_format); region.set_gcm_format(gcm_format);
region.set_image_type(type); region.set_image_type(type);
region.create(width, height, section_depth, mipmaps, image, 0, true, gcm_format); region.create(width, height, section_depth, mipmaps, image, pitch, true, gcm_format);
region.set_dirty(false); region.set_dirty(false);
//Its not necessary to lock blit dst textures as they are just reused as necessary //Its not necessary to lock blit dst textures as they are just reused as necessary
@ -873,7 +870,7 @@ namespace vk
cached_texture_section* upload_image_from_cpu(vk::command_buffer& cmd, const utils::address_range& rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format, cached_texture_section* upload_image_from_cpu(vk::command_buffer& cmd, const utils::address_range& rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format,
rsx::texture_upload_context context, const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, bool swizzled) override rsx::texture_upload_context context, const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, bool swizzled) override
{ {
auto section = create_new_texture(cmd, rsx_range, width, height, depth, mipmaps, gcm_format, context, type, auto section = create_new_texture(cmd, rsx_range, width, height, depth, mipmaps, pitch, gcm_format, context, type,
rsx::texture_create_flags::default_component_order); rsx::texture_create_flags::default_component_order);
auto image = section->get_raw_texture(); auto image = section->get_raw_texture();