mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 06:51:26 +12:00
rsx: Implement render-to-cubemap; Also simplify unnormalized samplers [WIP, DELETE SHADER CACHE, VERY SLOW]
- Enables real-time cubemap reflections - TODO: Vulkan is broke; rsx is very slow with this feature
This commit is contained in:
parent
fbb7186e66
commit
1fa18757fc
10 changed files with 185 additions and 49 deletions
|
@ -204,7 +204,7 @@ namespace rsx
|
|||
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 insert_texture_barrier() = 0;
|
||||
virtual image_view_type generate_cubemap_from_images(commandbuffer_type&, std::array<image_resource_type, 6>& sources) = 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;
|
||||
|
||||
constexpr u32 get_block_size() const { return 0x1000000; }
|
||||
inline u32 get_block_address(u32 address) const { return (address & ~0xFFFFFF); }
|
||||
|
@ -229,11 +229,13 @@ namespace rsx
|
|||
struct deferred_subresource
|
||||
{
|
||||
image_resource_type external_handle = 0;
|
||||
std::array<image_resource_type, 6> external_cubemap_sources;
|
||||
u32 gcm_format = 0;
|
||||
u16 x = 0;
|
||||
u16 y = 0;
|
||||
u16 width = 0;
|
||||
u16 height = 0;
|
||||
bool is_cubemap = false;
|
||||
|
||||
deferred_subresource()
|
||||
{}
|
||||
|
@ -246,7 +248,7 @@ namespace rsx
|
|||
struct sampled_image_descriptor : public sampled_image_descriptor_base
|
||||
{
|
||||
image_view_type image_handle = 0;
|
||||
deferred_subresource external_subresource_desc;
|
||||
deferred_subresource external_subresource_desc = {};
|
||||
bool flag = false;
|
||||
|
||||
sampled_image_descriptor()
|
||||
|
@ -274,6 +276,12 @@ namespace rsx
|
|||
scale_y = y_scale;
|
||||
image_type = type;
|
||||
}
|
||||
|
||||
void set_external_cubemap_resources(std::array<image_resource_type, 6> images)
|
||||
{
|
||||
external_subresource_desc.external_cubemap_sources = images;
|
||||
external_subresource_desc.is_cubemap = true;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -990,15 +998,65 @@ namespace rsx
|
|||
sampled_image_descriptor process_framebuffer_resource(render_target_type texptr, const u32 texaddr, const u32 gcm_format, surface_store_type& m_rtts,
|
||||
const u16 tex_width, const u16 tex_height, const rsx::texture_dimension_extended extended_dimension, const bool is_depth)
|
||||
{
|
||||
const u32 format = gcm_format & ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN);
|
||||
const auto surface_width = texptr->get_surface_width();
|
||||
const auto surface_height = texptr->get_surface_height();
|
||||
|
||||
if (extended_dimension != rsx::texture_dimension_extended::texture_dimension_2d &&
|
||||
extended_dimension != rsx::texture_dimension_extended::texture_dimension_1d)
|
||||
{
|
||||
if (extended_dimension == rsx::texture_dimension_extended::texture_dimension_cubemap)
|
||||
{
|
||||
if (surface_height == (surface_width * 6))
|
||||
{
|
||||
//TODO: Unwrap long RTT block into 6 images and generate cubemap from them
|
||||
LOG_ERROR(RSX, "Unwrapping block rtt to cubemap is unimplemented!");
|
||||
return{};
|
||||
}
|
||||
|
||||
std::array<image_resource_type, 6> image_array;
|
||||
image_array[0] = texptr->get_surface();
|
||||
bool can_cast = true;
|
||||
|
||||
u32 image_size = texptr->get_rsx_pitch() * texptr->get_surface_height();
|
||||
u32 image_address = texaddr + image_size;
|
||||
|
||||
for (int n = 1; n < 6; ++n)
|
||||
{
|
||||
render_target_type img = nullptr;
|
||||
if (!!(img = m_rtts.get_texture_from_render_target_if_applicable(image_address)) ||
|
||||
!!(img = m_rtts.get_texture_from_depth_stencil_if_applicable(image_address)))
|
||||
{
|
||||
if (img->get_surface_width() != surface_width ||
|
||||
img->get_surface_width() != img->get_surface_height())
|
||||
{
|
||||
can_cast = false;
|
||||
break;
|
||||
}
|
||||
|
||||
image_address += image_size;
|
||||
image_array[n] = img->get_surface();
|
||||
}
|
||||
else
|
||||
{
|
||||
can_cast = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (can_cast)
|
||||
{
|
||||
sampled_image_descriptor desc = { texptr->get_surface(), format, 0, 0, surface_width, surface_height, texture_upload_context::framebuffer_storage,
|
||||
is_depth, 1.f, 1.f, rsx::texture_dimension_extended::texture_dimension_cubemap };
|
||||
|
||||
desc.set_external_cubemap_resources(image_array);
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR(RSX, "Texture resides in render target memory, but requested type is not 2D (%d)", (u32)extended_dimension);
|
||||
}
|
||||
|
||||
const auto surface_width = texptr->get_surface_width();
|
||||
const auto surface_height = texptr->get_surface_height();
|
||||
|
||||
u32 internal_width = tex_width;
|
||||
u32 internal_height = tex_height;
|
||||
get_native_dimensions(internal_width, internal_height, texptr);
|
||||
|
@ -1025,10 +1083,9 @@ namespace rsx
|
|||
texptr->aa_mode = aa_mode;
|
||||
}
|
||||
|
||||
const u32 format = gcm_format & ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN);
|
||||
const bool unnormalized = (gcm_format & CELL_GCM_TEXTURE_UN) != 0;
|
||||
f32 scale_x = (unnormalized)? get_internal_scaling_x(texptr) : 1.f;
|
||||
f32 scale_y = (unnormalized)? get_internal_scaling_y(texptr) : 1.f;
|
||||
f32 scale_x = (unnormalized)? (1.f / tex_width) : 1.f;
|
||||
f32 scale_y = (unnormalized)? (1.f / tex_height) : 1.f;
|
||||
|
||||
if (extended_dimension == rsx::texture_dimension_extended::texture_dimension_1d)
|
||||
{
|
||||
|
@ -1188,8 +1245,8 @@ namespace rsx
|
|||
else
|
||||
{
|
||||
const bool unnormalized = (tex.format() & CELL_GCM_TEXTURE_UN) != 0;
|
||||
f32 scale_x = (unnormalized)? get_internal_scaling_x(rsc.surface) : 1.f;
|
||||
f32 scale_y = (unnormalized)? get_internal_scaling_x(rsc.surface) : 1.f;
|
||||
f32 scale_x = (unnormalized)? (1.f / tex_width) : 1.f;
|
||||
f32 scale_y = (unnormalized)? (1.f / tex_height) : 1.f;
|
||||
u16 internal_height = rsx::apply_resolution_scale(rsc.h, true);
|
||||
|
||||
if (extended_dimension == rsx::texture_dimension_extended::texture_dimension_1d)
|
||||
|
|
|
@ -37,13 +37,13 @@ namespace gl
|
|||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_GRAD:
|
||||
return "textureGrad($t, $0.x, $1.x, $2.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D:
|
||||
return "texture($t, $0.xy * $t_coord_scale)";
|
||||
return "texture($t, $0.xy * texture_parameters[$_i].xy)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ:
|
||||
return "textureProj($t, $0 , $1.x)"; // Note: $1.x is bias
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD:
|
||||
return "textureLod($t, $0.xy * $t_coord_scale, $1.x)";
|
||||
return "textureLod($t, $0.xy * texture_parameters[$_i].xy, $1.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD:
|
||||
return "textureGrad($t, $0.xy * $t_coord_scale , $1.xy, $2.xy)";
|
||||
return "textureGrad($t, $0.xy * texture_parameters[$_i].xy , $1.xy, $2.xy)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SHADOW2D:
|
||||
return "texture($t, $0.xyz)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SHADOW2D_PROJ:
|
||||
|
@ -71,7 +71,7 @@ namespace gl
|
|||
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D:
|
||||
return "textureLod($t, $0.xy, 0)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA:
|
||||
return "texture2DReconstruct($t, $0.xy * $t_coord_scale)";
|
||||
return "texture2DReconstruct($t, $0.xy * texture_parameters[$_i].xy)";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -173,11 +173,6 @@ namespace
|
|||
case rsx::texture_dimension_extended::texture_dimension_3d:
|
||||
case rsx::texture_dimension_extended::texture_dimension_cubemap: vec_type = "vec3";
|
||||
}
|
||||
|
||||
if (prog.unnormalized_coords & (1 << index))
|
||||
OS << "\t" << vec_type << " tex" << index << "_coord_scale = texture_parameters[" << index << "].xy / textureSize(tex" << index << ", 0);\n";
|
||||
else
|
||||
OS << "\t" << vec_type << " tex" << index << "_coord_scale = texture_parameters[" << index << "].xy;\n";
|
||||
}
|
||||
|
||||
std::string insert_texture_fetch(const RSXFragmentProgram& prog, int index)
|
||||
|
|
|
@ -945,6 +945,7 @@ void GLGSRender::load_program(u32 vertex_base, u32 vertex_count)
|
|||
auto &vertex_program = current_vertex_program;
|
||||
|
||||
vertex_program.skip_vertex_input_check = true; //not needed for us since decoding is done server side
|
||||
fragment_program.unnormalized_coords = 0; //unused
|
||||
void* pipeline_properties = nullptr;
|
||||
|
||||
m_program = &m_prog_buffer.getGraphicPipelineState(vertex_program, fragment_program, pipeline_properties);
|
||||
|
|
|
@ -645,9 +645,38 @@ namespace gl
|
|||
}
|
||||
}
|
||||
|
||||
u32 generate_cubemap_from_images(void*&, std::array<u32, 6>& sources) override
|
||||
u32 generate_cubemap_from_images(void*&, const u32 gcm_format, u16 size, std::array<u32, 6>& sources) override
|
||||
{
|
||||
return 0;
|
||||
const GLenum ifmt = gl::get_sized_internal_format(gcm_format);
|
||||
GLuint dst_id = 0;
|
||||
|
||||
glGenTextures(1, &dst_id);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, dst_id);
|
||||
glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, ifmt, size, size);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
|
||||
//Empty GL_ERROR
|
||||
glGetError();
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
glCopyImageSubData(sources[i], GL_TEXTURE_2D, 0, 0, 0, 0,
|
||||
dst_id, GL_TEXTURE_CUBE_MAP, 0, 0, 0, i, size, size, 1);
|
||||
}
|
||||
|
||||
m_temporary_surfaces.push_back(dst_id);
|
||||
|
||||
if (GLenum err = glGetError())
|
||||
{
|
||||
LOG_WARNING(RSX, "Failed to copy image subresource with GL error 0x%X", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return dst_id;
|
||||
}
|
||||
|
||||
cached_texture_section* create_new_texture(void*&, u32 rsx_address, u32 rsx_size, u16 width, u16 height, u16 depth, u16 mipmaps, const u32 gcm_format,
|
||||
|
@ -755,7 +784,10 @@ namespace gl
|
|||
inline u32 create_temporary_subresource(deferred_subresource& desc)
|
||||
{
|
||||
void* unused = nullptr;
|
||||
return create_temporary_subresource_view(unused, &desc.external_handle, desc.gcm_format, desc.x, desc.y, desc.width, desc.height);
|
||||
if (!desc.is_cubemap)
|
||||
return create_temporary_subresource_view(unused, &desc.external_handle, desc.gcm_format, desc.x, desc.y, desc.width, desc.height);
|
||||
else
|
||||
return generate_cubemap_from_images(unused, desc.gcm_format, desc.width, desc.external_cubemap_sources);
|
||||
}
|
||||
|
||||
bool is_depth_texture(const u32 rsx_address, const u32 rsx_size) override
|
||||
|
|
|
@ -1353,8 +1353,8 @@ namespace rsx
|
|||
for (u32 i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
||||
{
|
||||
auto &tex = rsx::method_registers.fragment_textures[i];
|
||||
result.texture_scale[i][0] = 1.f;
|
||||
result.texture_scale[i][1] = 1.f;
|
||||
result.texture_scale[i][0] = sampler_descriptors[i]->scale_x;
|
||||
result.texture_scale[i][1] = sampler_descriptors[i]->scale_y;
|
||||
result.textures_alpha_kill[i] = 0;
|
||||
result.textures_zfunc[i] = 0;
|
||||
|
||||
|
@ -1383,18 +1383,6 @@ namespace rsx
|
|||
if (raw_format & CELL_GCM_TEXTURE_UN)
|
||||
result.unnormalized_coords |= (1 << i);
|
||||
|
||||
if (sampler_descriptors[i]->upload_context == rsx::texture_upload_context::framebuffer_storage &&
|
||||
raw_format & CELL_GCM_TEXTURE_UN)
|
||||
{
|
||||
result.texture_scale[i][0] = (resolution_scale * sampler_descriptors[i]->scale_x);
|
||||
result.texture_scale[i][1] = (resolution_scale * sampler_descriptors[i]->scale_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.texture_scale[i][0] = sampler_descriptors[i]->scale_x;
|
||||
result.texture_scale[i][1] = sampler_descriptors[i]->scale_y;
|
||||
}
|
||||
|
||||
if (sampler_descriptors[i]->is_depth_texture)
|
||||
{
|
||||
const u32 format = raw_format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
|
|
|
@ -118,11 +118,7 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
|
|||
|
||||
const auto mask = (1 << index);
|
||||
|
||||
if (m_prog.unnormalized_coords & mask)
|
||||
{
|
||||
samplerType = "sampler2DRect";
|
||||
}
|
||||
else if (m_prog.shadow_textures & mask)
|
||||
if (m_prog.shadow_textures & mask)
|
||||
{
|
||||
if (m_shadow_sampled_textures & mask)
|
||||
{
|
||||
|
|
|
@ -1085,7 +1085,6 @@ void VKGSRender::end()
|
|||
const auto wrap_s = vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_s());
|
||||
const auto wrap_t = vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_t());
|
||||
const auto wrap_r = vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_r());
|
||||
const auto unnormalized_coords = !!(rsx::method_registers.fragment_textures[i].format() & CELL_GCM_TEXTURE_UN);
|
||||
const auto mag_filter = vk::get_mag_filter(rsx::method_registers.fragment_textures[i].mag_filter());
|
||||
const auto border_color = vk::get_border_color(rsx::method_registers.fragment_textures[i].border_color());
|
||||
|
||||
|
@ -1104,7 +1103,7 @@ void VKGSRender::end()
|
|||
|
||||
if (fs_sampler_handles[i])
|
||||
{
|
||||
if (!fs_sampler_handles[i]->matches(wrap_s, wrap_t, wrap_r, unnormalized_coords, lod_bias, af_level, min_lod, max_lod,
|
||||
if (!fs_sampler_handles[i]->matches(wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
|
||||
min_filter, mag_filter, mip_mode, border_color, fs_sampler_state[i]->is_depth_texture, depth_compare))
|
||||
{
|
||||
m_current_frame->samplers_to_clean.push_back(std::move(fs_sampler_handles[i]));
|
||||
|
@ -1114,7 +1113,7 @@ void VKGSRender::end()
|
|||
|
||||
if (replace)
|
||||
{
|
||||
fs_sampler_handles[i] = std::make_unique<vk::sampler>(*m_device, wrap_s, wrap_t, wrap_r, unnormalized_coords, lod_bias, af_level, min_lod, max_lod,
|
||||
fs_sampler_handles[i] = std::make_unique<vk::sampler>(*m_device, wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
|
||||
min_filter, mag_filter, mip_mode, border_color, fs_sampler_state[i]->is_depth_texture, depth_compare);
|
||||
}
|
||||
}
|
||||
|
@ -2135,6 +2134,7 @@ void VKGSRender::load_program(u32 vertex_count, u32 vertex_base)
|
|||
|
||||
//Load current program from buffer
|
||||
vertex_program.skip_vertex_input_check = true;
|
||||
fragment_program.unnormalized_coords = 0;
|
||||
m_program = m_prog_buffer->getGraphicPipelineState(vertex_program, fragment_program, properties, *m_device, pipeline_layout).get();
|
||||
|
||||
if (m_prog_buffer->check_cache_missed())
|
||||
|
|
|
@ -22,6 +22,10 @@ namespace vk
|
|||
bool dirty = false;
|
||||
u16 native_pitch = 0;
|
||||
u16 rsx_pitch = 0;
|
||||
|
||||
u16 surface_width = 0;
|
||||
u16 surface_height = 0;
|
||||
|
||||
VkImageAspectFlags attachment_aspect_flag = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
std::unique_ptr<vk::image_view> view;
|
||||
|
||||
|
@ -61,12 +65,12 @@ namespace vk
|
|||
|
||||
u16 get_surface_width() const override
|
||||
{
|
||||
return rsx::apply_inverse_resolution_scale(width(), true);
|
||||
return surface_width;
|
||||
}
|
||||
|
||||
u16 get_surface_height() const override
|
||||
{
|
||||
return rsx::apply_inverse_resolution_scale(height(), true);
|
||||
return surface_height;
|
||||
}
|
||||
|
||||
u16 get_rsx_pitch() const override
|
||||
|
@ -143,6 +147,8 @@ namespace rsx
|
|||
|
||||
rtt->native_component_map = fmt.second;
|
||||
rtt->native_pitch = (u16)width * get_format_block_size_in_bytes(format);
|
||||
rtt->surface_width = (u16)width;
|
||||
rtt->surface_height = (u16)height;
|
||||
|
||||
if (old_surface != nullptr && old_surface->info.format == requested_format)
|
||||
{
|
||||
|
@ -197,6 +203,8 @@ namespace rsx
|
|||
ds->native_pitch *= 2;
|
||||
|
||||
ds->attachment_aspect_flag = range.aspectMask;
|
||||
ds->surface_width = (u16)width;
|
||||
ds->surface_height = (u16)height;
|
||||
|
||||
if (old_surface != nullptr && old_surface->info.format == requested_format)
|
||||
{
|
||||
|
|
|
@ -511,9 +511,65 @@ namespace vk
|
|||
return create_temporary_subresource_view(cmd, *source, gcm_format, x, y, w, h);
|
||||
}
|
||||
|
||||
vk::image_view* generate_cubemap_from_images(vk::command_buffer&, std::array<vk::image*, 6>& sources) override
|
||||
vk::image_view* generate_cubemap_from_images(vk::command_buffer& cmd, const u32 gcm_format, u16 size, std::array<vk::image*, 6>& sources) override
|
||||
{
|
||||
return nullptr;
|
||||
std::unique_ptr<vk::image> image;
|
||||
std::unique_ptr<vk::image_view> view;
|
||||
|
||||
image.reset(new vk::image(*vk::get_current_renderer(), m_memory_types.device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
VK_IMAGE_TYPE_2D,
|
||||
vk::get_compatible_sampler_format(gcm_format),
|
||||
size, size, 1, 1, 6, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT));
|
||||
|
||||
VkImageSubresourceRange subresource_range = {};
|
||||
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
for (u32 n = 0; n < 6; ++n)
|
||||
{
|
||||
if (!view)
|
||||
{
|
||||
switch (sources[0]->info.format)
|
||||
{
|
||||
case VK_FORMAT_D16_UNORM:
|
||||
aspect = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
break;
|
||||
case VK_FORMAT_D24_UNORM_S8_UINT:
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
break;
|
||||
}
|
||||
|
||||
VkImageSubresourceRange view_range = { aspect & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 1, 0, 6 };
|
||||
view.reset(new vk::image_view(*vk::get_current_renderer(), image->value, VK_IMAGE_VIEW_TYPE_CUBE, image->info.format, image->native_component_map, view_range));
|
||||
subresource_range = view_range;
|
||||
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresource_range);
|
||||
subresource_range.layerCount = 1;
|
||||
}
|
||||
|
||||
VkImageLayout old_src_layout = sources[n]->current_layout;
|
||||
vk::change_image_layout(cmd, sources[n], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresource_range);
|
||||
|
||||
VkImageCopy copy_rgn;
|
||||
copy_rgn.srcOffset = { 0, 0, 0 };
|
||||
copy_rgn.dstOffset = { 0, 0, 0 };
|
||||
copy_rgn.dstSubresource = { aspect, 0, n, 1 };
|
||||
copy_rgn.srcSubresource = { aspect, 0, 0, 1 };
|
||||
copy_rgn.extent = { size, size, 1 };
|
||||
|
||||
vkCmdCopyImage(cmd, sources[n]->value, sources[n]->current_layout, image->value, image->current_layout, 1, ©_rgn);
|
||||
vk::change_image_layout(cmd, sources[n], old_src_layout, subresource_range);
|
||||
}
|
||||
|
||||
subresource_range.layerCount = 6;
|
||||
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresource_range);
|
||||
|
||||
const u32 resource_memory = size * size * 6 * 4; //Rough approximate
|
||||
m_discardable_storage.push_back({ image, view });
|
||||
m_discardable_storage.back().block_size = resource_memory;
|
||||
m_discarded_memory_size += resource_memory;
|
||||
|
||||
return m_discardable_storage.back().view.get();
|
||||
}
|
||||
|
||||
cached_texture_section* create_new_texture(vk::command_buffer& cmd, u32 rsx_address, u32 rsx_size, u16 width, u16 height, u16 depth, u16 mipmaps, const u32 gcm_format,
|
||||
|
@ -732,7 +788,10 @@ namespace vk
|
|||
|
||||
inline vk::image_view* create_temporary_subresource(vk::command_buffer &cmd, deferred_subresource& desc)
|
||||
{
|
||||
return create_temporary_subresource_view(cmd, desc.external_handle, desc.gcm_format, desc.x, desc.y, desc.width, desc.height);
|
||||
if (!desc.is_cubemap)
|
||||
return create_temporary_subresource_view(cmd, desc.external_handle, desc.gcm_format, desc.x, desc.y, desc.width, desc.height);
|
||||
else
|
||||
return generate_cubemap_from_images(cmd, desc.gcm_format, desc.width, desc.external_cubemap_sources);
|
||||
}
|
||||
|
||||
bool is_depth_texture(const u32 rsx_address, const u32 rsx_size) override
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue