gl_rasterizer: Implement image bindings

This commit is contained in:
ReinUsesLisp 2019-07-12 02:01:27 -03:00
parent 5edf24b510
commit 6170337001
5 changed files with 106 additions and 32 deletions

View File

@ -62,6 +62,7 @@ public:
static constexpr std::size_t NumVertexAttributes = 32; static constexpr std::size_t NumVertexAttributes = 32;
static constexpr std::size_t NumVaryings = 31; static constexpr std::size_t NumVaryings = 31;
static constexpr std::size_t NumTextureSamplers = 32; static constexpr std::size_t NumTextureSamplers = 32;
static constexpr std::size_t NumImages = 8; // TODO(Rodrigo): Investigate this number
static constexpr std::size_t NumClipDistances = 8; static constexpr std::size_t NumClipDistances = 8;
static constexpr std::size_t MaxShaderProgram = 6; static constexpr std::size_t MaxShaderProgram = 6;
static constexpr std::size_t MaxShaderStage = 5; static constexpr std::size_t MaxShaderStage = 5;

View File

@ -1022,7 +1022,7 @@ bool RasterizerOpenGL::SetupTexture(const Shader& shader, u32 binding,
auto& unit{state.texture_units[binding]}; auto& unit{state.texture_units[binding]};
unit.sampler = sampler_cache.GetSampler(texture.tsc); unit.sampler = sampler_cache.GetSampler(texture.tsc);
const auto view = texture_cache.GetImageSurface(texture.tic, entry); const auto view = texture_cache.GetTextureSurface(texture.tic, entry);
if (!view) { if (!view) {
// Can occur when texture addr is null or its memory is unmapped/invalid // Can occur when texture addr is null or its memory is unmapped/invalid
unit.texture = 0; unit.texture = 0;
@ -1054,7 +1054,12 @@ void RasterizerOpenGL::SetupComputeImages(const Shader& shader) {
tex_handle.raw = compute.AccessConstBuffer32(cbuf.first, cbuf.second); tex_handle.raw = compute.AccessConstBuffer32(cbuf.first, cbuf.second);
return compute.GetTextureInfo(tex_handle, entry.GetOffset()); return compute.GetTextureInfo(tex_handle, entry.GetOffset());
}(); }();
UNIMPLEMENTED(); const auto view = texture_cache.GetImageSurface(texture.tic, entry);
if (!view) {
state.images[bindpoint] = 0;
continue;
}
state.images[bindpoint] = view->GetTexture();
} }
} }

View File

@ -24,44 +24,52 @@ using VideoCore::Surface::SurfaceTarget;
using VideoCore::Surface::SurfaceTargetFromTextureType; using VideoCore::Surface::SurfaceTargetFromTextureType;
using VideoCore::Surface::SurfaceType; using VideoCore::Surface::SurfaceType;
SurfaceTarget TextureType2SurfaceTarget(Tegra::Shader::TextureType type, bool is_array) { namespace {
SurfaceTarget TextureTypeToSurfaceTarget(Tegra::Shader::TextureType type, bool is_array) {
switch (type) { switch (type) {
case Tegra::Shader::TextureType::Texture1D: { case Tegra::Shader::TextureType::Texture1D:
if (is_array) return is_array ? SurfaceTarget::Texture1DArray : SurfaceTarget::Texture1D;
return SurfaceTarget::Texture1DArray; case Tegra::Shader::TextureType::Texture2D:
else return is_array ? SurfaceTarget::Texture2DArray : SurfaceTarget::Texture2D;
return SurfaceTarget::Texture1D; case Tegra::Shader::TextureType::Texture3D:
}
case Tegra::Shader::TextureType::Texture2D: {
if (is_array)
return SurfaceTarget::Texture2DArray;
else
return SurfaceTarget::Texture2D;
}
case Tegra::Shader::TextureType::Texture3D: {
ASSERT(!is_array); ASSERT(!is_array);
return SurfaceTarget::Texture3D; return SurfaceTarget::Texture3D;
} case Tegra::Shader::TextureType::TextureCube:
case Tegra::Shader::TextureType::TextureCube: { return is_array ? SurfaceTarget::TextureCubeArray : SurfaceTarget::TextureCubemap;
if (is_array) default:
return SurfaceTarget::TextureCubeArray;
else
return SurfaceTarget::TextureCubemap;
}
default: {
UNREACHABLE(); UNREACHABLE();
return SurfaceTarget::Texture2D; return SurfaceTarget::Texture2D;
} }
} }
SurfaceTarget ImageTypeToSurfaceTarget(Tegra::Shader::ImageType type) {
switch (type) {
case Tegra::Shader::ImageType::Texture1D:
return SurfaceTarget::Texture1D;
case Tegra::Shader::ImageType::TextureBuffer:
return SurfaceTarget::TextureBuffer;
case Tegra::Shader::ImageType::Texture1DArray:
return SurfaceTarget::Texture1DArray;
case Tegra::Shader::ImageType::Texture2D:
return SurfaceTarget::Texture2D;
case Tegra::Shader::ImageType::Texture2DArray:
return SurfaceTarget::Texture2DArray;
case Tegra::Shader::ImageType::Texture3D:
return SurfaceTarget::Texture3D;
default:
UNREACHABLE();
return SurfaceTarget::Texture2D;
}
} }
namespace {
constexpr u32 GetMipmapSize(bool uncompressed, u32 mip_size, u32 tile) { constexpr u32 GetMipmapSize(bool uncompressed, u32 mip_size, u32 tile) {
return uncompressed ? mip_size : std::max(1U, (mip_size + tile - 1) / tile); return uncompressed ? mip_size : std::max(1U, (mip_size + tile - 1) / tile);
} }
} // Anonymous namespace } // Anonymous namespace
SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic, SurfaceParams SurfaceParams::CreateForTexture(const Tegra::Texture::TICEntry& tic,
const VideoCommon::Shader::Sampler& entry) { const VideoCommon::Shader::Sampler& entry) {
SurfaceParams params; SurfaceParams params;
params.is_tiled = tic.IsTiled(); params.is_tiled = tic.IsTiled();
@ -94,8 +102,17 @@ SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic,
params.component_type = ComponentTypeFromTexture(tic.r_type.Value()); params.component_type = ComponentTypeFromTexture(tic.r_type.Value());
params.type = GetFormatType(params.pixel_format); params.type = GetFormatType(params.pixel_format);
// TODO: on 1DBuffer we should use the tic info. // TODO: on 1DBuffer we should use the tic info.
if (!tic.IsBuffer()) { if (tic.IsBuffer()) {
params.target = TextureType2SurfaceTarget(entry.GetType(), entry.IsArray()); params.target = SurfaceTarget::TextureBuffer;
params.width = tic.Width();
params.pitch = params.width * params.GetBytesPerPixel();
params.height = 1;
params.depth = 1;
params.num_levels = 1;
params.emulated_levels = 1;
params.is_layered = false;
} else {
params.target = TextureTypeToSurfaceTarget(entry.GetType(), entry.IsArray());
params.width = tic.Width(); params.width = tic.Width();
params.height = tic.Height(); params.height = tic.Height();
params.depth = tic.Depth(); params.depth = tic.Depth();
@ -107,7 +124,27 @@ SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic,
params.num_levels = tic.max_mip_level + 1; params.num_levels = tic.max_mip_level + 1;
params.emulated_levels = std::min(params.num_levels, params.MaxPossibleMipmap()); params.emulated_levels = std::min(params.num_levels, params.MaxPossibleMipmap());
params.is_layered = params.IsLayered(); params.is_layered = params.IsLayered();
} else { }
return params;
}
SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic,
const VideoCommon::Shader::Image& entry) {
SurfaceParams params;
params.is_tiled = tic.IsTiled();
params.srgb_conversion = tic.IsSrgbConversionEnabled();
params.block_width = params.is_tiled ? tic.BlockWidth() : 0,
params.block_height = params.is_tiled ? tic.BlockHeight() : 0,
params.block_depth = params.is_tiled ? tic.BlockDepth() : 0,
params.tile_width_spacing = params.is_tiled ? (1 << tic.tile_width_spacing.Value()) : 1;
params.pixel_format =
PixelFormatFromTextureFormat(tic.format, tic.r_type.Value(), params.srgb_conversion);
params.type = GetFormatType(params.pixel_format);
params.component_type = ComponentTypeFromTexture(tic.r_type.Value());
params.type = GetFormatType(params.pixel_format);
params.target = ImageTypeToSurfaceTarget(entry.GetType());
// TODO: on 1DBuffer we should use the tic info.
if (tic.IsBuffer()) {
params.target = SurfaceTarget::TextureBuffer; params.target = SurfaceTarget::TextureBuffer;
params.width = tic.Width(); params.width = tic.Width();
params.pitch = params.width * params.GetBytesPerPixel(); params.pitch = params.width * params.GetBytesPerPixel();
@ -116,6 +153,18 @@ SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic,
params.num_levels = 1; params.num_levels = 1;
params.emulated_levels = 1; params.emulated_levels = 1;
params.is_layered = false; params.is_layered = false;
} else {
params.width = tic.Width();
params.height = tic.Height();
params.depth = tic.Depth();
params.pitch = params.is_tiled ? 0 : tic.Pitch();
if (params.target == SurfaceTarget::TextureCubemap ||
params.target == SurfaceTarget::TextureCubeArray) {
params.depth *= 6;
}
params.num_levels = tic.max_mip_level + 1;
params.emulated_levels = std::min(params.num_levels, params.MaxPossibleMipmap());
params.is_layered = params.IsLayered();
} }
return params; return params;
} }

View File

@ -23,9 +23,13 @@ using VideoCore::Surface::SurfaceCompression;
class SurfaceParams { class SurfaceParams {
public: public:
/// Creates SurfaceCachedParams from a texture configuration. /// Creates SurfaceCachedParams from a texture configuration.
static SurfaceParams CreateForImage(const Tegra::Texture::TICEntry& tic, static SurfaceParams CreateForTexture(const Tegra::Texture::TICEntry& tic,
const VideoCommon::Shader::Sampler& entry); const VideoCommon::Shader::Sampler& entry);
/// Creates SurfaceCachedParams from an image configuration.
static SurfaceParams CreateForImage(const Tegra::Texture::TICEntry& tic,
const VideoCommon::Shader::Image& entry);
/// Creates SurfaceCachedParams for a depth buffer configuration. /// Creates SurfaceCachedParams for a depth buffer configuration.
static SurfaceParams CreateForDepthBuffer( static SurfaceParams CreateForDepthBuffer(
Core::System& system, u32 zeta_width, u32 zeta_height, Tegra::DepthFormat format, Core::System& system, u32 zeta_width, u32 zeta_height, Tegra::DepthFormat format,

View File

@ -89,13 +89,28 @@ public:
} }
} }
TView GetImageSurface(const Tegra::Texture::TICEntry& tic, TView GetTextureSurface(const Tegra::Texture::TICEntry& tic,
const VideoCommon::Shader::Sampler& entry) { const VideoCommon::Shader::Sampler& entry) {
std::lock_guard lock{mutex}; std::lock_guard lock{mutex};
const auto gpu_addr{tic.Address()}; const auto gpu_addr{tic.Address()};
if (!gpu_addr) { if (!gpu_addr) {
return {}; return {};
} }
const auto params{SurfaceParams::CreateForTexture(tic, entry)};
const auto [surface, view] = GetSurface(gpu_addr, params, true, false);
if (guard_samplers) {
sampled_textures.push_back(surface);
}
return view;
}
TView GetImageSurface(const Tegra::Texture::TICEntry& tic,
const VideoCommon::Shader::Image& entry) {
std::lock_guard lock{mutex};
const auto gpu_addr{tic.Address()};
if (!gpu_addr) {
return {};
}
const auto params{SurfaceParams::CreateForImage(tic, entry)}; const auto params{SurfaceParams::CreateForImage(tic, entry)};
const auto [surface, view] = GetSurface(gpu_addr, params, true, false); const auto [surface, view] = GetSurface(gpu_addr, params, true, false);
if (guard_samplers) { if (guard_samplers) {