|
|
|
@ -19,6 +19,7 @@ |
|
|
|
#include "video_core/engines/kepler_compute.h"
|
|
|
|
#include "video_core/memory_manager.h"
|
|
|
|
#include "video_core/shader_environment.h"
|
|
|
|
#include "video_core/texture_cache/format_lookup_table.h"
|
|
|
|
#include "video_core/textures/texture.h"
|
|
|
|
|
|
|
|
namespace VideoCommon { |
|
|
|
@ -33,7 +34,7 @@ static u64 MakeCbufKey(u32 index, u32 offset) { |
|
|
|
return (static_cast<u64>(index) << 32) | offset; |
|
|
|
} |
|
|
|
|
|
|
|
static Shader::TextureType ConvertType(const Tegra::Texture::TICEntry& entry) { |
|
|
|
static Shader::TextureType ConvertTextureType(const Tegra::Texture::TICEntry& entry) { |
|
|
|
switch (entry.texture_type) { |
|
|
|
case Tegra::Texture::TextureType::Texture1D: |
|
|
|
return Shader::TextureType::Color1D; |
|
|
|
@ -59,6 +60,26 @@ static Shader::TextureType ConvertType(const Tegra::Texture::TICEntry& entry) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static Shader::TexturePixelFormat ConvertTexturePixelFormat(const Tegra::Texture::TICEntry& entry) { |
|
|
|
switch (PixelFormatFromTextureInfo(entry.format, entry.r_type, entry.g_type, entry.b_type, |
|
|
|
entry.a_type, entry.srgb_conversion)) { |
|
|
|
case VideoCore::Surface::PixelFormat::A8B8G8R8_SNORM: |
|
|
|
return Shader::TexturePixelFormat::A8B8G8R8_SNORM; |
|
|
|
case VideoCore::Surface::PixelFormat::R8_SNORM: |
|
|
|
return Shader::TexturePixelFormat::R8_SNORM; |
|
|
|
case VideoCore::Surface::PixelFormat::R8G8_SNORM: |
|
|
|
return Shader::TexturePixelFormat::R8G8_SNORM; |
|
|
|
case VideoCore::Surface::PixelFormat::R16G16B16A16_SNORM: |
|
|
|
return Shader::TexturePixelFormat::R16G16B16A16_SNORM; |
|
|
|
case VideoCore::Surface::PixelFormat::R16G16_SNORM: |
|
|
|
return Shader::TexturePixelFormat::R16G16_SNORM; |
|
|
|
case VideoCore::Surface::PixelFormat::R16_SNORM: |
|
|
|
return Shader::TexturePixelFormat::R16_SNORM; |
|
|
|
default: |
|
|
|
return Shader::TexturePixelFormat::OTHER; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static std::string_view StageToPrefix(Shader::Stage stage) { |
|
|
|
switch (stage) { |
|
|
|
case Shader::Stage::VertexB: |
|
|
|
@ -178,10 +199,13 @@ void GenericEnvironment::Dump(u64 hash) { |
|
|
|
void GenericEnvironment::Serialize(std::ofstream& file) const { |
|
|
|
const u64 code_size{static_cast<u64>(CachedSize())}; |
|
|
|
const u64 num_texture_types{static_cast<u64>(texture_types.size())}; |
|
|
|
const u64 num_texture_pixel_formats{static_cast<u64>(texture_pixel_formats.size())}; |
|
|
|
const u64 num_cbuf_values{static_cast<u64>(cbuf_values.size())}; |
|
|
|
|
|
|
|
file.write(reinterpret_cast<const char*>(&code_size), sizeof(code_size)) |
|
|
|
.write(reinterpret_cast<const char*>(&num_texture_types), sizeof(num_texture_types)) |
|
|
|
.write(reinterpret_cast<const char*>(&num_texture_pixel_formats), |
|
|
|
sizeof(num_texture_pixel_formats)) |
|
|
|
.write(reinterpret_cast<const char*>(&num_cbuf_values), sizeof(num_cbuf_values)) |
|
|
|
.write(reinterpret_cast<const char*>(&local_memory_size), sizeof(local_memory_size)) |
|
|
|
.write(reinterpret_cast<const char*>(&texture_bound), sizeof(texture_bound)) |
|
|
|
@ -196,6 +220,10 @@ void GenericEnvironment::Serialize(std::ofstream& file) const { |
|
|
|
file.write(reinterpret_cast<const char*>(&key), sizeof(key)) |
|
|
|
.write(reinterpret_cast<const char*>(&type), sizeof(type)); |
|
|
|
} |
|
|
|
for (const auto& [key, format] : texture_pixel_formats) { |
|
|
|
file.write(reinterpret_cast<const char*>(&key), sizeof(key)) |
|
|
|
.write(reinterpret_cast<const char*>(&format), sizeof(format)); |
|
|
|
} |
|
|
|
for (const auto& [key, type] : cbuf_values) { |
|
|
|
file.write(reinterpret_cast<const char*>(&key), sizeof(key)) |
|
|
|
.write(reinterpret_cast<const char*>(&type), sizeof(type)); |
|
|
|
@ -239,15 +267,13 @@ std::optional<u64> GenericEnvironment::TryFindSize() { |
|
|
|
return std::nullopt; |
|
|
|
} |
|
|
|
|
|
|
|
Shader::TextureType GenericEnvironment::ReadTextureTypeImpl(GPUVAddr tic_addr, u32 tic_limit, |
|
|
|
Tegra::Texture::TICEntry GenericEnvironment::ReadTextureInfo(GPUVAddr tic_addr, u32 tic_limit, |
|
|
|
bool via_header_index, u32 raw) { |
|
|
|
const auto handle{Tegra::Texture::TexturePair(raw, via_header_index)}; |
|
|
|
const GPUVAddr descriptor_addr{tic_addr + handle.first * sizeof(Tegra::Texture::TICEntry)}; |
|
|
|
Tegra::Texture::TICEntry entry; |
|
|
|
gpu_memory->ReadBlock(descriptor_addr, &entry, sizeof(entry)); |
|
|
|
const Shader::TextureType result{ConvertType(entry)}; |
|
|
|
texture_types.emplace(raw, result); |
|
|
|
return result; |
|
|
|
return entry; |
|
|
|
} |
|
|
|
|
|
|
|
GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_, |
|
|
|
@ -307,13 +333,26 @@ u32 GraphicsEnvironment::ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) { |
|
|
|
Shader::TextureType GraphicsEnvironment::ReadTextureType(u32 handle) { |
|
|
|
const auto& regs{maxwell3d->regs}; |
|
|
|
const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding}; |
|
|
|
return ReadTextureTypeImpl(regs.tex_header.Address(), regs.tex_header.limit, via_header_index, |
|
|
|
handle); |
|
|
|
auto entry = |
|
|
|
ReadTextureInfo(regs.tex_header.Address(), regs.tex_header.limit, via_header_index, handle); |
|
|
|
const Shader::TextureType result{ConvertTextureType(entry)}; |
|
|
|
texture_types.emplace(handle, result); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
Shader::TexturePixelFormat GraphicsEnvironment::ReadTexturePixelFormat(u32 handle) { |
|
|
|
const auto& regs{maxwell3d->regs}; |
|
|
|
const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding}; |
|
|
|
auto entry = |
|
|
|
ReadTextureInfo(regs.tex_header.Address(), regs.tex_header.limit, via_header_index, handle); |
|
|
|
const Shader::TexturePixelFormat result(ConvertTexturePixelFormat(entry)); |
|
|
|
texture_pixel_formats.emplace(handle, result); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
u32 GraphicsEnvironment::ReadViewportTransformState() { |
|
|
|
const auto& regs{maxwell3d->regs}; |
|
|
|
viewport_transform_state = regs.viewport_transform_enabled; |
|
|
|
viewport_transform_state = regs.viewport_scale_offset_enbled; |
|
|
|
return viewport_transform_state; |
|
|
|
} |
|
|
|
|
|
|
|
@ -345,7 +384,19 @@ u32 ComputeEnvironment::ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) { |
|
|
|
Shader::TextureType ComputeEnvironment::ReadTextureType(u32 handle) { |
|
|
|
const auto& regs{kepler_compute->regs}; |
|
|
|
const auto& qmd{kepler_compute->launch_description}; |
|
|
|
return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, qmd.linked_tsc != 0, handle); |
|
|
|
auto entry = ReadTextureInfo(regs.tic.Address(), regs.tic.limit, qmd.linked_tsc != 0, handle); |
|
|
|
const Shader::TextureType result{ConvertTextureType(entry)}; |
|
|
|
texture_types.emplace(handle, result); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
Shader::TexturePixelFormat ComputeEnvironment::ReadTexturePixelFormat(u32 handle) { |
|
|
|
const auto& regs{kepler_compute->regs}; |
|
|
|
const auto& qmd{kepler_compute->launch_description}; |
|
|
|
auto entry = ReadTextureInfo(regs.tic.Address(), regs.tic.limit, qmd.linked_tsc != 0, handle); |
|
|
|
const Shader::TexturePixelFormat result(ConvertTexturePixelFormat(entry)); |
|
|
|
texture_pixel_formats.emplace(handle, result); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
u32 ComputeEnvironment::ReadViewportTransformState() { |
|
|
|
@ -355,9 +406,12 @@ u32 ComputeEnvironment::ReadViewportTransformState() { |
|
|
|
void FileEnvironment::Deserialize(std::ifstream& file) { |
|
|
|
u64 code_size{}; |
|
|
|
u64 num_texture_types{}; |
|
|
|
u64 num_texture_pixel_formats{}; |
|
|
|
u64 num_cbuf_values{}; |
|
|
|
file.read(reinterpret_cast<char*>(&code_size), sizeof(code_size)) |
|
|
|
.read(reinterpret_cast<char*>(&num_texture_types), sizeof(num_texture_types)) |
|
|
|
.read(reinterpret_cast<char*>(&num_texture_pixel_formats), |
|
|
|
sizeof(num_texture_pixel_formats)) |
|
|
|
.read(reinterpret_cast<char*>(&num_cbuf_values), sizeof(num_cbuf_values)) |
|
|
|
.read(reinterpret_cast<char*>(&local_memory_size), sizeof(local_memory_size)) |
|
|
|
.read(reinterpret_cast<char*>(&texture_bound), sizeof(texture_bound)) |
|
|
|
@ -375,6 +429,13 @@ void FileEnvironment::Deserialize(std::ifstream& file) { |
|
|
|
.read(reinterpret_cast<char*>(&type), sizeof(type)); |
|
|
|
texture_types.emplace(key, type); |
|
|
|
} |
|
|
|
for (size_t i = 0; i < num_texture_pixel_formats; ++i) { |
|
|
|
u32 key; |
|
|
|
Shader::TexturePixelFormat format; |
|
|
|
file.read(reinterpret_cast<char*>(&key), sizeof(key)) |
|
|
|
.read(reinterpret_cast<char*>(&format), sizeof(format)); |
|
|
|
texture_pixel_formats.emplace(key, format); |
|
|
|
} |
|
|
|
for (size_t i = 0; i < num_cbuf_values; ++i) { |
|
|
|
u64 key; |
|
|
|
u32 value; |
|
|
|
@ -422,6 +483,14 @@ Shader::TextureType FileEnvironment::ReadTextureType(u32 handle) { |
|
|
|
return it->second; |
|
|
|
} |
|
|
|
|
|
|
|
Shader::TexturePixelFormat FileEnvironment::ReadTexturePixelFormat(u32 handle) { |
|
|
|
const auto it{texture_pixel_formats.find(handle)}; |
|
|
|
if (it == texture_pixel_formats.end()) { |
|
|
|
throw Shader::LogicError("Uncached read texture pixel format"); |
|
|
|
} |
|
|
|
return it->second; |
|
|
|
} |
|
|
|
|
|
|
|
u32 FileEnvironment::ReadViewportTransformState() { |
|
|
|
return viewport_transform_state; |
|
|
|
} |
|
|
|
|