|
|
@ -19,6 +19,7 @@
|
|
|
|
#include "video_core/engines/kepler_compute.h"
|
|
|
|
#include "video_core/engines/kepler_compute.h"
|
|
|
|
#include "video_core/memory_manager.h"
|
|
|
|
#include "video_core/memory_manager.h"
|
|
|
|
#include "video_core/shader_environment.h"
|
|
|
|
#include "video_core/shader_environment.h"
|
|
|
|
|
|
|
|
#include "video_core/texture_cache/format_lookup_table.h"
|
|
|
|
#include "video_core/textures/texture.h"
|
|
|
|
#include "video_core/textures/texture.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace VideoCommon {
|
|
|
|
namespace VideoCommon {
|
|
|
@ -33,7 +34,7 @@ static u64 MakeCbufKey(u32 index, u32 offset) {
|
|
|
|
return (static_cast<u64>(index) << 32) | 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) {
|
|
|
|
switch (entry.texture_type) {
|
|
|
|
case Tegra::Texture::TextureType::Texture1D:
|
|
|
|
case Tegra::Texture::TextureType::Texture1D:
|
|
|
|
return Shader::TextureType::Color1D;
|
|
|
|
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) {
|
|
|
|
static std::string_view StageToPrefix(Shader::Stage stage) {
|
|
|
|
switch (stage) {
|
|
|
|
switch (stage) {
|
|
|
|
case Shader::Stage::VertexB:
|
|
|
|
case Shader::Stage::VertexB:
|
|
|
@ -178,10 +199,13 @@ void GenericEnvironment::Dump(u64 hash) {
|
|
|
|
void GenericEnvironment::Serialize(std::ofstream& file) const {
|
|
|
|
void GenericEnvironment::Serialize(std::ofstream& file) const {
|
|
|
|
const u64 code_size{static_cast<u64>(CachedSize())};
|
|
|
|
const u64 code_size{static_cast<u64>(CachedSize())};
|
|
|
|
const u64 num_texture_types{static_cast<u64>(texture_types.size())};
|
|
|
|
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())};
|
|
|
|
const u64 num_cbuf_values{static_cast<u64>(cbuf_values.size())};
|
|
|
|
|
|
|
|
|
|
|
|
file.write(reinterpret_cast<const char*>(&code_size), sizeof(code_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_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*>(&num_cbuf_values), sizeof(num_cbuf_values))
|
|
|
|
.write(reinterpret_cast<const char*>(&local_memory_size), sizeof(local_memory_size))
|
|
|
|
.write(reinterpret_cast<const char*>(&local_memory_size), sizeof(local_memory_size))
|
|
|
|
.write(reinterpret_cast<const char*>(&texture_bound), sizeof(texture_bound))
|
|
|
|
.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))
|
|
|
|
file.write(reinterpret_cast<const char*>(&key), sizeof(key))
|
|
|
|
.write(reinterpret_cast<const char*>(&type), sizeof(type));
|
|
|
|
.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) {
|
|
|
|
for (const auto& [key, type] : cbuf_values) {
|
|
|
|
file.write(reinterpret_cast<const char*>(&key), sizeof(key))
|
|
|
|
file.write(reinterpret_cast<const char*>(&key), sizeof(key))
|
|
|
|
.write(reinterpret_cast<const char*>(&type), sizeof(type));
|
|
|
|
.write(reinterpret_cast<const char*>(&type), sizeof(type));
|
|
|
@ -239,15 +267,13 @@ std::optional<u64> GenericEnvironment::TryFindSize() {
|
|
|
|
return std::nullopt;
|
|
|
|
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) {
|
|
|
|
bool via_header_index, u32 raw) {
|
|
|
|
const auto handle{Tegra::Texture::TexturePair(raw, via_header_index)};
|
|
|
|
const auto handle{Tegra::Texture::TexturePair(raw, via_header_index)};
|
|
|
|
const GPUVAddr descriptor_addr{tic_addr + handle.first * sizeof(Tegra::Texture::TICEntry)};
|
|
|
|
const GPUVAddr descriptor_addr{tic_addr + handle.first * sizeof(Tegra::Texture::TICEntry)};
|
|
|
|
Tegra::Texture::TICEntry entry;
|
|
|
|
Tegra::Texture::TICEntry entry;
|
|
|
|
gpu_memory->ReadBlock(descriptor_addr, &entry, sizeof(entry));
|
|
|
|
gpu_memory->ReadBlock(descriptor_addr, &entry, sizeof(entry));
|
|
|
|
const Shader::TextureType result{ConvertType(entry)};
|
|
|
|
return entry;
|
|
|
|
texture_types.emplace(raw, result);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_,
|
|
|
|
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) {
|
|
|
|
Shader::TextureType GraphicsEnvironment::ReadTextureType(u32 handle) {
|
|
|
|
const auto& regs{maxwell3d->regs};
|
|
|
|
const auto& regs{maxwell3d->regs};
|
|
|
|
const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding};
|
|
|
|
const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding};
|
|
|
|
return ReadTextureTypeImpl(regs.tex_header.Address(), regs.tex_header.limit, via_header_index,
|
|
|
|
auto entry =
|
|
|
|
handle);
|
|
|
|
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() {
|
|
|
|
u32 GraphicsEnvironment::ReadViewportTransformState() {
|
|
|
|
const auto& regs{maxwell3d->regs};
|
|
|
|
const auto& regs{maxwell3d->regs};
|
|
|
|
viewport_transform_state = regs.viewport_transform_enabled;
|
|
|
|
viewport_transform_state = regs.viewport_scale_offset_enbled;
|
|
|
|
return viewport_transform_state;
|
|
|
|
return viewport_transform_state;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -345,7 +384,19 @@ u32 ComputeEnvironment::ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) {
|
|
|
|
Shader::TextureType ComputeEnvironment::ReadTextureType(u32 handle) {
|
|
|
|
Shader::TextureType ComputeEnvironment::ReadTextureType(u32 handle) {
|
|
|
|
const auto& regs{kepler_compute->regs};
|
|
|
|
const auto& regs{kepler_compute->regs};
|
|
|
|
const auto& qmd{kepler_compute->launch_description};
|
|
|
|
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() {
|
|
|
|
u32 ComputeEnvironment::ReadViewportTransformState() {
|
|
|
@ -355,9 +406,12 @@ u32 ComputeEnvironment::ReadViewportTransformState() {
|
|
|
|
void FileEnvironment::Deserialize(std::ifstream& file) {
|
|
|
|
void FileEnvironment::Deserialize(std::ifstream& file) {
|
|
|
|
u64 code_size{};
|
|
|
|
u64 code_size{};
|
|
|
|
u64 num_texture_types{};
|
|
|
|
u64 num_texture_types{};
|
|
|
|
|
|
|
|
u64 num_texture_pixel_formats{};
|
|
|
|
u64 num_cbuf_values{};
|
|
|
|
u64 num_cbuf_values{};
|
|
|
|
file.read(reinterpret_cast<char*>(&code_size), sizeof(code_size))
|
|
|
|
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_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*>(&num_cbuf_values), sizeof(num_cbuf_values))
|
|
|
|
.read(reinterpret_cast<char*>(&local_memory_size), sizeof(local_memory_size))
|
|
|
|
.read(reinterpret_cast<char*>(&local_memory_size), sizeof(local_memory_size))
|
|
|
|
.read(reinterpret_cast<char*>(&texture_bound), sizeof(texture_bound))
|
|
|
|
.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));
|
|
|
|
.read(reinterpret_cast<char*>(&type), sizeof(type));
|
|
|
|
texture_types.emplace(key, 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) {
|
|
|
|
for (size_t i = 0; i < num_cbuf_values; ++i) {
|
|
|
|
u64 key;
|
|
|
|
u64 key;
|
|
|
|
u32 value;
|
|
|
|
u32 value;
|
|
|
@ -422,6 +483,14 @@ Shader::TextureType FileEnvironment::ReadTextureType(u32 handle) {
|
|
|
|
return it->second;
|
|
|
|
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() {
|
|
|
|
u32 FileEnvironment::ReadViewportTransformState() {
|
|
|
|
return viewport_transform_state;
|
|
|
|
return viewport_transform_state;
|
|
|
|
}
|
|
|
|
}
|
|
|
|