rsx: Make the 3rd texture dimension matter

- Affects cube maps and texture3D surfaces
This commit is contained in:
kd-11 2017-09-22 16:12:10 +03:00
parent 4d83d749a0
commit b74cdcde00
3 changed files with 62 additions and 46 deletions

View File

@ -39,7 +39,7 @@ namespace rsx
return rsx::buffered_section::matches(rsx_address, rsx_size); return rsx::buffered_section::matches(rsx_address, rsx_size);
} }
bool matches(const u32 rsx_address, const u32 width, const u32 height, const u32 mipmaps) bool matches(const u32 rsx_address, const u32 width, const u32 height, const u32 depth, const u32 mipmaps)
{ {
if (rsx_address == cpu_address_base) if (rsx_address == cpu_address_base)
{ {
@ -52,6 +52,9 @@ namespace rsx
if (height && height != this->height) if (height && height != this->height)
return false; return false;
if (depth && depth != this->depth)
return false;
if (mipmaps && mipmaps != this->mipmaps) if (mipmaps && mipmaps != this->mipmaps)
return false; return false;
@ -71,12 +74,12 @@ namespace rsx
context = upload_context; context = upload_context;
} }
u32 get_width() const u16 get_width() const
{ {
return width; return width;
} }
u32 get_height() const u16 get_height() const
{ {
return height; return height;
} }
@ -362,7 +365,7 @@ namespace rsx
return results; return results;
} }
section_storage_type *find_texture_from_dimensions(u32 rsx_address, u16 width = 0, u16 height = 0, u16 mipmaps = 0) section_storage_type *find_texture_from_dimensions(u32 rsx_address, u16 width = 0, u16 height = 0, u16 depth = 0, u16 mipmaps = 0)
{ {
auto found = m_cache.find(get_block_address(rsx_address)); auto found = m_cache.find(get_block_address(rsx_address));
if (found != m_cache.end()) if (found != m_cache.end())
@ -370,7 +373,7 @@ namespace rsx
auto &range_data = found->second; auto &range_data = found->second;
for (auto &tex : range_data.data) for (auto &tex : range_data.data)
{ {
if (tex.matches(rsx_address, width, height, mipmaps) && !tex.is_dirty()) if (tex.matches(rsx_address, width, height, depth, mipmaps) && !tex.is_dirty())
{ {
return &tex; return &tex;
} }
@ -380,7 +383,7 @@ namespace rsx
return nullptr; return nullptr;
} }
section_storage_type& find_cached_texture(u32 rsx_address, u32 rsx_size, bool confirm_dimensions = false, u16 width = 0, u16 height = 0, u16 mipmaps = 0) section_storage_type& find_cached_texture(u32 rsx_address, u32 rsx_size, bool confirm_dimensions = false, u16 width = 0, u16 height = 0, u16 depth = 0, u16 mipmaps = 0)
{ {
const u32 block_address = get_block_address(rsx_address); const u32 block_address = get_block_address(rsx_address);
@ -393,7 +396,7 @@ namespace rsx
{ {
if (tex.matches(rsx_address, rsx_size) && !tex.is_dirty()) if (tex.matches(rsx_address, rsx_size) && !tex.is_dirty())
{ {
if (!confirm_dimensions || tex.matches(rsx_address, width, height, mipmaps)) if (!confirm_dimensions || tex.matches(rsx_address, width, height, depth, mipmaps))
{ {
if (!tex.is_locked()) if (!tex.is_locked())
range_data.notify(rsx_address, rsx_size); range_data.notify(rsx_address, rsx_size);
@ -676,11 +679,7 @@ namespace rsx
{ {
const u32 texaddr = rsx::get_address(tex.offset(), tex.location()); const u32 texaddr = rsx::get_address(tex.offset(), tex.location());
const u32 tex_size = (u32)get_texture_size(tex); const u32 tex_size = (u32)get_texture_size(tex);
const u32 format = tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); const u32 format = tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
const u32 tex_width = tex.width();
const u32 tex_height = tex.height();
const u32 tex_pitch = (tex_size / tex_height); //NOTE: Compressed textures dont have a real pitch (tex_size = (w*h)/6)
if (!texaddr || !tex_size) if (!texaddr || !tex_size)
{ {
@ -688,9 +687,14 @@ namespace rsx
return 0; return 0;
} }
const auto extended_dimension = tex.get_extended_texture_dimension();
//Check for sampleable rtts from previous render passes //Check for sampleable rtts from previous render passes
if (auto texptr = m_rtts.get_texture_from_render_target_if_applicable(texaddr)) if (auto texptr = m_rtts.get_texture_from_render_target_if_applicable(texaddr))
{ {
if (extended_dimension != rsx::texture_dimension_extended::texture_dimension_2d)
LOG_ERROR(RSX, "Texture resides in render target memory, but requested type is not 2D (%d)", (u32)extended_dimension);
for (const auto& tex : m_rtts.m_bound_render_targets) for (const auto& tex : m_rtts.m_bound_render_targets)
{ {
if (std::get<0>(tex) == texaddr) if (std::get<0>(tex) == texaddr)
@ -714,6 +718,9 @@ namespace rsx
if (auto texptr = m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr)) if (auto texptr = m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr))
{ {
if (extended_dimension != rsx::texture_dimension_extended::texture_dimension_2d)
LOG_ERROR(RSX, "Texture resides in depth buffer memory, but requested type is not 2D (%d)", (u32)extended_dimension);
if (texaddr == std::get<0>(m_rtts.m_bound_depth_stencil)) if (texaddr == std::get<0>(m_rtts.m_bound_depth_stencil))
{ {
if (g_cfg.video.strict_rendering_mode) if (g_cfg.video.strict_rendering_mode)
@ -731,11 +738,33 @@ namespace rsx
return texptr->get_view(); return texptr->get_view();
} }
u16 depth = 0;
u16 tex_height = (u16)tex.height();
const u16 tex_width = tex.width();
const u16 tex_pitch = (tex_size / tex_height); //NOTE: Compressed textures dont have a real pitch (tex_size = (w*h)/6)
switch (extended_dimension)
{
case rsx::texture_dimension_extended::texture_dimension_1d:
tex_height = 1;
depth = 1;
break;
case rsx::texture_dimension_extended::texture_dimension_2d:
depth = 1;
break;
case rsx::texture_dimension_extended::texture_dimension_cubemap:
depth = 6;
break;
case rsx::texture_dimension_extended::texture_dimension_3d:
depth = tex.depth();
break;
}
{ {
//Search in cache and upload/bind //Search in cache and upload/bind
reader_lock lock(m_cache_mutex); reader_lock lock(m_cache_mutex);
auto cached_texture = find_texture_from_dimensions(texaddr, tex_width, tex_height); auto cached_texture = find_texture_from_dimensions(texaddr, tex_width, tex_height, depth);
if (cached_texture) if (cached_texture)
{ {
return cached_texture->get_raw_view(); return cached_texture->get_raw_view();
@ -765,6 +794,12 @@ namespace rsx
if ((offset_x + tex_width) <= surface->get_width() && if ((offset_x + tex_width) <= surface->get_width() &&
(offset_y + tex_height) <= surface->get_height()) (offset_y + tex_height) <= surface->get_height())
{ {
if (extended_dimension != rsx::texture_dimension_extended::texture_dimension_2d)
{
LOG_ERROR(RSX, "Texture resides in blit engine memory, but requested type is not 2D (%d)", (u32)extended_dimension);
break;
}
if (!blit_engine_incompatibility_warning_raised && !is_hw_blit_engine_compatible(format)) if (!blit_engine_incompatibility_warning_raised && !is_hw_blit_engine_compatible(format))
{ {
LOG_ERROR(RSX, "Format 0x%X is not compatible with the hardware blit acceleration." LOG_ERROR(RSX, "Format 0x%X is not compatible with the hardware blit acceleration."
@ -833,36 +868,12 @@ namespace rsx
} }
//Do direct upload from CPU as the last resort //Do direct upload from CPU as the last resort
const auto extended_dimension = tex.get_extended_texture_dimension();
u16 height = 0;
u16 depth = 0;
switch (extended_dimension)
{
case rsx::texture_dimension_extended::texture_dimension_1d:
height = 1;
depth = 1;
break;
case rsx::texture_dimension_extended::texture_dimension_2d:
height = tex_height;
depth = 1;
break;
case rsx::texture_dimension_extended::texture_dimension_cubemap:
height = tex_height;
depth = 1;
break;
case rsx::texture_dimension_extended::texture_dimension_3d:
height = tex_height;
depth = tex.depth();
break;
}
writer_lock lock(m_cache_mutex); writer_lock lock(m_cache_mutex);
const bool is_swizzled = !(tex.format() & CELL_GCM_TEXTURE_LN); const bool is_swizzled = !(tex.format() & CELL_GCM_TEXTURE_LN);
auto subresources_layout = get_subresources_layout(tex); auto subresources_layout = get_subresources_layout(tex);
auto remap_vector = tex.decoded_remap(); auto remap_vector = tex.decoded_remap();
return upload_image_from_cpu(cmd, texaddr, tex_width, height, depth, tex.get_exact_mipmap_count(), tex_pitch, format, return upload_image_from_cpu(cmd, texaddr, tex_width, tex_height, depth, tex.get_exact_mipmap_count(), tex_pitch, format,
texture_upload_context::shader_read, subresources_layout, extended_dimension, is_swizzled, remap_vector)->get_raw_view(); texture_upload_context::shader_read, subresources_layout, extended_dimension, is_swizzled, remap_vector)->get_raw_view();
} }

View File

@ -142,7 +142,7 @@ namespace gl
vram_texture = 0; vram_texture = 0;
} }
void create(const u16 w, const u16 h, const u16 /*depth*/, const u16 /*mipmaps*/, void*, void create(const u16 w, const u16 h, const u16 depth, const u16 mipmaps, void*,
gl::texture* image, const u32 rsx_pitch, bool read_only, gl::texture* image, const u32 rsx_pitch, bool read_only,
gl::texture::format gl_format, gl::texture::type gl_type, bool swap_bytes) gl::texture::format gl_format, gl::texture::type gl_type, bool swap_bytes)
{ {
@ -156,23 +156,27 @@ namespace gl
this->width = w; this->width = w;
this->height = h; this->height = h;
this->rsx_pitch = rsx_pitch; this->rsx_pitch = rsx_pitch;
this->depth = depth;
this->mipmaps = mipmaps;
vram_texture = image->id(); vram_texture = image->id();
set_format(gl_format, gl_type, swap_bytes); set_format(gl_format, gl_type, swap_bytes);
} }
void create_read_only(const u32 id, const u32 width, const u32 height) void create_read_only(const u32 id, const u32 width, const u32 height, const u32 depth, const u32 mipmaps)
{ {
//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;
this->depth = depth;
this->mipmaps = mipmaps;
vram_texture = id; vram_texture = id;
rsx_pitch = 0; rsx_pitch = 0;
real_pitch = 0; real_pitch = 0;
} }
void set_dimensions(u32 width, u32 height, u32 pitch) void set_dimensions(u32 width, u32 height, u32 depth, u32 pitch)
{ {
this->width = width; this->width = width;
this->height = height; this->height = height;
@ -437,11 +441,11 @@ namespace gl
blitter m_hw_blitter; blitter m_hw_blitter;
std::vector<u32> m_temporary_surfaces; std::vector<u32> m_temporary_surfaces;
cached_texture_section& create_texture(u32 id, u32 texaddr, u32 texsize, u32 w, u32 h) cached_texture_section& create_texture(u32 id, u32 texaddr, u32 texsize, u32 w, u32 h, u32 depth, u32 mipmaps)
{ {
cached_texture_section& tex = find_cached_texture(texaddr, texsize, true, w, h); cached_texture_section& tex = find_cached_texture(texaddr, texsize, true, w, h, depth);
tex.reset(texaddr, texsize, false); tex.reset(texaddr, texsize, false);
tex.create_read_only(id, w, h); tex.create_read_only(id, w, h, depth, mipmaps);
read_only_range = tex.get_min_max(read_only_range); read_only_range = tex.get_min_max(read_only_range);
return tex; return tex;
} }
@ -565,7 +569,7 @@ namespace gl
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_BLUE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_BLUE);
} }
auto& cached = create_texture(vram_texture, rsx_address, rsx_size, width, height); auto& cached = create_texture(vram_texture, rsx_address, rsx_size, width, height, depth, mipmaps);
cached.set_dirty(false); cached.set_dirty(false);
cached.set_depth_flag(depth_flag); cached.set_depth_flag(depth_flag);
cached.set_view_flags(flags); cached.set_view_flags(flags);

View File

@ -392,6 +392,7 @@ namespace vk
const rsx::texture_upload_context context, const rsx::texture_dimension_extended type, const rsx::texture_create_flags flags, const rsx::texture_upload_context context, const rsx::texture_dimension_extended type, const rsx::texture_create_flags flags,
std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) override std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap_vector) override
{ {
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;
VkFormat vk_format; VkFormat vk_format;
VkComponentMapping mapping; VkComponentMapping mapping;
@ -494,9 +495,9 @@ namespace vk
change_image_layout(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, { aspect_flags, 0, mipmaps, 0, layer }); change_image_layout(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, { aspect_flags, 0, mipmaps, 0, layer });
cached_texture_section& region = find_cached_texture(rsx_address, rsx_size, true, width, height, 0); cached_texture_section& region = find_cached_texture(rsx_address, rsx_size, true, width, height, section_depth);
region.reset(rsx_address, rsx_size); region.reset(rsx_address, rsx_size);
region.create(width, height, depth, mipmaps, view, image); region.create(width, height, section_depth, mipmaps, view, image);
region.set_dirty(false); region.set_dirty(false);
region.set_context(context); region.set_context(context);