treat paletted textures as always being twiddled

fix palette ram index calculations
only store a textue's actual palette in each trace event, not all of the palette ram
This commit is contained in:
Anthony Pesch 2015-09-09 01:51:51 -07:00
parent c16da7c84a
commit 4549589d46
11 changed files with 123 additions and 102 deletions

View File

@ -146,12 +146,12 @@ void Dreamcast::InitMemory() {
std::bind(&AICA::WriteRegister32, aica(), _1, _2), //
nullptr);
memory_->Handle(WAVE_RAM_START, WAVE_RAM_END, MIRROR_MASK,
nullptr, //
nullptr, //
nullptr, //
nullptr, //
std::bind(&AICA::ReadWave32, aica(), _1), //
nullptr, //
nullptr, //
nullptr, //
nullptr, //
nullptr, //
nullptr, //
std::bind(&AICA::WriteWave32, aica(), _1, _2), //
nullptr);

View File

@ -144,10 +144,15 @@ void Holly::WriteRegister32(uint32_t addr, uint32_t value) {
case SB_E2ST_OFFSET:
case SB_DDEN_OFFSET:
case SB_DDST_OFFSET:
if (value) {
LOG_WARNING("Ignored AICA DMA request");
}
break;
case SB_PDEN_OFFSET:
case SB_PDST_OFFSET:
if (value) {
LOG_FATAL("AICA DMA request");
LOG_WARNING("Ignored palette DMA request");
}
break;

View File

@ -156,8 +156,8 @@ class PixelConvert {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
FROM::Read(src[y * width + x], &r, &g, &b, &a);
TO::Write(&dst[y * width + x], r, g, b, a);
FROM::Read(*(src++), &r, &g, &b, &a);
TO::Write(dst++, r, g, b, a);
}
}
}
@ -180,23 +180,24 @@ class PixelConvert {
template <typename FROM, typename TO>
static void ConvertPal4(const uint8_t *src, typename TO::data_type *dst,
uint32_t *palette, int width, int height) {
// int min = std::min(width, height);
const uint32_t *palette, int width, int height) {
int min = std::min(width, height);
uint8_t r, g, b, a;
// always twiddled
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
// int tidx = TWIDIDX(x, y, min);
int tidx = y * width + x;
int tidx = TWIDIDX(x, y, min);
int palette_idx = src[tidx >> 1];
if (tidx & 1) {
palette_idx >>= 4;
} else {
palette_idx &= 0xf;
}
auto entry = reinterpret_cast<const typename FROM::data_type *>(
&palette[palette_idx]);
FROM::Read(*entry, &r, &g, &b, &a);
typename FROM::data_type entry =
*(reinterpret_cast<const typename FROM::data_type *>(
&palette[palette_idx]));
FROM::Read(entry, &r, &g, &b, &a);
TO::Write(dst++, r, g, b, a);
}
}
@ -204,16 +205,18 @@ class PixelConvert {
template <typename FROM, typename TO>
static void ConvertPal8(const uint8_t *src, typename TO::data_type *dst,
uint32_t *palette, int width, int height) {
const uint32_t *palette, int width, int height) {
int min = std::min(width, height);
uint8_t r, g, b, a;
// always twiddled
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
int tidx = TWIDIDX(x, y, min);
auto entry = reinterpret_cast<const typename FROM::data_type *>(
&palette[src[tidx]]);
FROM::Read(*entry, &r, &g, &b, &a);
int palette_idx = src[TWIDIDX(x, y, min)];
typename FROM::data_type entry =
*reinterpret_cast<const typename FROM::data_type *>(
&palette[palette_idx]);
FROM::Read(entry, &r, &g, &b, &a);
TO::Write(dst++, r, g, b, a);
}
}
@ -225,6 +228,7 @@ class PixelConvert {
int min = std::min(width, height);
uint8_t r, g, b, a;
// always twiddled
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
int tidx = TWIDIDX(x, y, min);

View File

@ -210,41 +210,44 @@ TextureHandle TileTextureCache::GetTexture(
uint32_t texture_addr = tcw.texture_addr << 3;
// get the texture data
const uint8_t *video_ram = dc_->video_ram();
const uint8_t *texture = &video_ram[texture_addr];
int width = 8 << tsp.texture_u_size;
int height = 8 << tsp.texture_v_size;
int element_size_bits = tcw.pixel_format == TA_PIXEL_8BPP
? 8
: tcw.pixel_format == TA_PIXEL_4BPP ? 4 : 16;
int texture_size = (width * height * element_size_bits) >> 3;
const uint8_t *texture = &dc_->video_ram()[texture_addr];
// get the palette data
const uint8_t *palette = dc_->palette_ram();
int palette_size = 0;
const uint8_t *palette = nullptr;
if (tcw.pixel_format == TA_PIXEL_4BPP || tcw.pixel_format == TA_PIXEL_8BPP) {
uint32_t palette_addr = 0;
// palette ram is 4096 bytes, with each palette entry being 4 bytes each,
// resulting in 1 << 10 indexes
if (tcw.pixel_format == TA_PIXEL_4BPP) {
palette_addr = (tcw.p.palette_selector << 4);
} else {
// in 8BPP palette mode, only the upper two bits are valid
palette_addr = ((tcw.p.palette_selector & 0x30) << 4);
// in 4bpp mode, the palette selector represents the upper 6 bits of the
// palette index, with the remaining 4 bits being filled in by the texture
palette += (tcw.p.palette_selector << 4) * 4;
palette_size = (1 << 4) * 4;
} else if (tcw.pixel_format == TA_PIXEL_8BPP) {
// in 4bpp mode, the palette selector represents the upper 2 bits of the
// palette index, with the remaining 8 bits being filled in by the texture
palette += ((tcw.p.palette_selector & 0x30) << 4) * 4;
palette_size = (1 << 8) * 4;
}
palette_size = 0x1000;
palette = &dc_->palette_ram()[palette_addr];
}
// register and insert into the cache
TextureHandle handle = register_cb(texture, palette);
TextureHandle handle = register_cb(palette, texture);
auto result = textures_.insert(std::make_pair(texture_key, handle));
CHECK(result.second, "Texture already in the map?");
// add insert to trace
if (trace_writer_) {
trace_writer_->WriteInsertTexture(tsp, tcw, texture, texture_size, palette,
palette_size);
trace_writer_->WriteInsertTexture(tsp, tcw, palette, palette_size, texture,
texture_size);
}
return result.first->second;

View File

@ -49,20 +49,18 @@ enum {
};
enum {
TA_PIXEL_1555 = 0,
TA_PIXEL_565 = 1,
TA_PIXEL_4444 = 2,
TA_PIXEL_YUV422 = 3,
TA_PIXEL_BUMPMAP = 4,
TA_PIXEL_4BPP = 5,
TA_PIXEL_8BPP = 6,
TA_PIXEL_RESERVED = 7,
TA_PAL_ARGB1555 = 0,
TA_PAL_RGB565 = 1,
TA_PAL_ARGB4444 = 2,
TA_PAL_ARGB8888 = 3
TA_PIXEL_1555,
TA_PIXEL_565,
TA_PIXEL_4444,
TA_PIXEL_YUV422,
TA_PIXEL_BUMPMAP,
TA_PIXEL_4BPP,
TA_PIXEL_8BPP,
TA_PIXEL_RESERVED
};
enum { TA_PAL_ARGB1555, TA_PAL_RGB565, TA_PAL_ARGB4444, TA_PAL_ARGB8888 };
//
//
//

View File

@ -85,7 +85,7 @@ inline ShadeMode TranslateShadeMode(uint32_t shade_mode) {
return shade_modes[shade_mode];
}
static inline uint32_t argb_to_abgr(uint32_t v) {
static inline uint32_t abgr_to_rgba(uint32_t v) {
return (v & 0xff000000) | ((v & 0xff) << 16) | (v & 0xff00) |
((v & 0xff0000) >> 16);
}
@ -94,7 +94,7 @@ static inline uint8_t float_to_u8(float x) {
return std::min(std::max((uint32_t)(x * 255.0f), 0u), 255u);
}
static inline uint32_t float_to_abgr(float r, float g, float b, float a) {
static inline uint32_t float_to_rgba(float r, float g, float b, float a) {
return (float_to_u8(a) << 24) | (float_to_u8(b) << 16) |
(float_to_u8(g) << 8) | float_to_u8(r);
}
@ -220,7 +220,7 @@ Vertex *TileRenderer::AllocVert() {
// FIXME honor use alpha
// FIXME honor ignore tex alpha
void TileRenderer::ParseColor(uint32_t base_color, uint32_t *color) {
*color = argb_to_abgr(base_color);
*color = abgr_to_rgba(base_color);
// if (!last_poly_->type0.tsp.use_alpha) {
// color[3] = 1.0f;
@ -229,7 +229,7 @@ void TileRenderer::ParseColor(uint32_t base_color, uint32_t *color) {
void TileRenderer::ParseColor(float r, float g, float b, float a,
uint32_t *color) {
*color = float_to_abgr(r, g, b, a);
*color = float_to_rgba(r, g, b, a);
// if (!last_poly_->type0.tsp.use_alpha) {
// color[3] = 1.0f;
@ -237,7 +237,7 @@ void TileRenderer::ParseColor(float r, float g, float b, float a,
}
void TileRenderer::ParseColor(float intensity, uint32_t *color) {
*color = float_to_abgr(face_color_[0] * intensity, face_color_[1] * intensity,
*color = float_to_rgba(face_color_[0] * intensity, face_color_[1] * intensity,
face_color_[2] * intensity, face_color_[3]);
// if (!last_poly_->type0.tsp.use_alpha) {
@ -249,7 +249,7 @@ void TileRenderer::ParseOffsetColor(uint32_t offset_color, uint32_t *color) {
if (!last_poly_->type0.isp_tsp.offset) {
*color = 0;
} else {
*color = argb_to_abgr(offset_color);
*color = abgr_to_rgba(offset_color);
}
}
@ -258,7 +258,7 @@ void TileRenderer::ParseOffsetColor(float r, float g, float b, float a,
if (!last_poly_->type0.isp_tsp.offset) {
*color = 0;
} else {
*color = float_to_abgr(r, g, b, a);
*color = float_to_rgba(r, g, b, a);
}
}
@ -266,7 +266,7 @@ void TileRenderer::ParseOffsetColor(float intensity, uint32_t *color) {
if (!last_poly_->type0.isp_tsp.offset) {
*color = 0;
} else {
*color = float_to_abgr(
*color = float_to_rgba(
face_offset_color_[0] * intensity, face_offset_color_[1] * intensity,
face_offset_color_[2] * intensity, face_offset_color_[3]);
}
@ -307,7 +307,7 @@ void TileRenderer::ParseBackground(const TileContext *tactx) {
uint32_t base_color =
*reinterpret_cast<const uint32_t *>(&tactx->bg_vertices[offset]);
v->color = argb_to_abgr(base_color);
v->color = abgr_to_rgba(base_color);
offset += 4;
if (tactx->bg_isp.offset) {
@ -692,8 +692,8 @@ Eigen::Matrix4f TileRenderer::GetProjectionMatrix(const TileContext *tactx) {
TextureHandle TileRenderer::RegisterTexture(const TileContext *tactx,
Backend *rb, const TSP &tsp,
const TCW &tcw,
const uint8_t *texture,
const uint8_t *palette) {
const uint8_t *palette,
const uint8_t *texture) {
static uint8_t converted[1024 * 1024 * 4];
const uint8_t *input = texture;
const uint8_t *output = texture;
@ -745,13 +745,16 @@ TextureHandle TileRenderer::RegisterTexture(const TileContext *tactx,
pixel_fmt = PXL_RGBA5551;
if (compressed) {
PixelConvert::ConvertVQ<ARGB1555, RGBA5551>(
codebook, index, (uint16_t *)converted, width, height);
codebook, index, reinterpret_cast<uint16_t *>(converted), width,
height);
} else if (twiddled) {
PixelConvert::ConvertTwiddled<ARGB1555, RGBA5551>(
(uint16_t *)input, (uint16_t *)converted, width, height);
reinterpret_cast<const uint16_t *>(input),
reinterpret_cast<uint16_t *>(converted), width, height);
} else {
PixelConvert::Convert<ARGB1555, RGBA5551>(
(uint16_t *)input, (uint16_t *)converted, stride, height);
reinterpret_cast<const uint16_t *>(input),
reinterpret_cast<uint16_t *>(converted), stride, height);
}
break;
@ -760,13 +763,16 @@ TextureHandle TileRenderer::RegisterTexture(const TileContext *tactx,
pixel_fmt = PXL_RGB565;
if (compressed) {
PixelConvert::ConvertVQ<RGB565, RGB565>(
codebook, index, (uint16_t *)converted, width, height);
codebook, index, reinterpret_cast<uint16_t *>(converted), width,
height);
} else if (twiddled) {
PixelConvert::ConvertTwiddled<RGB565, RGB565>(
(uint16_t *)input, (uint16_t *)converted, width, height);
reinterpret_cast<const uint16_t *>(input),
reinterpret_cast<uint16_t *>(converted), width, height);
} else {
PixelConvert::Convert<RGB565, RGB565>(
(uint16_t *)input, (uint16_t *)converted, stride, height);
reinterpret_cast<const uint16_t *>(input),
reinterpret_cast<uint16_t *>(converted), stride, height);
}
break;
@ -775,17 +781,21 @@ TextureHandle TileRenderer::RegisterTexture(const TileContext *tactx,
pixel_fmt = PXL_RGBA4444;
if (compressed) {
PixelConvert::ConvertVQ<ARGB4444, RGBA4444>(
codebook, index, (uint16_t *)converted, width, height);
codebook, index, reinterpret_cast<uint16_t *>(converted), width,
height);
} else if (twiddled) {
PixelConvert::ConvertTwiddled<ARGB4444, RGBA4444>(
(uint16_t *)input, (uint16_t *)converted, width, height);
reinterpret_cast<const uint16_t *>(input),
reinterpret_cast<uint16_t *>(converted), width, height);
} else {
PixelConvert::Convert<ARGB4444, RGBA4444>(
(uint16_t *)input, (uint16_t *)converted, stride, height);
reinterpret_cast<const uint16_t *>(input),
reinterpret_cast<uint16_t *>(converted), stride, height);
}
break;
case TA_PIXEL_4BPP:
CHECK(!compressed);
output = converted;
switch (tactx->pal_pxl_format) {
case TA_PAL_ARGB1555:
@ -799,14 +809,13 @@ TextureHandle TileRenderer::RegisterTexture(const TileContext *tactx,
break;
case TA_PAL_ARGB4444:
CHECK_EQ(false, twiddled);
pixel_fmt = PXL_RGBA4444;
PixelConvert::ConvertPal4<ARGB4444, RGBA4444>(
input, (uint16_t *)converted, (uint32_t *)palette, width, height);
input, reinterpret_cast<uint16_t *>(converted),
reinterpret_cast<const uint32_t *>(palette), width, height);
break;
case TA_PAL_ARGB8888:
CHECK_EQ(true, twiddled);
pixel_fmt = PXL_RGBA8888;
LOG_FATAL("Unhandled");
break;
@ -814,6 +823,7 @@ TextureHandle TileRenderer::RegisterTexture(const TileContext *tactx,
break;
case TA_PIXEL_8BPP:
CHECK(!compressed);
output = converted;
switch (tactx->pal_pxl_format) {
case TA_PAL_ARGB1555:
@ -827,17 +837,17 @@ TextureHandle TileRenderer::RegisterTexture(const TileContext *tactx,
break;
case TA_PAL_ARGB4444:
CHECK_EQ(true, twiddled);
pixel_fmt = PXL_RGBA4444;
PixelConvert::ConvertPal8<ARGB4444, RGBA4444>(
input, (uint16_t *)converted, (uint32_t *)palette, width, height);
input, reinterpret_cast<uint16_t *>(converted),
reinterpret_cast<const uint32_t *>(palette), width, height);
break;
case TA_PAL_ARGB8888:
CHECK_EQ(true, twiddled);
pixel_fmt = PXL_RGBA8888;
PixelConvert::ConvertPal8<ARGB8888, RGBA8888>(
input, (uint32_t *)converted, (uint32_t *)palette, width, height);
input, reinterpret_cast<uint32_t *>(converted),
reinterpret_cast<const uint32_t *>(palette), width, height);
break;
}
break;
@ -858,6 +868,7 @@ TextureHandle TileRenderer::RegisterTexture(const TileContext *tactx,
TextureHandle handle = rb->RegisterTexture(pixel_fmt, filter, wrap_u, wrap_v,
mip_mapped, width, height, output);
if (!handle) {
LOG_WARNING("Failed to register texture");
return 0;
@ -869,7 +880,7 @@ TextureHandle TileRenderer::RegisterTexture(const TileContext *tactx,
TextureHandle TileRenderer::GetTexture(const TileContext *tactx, Backend *rb,
const TSP &tsp, const TCW &tcw) {
return texcache_.GetTexture(
tsp, tcw, [&](const uint8_t *texture, const uint8_t *palette) {
return RegisterTexture(tactx, rb, tsp, tcw, texture, palette);
tsp, tcw, [&](const uint8_t *palette, const uint8_t *texture) {
return RegisterTexture(tactx, rb, tsp, tcw, palette, texture);
});
}

View File

@ -63,8 +63,8 @@ class TileRenderer {
renderer::TextureHandle RegisterTexture(const TileContext *tactx,
renderer::Backend *rb, const TSP &tsp,
const TCW &tcw,
const uint8_t *texture,
const uint8_t *palette);
const uint8_t *palette,
const uint8_t *texture);
renderer::TextureHandle GetTexture(const TileContext *tactx,
renderer::Backend *rb, const TSP &tsp,
const TCW &tcw);

View File

@ -79,10 +79,10 @@ bool TraceReader::PatchPointers() {
// patch relative data pointers
switch (curr_cmd->type) {
case TRACE_INSERT_TEXTURE: {
curr_cmd->insert_texture.texture += reinterpret_cast<intptr_t>(ptr);
curr_cmd->insert_texture.palette += reinterpret_cast<intptr_t>(ptr);
ptr += sizeof(*curr_cmd) + curr_cmd->insert_texture.texture_size +
curr_cmd->insert_texture.palette_size;
curr_cmd->insert_texture.texture += reinterpret_cast<intptr_t>(ptr);
ptr += sizeof(*curr_cmd) + curr_cmd->insert_texture.palette_size +
curr_cmd->insert_texture.texture_size;
} break;
case TRACE_RENDER_CONTEXT: {
@ -157,25 +157,25 @@ void TraceWriter::Close() {
}
void TraceWriter::WriteInsertTexture(const TSP &tsp, const TCW &tcw,
const uint8_t *texture, int texture_size,
const uint8_t *palette, int palette_size) {
const uint8_t *palette, int palette_size,
const uint8_t *texture, int texture_size) {
TraceCommand cmd;
cmd.type = TRACE_INSERT_TEXTURE;
cmd.insert_texture.tsp = tsp;
cmd.insert_texture.tcw = tcw;
cmd.insert_texture.texture_size = texture_size;
cmd.insert_texture.texture = reinterpret_cast<const uint8_t *>(sizeof(cmd));
cmd.insert_texture.palette_size = palette_size;
cmd.insert_texture.palette =
reinterpret_cast<const uint8_t *>(sizeof(cmd) + texture_size);
cmd.insert_texture.palette = reinterpret_cast<const uint8_t *>(sizeof(cmd));
cmd.insert_texture.texture_size = texture_size;
cmd.insert_texture.texture =
reinterpret_cast<const uint8_t *>(sizeof(cmd) + palette_size);
CHECK_EQ(fwrite(&cmd, sizeof(cmd), 1, file_), 1);
if (texture_size) {
CHECK_EQ(fwrite(texture, texture_size, 1, file_), 1);
}
if (palette_size) {
CHECK_EQ(fwrite(palette, palette_size, 1, file_), 1);
}
if (texture_size) {
CHECK_EQ(fwrite(texture, texture_size, 1, file_), 1);
}
}
void TraceWriter::WriteRenderContext(TileContext *tactx) {

View File

@ -24,10 +24,10 @@ struct TraceCommand {
struct {
holly::TSP tsp;
holly::TCW tcw;
uint32_t texture_size;
const uint8_t *texture;
uint32_t palette_size;
const uint8_t *palette;
uint32_t texture_size;
const uint8_t *texture;
} insert_texture;
// slimmed down version of the TileContext structure, will need to be in
@ -79,8 +79,8 @@ class TraceWriter {
void Close();
void WriteInsertTexture(const holly::TSP &tsp, const holly::TCW &tcw,
const uint8_t *texture, int texture_size,
const uint8_t *palette, int palette_size);
const uint8_t *palette, int palette_size,
const uint8_t *texture, int texture_size);
void WriteRenderContext(holly::TileContext *tactx);
private:

View File

@ -12,11 +12,11 @@ using namespace dreavm::system;
using namespace dreavm::trace;
void TraceTextureCache::AddTexture(const TSP &tsp, TCW &tcw,
const uint8_t *texture,
const uint8_t *palette) {
const uint8_t *palette,
const uint8_t *texture) {
uint32_t texture_key = TextureCache::GetTextureKey(tsp, tcw);
textures_[texture_key] =
TextureInst{tsp, tcw, texture, palette, (TextureHandle)0};
TextureInst{tsp, tcw, palette, texture, (TextureHandle)0};
}
void TraceTextureCache::RemoveTexture(const TSP &tsp, TCW &tcw) {
@ -36,7 +36,7 @@ TextureHandle TraceTextureCache::GetTexture(
// register the texture if it hasn't already been
if (!texture.handle) {
// TODO compare tex_it->tsp and tex_it->tcw with incoming?
texture.handle = register_cb(texture.texture, texture.palette);
texture.handle = register_cb(texture.palette, texture.texture);
}
return texture.handle;
@ -186,7 +186,7 @@ void TraceViewer::PrevContext() {
CHECK_EQ(override->type, TRACE_INSERT_TEXTURE);
texcache_.AddTexture(
override->insert_texture.tsp, override->insert_texture.tcw,
override->insert_texture.texture, override->insert_texture.palette);
override->insert_texture.palette, override->insert_texture.texture);
}
} else if (current_cmd_->type == TRACE_RENDER_CONTEXT) {
if (--current_frame_ == prev_frame) {
@ -214,8 +214,8 @@ void TraceViewer::NextContext() {
if (current_cmd_->type == TRACE_INSERT_TEXTURE) {
texcache_.AddTexture(current_cmd_->insert_texture.tsp,
current_cmd_->insert_texture.tcw,
current_cmd_->insert_texture.texture,
current_cmd_->insert_texture.palette);
current_cmd_->insert_texture.palette,
current_cmd_->insert_texture.texture);
} else if (current_cmd_->type == TRACE_RENDER_CONTEXT) {
if (++current_frame_ == next_frame) {
break;

View File

@ -13,15 +13,15 @@ namespace trace {
struct TextureInst {
holly::TSP tsp;
holly::TCW tcw;
const uint8_t *texture;
const uint8_t *palette;
const uint8_t *texture;
renderer::TextureHandle handle;
};
class TraceTextureCache : public holly::TextureCache {
public:
void AddTexture(const holly::TSP &tsp, holly::TCW &tcw,
const uint8_t *texture, const uint8_t *palette);
const uint8_t *palette, const uint8_t *texture);
void RemoveTexture(const holly::TSP &tsp, holly::TCW &tcw);
renderer::TextureHandle GetTexture(