Counter Strike : Global Offensive Source Code
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

//================ 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