You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
250 lines
8.0 KiB
250 lines
8.0 KiB
//================ Copyright (c) Valve Corporation. All Rights Reserved. ===========================
|
|
//
|
|
// Texture Layout, CPs3gcmTexture, and CPs3gcmTextureData_t
|
|
//
|
|
//==================================================================================================
|
|
|
|
#ifndef INCLUDED_GCMTEXTURE_H
|
|
#define INCLUDED_GCMTEXTURE_H
|
|
|
|
#include "ps3/ps3_platform.h"
|
|
|
|
#include "ps3gcmmemory.h"
|
|
#include "gcmstate.h"
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Literals
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
#define PS3_TEX_MAX_FORMAT_COUNT 48
|
|
#define PS3_TEX_CANONICAL_FORMAT_COUNT 19
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Texture layout, texture etc..
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
struct ALIGN16 CPs3gcmTextureLayout
|
|
{
|
|
#ifndef _CERT
|
|
char *m_layoutSummary; // for debug visibility
|
|
#endif
|
|
|
|
// format mapping description
|
|
struct ALIGN16 Format_t
|
|
{
|
|
#ifndef _CERT
|
|
char *m_formatSummary; // for debug visibility
|
|
#endif
|
|
|
|
enum GcmCaps_t
|
|
{
|
|
kCapSRGB = (1<<0), // GCM can sample it as SRGB
|
|
kCap4xBlocks = (1<<1), // Pitch is referring to 4 texel blocks and not single texel blocks (DXT)
|
|
};
|
|
|
|
D3DFORMAT m_d3dFormat; // what D3D knows it as; see public/bitmap/imageformat.h
|
|
|
|
uint32 m_gcmRemap; // GCM remap mask
|
|
uint16 m_gcmPitchPer4X; // GCM pitch multiplier per every 4 pixels of width
|
|
uint8 m_gcmFormat; // GCM format
|
|
uint8 m_gcmCaps; // GCM caps of this texture
|
|
}
|
|
ALIGN16_POST;
|
|
|
|
// const inputs used for hashing
|
|
struct Key_t
|
|
{
|
|
D3DFORMAT m_texFormat; // D3D texel format
|
|
uint16 m_size[3]; // dimensions of the base mip
|
|
uint8 m_texFlags; // mipped, autogen mips, render target, ... ?
|
|
uint8 m_nActualMipCount; // Actual number of mips; on console builds, we typically drop the smallest (highest index)
|
|
// mips to save space (they waste a lot of space for page-alignment reasons)
|
|
// high-bit 0x80 indicates cubemap
|
|
};
|
|
|
|
// layout flags
|
|
enum Flags_t
|
|
{
|
|
kfDynamicNoSwizzle = (1<<0), // Indicates whether this texture needs to keep a backing store for incremental updates.
|
|
// (On PS3 this will prevent texture from being swizzled to allow CPU writes at subrect offsets)
|
|
kfMip = (1<<1),
|
|
kfMipAuto = (1<<2),
|
|
kfTypeRenderable = (1<<3),
|
|
kfTypeDepthStencil = (1<<4),
|
|
kfTypeCubeMap = (1<<5),
|
|
kfSrgbEnabled = (1<<6),
|
|
kfNoD3DMemory = (1<<7), // Allocation of storage for the bits has been deferred (call IDirect3DDevice9::AllocateTextureStorage to do the allocation)
|
|
// -!!--!!- DO NOT ADD MORE FLAGS -!!--!!- (m_texFlags is only 8 bits)
|
|
};
|
|
|
|
// slice information
|
|
struct Slice_t
|
|
{
|
|
uint32 m_storageOffset; //where in the storage slab does this slice live
|
|
uint32 m_storageSize; //how much storage does this slice occupy
|
|
uint16 m_size[3]; //texel dimensions of this slice
|
|
};
|
|
|
|
//
|
|
// Structure definition
|
|
//
|
|
|
|
Key_t m_key; // key of the layout
|
|
int32 mutable m_refCount; // refcount
|
|
uint32 m_storageTotalSize; // size of storage slab required
|
|
uint16 m_nFormat; // format specific info; index in g_ps3texFormats table
|
|
uint8 m_mipCount; // derived by starting at base size and working down towards 1x1
|
|
CPs3gcmAllocationType_t mutable m_gcmAllocType; // type of GCM allocation to determine pool/alignment/etc.
|
|
#ifndef SPU
|
|
// slice array
|
|
Slice_t m_slices[0]; // dynamically allocated 2-d array [faces][mips]
|
|
public:
|
|
inline int SlicePitch( int iSlice ) const;
|
|
inline int DefaultPitch() const;
|
|
inline const Format_t * GetFormatPtr()const;
|
|
#endif
|
|
public:
|
|
|
|
inline bool IsSwizzled() const { return !( m_key.m_texFlags & ( kfDynamicNoSwizzle | kfTypeRenderable ) ) && IsPowerOfTwo( m_key.m_size[0] ) && IsPowerOfTwo( m_key.m_size[1] ) && IsPowerOfTwo( m_key.m_size[2] ); }
|
|
inline bool IsCubeMap() const { return !!(m_key.m_texFlags & kfTypeCubeMap); }
|
|
inline bool IsVolumeTex() const { return !!(m_key.m_size[2] > 1); }
|
|
inline bool IsTiledMemory() const { return (m_key.m_texFlags & ( kfTypeRenderable | kfDynamicNoSwizzle )) == kfTypeRenderable; }
|
|
|
|
inline int FaceCount() const { return ( !IsCubeMap() ) ? 1 : 6; }
|
|
inline int MipCount() const { return ( m_key.m_texFlags & kfMip ) ? m_key.m_nActualMipCount : 1; }
|
|
|
|
inline int SlicePitch2( int iSlice, const Slice_t* pSlices, const Format_t *pTexFormats ) const{ return !IsTiledMemory() ? ( ( IsSwizzled() ? pSlices[iSlice].m_size[0] : m_key.m_size[0] ) * pTexFormats[m_nFormat].m_gcmPitchPer4X / 4 ) : pTexFormats[m_nFormat].m_gcmPitchPer4X; }
|
|
inline int DefaultPitch2( const Format_t *pTexFormats ) const { return !IsTiledMemory() ? m_key.m_size[0] * pTexFormats[m_nFormat].m_gcmPitchPer4X / 4 : pTexFormats[m_nFormat].m_gcmPitchPer4X; }
|
|
|
|
inline int SliceIndex( int face, int mip ) const { return mip + ( face * MipCount() ); }
|
|
|
|
public:
|
|
#ifndef SPU
|
|
static CPs3gcmTextureLayout const * New( Key_t const &k );
|
|
void Release() const;
|
|
#endif
|
|
}
|
|
ALIGN16_POST;
|
|
|
|
extern CPs3gcmTextureLayout::Format_t g_ps3texFormats[PS3_TEX_MAX_FORMAT_COUNT];
|
|
extern uint g_nPs3texFormatCount;
|
|
|
|
|
|
#ifndef SPU
|
|
// convenience functions on PPU that use implicit tables always accessible on PPU
|
|
inline int CPs3gcmTextureLayout::SlicePitch( int iSlice ) const
|
|
{
|
|
return SlicePitch2( iSlice, &m_slices[0], g_ps3texFormats );
|
|
}
|
|
inline int CPs3gcmTextureLayout::DefaultPitch() const
|
|
{
|
|
return DefaultPitch2( g_ps3texFormats );
|
|
}
|
|
inline const CPs3gcmTextureLayout::Format_t * CPs3gcmTextureLayout::GetFormatPtr()const
|
|
{
|
|
return &g_ps3texFormats[ m_nFormat ];
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
struct ALIGN16 CPs3gcmTexture
|
|
{
|
|
CPs3gcmTextureLayout const *m_layout; // this structure persists. see CPs3gcmTextureLayout::Release( it asserts if refcount goes down to zero )
|
|
ALIGN16 CPs3gcmLocalMemoryBlock m_lmBlock ALIGN16_POST; // this structure has the Offset, and the texture bits at that offset persist until all Draw calls are made that use it
|
|
|
|
inline uint32 Offset()const { Assert( m_lmBlock.Size() ); return m_lmBlock.Offset(); }
|
|
#ifndef SPU
|
|
inline char * Data() { Assert( m_lmBlock.Size() ); return m_lmBlock.DataInAnyMemory(); }
|
|
#endif
|
|
public:
|
|
#ifndef SPU
|
|
static CPs3gcmTexture * New( CPs3gcmTextureLayout::Key_t const &key );
|
|
void Release();
|
|
bool Allocate();
|
|
#endif
|
|
}
|
|
ALIGN16_POST;
|
|
|
|
struct CPs3gcmTextureData_t
|
|
{
|
|
// CPs3gcmTextureLayout const *m_eaLayout
|
|
uint32 m_eaLayout; // this structure persists. see CPs3gcmTextureLayout::Release( it asserts if refcount goes down to zero )
|
|
uint32 m_nLocalOffset; // the offset of the texture bits
|
|
|
|
void Assign( const CPs3gcmTexture * pThat )
|
|
{
|
|
if( pThat )
|
|
{
|
|
m_eaLayout = ( uint32 )pThat->m_layout;
|
|
m_nLocalOffset = pThat->Offset();
|
|
Assert( m_eaLayout ? !( 15 & ( uintp( m_eaLayout ) | m_nLocalOffset ) ) && m_nLocalOffset : !m_nLocalOffset );
|
|
}
|
|
else
|
|
{
|
|
Reset();
|
|
}
|
|
}
|
|
|
|
inline uint32 Offset()const { return m_nLocalOffset; }
|
|
|
|
void Reset()
|
|
{
|
|
m_eaLayout = 0;
|
|
m_nLocalOffset = 0;
|
|
}
|
|
|
|
bool IsNull()const
|
|
{
|
|
return !NotNull();
|
|
}
|
|
bool NotNull()const
|
|
{
|
|
// either both are null, or none is null
|
|
Assert( ( m_eaLayout == 0 ) == ( m_nLocalOffset == 0 ) );
|
|
return m_eaLayout != 0;
|
|
}
|
|
|
|
operator bool() const { return NotNull(); }
|
|
};
|
|
|
|
|
|
//
|
|
// CPs3BindTexture_t : Everything we need to bind a texture
|
|
//
|
|
|
|
// This is what the SPU needs to bind the texture
|
|
|
|
struct CPs3BindTexture_t
|
|
{
|
|
uint8 m_sampler;
|
|
uint8 m_nBindFlags;
|
|
uint8 m_UWrap;
|
|
uint8 m_VWrap;
|
|
uint8 m_WWrap;
|
|
uint8 m_minFilter;
|
|
uint8 m_magFilter;
|
|
uint8 m_mipFilter;
|
|
|
|
uint32 m_nLayout;
|
|
CPs3gcmLocalMemoryBlock *m_pLmBlock;
|
|
|
|
int m_boundStd;
|
|
int m_hTexture;
|
|
};
|
|
|
|
// This is what we store when asked to bind a texture
|
|
// When the cmd buffer is executed, at this time we lookup
|
|
// the remaining fields and pack some CPs3BindTexture_t to actually use on the SPU
|
|
|
|
struct CPs3BindParams_t
|
|
{
|
|
uint16 m_nBindTexIndex;
|
|
uint8 m_sampler;
|
|
uint8 m_nBindFlags;
|
|
int m_boundStd;
|
|
int m_hTexture;
|
|
};
|
|
|
|
|
|
#endif // INCLUDED_GCMTEXTURE_H
|