rpcsx/rpcs3/Emu/RSX/Common/TextureUtils.h
kd-11 aa3eeaa417 rsx: Separate subresource_layout:dim_in_block and
subresource_layout::dim_in_texel

- These two are not always linked when working with compressed textures.
The actual texels extend past the actual size of the image if the size
is not aligned. e.g if height is 1, the real height is 4, but its not
possible to determine this from the aligned size. It could be 1, 2, 3 or
4 for example.
- Fixes image out-of-bounds writes when uploading from CPU
2019-10-29 20:03:54 +03:00

166 lines
4.2 KiB
C++

#pragma once
#include "../RSXTexture.h"
#include <vector>
#include "Utilities/GSL.h"
namespace rsx
{
enum texture_upload_context : u32
{
shader_read = 1,
blit_engine_src = 2,
blit_engine_dst = 4,
framebuffer_storage = 8,
dma = 16
};
enum texture_colorspace : u32
{
rgb_linear = 0,
srgb_nonlinear = 1
};
enum surface_usage_flags : u32
{
unknown = 0,
attachment = 1,
storage = 2,
};
enum surface_metrics : u32
{
pixels = 0,
samples = 1,
bytes = 2
};
enum surface_access : u32
{
read = 0,
write = 1,
transfer = 2
};
enum format_type : u8
{
color = 0,
depth_uint = 1,
depth_float = 2
};
//Sampled image descriptor
struct sampled_image_descriptor_base
{
texture_upload_context upload_context = texture_upload_context::shader_read;
rsx::texture_dimension_extended image_type = texture_dimension_extended::texture_dimension_2d;
rsx::format_type format_class = rsx::format_type::color;
bool is_cyclic_reference = false;
f32 scale_x = 1.f;
f32 scale_y = 1.f;
virtual ~sampled_image_descriptor_base() = default;
virtual u32 encoded_component_map() const = 0;
};
struct typeless_xfer
{
bool src_is_typeless = false;
bool dst_is_typeless = false;
bool src_is_depth = false;
bool dst_is_depth = false;
bool flip_vertical = false;
bool flip_horizontal = false;
u32 src_gcm_format = 0;
u32 dst_gcm_format = 0;
u32 src_native_format_override = 0;
u32 dst_native_format_override = 0;
f32 src_scaling_hint = 1.f;
f32 dst_scaling_hint = 1.f;
texture_upload_context src_context = texture_upload_context::blit_engine_src;
texture_upload_context dst_context = texture_upload_context::blit_engine_dst;
void analyse();
};
}
struct rsx_subresource_layout
{
gsl::span<const gsl::byte> data;
u16 width_in_texel;
u16 height_in_texel;
u16 width_in_block;
u16 height_in_block;
u16 depth;
u16 level;
u16 layer;
u8 border;
u8 reserved;
u32 pitch_in_block;
};
struct texture_memory_info
{
int element_size;
bool require_swap;
};
struct texture_uploader_capabilities
{
bool supports_byteswap;
bool supports_vtc_decoding;
size_t alignment;
};
/**
* Get size to store texture in a linear fashion.
* Storage is assumed to use a rowPitchAlignment boundary for every row of texture.
*/
size_t get_placed_texture_storage_size(u16 width, u16 height, u32 depth, u8 format, u16 mipmap, bool cubemap, size_t row_pitch_alignment, size_t mipmap_alignment);
size_t get_placed_texture_storage_size(const rsx::fragment_texture &texture, size_t row_pitch_alignment, size_t mipmap_alignment = 0x200);
size_t get_placed_texture_storage_size(const rsx::vertex_texture &texture, size_t row_pitch_alignment, size_t mipmap_alignment = 0x200);
/**
* get all rsx_subresource_layout for texture.
* The subresources are ordered per layer then per mipmap level (as in rsx memory).
*/
std::vector<rsx_subresource_layout> get_subresources_layout(const rsx::fragment_texture &texture);
std::vector<rsx_subresource_layout> get_subresources_layout(const rsx::vertex_texture &texture);
texture_memory_info upload_texture_subresource(gsl::span<gsl::byte> dst_buffer, const rsx_subresource_layout &src_layout, int format, bool is_swizzled, const texture_uploader_capabilities& caps);
u8 get_format_block_size_in_bytes(int format);
u8 get_format_block_size_in_texel(int format);
u8 get_format_block_size_in_bytes(rsx::surface_color_format format);
u8 get_format_sample_count(rsx::surface_antialiasing antialias);
/**
* Returns number of texel rows encoded in one pitch-length line of bytes
*/
u8 get_format_texel_rows_per_line(u32 format);
/**
* Get number of bytes occupied by texture in RSX mem
*/
size_t get_texture_size(const rsx::fragment_texture &texture);
size_t get_texture_size(const rsx::vertex_texture &texture);
/**
* Get packed pitch
*/
u32 get_format_packed_pitch(u32 format, u16 width, bool border = false, bool swizzled = false);
/**
* Reverse encoding
*/
u32 get_remap_encoding(const std::pair<std::array<u8, 4>, std::array<u8, 4>>& remap);
/**
* Get gcm texel layout. Returns <format, byteswapped>
*/
std::pair<u32, bool> get_compatible_gcm_format(rsx::surface_color_format format);
std::pair<u32, bool> get_compatible_gcm_format(rsx::surface_depth_format format);