[D3D12] Allow different loading modes for unsigned and signed textures

This commit is contained in:
Triang3l
2018-11-14 13:51:20 +03:00
parent b4706054d0
commit 8ff03bcfa0
2 changed files with 339 additions and 229 deletions

View File

@@ -148,6 +148,7 @@ class TextureCache {
k64bpb,
k128bpb,
kR11G11B10ToRGBA16,
kR11G11B10ToRGBA16SNorm,
kDXT1ToRGBA8,
kDXT3ToRGBA8,
kDXT5ToRGBA8,
@@ -166,9 +167,6 @@ class TextureCache {
struct LoadModeInfo {
const void* shader;
size_t shader_size;
// TODO(Triang3l): Whether signed and integer textures need to be separate
// resources loaded differently than unorm textures (k_10_11_11,
// k_11_11_10 because they are expanded to R16G16B16A16).
};
// Tiling modes for storing textures after resolving - needed only for the
@@ -206,9 +204,16 @@ class TextureCache {
DXGI_FORMAT dxgi_format_resource;
// DXGI format for unsigned normalized or unsigned/signed float SRV.
DXGI_FORMAT dxgi_format_unorm;
// The regular load mode, used when special modes (like signed-specific or
// decompressing) aren't needed.
LoadMode load_mode;
// DXGI format for signed normalized or unsigned/signed float SRV.
DXGI_FORMAT dxgi_format_snorm;
LoadMode load_mode;
// If the signed version needs a different bit representation on the host,
// this is the load mode for the signed version. Otherwise the regular
// load_mode will be used for the signed version, and a single copy will be
// created if both unsigned and signed are used.
LoadMode load_mode_snorm;
// TODO(Triang3l): Integer formats.
@@ -247,6 +252,9 @@ class TextureCache {
uint32_t mip_max_level : 4; // 78
TextureFormat format : 6; // 84
Endian endianness : 2; // 86
// Whether this texture is signed and has a different host representation
// than an unsigned view of the same guest texture.
uint32_t signed_separate : 1; // 87
};
struct {
// The key used for unordered_multimap lookup. Single uint32_t instead of
@@ -279,7 +287,7 @@ class TextureCache {
map_key[0] = uint32_t(key);
map_key[1] = uint32_t(key >> 32);
}
inline bool IsInvalid() {
inline bool IsInvalid() const {
// Zero base and zero width is enough for a binding to be invalid.
return map_key[0] == 0;
}
@@ -377,9 +385,21 @@ class TextureCache {
bool has_unsigned;
// Whether the fetch has signed components.
bool has_signed;
// Unsigned version of the texture (or signed if they have the same data).
Texture* texture;
// Signed version of the texture if the data in the signed version is
// different on the host.
Texture* texture_signed;
};
// Whether the signed version of the texture has a different representation on
// the host than its unsigned version (for example, if it's a normalized or an
// integer texture emulated with a larger host pixel format).
static inline bool IsSignedVersionSeparate(TextureFormat format) {
const HostFormat& host_format = host_formats_[uint32_t(format)];
return host_format.load_mode_snorm != LoadMode::kUnknown &&
host_format.load_mode_snorm != host_format.load_mode;
}
// Whether decompression is needed on the host (Direct3D only allows creation
// of block-compressed textures with 4x4-aligned dimensions on PC).
static bool IsDecompressionNeeded(TextureFormat format, uint32_t width,