Skip to content

Commit

Permalink
Merge pull request #1625 from vlj/rsx
Browse files Browse the repository at this point in the history
rsx/common/gl/d3d12/vulkan: Use exact mipmap counts.
  • Loading branch information
vlj committed Mar 26, 2016
2 parents cf402c8 + 9485fe2 commit 0838e32
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 74 deletions.
18 changes: 9 additions & 9 deletions rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,17 @@ namespace

if (texture.dimension() == 1) // 1D texture or cubemap
{
return CD3DX12_RESOURCE_DESC::Tex1D(dxgi_format, texture.width(), 1, texture.mipmap());
return CD3DX12_RESOURCE_DESC::Tex1D(dxgi_format, texture.width(), 1, texture.get_exact_mipmap_count());
}
else if (texture.dimension() == 2) // 2D texture or cubemap
{
// if (texture.depth() < 2);
size_t depth = (texture.cubemap()) ? 6 : 1;
return CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, texture.width(), texture.height(), (UINT)depth, texture.mipmap());
return CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, texture.width(), texture.height(), (UINT)depth, texture.get_exact_mipmap_count());
}
else if (texture.dimension() == 3) // 3d texture
{
return CD3DX12_RESOURCE_DESC::Tex3D(dxgi_format, texture.width(), texture.height(), texture.depth(), texture.mipmap());
return CD3DX12_RESOURCE_DESC::Tex3D(dxgi_format, texture.width(), texture.height(), texture.depth(), texture.get_exact_mipmap_count());
}
throw EXCEPTION("Unknow texture dimension");
}
Expand Down Expand Up @@ -182,25 +182,25 @@ D3D12_SHADER_RESOURCE_VIEW_DESC get_srv_descriptor_with_dimensions(const rsx::te
if (tex.dimension() == 1)
{
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
shared_resource_view_desc.Texture1D.MipLevels = tex.mipmap();
shared_resource_view_desc.Texture1D.MipLevels = tex.get_exact_mipmap_count();
return shared_resource_view_desc;
}
if (tex.dimension() == 2)
{
if (tex.cubemap())
{
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
shared_resource_view_desc.TextureCube.MipLevels = tex.mipmap();
shared_resource_view_desc.TextureCube.MipLevels = tex.get_exact_mipmap_count();
return shared_resource_view_desc;
}
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
shared_resource_view_desc.Texture2D.MipLevels = tex.mipmap();
shared_resource_view_desc.Texture2D.MipLevels = tex.get_exact_mipmap_count();
return shared_resource_view_desc;
}
if (tex.dimension() == 3)
{
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
shared_resource_view_desc.Texture3D.MipLevels = tex.mipmap();
shared_resource_view_desc.Texture3D.MipLevels = tex.get_exact_mipmap_count();
return shared_resource_view_desc;
}
throw EXCEPTION("Wrong texture dimension %d", tex.dimension());
Expand Down Expand Up @@ -266,7 +266,7 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz
{
is_depth_stencil_texture = true;
}
else if (cached_texture != nullptr && (cached_texture->first == texture_entry(format, w, h, textures[i].depth(), textures[i].mipmap())))
else if (cached_texture != nullptr && (cached_texture->first == texture_entry(format, w, h, textures[i].depth(), textures[i].get_exact_mipmap_count())))
{
if (cached_texture->first.m_is_dirty)
{
Expand All @@ -283,7 +283,7 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz
std::wstring name = L"texture_@" + std::to_wstring(texaddr);
tex->SetName(name.c_str());
vram_texture = tex.Get();
m_texture_cache.store_and_protect_data(texaddr, texaddr, get_texture_size(textures[i]), format, w, h, textures[i].depth(), textures[i].mipmap(), tex);
m_texture_cache.store_and_protect_data(texaddr, texaddr, get_texture_size(textures[i]), format, w, h, textures[i].depth(), textures[i].get_exact_mipmap_count(), tex);
}

D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = get_srv_descriptor_with_dimensions(textures[i]);
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/RSX/GL/gl_texture_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ namespace gl
gl_cached_texture *obj = nullptr;

if (!rtt)
obj = find_obj_for_params(texaddr, tex.width(), tex.height(), tex.mipmap());
obj = find_obj_for_params(texaddr, tex.width(), tex.height(), tex.get_exact_mipmap_count());

if (obj && !obj->deleted)
{
Expand All @@ -497,7 +497,7 @@ namespace gl
}

__glcheck gl_texture.init(index, tex);
gl_cached_texture &_obj = create_obj_for_params(gl_texture.id(), texaddr, tex.width(), tex.height(), tex.mipmap());
gl_cached_texture &_obj = create_obj_for_params(gl_texture.id(), texaddr, tex.width(), tex.height(), tex.get_exact_mipmap_count());

_obj.block_sz = (u32)get_texture_size(tex);
lock_gl_object(_obj);
Expand Down
6 changes: 3 additions & 3 deletions rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ namespace rsx

const std::vector<rsx_subresource_layout> &input_layouts = get_subresources_layout(tex);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glTexStorage2D(m_target, tex.mipmap(), get_sized_internal_format(format), tex.width(), tex.height());
glTexStorage2D(m_target, tex.get_exact_mipmap_count(), get_sized_internal_format(format), tex.width(), tex.height());

if (!is_compressed_format(format))
{
Expand All @@ -345,7 +345,7 @@ namespace rsx

const std::array<GLenum, 4>& glRemap = get_swizzle_remap(format);

glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, tex.mipmap() - 1);
glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, tex.get_exact_mipmap_count() - 1);

if (format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16 && format != CELL_GCM_TEXTURE_X32_FLOAT)
{
Expand Down Expand Up @@ -382,7 +382,7 @@ namespace rsx

if (min_filter != GL_LINEAR && min_filter != GL_NEAREST)
{
if (tex.mipmap() <= 1 || m_target == GL_TEXTURE_RECTANGLE)
if (tex.get_exact_mipmap_count() <= 1 || m_target == GL_TEXTURE_RECTANGLE)
{
LOG_WARNING(RSX, "Texture %d, target 0x%X, requesting mipmap filtering without any mipmaps set!", m_id, m_target);
min_filter = GL_LINEAR;
Expand Down
6 changes: 6 additions & 0 deletions rpcs3/Emu/RSX/RSXTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ namespace rsx
return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 16) & 0xffff);
}

u16 texture::get_exact_mipmap_count() const
{
u16 max_mipmap_count = static_cast<u16>(floor(log2(std::max(width(), height()))) + 1);
return std::min(mipmap(), max_mipmap_count);
}

u8 texture::wrap_s() const
{
return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)]) & 0xf);
Expand Down
5 changes: 5 additions & 0 deletions rpcs3/Emu/RSX/RSXTexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ namespace rsx
u8 dimension() const;
u8 format() const;
u16 mipmap() const;
/**
* mipmap() returns value from register which can be higher than the actual number of mipmap level.
* This function clamp the result with the mipmap count allowed by texture size.
*/
u16 get_exact_mipmap_count() const;

// Address
u8 wrap_s() const;
Expand Down
23 changes: 11 additions & 12 deletions rpcs3/Emu/RSX/VK/VKGSRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,14 +395,14 @@ VKGSRender::VKGSRender() : GSRender(frame_type::Vulkan)
{
vk::change_image_layout(m_command_buffer, m_swap_chain->get_swap_chain_image(i),
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
VK_IMAGE_ASPECT_COLOR_BIT);
vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT));

VkClearColorValue clear_color{};
auto range = vk::default_image_subresource_range();
auto range = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT);
vkCmdClearColorImage(m_command_buffer, m_swap_chain->get_swap_chain_image(i), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range);
vk::change_image_layout(m_command_buffer, m_swap_chain->get_swap_chain_image(i),
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
VK_IMAGE_ASPECT_COLOR_BIT);
vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT));

}

Expand Down Expand Up @@ -690,8 +690,7 @@ void VKGSRender::clear_surface(u32 mask)
u32 stencil_clear = 0;

VkClearValue depth_stencil_clear_values, color_clear_values;
VkImageSubresourceRange depth_range = vk::default_image_subresource_range();
depth_range.aspectMask = 0;
VkImageSubresourceRange depth_range = vk::get_image_subresource_range(0, 0, 1, 1, 0);

if (mask & 0x1)
{
Expand Down Expand Up @@ -735,25 +734,25 @@ void VKGSRender::clear_surface(u32 mask)
color_clear_values.color.float32[2] = (float)clear_b / 255;
color_clear_values.color.float32[3] = (float)clear_a / 255;

VkImageSubresourceRange range = vk::default_image_subresource_range();

for (u32 i = 0; i < m_rtts.m_bound_render_targets.size(); ++i)
{
VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT);
if (std::get<1>(m_rtts.m_bound_render_targets[i]) == nullptr) continue;

VkImage color_image = std::get<1>(m_rtts.m_bound_render_targets[i])->value;
change_image_layout(m_command_buffer, color_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_ASPECT_COLOR_BIT);
change_image_layout(m_command_buffer, color_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, range);
vkCmdClearColorImage(m_command_buffer, color_image, VK_IMAGE_LAYOUT_GENERAL, &color_clear_values.color, 1, &range);
change_image_layout(m_command_buffer, color_image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT);
change_image_layout(m_command_buffer, color_image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, range);
}
}

if (mask & 0x3)
{
VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT);
VkImage depth_stencil_image = std::get<1>(m_rtts.m_bound_depth_stencil)->value;
change_image_layout(m_command_buffer, depth_stencil_image, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_ASPECT_DEPTH_BIT);
change_image_layout(m_command_buffer, depth_stencil_image, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, range);
vkCmdClearDepthStencilImage(m_command_buffer, std::get<1>(m_rtts.m_bound_depth_stencil)->value, VK_IMAGE_LAYOUT_GENERAL, &depth_stencil_clear_values.depthStencil, 1, &depth_range);
change_image_layout(m_command_buffer, depth_stencil_image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT);
change_image_layout(m_command_buffer, depth_stencil_image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, range);
}

if (!was_recording)
Expand Down Expand Up @@ -1209,7 +1208,7 @@ void VKGSRender::flip(int buffer)
//TODO: Properly clear the background to rsx value
m_swap_chain->acquireNextImageKHR((*m_device), (*m_swap_chain), ~0ULL, VK_NULL_HANDLE, VK_NULL_HANDLE, &next_image_temp);

VkImageSubresourceRange range = vk::default_image_subresource_range();
VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT);
VkClearColorValue clear_black = { 0 };
vkCmdClearColorImage(m_command_buffer, m_swap_chain->get_swap_chain_image(next_image_temp), VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, &clear_black, 1, &range);

Expand Down
5 changes: 1 addition & 4 deletions rpcs3/Emu/RSX/VK/VKHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,9 @@ namespace vk
g_current_renderer = device;
}

void change_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageAspectFlags aspect_flags)
void change_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageSubresourceRange range)
{
//Prepare an image to match the new layout..
VkImageSubresourceRange range = default_image_subresource_range();
range.aspectMask = aspect_flags;

VkImageMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.newLayout = new_layout;
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/RSX/VK/VKHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ namespace vk

VkComponentMapping default_component_map();
VkImageSubresource default_image_subresource();
VkImageSubresourceRange default_image_subresource_range();
VkImageSubresourceRange get_image_subresource_range(uint32_t base_layer, uint32_t base_mip, uint32_t layer_count, uint32_t level_count, VkImageAspectFlags aspect);

VkSampler null_sampler();
VkImageView null_image_view();

void destroy_global_resources();

void change_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageAspectFlags aspect_flags);
void change_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageSubresourceRange range);
void copy_image(VkCommandBuffer cmd, VkImage &src, VkImage &dst, VkImageLayout srcLayout, VkImageLayout dstLayout, u32 width, u32 height, u32 mipmaps, VkImageAspectFlagBits aspect);
void copy_scaled_image(VkCommandBuffer cmd, VkImage &src, VkImage &dst, VkImageLayout srcLayout, VkImageLayout dstLayout, u32 src_width, u32 src_height, u32 dst_width, u32 dst_height, u32 mipmaps, VkImageAspectFlagBits aspect);

Expand Down
17 changes: 6 additions & 11 deletions rpcs3/Emu/RSX/VK/VKRenderTargets.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@ namespace rsx
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_SAMPLED_BIT,
0));
change_image_layout(*cmd, rtt->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_ASPECT_COLOR_BIT);
change_image_layout(*cmd, rtt->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT));
//Clear new surface
VkClearColorValue clear_color;
VkImageSubresourceRange range = vk::default_image_subresource_range();
VkImageSubresourceRange range = vk::get_image_subresource_range(0,0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT);

clear_color.float32[0] = 0.f;
clear_color.float32[1] = 0.f;
clear_color.float32[2] = 0.f;
clear_color.float32[3] = 0.f;

vkCmdClearColorImage(*cmd, rtt->value, VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range);
change_image_layout(*cmd, rtt->value, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT);
change_image_layout(*cmd, rtt->value, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT));

return rtt;
}
Expand All @@ -52,16 +52,11 @@ namespace rsx
std::unique_ptr<vk::image> ds;
ds.reset(new vk::image(device, mem_mapping.device_local,
VK_IMAGE_TYPE_2D, requested_format, width, height, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, 0));
change_image_layout(*cmd, ds->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
change_image_layout(*cmd, ds->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));

//Clear new surface..
VkClearDepthStencilValue clear_depth = {};
VkImageSubresourceRange range = {};
range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
range.baseArrayLayer = 0;
range.baseMipLevel = 0;
range.layerCount = 1;
range.levelCount = 1;
VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT);

if (requested_format != VK_FORMAT_D16_UNORM)
range.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
Expand All @@ -70,7 +65,7 @@ namespace rsx
clear_depth.stencil = 0;

vkCmdClearDepthStencilImage(*cmd, ds->value, VK_IMAGE_LAYOUT_GENERAL, &clear_depth, 1, &range);
change_image_layout(*cmd, ds->value, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
change_image_layout(*cmd, ds->value, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));

return ds;
}
Expand Down

0 comments on commit 0838e32

Please sign in to comment.