Merge pull request #1458 from FernandoS27/fix-render-target-block-settings
Fixed block height settings for RenderTargets and Depth Buffers
This commit is contained in:
		
						commit
						6d82c4adf9
					
				@ -36,9 +36,9 @@ public:
 | 
			
		||||
            RenderTargetFormat format;
 | 
			
		||||
            BitField<0, 1, u32> linear;
 | 
			
		||||
            union {
 | 
			
		||||
                BitField<0, 4, u32> block_depth;
 | 
			
		||||
                BitField<0, 4, u32> block_width;
 | 
			
		||||
                BitField<4, 4, u32> block_height;
 | 
			
		||||
                BitField<8, 4, u32> block_width;
 | 
			
		||||
                BitField<8, 4, u32> block_depth;
 | 
			
		||||
            };
 | 
			
		||||
            u32 depth;
 | 
			
		||||
            u32 layer;
 | 
			
		||||
@ -53,10 +53,20 @@ public:
 | 
			
		||||
                                             address_low);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            u32 BlockWidth() const {
 | 
			
		||||
                // The block width is stored in log2 format.
 | 
			
		||||
                return 1 << block_width;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            u32 BlockHeight() const {
 | 
			
		||||
                // The block height is stored in log2 format.
 | 
			
		||||
                return 1 << block_height;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            u32 BlockDepth() const {
 | 
			
		||||
                // The block depth is stored in log2 format.
 | 
			
		||||
                return 1 << block_depth;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        static_assert(sizeof(Surface) == 0x28, "Surface has incorrect size");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -347,6 +347,16 @@ public:
 | 
			
		||||
            DecrWrap = 8,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        enum class MemoryLayout : u32 {
 | 
			
		||||
            Linear = 0,
 | 
			
		||||
            BlockLinear = 1,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        enum class InvMemoryLayout : u32 {
 | 
			
		||||
            BlockLinear = 0,
 | 
			
		||||
            Linear = 1,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct Cull {
 | 
			
		||||
            enum class FrontFace : u32 {
 | 
			
		||||
                ClockWise = 0x0900,
 | 
			
		||||
@ -432,7 +442,12 @@ public:
 | 
			
		||||
            u32 width;
 | 
			
		||||
            u32 height;
 | 
			
		||||
            Tegra::RenderTargetFormat format;
 | 
			
		||||
            u32 block_dimensions;
 | 
			
		||||
            union {
 | 
			
		||||
                BitField<0, 3, u32> block_width;
 | 
			
		||||
                BitField<4, 3, u32> block_height;
 | 
			
		||||
                BitField<8, 3, u32> block_depth;
 | 
			
		||||
                BitField<12, 1, InvMemoryLayout> type;
 | 
			
		||||
            } memory_layout;
 | 
			
		||||
            u32 array_mode;
 | 
			
		||||
            u32 layer_stride;
 | 
			
		||||
            u32 base_layer;
 | 
			
		||||
@ -562,7 +577,12 @@ public:
 | 
			
		||||
                    u32 address_high;
 | 
			
		||||
                    u32 address_low;
 | 
			
		||||
                    Tegra::DepthFormat format;
 | 
			
		||||
                    u32 block_dimensions;
 | 
			
		||||
                    union {
 | 
			
		||||
                        BitField<0, 4, u32> block_width;
 | 
			
		||||
                        BitField<4, 4, u32> block_height;
 | 
			
		||||
                        BitField<8, 4, u32> block_depth;
 | 
			
		||||
                        BitField<20, 1, InvMemoryLayout> type;
 | 
			
		||||
                    } memory_layout;
 | 
			
		||||
                    u32 layer_stride;
 | 
			
		||||
 | 
			
		||||
                    GPUVAddr Address() const {
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,9 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
 | 
			
		||||
    SurfaceParams params{};
 | 
			
		||||
    params.addr = TryGetCpuAddr(config.tic.Address());
 | 
			
		||||
    params.is_tiled = config.tic.IsTiled();
 | 
			
		||||
    params.block_width = params.is_tiled ? config.tic.BlockWidth() : 0,
 | 
			
		||||
    params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0,
 | 
			
		||||
    params.block_depth = params.is_tiled ? config.tic.BlockDepth() : 0,
 | 
			
		||||
    params.pixel_format =
 | 
			
		||||
        PixelFormatFromTextureFormat(config.tic.format, config.tic.r_type.Value());
 | 
			
		||||
    params.component_type = ComponentTypeFromTexture(config.tic.r_type.Value());
 | 
			
		||||
@ -97,8 +99,11 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
 | 
			
		||||
    const auto& config{Core::System::GetInstance().GPU().Maxwell3D().regs.rt[index]};
 | 
			
		||||
    SurfaceParams params{};
 | 
			
		||||
    params.addr = TryGetCpuAddr(config.Address());
 | 
			
		||||
    params.is_tiled = true;
 | 
			
		||||
    params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight;
 | 
			
		||||
    params.is_tiled =
 | 
			
		||||
        config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
 | 
			
		||||
    params.block_width = 1 << config.memory_layout.block_width;
 | 
			
		||||
    params.block_height = 1 << config.memory_layout.block_height;
 | 
			
		||||
    params.block_depth = 1 << config.memory_layout.block_depth;
 | 
			
		||||
    params.pixel_format = PixelFormatFromRenderTargetFormat(config.format);
 | 
			
		||||
    params.component_type = ComponentTypeFromRenderTarget(config.format);
 | 
			
		||||
    params.type = GetFormatType(params.pixel_format);
 | 
			
		||||
@ -120,13 +125,16 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
 | 
			
		||||
    return params;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*static*/ SurfaceParams SurfaceParams::CreateForDepthBuffer(u32 zeta_width, u32 zeta_height,
 | 
			
		||||
                                                             Tegra::GPUVAddr zeta_address,
 | 
			
		||||
                                                             Tegra::DepthFormat format) {
 | 
			
		||||
/*static*/ SurfaceParams SurfaceParams::CreateForDepthBuffer(
 | 
			
		||||
    u32 zeta_width, u32 zeta_height, Tegra::GPUVAddr zeta_address, Tegra::DepthFormat format,
 | 
			
		||||
    u32 block_width, u32 block_height, u32 block_depth,
 | 
			
		||||
    Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout type) {
 | 
			
		||||
    SurfaceParams params{};
 | 
			
		||||
    params.addr = TryGetCpuAddr(zeta_address);
 | 
			
		||||
    params.is_tiled = true;
 | 
			
		||||
    params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight;
 | 
			
		||||
    params.is_tiled = type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
 | 
			
		||||
    params.block_width = 1 << std::min(block_width, 5U);
 | 
			
		||||
    params.block_height = 1 << std::min(block_height, 5U);
 | 
			
		||||
    params.block_depth = 1 << std::min(block_depth, 5U);
 | 
			
		||||
    params.pixel_format = PixelFormatFromDepthFormat(format);
 | 
			
		||||
    params.component_type = ComponentTypeFromDepthFormat(format);
 | 
			
		||||
    params.type = GetFormatType(params.pixel_format);
 | 
			
		||||
@ -148,7 +156,9 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
 | 
			
		||||
    SurfaceParams params{};
 | 
			
		||||
    params.addr = TryGetCpuAddr(config.Address());
 | 
			
		||||
    params.is_tiled = !config.linear;
 | 
			
		||||
    params.block_height = params.is_tiled ? config.BlockHeight() : 0,
 | 
			
		||||
    params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 32U) : 0,
 | 
			
		||||
    params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 32U) : 0,
 | 
			
		||||
    params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 32U) : 0,
 | 
			
		||||
    params.pixel_format = PixelFormatFromRenderTargetFormat(config.format);
 | 
			
		||||
    params.component_type = ComponentTypeFromRenderTarget(config.format);
 | 
			
		||||
    params.type = GetFormatType(params.pixel_format);
 | 
			
		||||
@ -818,6 +828,11 @@ void CachedSurface::LoadGLBuffer() {
 | 
			
		||||
    if (params.is_tiled) {
 | 
			
		||||
        gl_buffer.resize(total_size);
 | 
			
		||||
 | 
			
		||||
        ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture type {}",
 | 
			
		||||
                   params.block_width, static_cast<u32>(params.target));
 | 
			
		||||
        ASSERT_MSG(params.block_depth == 1, "Block depth is defined as {} on texture type {}",
 | 
			
		||||
                   params.block_depth, static_cast<u32>(params.target));
 | 
			
		||||
 | 
			
		||||
        // TODO(bunnei): This only unswizzles and copies a 2D texture - we do not yet know how to do
 | 
			
		||||
        // this for 3D textures, etc.
 | 
			
		||||
        switch (params.target) {
 | 
			
		||||
@ -989,7 +1004,9 @@ Surface RasterizerCacheOpenGL::GetDepthBufferSurface(bool preserve_contents) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SurfaceParams depth_params{SurfaceParams::CreateForDepthBuffer(
 | 
			
		||||
        regs.zeta_width, regs.zeta_height, regs.zeta.Address(), regs.zeta.format)};
 | 
			
		||||
        regs.zeta_width, regs.zeta_height, regs.zeta.Address(), regs.zeta.format,
 | 
			
		||||
        regs.zeta.memory_layout.block_width, regs.zeta.memory_layout.block_height,
 | 
			
		||||
        regs.zeta.memory_layout.block_depth, regs.zeta.memory_layout.type)};
 | 
			
		||||
 | 
			
		||||
    return GetSurface(depth_params, preserve_contents);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -716,9 +716,10 @@ struct SurfaceParams {
 | 
			
		||||
    static SurfaceParams CreateForFramebuffer(std::size_t index);
 | 
			
		||||
 | 
			
		||||
    /// Creates SurfaceParams for a depth buffer configuration
 | 
			
		||||
    static SurfaceParams CreateForDepthBuffer(u32 zeta_width, u32 zeta_height,
 | 
			
		||||
                                              Tegra::GPUVAddr zeta_address,
 | 
			
		||||
                                              Tegra::DepthFormat format);
 | 
			
		||||
    static SurfaceParams CreateForDepthBuffer(
 | 
			
		||||
        u32 zeta_width, u32 zeta_height, Tegra::GPUVAddr zeta_address, Tegra::DepthFormat format,
 | 
			
		||||
        u32 block_width, u32 block_height, u32 block_depth,
 | 
			
		||||
        Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout type);
 | 
			
		||||
 | 
			
		||||
    /// Creates SurfaceParams for a Fermi2D surface copy
 | 
			
		||||
    static SurfaceParams CreateForFermiCopySurface(
 | 
			
		||||
@ -733,7 +734,9 @@ struct SurfaceParams {
 | 
			
		||||
 | 
			
		||||
    VAddr addr;
 | 
			
		||||
    bool is_tiled;
 | 
			
		||||
    u32 block_width;
 | 
			
		||||
    u32 block_height;
 | 
			
		||||
    u32 block_depth;
 | 
			
		||||
    PixelFormat pixel_format;
 | 
			
		||||
    ComponentType component_type;
 | 
			
		||||
    SurfaceType type;
 | 
			
		||||
 | 
			
		||||
@ -161,7 +161,9 @@ struct TICEntry {
 | 
			
		||||
        BitField<21, 3, TICHeaderVersion> header_version;
 | 
			
		||||
    };
 | 
			
		||||
    union {
 | 
			
		||||
        BitField<0, 3, u32> block_width;
 | 
			
		||||
        BitField<3, 3, u32> block_height;
 | 
			
		||||
        BitField<6, 3, u32> block_depth;
 | 
			
		||||
 | 
			
		||||
        // High 16 bits of the pitch value
 | 
			
		||||
        BitField<0, 16, u32> pitch_high;
 | 
			
		||||
@ -202,13 +204,24 @@ struct TICEntry {
 | 
			
		||||
        return depth_minus_1 + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    u32 BlockWidth() const {
 | 
			
		||||
        ASSERT(IsTiled());
 | 
			
		||||
        // The block height is stored in log2 format.
 | 
			
		||||
        return 1 << block_width;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    u32 BlockHeight() const {
 | 
			
		||||
        ASSERT(header_version == TICHeaderVersion::BlockLinear ||
 | 
			
		||||
               header_version == TICHeaderVersion::BlockLinearColorKey);
 | 
			
		||||
        ASSERT(IsTiled());
 | 
			
		||||
        // The block height is stored in log2 format.
 | 
			
		||||
        return 1 << block_height;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    u32 BlockDepth() const {
 | 
			
		||||
        ASSERT(IsTiled());
 | 
			
		||||
        // The block height is stored in log2 format.
 | 
			
		||||
        return 1 << block_depth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool IsTiled() const {
 | 
			
		||||
        return header_version == TICHeaderVersion::BlockLinear ||
 | 
			
		||||
               header_version == TICHeaderVersion::BlockLinearColorKey;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user