mirror of
https://github.com/libretro/parallel-dc.git
synced 2026-11-08 08:10:08 -10:00
texdecode_test.sh builds texdecode_test.c, a C program, against the
texture cache itself (core/rend/TexCache.o, through the small C++ shim
texdecode_cpu.cpp) and runs it on a Vulkan device - Mesa's software one,
lavapipe, when it is installed - with the validation layer on when that
is.
Close to 8000 textures: every pixel format, the reserved one too;
twiddled, compressed, planar and planar compressed; with and without
mipmaps, every mipmapped size, and sizes from 8x8 to 1024x1024 square and
not; planar ones with no stride, narrower, wider and empty strides, and
running into the end of video memory; paletted ones with every palette
format and random selections, as colours and as the indices the GPU
looks up itself; 16-bit formats to 16 bits and to 32; Force Texture LOD0;
then 2000 random ones. Each is made by the texture cache, which converts
it on the CPU and says what it would hand a renderer that converts on
the GPU. From those bytes the C text of the kernel, and then the kernel
on the device, into images made as the renderer makes them, have to
make every level the CPU made, byte for byte. A planar 16-bit texture
the renderer copies to its image as it is has to read, texel by texel,
as the same colour the CPU's texels do.
The script also builds the header as C89 and C++, compiles the three
GLSL kernels and the HLSL one (texdecode_kernel.hlsl, the shape a
Direct3D renderer will have) with glslangValidator, and checks that
core/rend/texdecode_text.inc is still the header ('update' makes it
again).
116 lines
3.4 KiB
C++
116 lines
3.4 KiB
C++
/* The CPU's side of texdecode_test.c: the texture cache itself
|
|
* (core/rend/TexCache.o) making a texture, with what it would hand a
|
|
* renderer that converts on the GPU caught on the way.
|
|
*
|
|
* A texture is made with BaseTextureCacheData::Create() and Update(), as
|
|
* the renderers make them. Update() first offers the texture to
|
|
* GpuDecode(), which takes the plan and says no; then converts it on the
|
|
* CPU and hands the texels to UploadToGPU(), which takes those. So one
|
|
* Update() gives both, from the same state. */
|
|
// the registers the frame is rendered with, as the texture cache reads them
|
|
#define PVR_REGS_FOR_RENDERER
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include "types.h"
|
|
#include "rend/TexCache.h"
|
|
#include "rend/texdecode.h"
|
|
#include "hw/pvr/pvr_regs.h"
|
|
#include "texdecode_case.h"
|
|
|
|
// what the texture cache takes from the rest of the core
|
|
settings_t settings;
|
|
u32 FrameCount = 1;
|
|
unsigned VRAM_SIZE = 8 * 1024 * 1024;
|
|
unsigned VRAM_MASK = 8 * 1024 * 1024 - 1;
|
|
static u8 pvr_regs_mem[0x10000];
|
|
u8 *rend_pvr_regs = pvr_regs_mem;
|
|
void _vmem_protect_vram(u32, u32) {}
|
|
void _vmem_unprotect_vram(u32, u32) {}
|
|
u32 _vmem_get_vram_offset(void *) { return (u32)-1; }
|
|
bool _vmem_vram_page_protected(u32) { return false; }
|
|
void os_DebugBreak() { abort(); }
|
|
void GenericLog(LogTypes::LOG_LEVELS, LogTypes::LOG_TYPE, const char *, int, const char *, ...) {}
|
|
extern VArray2 vram;
|
|
|
|
namespace {
|
|
struct TestTexture : public BaseTextureCacheData
|
|
{
|
|
bool force32 = false;
|
|
bool planned = false;
|
|
texd_plan plan;
|
|
u8 *out = nullptr;
|
|
size_t cap = 0, bytes = 0;
|
|
|
|
std::string GetId() override { return "test"; }
|
|
bool Force32BitTexture(TextureType type) const override { return force32; }
|
|
bool GpuDecode(const texd_plan& p) override
|
|
{
|
|
plan = p;
|
|
planned = true;
|
|
return false;
|
|
}
|
|
void UploadToGPU(int width, int height, u8 *data, bool mipmapped, bool mipmapsIncluded) override
|
|
{
|
|
const size_t pixel = tex_type == TextureType::_8888 ? 4 : tex_type == TextureType::_8 ? 1 : 2;
|
|
size_t n = (size_t)width * height * pixel;
|
|
if (mipmapsIncluded)
|
|
for (int w = width / 2; w != 0; w /= 2)
|
|
n += (size_t)w * w * pixel;
|
|
bytes = n <= cap ? n : 0;
|
|
if (bytes != 0)
|
|
memcpy(out, data, n);
|
|
}
|
|
};
|
|
}
|
|
|
|
extern "C" void texd_cpu_init(void *video_memory)
|
|
{
|
|
vram.data = (u8 *)video_memory;
|
|
vram.size = VRAM_SIZE;
|
|
settings.rend.TextureUpscale = 1;
|
|
settings.rend.MaxFilteredTextureSize = 256;
|
|
settings.rend.GpuTextureDecode = true;
|
|
}
|
|
|
|
extern "C" int texd_cpu_run(const struct texd_case *c, struct texd_plan *plan, void *out, size_t cap, size_t *bytes, int *type)
|
|
{
|
|
TestTexture t;
|
|
t.tcw.full = 0;
|
|
t.tcw.TexAddr = c->addr >> 3;
|
|
t.tcw.PixelFmt = c->fmt;
|
|
t.tcw.ScanOrder = c->scan_order;
|
|
t.tcw.VQ_Comp = c->vq;
|
|
t.tcw.MipMapped = c->mip;
|
|
t.tcw.StrideSel = c->stride_sel;
|
|
if (c->fmt == PixelPal4 || c->fmt == PixelPal8)
|
|
t.tcw.PalSelect = c->pal_select; // (over the bits above it: as the hardware has it)
|
|
t.tsp.full = 0;
|
|
t.tsp.TexU = c->tex_u;
|
|
t.tsp.TexV = c->tex_v;
|
|
t.tsp.FilterMode = c->filter;
|
|
t.area = 0;
|
|
t.force32 = c->force32 != 0;
|
|
settings.rend.ForceTextureLOD0 = c->lod0 != 0;
|
|
TEXT_CONTROL = c->text_control;
|
|
PAL_RAM_CTRL = c->pal_ctrl;
|
|
palette_update();
|
|
t.out = (u8 *)out;
|
|
t.cap = cap;
|
|
|
|
t.Create();
|
|
t.Update();
|
|
t.Delete();
|
|
*bytes = t.bytes;
|
|
*type = (int)t.tex_type;
|
|
if (t.planned)
|
|
*plan = t.plan;
|
|
return t.planned;
|
|
}
|
|
|
|
/* For the palette: the registers' memory */
|
|
extern "C" void *texd_cpu_palette_ram(void)
|
|
{
|
|
return PALETTE_RAM;
|
|
}
|