Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Libretro
flycast
Commits
5c9f995b
Unverified
Commit
5c9f995b
authored
Sep 06, 2020
by
Libretro-Admin
Committed by
GitHub
Sep 06, 2020
Browse files
Merge pull request #947 from libretro/fh/gpu-palette
Handle some palette textures on the GPU. vulkan: some linear tiling
parents
2700c9e5
c2f73580
Changes
32
Hide whitespace changes
Inline
Side-by-side
core/rend/TexCache.cpp
View file @
5c9f995b
...
...
@@ -21,6 +21,7 @@ u32 palette16_ram[1024];
u32
palette32_ram
[
1024
];
u32
pal_hash_256
[
4
];
u32
pal_hash_16
[
64
];
bool
palette_updated
;
// Rough approximation of LoD bias from D adjust param, only used to increase LoD
const
std
::
array
<
f32
,
16
>
D_Adjust_LoD_Bias
=
{
...
...
@@ -86,8 +87,9 @@ void palette_update()
{
if
(
!
pal_needs_update
)
return
;
pal_needs_update
=
false
;
palette_updated
=
true
;
pal_needs_update
=
false
;
switch
(
PAL_RAM_CTRL
&
3
)
{
case
0
:
...
...
@@ -129,8 +131,7 @@ void palette_update()
}
static
std
::
vector
<
vram_block
*>
VramLocks
[
VRAM_SIZE_MAX
/
PAGE_SIZE
];
//vram 32-64b
VArray2
vram
;
VArray2
vram
;
// vram 32-64b
//List functions
//
...
...
@@ -251,14 +252,7 @@ bool VramLockedWrite(u8* address)
//unlocks mem
//also frees the handle
void
libCore_vramlock_Unlock_block
(
vram_block
*
block
)
{
vramlist_lock
.
Lock
();
libCore_vramlock_Unlock_block_wb
(
block
);
vramlist_lock
.
Unlock
();
}
void
libCore_vramlock_Unlock_block_wb
(
vram_block
*
block
)
static
void
libCore_vramlock_Unlock_block_wb
(
vram_block
*
block
)
{
if
(
mmu_enabled
())
vmem32_unprotect_vram
(
block
->
start
,
block
->
len
);
...
...
@@ -266,6 +260,13 @@ void libCore_vramlock_Unlock_block_wb(vram_block* block)
free
(
block
);
}
void
libCore_vramlock_Unlock_block
(
vram_block
*
block
)
{
vramlist_lock
.
Lock
();
libCore_vramlock_Unlock_block_wb
(
block
);
vramlist_lock
.
Unlock
();
}
#ifdef HAVE_TEXUPSCALE
//
// deposterization: smoothes posterized gradients from low-color-depth (e.g. 444, 565, compressed) sources
...
...
@@ -400,17 +401,19 @@ struct PvrTexInfo
TexConvFP32
*
PL32
;
TexConvFP32
*
TW32
;
TexConvFP32
*
VQ32
;
// Conversion to 8 bpp (palette)
TexConvFP8
*
TW8
;
};
static
const
PvrTexInfo
format
[
8
]
=
{
// name bpp Final format Planar Twiddled VQ Planar(32b) Twiddled(32b) VQ (32b)
{
"1555"
,
16
,
TextureType
::
_5551
,
tex1555_PL
,
tex1555_TW
,
tex1555_VQ
,
tex1555_PL32
,
tex1555_TW32
,
tex1555_VQ32
},
//1555
{
"565"
,
16
,
TextureType
::
_565
,
tex565_PL
,
tex565_TW
,
tex565_VQ
,
tex565_PL32
,
tex565_TW32
,
tex565_VQ32
},
//565
{
"4444"
,
16
,
TextureType
::
_4444
,
tex4444_PL
,
tex4444_TW
,
tex4444_VQ
,
tex4444_PL32
,
tex4444_TW32
,
tex4444_VQ32
},
//4444
{
"yuv"
,
16
,
TextureType
::
_8888
,
NULL
,
NULL
,
NULL
,
texYUV422_PL
,
texYUV422_TW
,
texYUV422_VQ
},
//yuv
{
"bumpmap"
,
16
,
TextureType
::
_4444
,
texBMP_PL
,
texBMP_TW
,
texBMP_VQ
,
tex4444_PL32
,
tex4444_TW32
,
tex4444_VQ32
},
//bump map
{
"pal4"
,
4
,
TextureType
::
_5551
,
0
,
texPAL4_TW
,
texPAL4_VQ
,
NULL
,
texPAL4_TW32
,
texPAL4_VQ32
},
//pal4
{
"pal8"
,
8
,
TextureType
::
_5551
,
0
,
texPAL8_TW
,
texPAL8_VQ
,
NULL
,
texPAL8_TW32
,
texPAL8_VQ32
},
//pal8
{
// name bpp Final format Planar Twiddled VQ Planar(32b) Twiddled(32b) VQ (32b)
Palette (8b)
{
"1555"
,
16
,
TextureType
::
_5551
,
tex1555_PL
,
tex1555_TW
,
tex1555_VQ
,
tex1555_PL32
,
tex1555_TW32
,
tex1555_VQ32
,
nullptr
},
//1555
{
"565"
,
16
,
TextureType
::
_565
,
tex565_PL
,
tex565_TW
,
tex565_VQ
,
tex565_PL32
,
tex565_TW32
,
tex565_VQ32
,
nullptr
},
//565
{
"4444"
,
16
,
TextureType
::
_4444
,
tex4444_PL
,
tex4444_TW
,
tex4444_VQ
,
tex4444_PL32
,
tex4444_TW32
,
tex4444_VQ32
,
nullptr
},
//4444
{
"yuv"
,
16
,
TextureType
::
_8888
,
nullptr
,
nullptr
,
nullptr
,
texYUV422_PL
,
texYUV422_TW
,
texYUV422_VQ
,
nullptr
},
//yuv
{
"bumpmap"
,
16
,
TextureType
::
_4444
,
texBMP_PL
,
texBMP_TW
,
texBMP_VQ
,
tex4444_PL32
,
tex4444_TW32
,
tex4444_VQ32
,
nullptr
},
//bump map
{
"pal4"
,
4
,
TextureType
::
_5551
,
nullptr
,
texPAL4_TW
,
texPAL4_VQ
,
nullptr
,
texPAL4_TW32
,
texPAL4_VQ32
,
texPAL4PT_TW
},
//pal4
{
"pal8"
,
8
,
TextureType
::
_5551
,
nullptr
,
texPAL8_TW
,
texPAL8_VQ
,
nullptr
,
texPAL8_TW32
,
texPAL8_VQ32
,
texPAL8PT_TW
},
//pal8
{
"ns/1555"
,
0
},
// Not supported (1555)
};
...
...
@@ -454,15 +457,15 @@ void BaseTextureCacheData::PrintTextureName()
if
(
tcw
.
VQ_Comp
)
strcat
(
str
,
" VQ"
);
if
(
tcw
.
ScanOrder
==
0
)
else
if
(
tcw
.
ScanOrder
==
0
)
strcat
(
str
,
" TW"
);
else
if
(
tcw
.
StrideSel
)
strcat
(
str
,
" Stride"
);
if
(
tcw
.
MipMapped
)
if
(
tcw
.
ScanOrder
==
0
&&
tcw
.
MipMapped
)
strcat
(
str
,
" MM"
);
if
(
tcw
.
StrideSel
)
strcat
(
str
,
" Stride"
);
if
(
tsp
.
FilterMode
!=
0
)
strcat
(
str
,
" Bilinear"
);
sprintf
(
str
+
strlen
(
str
),
" %dx%d @ 0x%X"
,
8
<<
tsp
.
TexU
,
8
<<
tsp
.
TexV
,
tcw
.
TexAddr
<<
3
);
std
::
string
id
=
GetId
();
...
...
@@ -472,9 +475,15 @@ void BaseTextureCacheData::PrintTextureName()
//true if : dirty or paletted texture and hashes don't match
bool
BaseTextureCacheData
::
NeedsUpdate
()
{
bool
rc
=
dirty
||
(
tcw
.
PixelFmt
==
PixelPal4
&&
palette_hash
!=
pal_hash_16
[
tcw
.
PalSelect
])
||
(
tcw
.
PixelFmt
==
PixelPal8
&&
palette_hash
!=
pal_hash_256
[
tcw
.
PalSelect
>>
4
]);
bool
rc
=
dirty
!=
0
;
if
(
tex_type
!=
TextureType
::
_8
)
{
if
(
tcw
.
PixelFmt
==
PixelPal4
&&
palette_hash
!=
pal_hash_16
[
tcw
.
PalSelect
])
rc
=
true
;
else
if
(
tcw
.
PixelFmt
==
PixelPal8
&&
palette_hash
!=
pal_hash_256
[
tcw
.
PalSelect
>>
4
])
rc
=
true
;
}
return
rc
;
}
...
...
@@ -500,7 +509,6 @@ bool BaseTextureCacheData::Delete()
void
BaseTextureCacheData
::
Create
()
{
//Reset state info ..
Lookups
=
0
;
Updates
=
0
;
dirty
=
FrameCount
;
lock_block
=
nullptr
;
...
...
@@ -521,19 +529,27 @@ void BaseTextureCacheData::Create()
else
if
(
tex
->
bpp
==
8
)
palette_index
=
(
tcw
.
PalSelect
>>
4
)
<<
8
;
texconv8
=
nullptr
;
if
(
tcw
.
ScanOrder
&&
(
tex
->
PL
||
tex
->
PL32
))
{
//Texture is stored 'planar' in memory, no deswizzle is needed
//verify(tcw.VQ_Comp==0);
if
(
tcw
.
VQ_Comp
!=
0
)
{
WARN_LOG
(
RENDERER
,
"Warning: planar texture with VQ set (invalid)"
);
tcw
.
VQ_Comp
=
0
;
}
if
(
tcw
.
MipMapped
!=
0
)
{
WARN_LOG
(
RENDERER
,
"Warning: planar texture with mipmaps (invalid)"
);
tcw
.
MipMapped
=
0
;
}
//Planar textures support stride selection, mostly used for non power of 2 textures (videos)
int
stride
=
0
;
int
stride
=
w
;
if
(
tcw
.
StrideSel
)
stride
=
(
TEXT_CONTROL
&
31
)
*
32
;
if
(
stride
==
0
)
stride
=
w
;
//Call the format specific conversion code
texconv
=
tex
->
PL
;
...
...
@@ -543,6 +559,8 @@ void BaseTextureCacheData::Create()
}
else
{
tcw
.
ScanOrder
=
0
;
tcw
.
StrideSel
=
0
;
// Quake 3 Arena uses one
if
(
tcw
.
MipMapped
)
// Mipmapped texture must be square and TexV is ignored
...
...
@@ -566,6 +584,7 @@ void BaseTextureCacheData::Create()
texconv
=
tex
->
TW
;
texconv32
=
tex
->
TW32
;
size
=
w
*
h
*
tex
->
bpp
/
8
;
texconv8
=
tex
->
TW8
;
}
}
}
...
...
@@ -590,9 +609,14 @@ void BaseTextureCacheData::Update()
bool
has_alpha
=
false
;
if
(
IsPaletted
())
{
tex_type
=
PAL_TYPE
[
PAL_RAM_CTRL
&
3
];
if
(
tex_type
!=
TextureType
::
_565
)
has_alpha
=
true
;
if
(
IsGpuHandledPaletted
(
tsp
,
tcw
))
tex_type
=
TextureType
::
_8
;
else
{
tex_type
=
PAL_TYPE
[
PAL_RAM_CTRL
&
3
];
if
(
tex_type
!=
TextureType
::
_565
)
has_alpha
=
true
;
}
// Get the palette hash to check for future updates
if
(
tcw
.
PixelFmt
==
PixelPal4
)
...
...
@@ -613,7 +637,7 @@ void BaseTextureCacheData::Update()
u32
original_h
=
h
;
if
(
sa_tex
>
VRAM_SIZE
||
size
==
0
||
sa
+
size
>
VRAM_SIZE
)
{
if
(
sa
+
size
>
VRAM_SIZE
)
if
(
sa
<
VRAM_SIZE
&&
sa
+
size
>
VRAM_SIZE
&&
tcw
.
ScanOrder
&&
stride
>
0
)
{
// Shenmue Space Harrier mini-arcade loads a texture that goes beyond the end of VRAM
// but only uses the top portion of it
...
...
@@ -635,11 +659,12 @@ void BaseTextureCacheData::Update()
PixelBuffer
<
u16
>
pb16
;
PixelBuffer
<
u32
>
pb32
;
PixelBuffer
<
u8
>
pb8
;
// Figure out if we really need to use a 32-bit pixel buffer
bool
textureUpscaling
=
settings
.
rend
.
TextureUpscale
>
1
// Don't process textures that are too big
&&
w
*
h
<=
settings
.
rend
.
MaxFilteredTextureSize
*
settings
.
rend
.
MaxFilteredTextureSize
&&
(
int
)(
w
*
h
)
<=
settings
.
rend
.
MaxFilteredTextureSize
*
settings
.
rend
.
MaxFilteredTextureSize
// Don't process YUV textures
&&
tcw
.
PixelFmt
!=
PixelYUV
;
bool
need_32bit_buffer
=
true
;
...
...
@@ -725,6 +750,26 @@ void BaseTextureCacheData::Update()
}
temp_tex_buffer
=
pb32
.
data
();
}
else
if
(
texconv8
!=
NULL
&&
tex_type
==
TextureType
::
_8
)
{
if
(
mipmapped
)
{
pb8
.
init
(
w
,
h
,
true
);
for
(
u32
i
=
0
;
i
<=
tsp
.
TexU
+
3u
;
i
++
)
{
pb8
.
set_mipmap
(
i
);
u32
vram_addr
=
sa_tex
+
OtherMipPoint
[
i
]
*
tex
->
bpp
/
8
;
texconv8
(
&
pb8
,
&
vram
[
vram_addr
],
1
<<
i
,
1
<<
i
);
}
pb8
.
set_mipmap
(
0
);
}
else
{
pb8
.
init
(
w
,
h
);
texconv8
(
&
pb8
,
&
vram
[
sa
],
stride
,
h
);
}
temp_tex_buffer
=
pb8
.
data
();
}
else
if
(
texconv
!=
NULL
)
{
if
(
mipmapped
)
...
...
core/rend/TexCache.h
View file @
5c9f995b
#pragma once
#include "hw/pvr/Renderer_if.h"
#include <algorithm>
#include <array>
#include <atomic>
#include <memory>
#include <unordered_map>
#include <array>
#include "hw/pvr/pvr_regs.h"
#undef ID
#include "hw/pvr/ta_structs.h"
#include "hw/pvr/Renderer_if.h"
extern
u8
*
vq_codebook
;
extern
u32
palette_index
;
...
...
@@ -16,6 +15,7 @@ extern bool pal_needs_update,fog_needs_update;
extern
u32
pal_hash_256
[
4
];
extern
u32
pal_hash_16
[
64
];
extern
bool
KillTex
;
extern
bool
palette_updated
;
extern
u32
detwiddle
[
2
][
11
][
1024
];
...
...
@@ -118,7 +118,7 @@ public:
}
};
void
palette_update
(
void
);
void
palette_update
();
#define clamp(minv,maxv,x) min(maxv,max(minv,x))
...
...
@@ -151,47 +151,22 @@ void palette_update(void);
#define ARGB8888_32( word ) ( ((word >> 0) & 0xFF000000) | (((word >> 16) & 0xFF) << 0) | (((word >> 8) & 0xFF) << 8) | ((word & 0xFF) << 16) )
template
<
class
PixelPacker
>
__forceinline
u32
YUV422
(
s32
Y
,
s32
Yu
,
s32
Yv
)
inline
static
u32
YUV422
(
s32
Y
,
s32
Yu
,
s32
Yv
)
{
Yu
-=
128
;
Yv
-=
128
;
//s32 B = (76283*(Y - 16) + 132252*(Yu - 128))>>16;
//s32 G = (76283*(Y - 16) - 53281 *(Yv - 128) - 25624*(Yu - 128))>>16;
//s32 R = (76283*(Y - 16) + 104595*(Yv - 128))>>16;
s32
R
=
Y
+
Yv
*
11
/
8
;
// Y + (Yv-128) * (11/8) ?
s32
G
=
Y
-
(
Yu
*
11
+
Yv
*
22
)
/
32
;
// Y - (Yu-128) * (11/8) * 0.25 - (Yv-128) * (11/8) * 0.5 ?
s32
B
=
Y
+
Yu
*
110
/
64
;
// Y + (Yu-128) * (11/8) * 1.25 ?
return
PixelPacker
::
packRGB
(
clamp
(
0
,
255
,
R
)
,
clamp
(
0
,
255
,
G
)
,
clamp
(
0
,
255
,
B
)
);
return
clamp
(
0
,
255
,
R
)
|
(
clamp
(
0
,
255
,
G
)
<<
8
)
|
(
clamp
(
0
,
255
,
B
)
<<
16
)
|
0xFF000000
;
}
#define twop(x,y,bcx,bcy) (detwiddle[0][bcy][x]+detwiddle[1][bcx][y])
//pixel packers !
struct
pp_565
{
__forceinline
static
u32
packRGB
(
u8
R
,
u8
G
,
u8
B
)
{
R
>>=
3
;
G
>>=
2
;
B
>>=
3
;
return
(
R
<<
11
)
|
(
G
<<
5
)
|
(
B
<<
0
);
}
};
struct
pp_8888
{
__forceinline
static
u32
packRGB
(
u8
R
,
u8
G
,
u8
B
)
{
return
(
R
<<
0
)
|
(
G
<<
8
)
|
(
B
<<
16
)
|
0xFF000000
;
}
};
//pixel convertors !
#define pixelcvt_start_base(name,x,y,type)
template<class PixelPacker> \
#define pixelcvt_start_base(name,x,y,type)
\
struct name \
{
\
static
const
u32
xpp
=
x
;
\
...
...
@@ -202,7 +177,7 @@ struct pp_8888
#define pixelcvt_start(name,x,y) pixelcvt_start_base(name, x, y, u16)
#define pixelcvt32_start(name,x,y) pixelcvt_start_base(name, x, y, u32)
#define pixelcvt_size_start(name, x, y) template<class
PixelPacker, class
pixel_size> \
#define pixelcvt_size_start(name, x, y) template<class pixel_size> \
struct name \
{
\
static
const
u32
xpp
=
x
;
\
...
...
@@ -315,9 +290,9 @@ pixelcvt32_start(convYUV_PL,4,1)
s32
Yv
=
(
p_in
[
0
]
>>
16
)
&
255
;
//p_in[2]
//0,0
pb
->
prel
(
0
,
YUV422
<
PixelPacker
>
(
Y0
,
Yu
,
Yv
));
pb
->
prel
(
0
,
YUV422
(
Y0
,
Yu
,
Yv
));
//1,0
pb
->
prel
(
1
,
YUV422
<
PixelPacker
>
(
Y1
,
Yu
,
Yv
));
pb
->
prel
(
1
,
YUV422
(
Y1
,
Yu
,
Yv
));
//next 4 bytes
p_in
+=
1
;
...
...
@@ -328,9 +303,9 @@ pixelcvt32_start(convYUV_PL,4,1)
Yv
=
(
p_in
[
0
]
>>
16
)
&
255
;
//p_in[2]
//0,0
pb
->
prel
(
2
,
YUV422
<
PixelPacker
>
(
Y0
,
Yu
,
Yv
));
pb
->
prel
(
2
,
YUV422
(
Y0
,
Yu
,
Yv
));
//1,0
pb
->
prel
(
3
,
YUV422
<
PixelPacker
>
(
Y1
,
Yu
,
Yv
));
pb
->
prel
(
3
,
YUV422
(
Y1
,
Yu
,
Yv
));
}
pixelcvt_end
;
...
...
@@ -436,9 +411,9 @@ pixelcvt32_start(convYUV_TW,2,2)
s32
Yv
=
(
p_in
[
2
]
>>
0
)
&
255
;
//p_in[2]
//0,0
pb
->
prel
(
0
,
0
,
YUV422
<
PixelPacker
>
(
Y0
,
Yu
,
Yv
));
pb
->
prel
(
0
,
0
,
YUV422
(
Y0
,
Yu
,
Yv
));
//1,0
pb
->
prel
(
1
,
0
,
YUV422
<
PixelPacker
>
(
Y1
,
Yu
,
Yv
));
pb
->
prel
(
1
,
0
,
YUV422
(
Y1
,
Yu
,
Yv
));
//next 4 bytes
//p_in+=2;
...
...
@@ -449,9 +424,9 @@ pixelcvt32_start(convYUV_TW,2,2)
Yv
=
(
p_in
[
3
]
>>
0
)
&
255
;
//p_in[2]
//0,1
pb
->
prel
(
0
,
1
,
YUV422
<
PixelPacker
>
(
Y0
,
Yu
,
Yv
));
pb
->
prel
(
0
,
1
,
YUV422
(
Y0
,
Yu
,
Yv
));
//1,1
pb
->
prel
(
1
,
1
,
YUV422
<
PixelPacker
>
(
Y1
,
Yu
,
Yv
));
pb
->
prel
(
1
,
1
,
YUV422
(
Y1
,
Yu
,
Yv
));
}
pixelcvt_end
;
...
...
@@ -483,6 +458,33 @@ pixelcvt_size_start(convPAL4_TW,4,4)
}
pixelcvt_end
;
// Palette 4bpp -> 8bpp
pixelcvt_size_start
(
convPAL4PT_TW
,
4
,
4
)
{
u8
*
p_in
=
(
u8
*
)
data
;
pb
->
prel
(
0
,
0
,
p_in
[
0
]
&
0xF
);
pb
->
prel
(
0
,
1
,
(
p_in
[
0
]
>>
4
)
&
0xF
);
p_in
++
;
pb
->
prel
(
1
,
0
,
p_in
[
0
]
&
0xF
);
pb
->
prel
(
1
,
1
,
(
p_in
[
0
]
>>
4
)
&
0xF
);
p_in
++
;
pb
->
prel
(
0
,
2
,
p_in
[
0
]
&
0xF
);
pb
->
prel
(
0
,
3
,
(
p_in
[
0
]
>>
4
)
&
0xF
);
p_in
++
;
pb
->
prel
(
1
,
2
,
p_in
[
0
]
&
0xF
);
pb
->
prel
(
1
,
3
,
(
p_in
[
0
]
>>
4
)
&
0xF
);
p_in
++
;
pb
->
prel
(
2
,
0
,
p_in
[
0
]
&
0xF
);
pb
->
prel
(
2
,
1
,
(
p_in
[
0
]
>>
4
)
&
0xF
);
p_in
++
;
pb
->
prel
(
3
,
0
,
p_in
[
0
]
&
0xF
);
pb
->
prel
(
3
,
1
,
(
p_in
[
0
]
>>
4
)
&
0xF
);
p_in
++
;
pb
->
prel
(
2
,
2
,
p_in
[
0
]
&
0xF
);
pb
->
prel
(
2
,
3
,
(
p_in
[
0
]
>>
4
)
&
0xF
);
p_in
++
;
pb
->
prel
(
3
,
2
,
p_in
[
0
]
&
0xF
);
pb
->
prel
(
3
,
3
,
(
p_in
[
0
]
>>
4
)
&
0xF
);
p_in
++
;
}
pixelcvt_end
;
pixelcvt_size_start
(
convPAL8_TW
,
2
,
4
)
{
u8
*
p_in
=
(
u8
*
)
data
;
...
...
@@ -500,6 +502,24 @@ pixelcvt_size_start(convPAL8_TW,2,4)
}
pixelcvt_end
;
// Palette 8bpp -> 8bpp (untwiddle only)
pixelcvt_size_start
(
convPAL8PT_TW
,
2
,
4
)
{
u8
*
p_in
=
(
u8
*
)
data
;
pb
->
prel
(
0
,
0
,
p_in
[
0
]);
p_in
++
;
pb
->
prel
(
0
,
1
,
p_in
[
0
]);
p_in
++
;
pb
->
prel
(
1
,
0
,
p_in
[
0
]);
p_in
++
;
pb
->
prel
(
1
,
1
,
p_in
[
0
]);
p_in
++
;
pb
->
prel
(
0
,
2
,
p_in
[
0
]);
p_in
++
;
pb
->
prel
(
0
,
3
,
p_in
[
0
]);
p_in
++
;
pb
->
prel
(
1
,
2
,
p_in
[
0
]);
p_in
++
;
pb
->
prel
(
1
,
3
,
p_in
[
0
]);
p_in
++
;
}
pixelcvt_end
;
//handler functions
template
<
class
PixelConvertor
,
class
pixel_type
>
void
texture_PL
(
PixelBuffer
<
pixel_type
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
)
...
...
@@ -569,74 +589,51 @@ void texture_VQ(PixelBuffer<pixel_type>* pb,u8* p_in,u32 Width,u32 Height)
}
}
//We ask the compiler to generate the templates here
//;)
//planar formats !
template
void
texture_PL
<
conv565_PL
<
pp_565
>,
u16
>
(
PixelBuffer
<
u16
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_PL
<
conv1555_PL
<
pp_565
>,
u16
>
(
PixelBuffer
<
u16
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_PL
<
conv4444_PL
<
pp_565
>,
u16
>
(
PixelBuffer
<
u16
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_PL
<
convYUV_PL
<
pp_8888
>,
u32
>
(
PixelBuffer
<
u32
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
//twiddled formats !
template
void
texture_TW
<
conv565_TW
<
pp_565
>,
u16
>
(
PixelBuffer
<
u16
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_TW
<
conv1555_TW
<
pp_565
>,
u16
>
(
PixelBuffer
<
u16
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_TW
<
conv4444_TW
<
pp_565
>,
u16
>
(
PixelBuffer
<
u16
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_TW
<
convYUV_TW
<
pp_8888
>,
u32
>
(
PixelBuffer
<
u32
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_TW
<
convPAL4_TW
<
pp_565
,
u16
>,
u16
>
(
PixelBuffer
<
u16
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_TW
<
convPAL8_TW
<
pp_565
,
u16
>,
u16
>
(
PixelBuffer
<
u16
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_TW
<
convPAL4_TW
<
pp_8888
,
u32
>,
u32
>
(
PixelBuffer
<
u32
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_TW
<
convPAL8_TW
<
pp_8888
,
u32
>,
u32
>
(
PixelBuffer
<
u32
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
//VQ formats !
template
void
texture_VQ
<
conv565_TW
<
pp_565
>,
u16
>
(
PixelBuffer
<
u16
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_VQ
<
conv1555_TW
<
pp_565
>,
u16
>
(
PixelBuffer
<
u16
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_VQ
<
conv4444_TW
<
pp_565
>,
u16
>
(
PixelBuffer
<
u16
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
template
void
texture_VQ
<
convYUV_TW
<
pp_8888
>,
u32
>
(
PixelBuffer
<
u32
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
//Planar
#define tex565_PL texture_PL<conv565_PL
<pp_565>
, u16>
#define tex1555_PL texture_PL<conv1555_PL
<pp_565>
, u16>
#define tex4444_PL texture_PL<conv4444_PL
<pp_565>
, u16>
#define texYUV422_PL texture_PL<convYUV_PL
<pp_8888>
, u32>
#define tex565_PL texture_PL<conv565_PL, u16>
#define tex1555_PL texture_PL<conv1555_PL, u16>
#define tex4444_PL texture_PL<conv4444_PL, u16>
#define texYUV422_PL texture_PL<convYUV_PL, u32>
#define texBMP_PL tex4444_PL
#define tex565_PL32 texture_PL<conv565_PL32
<pp_8888>
, u32>
#define tex1555_PL32 texture_PL<conv1555_PL32
<pp_8888>
, u32>
#define tex4444_PL32 texture_PL<conv4444_PL32
<pp_8888>
, u32>
#define tex565_PL32 texture_PL<conv565_PL32, u32>
#define tex1555_PL32 texture_PL<conv1555_PL32, u32>
#define tex4444_PL32 texture_PL<conv4444_PL32, u32>
//Twiddle
#define tex565_TW texture_TW<conv565_TW
<pp_565>
, u16>
#define tex1555_TW texture_TW<conv1555_TW
<pp_565>
, u16>
#define tex4444_TW texture_TW<conv4444_TW
<pp_565>
, u16>
#define texYUV422_TW texture_TW<convYUV_TW
<pp_8888>
, u32>
#define tex565_TW texture_TW<conv565_TW, u16>
#define tex1555_TW texture_TW<conv1555_TW, u16>
#define tex4444_TW texture_TW<conv4444_TW, u16>
#define texYUV422_TW texture_TW<convYUV_TW, u32>
#define texBMP_TW tex4444_TW
#define texPAL4_TW texture_TW<convPAL4_TW<pp_565, u16>, u16>
#define texPAL8_TW texture_TW<convPAL8_TW<pp_565, u16>, u16>
#define texPAL4_TW32 texture_TW<convPAL4_TW<pp_8888, u32>, u32>
#define texPAL8_TW32 texture_TW<convPAL8_TW<pp_8888, u32>, u32>
#define texPAL4_TW texture_TW<convPAL4_TW<u16>, u16>
#define texPAL8_TW texture_TW<convPAL8_TW<u16>, u16>
#define texPAL4_TW32 texture_TW<convPAL4_TW<u32>, u32>
#define texPAL8_TW32 texture_TW<convPAL8_TW<u32>, u32>
#define texPAL4PT_TW texture_TW<convPAL4PT_TW<u8>, u8>
#define texPAL8PT_TW texture_TW<convPAL8PT_TW<u8>, u8>
#define tex565_TW32 texture_TW<conv565_TW32
<pp_8888>
, u32>
#define tex1555_TW32 texture_TW<conv1555_TW32
<pp_8888>
, u32>
#define tex4444_TW32 texture_TW<conv4444_TW32
<pp_8888>
, u32>
#define tex565_TW32 texture_TW<conv565_TW32, u32>
#define tex1555_TW32 texture_TW<conv1555_TW32, u32>
#define tex4444_TW32 texture_TW<conv4444_TW32, u32>
//VQ
#define tex565_VQ texture_VQ<conv565_TW
<pp_565>
, u16>
#define tex1555_VQ texture_VQ<conv1555_TW
<pp_565>
, u16>
#define tex4444_VQ texture_VQ<conv4444_TW
<pp_565>
, u16>
#define texYUV422_VQ texture_VQ<convYUV_TW
<pp_8888>
, u32>
#define tex565_VQ texture_VQ<conv565_TW, u16>
#define tex1555_VQ texture_VQ<conv1555_TW, u16>
#define tex4444_VQ texture_VQ<conv4444_TW, u16>
#define texYUV422_VQ texture_VQ<convYUV_TW, u32>
#define texBMP_VQ tex4444_VQ
// According to the documentation, a texture cannot be compressed and use
// a palette at the same time. However the hardware displays them
// just fine.
#define texPAL4_VQ texture_VQ<convPAL4_TW<
pp_565,
u16>, u16>
#define texPAL8_VQ texture_VQ<convPAL8_TW<
pp_565,
u16>, u16>
#define texPAL4_VQ texture_VQ<convPAL4_TW<u16>, u16>
#define texPAL8_VQ texture_VQ<convPAL8_TW<u16>, u16>
#define tex565_VQ32 texture_VQ<conv565_TW32
<pp_8888>
, u32>
#define tex1555_VQ32 texture_VQ<conv1555_TW32
<pp_8888>
, u32>
#define tex4444_VQ32 texture_VQ<conv4444_TW32
<pp_8888>
, u32>
#define texPAL4_VQ32 texture_VQ<convPAL4_TW<
pp_8888,
u32>, u32>
#define texPAL8_VQ32 texture_VQ<convPAL8_TW<
pp_8888,
u32>, u32>
#define tex565_VQ32 texture_VQ<conv565_TW32, u32>
#define tex1555_VQ32 texture_VQ<conv1555_TW32, u32>
#define tex4444_VQ32 texture_VQ<conv4444_TW32, u32>
#define texPAL4_VQ32 texture_VQ<convPAL4_TW<u32>, u32>
#define texPAL8_VQ32 texture_VQ<convPAL8_TW<u32>, u32>
bool
VramLockedWriteOffset
(
size_t
offset
);
#ifdef HAVE_TEXUPSCALE
...
...
@@ -647,19 +644,19 @@ void UpscalexBRZ(int factor, u32* source, u32* dest, int width, int height, bool
struct
PvrTexInfo
;
template
<
class
pixel_type
>
class
PixelBuffer
;
typedef
void
TexConvFP
(
PixelBuffer
<
u16
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
typedef
void
TexConvFP8
(
PixelBuffer
<
u8
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
typedef
void
TexConvFP32
(
PixelBuffer
<
u32
>*
pb
,
u8
*
p_in
,
u32
Width
,
u32
Height
);
enum
class
TextureType
{
_565
,
_5551
,
_4444
,
_8888
,
_8
};
struct
BaseTextureCacheData
class
BaseTextureCacheData
{
public:
TSP
tsp
;
//dreamcast texture parameters
TCW
tcw
;
// Decoded/filtered texture format
TextureType
tex_type
;
u32
Lookups
;
u32
sa
;
//pixel data start address in vram (might be offset for mipmaps/etc)
u32
sa_tex
;
//texture data start address in vram
u32
w
,
h
;
//width & height of the texture
...
...
@@ -668,6 +665,7 @@ struct BaseTextureCacheData
const
PvrTexInfo
*
tex
;
TexConvFP
*
texconv
;
TexConvFP32
*
texconv32
;
TexConvFP8
*
texconv8
;
u32
dirty
;
vram_block
*
lock_block
;
...
...
@@ -728,6 +726,18 @@ struct BaseTextureCacheData
bool
NeedsUpdate
();
virtual
bool
Delete
();
virtual
~
BaseTextureCacheData
()
{}
static
bool
IsGpuHandledPaletted
(
TSP
tsp
,
TCW
tcw
)
{
// Some palette textures are handled on the GPU
// This is currently limited to textures using nearest filtering and not mipmapped.
// Enabling texture upscaling or dumping also disables this mode.
return
(
tcw
.
PixelFmt
==
PixelPal4
||
tcw
.
PixelFmt
==
PixelPal8
)
&&
settings
.
rend
.
TextureUpscale
==
1
&&
!
settings
.
rend
.
DumpTextures
&&
tsp
.
FilterMode
==
0
&&
!
tcw
.
MipMapped
&&
!
tcw
.
VQ_Comp
;
}
};
template
<
typename
Texture
>
...
...
@@ -738,12 +748,13 @@ public:
Texture
*
getTextureCacheData
(
TSP
tsp
,
TCW
tcw
)
{
u64
key
=
tsp
.
full
&
TSPTextureCacheMask
.
full
;
if
(
tcw
.
PixelFmt
==
PixelPal4
||
tcw
.
PixelFmt
==
PixelPal8
)
if
((
tcw
.
PixelFmt
==
PixelPal4
||
tcw
.
PixelFmt
==
PixelPal8
)
&&
!
BaseTextureCacheData
::
IsGpuHandledPaletted
(
tsp
,
tcw
))
// Paletted textures have a palette selection that must be part of the key
// We also add the palette type to the key to avoid thrashing the cache
// when the palette type is changed. If the palette type is changed back in the future,
// this texture will stil be available.
key
|=
((
u64
)
tcw
.
full
<<
32
)
|
((
PAL_RAM_CTRL
&
3
)
<<
6
);
key
|=
((
u64
)
tcw
.
full
<<
32
)
|
((
PAL_RAM_CTRL
&
3
)
<<
6
)
|
((
tsp
.
FilterMode
!=
0
)
<<
8
)
;