mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-03 16:39:01 -06:00 
			
		
		
		
	gl_rasterizer: Implement image bindings
This commit is contained in:
		@@ -62,6 +62,7 @@ public:
 | 
			
		||||
        static constexpr std::size_t NumVertexAttributes = 32;
 | 
			
		||||
        static constexpr std::size_t NumVaryings = 31;
 | 
			
		||||
        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 MaxShaderProgram = 6;
 | 
			
		||||
        static constexpr std::size_t MaxShaderStage = 5;
 | 
			
		||||
 
 | 
			
		||||
@@ -1022,7 +1022,7 @@ bool RasterizerOpenGL::SetupTexture(const Shader& shader, u32 binding,
 | 
			
		||||
    auto& unit{state.texture_units[binding]};
 | 
			
		||||
    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) {
 | 
			
		||||
        // Can occur when texture addr is null or its memory is unmapped/invalid
 | 
			
		||||
        unit.texture = 0;
 | 
			
		||||
@@ -1054,7 +1054,12 @@ void RasterizerOpenGL::SetupComputeImages(const Shader& shader) {
 | 
			
		||||
            tex_handle.raw = compute.AccessConstBuffer32(cbuf.first, cbuf.second);
 | 
			
		||||
            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();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,45 +24,53 @@ using VideoCore::Surface::SurfaceTarget;
 | 
			
		||||
using VideoCore::Surface::SurfaceTargetFromTextureType;
 | 
			
		||||
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) {
 | 
			
		||||
    case Tegra::Shader::TextureType::Texture1D: {
 | 
			
		||||
        if (is_array)
 | 
			
		||||
            return SurfaceTarget::Texture1DArray;
 | 
			
		||||
        else
 | 
			
		||||
            return SurfaceTarget::Texture1D;
 | 
			
		||||
    }
 | 
			
		||||
    case Tegra::Shader::TextureType::Texture2D: {
 | 
			
		||||
        if (is_array)
 | 
			
		||||
            return SurfaceTarget::Texture2DArray;
 | 
			
		||||
        else
 | 
			
		||||
            return SurfaceTarget::Texture2D;
 | 
			
		||||
    }
 | 
			
		||||
    case Tegra::Shader::TextureType::Texture3D: {
 | 
			
		||||
    case Tegra::Shader::TextureType::Texture1D:
 | 
			
		||||
        return is_array ? SurfaceTarget::Texture1DArray : SurfaceTarget::Texture1D;
 | 
			
		||||
    case Tegra::Shader::TextureType::Texture2D:
 | 
			
		||||
        return is_array ? SurfaceTarget::Texture2DArray : SurfaceTarget::Texture2D;
 | 
			
		||||
    case Tegra::Shader::TextureType::Texture3D:
 | 
			
		||||
        ASSERT(!is_array);
 | 
			
		||||
        return SurfaceTarget::Texture3D;
 | 
			
		||||
    }
 | 
			
		||||
    case Tegra::Shader::TextureType::TextureCube: {
 | 
			
		||||
        if (is_array)
 | 
			
		||||
            return SurfaceTarget::TextureCubeArray;
 | 
			
		||||
        else
 | 
			
		||||
            return SurfaceTarget::TextureCubemap;
 | 
			
		||||
    }
 | 
			
		||||
    default: {
 | 
			
		||||
    case Tegra::Shader::TextureType::TextureCube:
 | 
			
		||||
        return is_array ? SurfaceTarget::TextureCubeArray : SurfaceTarget::TextureCubemap;
 | 
			
		||||
    default:
 | 
			
		||||
        UNREACHABLE();
 | 
			
		||||
        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) {
 | 
			
		||||
    return uncompressed ? mip_size : std::max(1U, (mip_size + tile - 1) / tile);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // Anonymous namespace
 | 
			
		||||
 | 
			
		||||
SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic,
 | 
			
		||||
                                            const VideoCommon::Shader::Sampler& entry) {
 | 
			
		||||
SurfaceParams SurfaceParams::CreateForTexture(const Tegra::Texture::TICEntry& tic,
 | 
			
		||||
                                              const VideoCommon::Shader::Sampler& entry) {
 | 
			
		||||
    SurfaceParams params;
 | 
			
		||||
    params.is_tiled = tic.IsTiled();
 | 
			
		||||
    params.srgb_conversion = tic.IsSrgbConversionEnabled();
 | 
			
		||||
@@ -94,8 +102,17 @@ SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic,
 | 
			
		||||
    params.component_type = ComponentTypeFromTexture(tic.r_type.Value());
 | 
			
		||||
    params.type = GetFormatType(params.pixel_format);
 | 
			
		||||
    // TODO: on 1DBuffer we should use the tic info.
 | 
			
		||||
    if (!tic.IsBuffer()) {
 | 
			
		||||
        params.target = TextureType2SurfaceTarget(entry.GetType(), entry.IsArray());
 | 
			
		||||
    if (tic.IsBuffer()) {
 | 
			
		||||
        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.height = tic.Height();
 | 
			
		||||
        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.emulated_levels = std::min(params.num_levels, params.MaxPossibleMipmap());
 | 
			
		||||
        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.width = tic.Width();
 | 
			
		||||
        params.pitch = params.width * params.GetBytesPerPixel();
 | 
			
		||||
@@ -116,6 +153,18 @@ SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic,
 | 
			
		||||
        params.num_levels = 1;
 | 
			
		||||
        params.emulated_levels = 1;
 | 
			
		||||
        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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,8 +23,12 @@ using VideoCore::Surface::SurfaceCompression;
 | 
			
		||||
class SurfaceParams {
 | 
			
		||||
public:
 | 
			
		||||
    /// Creates SurfaceCachedParams from a texture configuration.
 | 
			
		||||
    static SurfaceParams CreateForTexture(const Tegra::Texture::TICEntry& tic,
 | 
			
		||||
                                          const VideoCommon::Shader::Sampler& entry);
 | 
			
		||||
 | 
			
		||||
    /// Creates SurfaceCachedParams from an image configuration.
 | 
			
		||||
    static SurfaceParams CreateForImage(const Tegra::Texture::TICEntry& tic,
 | 
			
		||||
                                        const VideoCommon::Shader::Sampler& entry);
 | 
			
		||||
                                        const VideoCommon::Shader::Image& entry);
 | 
			
		||||
 | 
			
		||||
    /// Creates SurfaceCachedParams for a depth buffer configuration.
 | 
			
		||||
    static SurfaceParams CreateForDepthBuffer(
 | 
			
		||||
 
 | 
			
		||||
@@ -89,8 +89,23 @@ public:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    TView GetTextureSurface(const Tegra::Texture::TICEntry& tic,
 | 
			
		||||
                            const VideoCommon::Shader::Sampler& entry) {
 | 
			
		||||
        std::lock_guard lock{mutex};
 | 
			
		||||
        const auto gpu_addr{tic.Address()};
 | 
			
		||||
        if (!gpu_addr) {
 | 
			
		||||
            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::Sampler& entry) {
 | 
			
		||||
                          const VideoCommon::Shader::Image& entry) {
 | 
			
		||||
        std::lock_guard lock{mutex};
 | 
			
		||||
        const auto gpu_addr{tic.Address()};
 | 
			
		||||
        if (!gpu_addr) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user