The r100 stores a full GPU address in the dst, src, and default offset registers. For this reason the addresses need to be routed via the memory controller to obtain offsets. This differs from the r128 which directly stores framebuffer offsets.
Blits outside of VRAM are still not supported. The existing bounds checks catch this in most cases. A small edge case exists where an offset register could be set to a low memory address outside of the VRAM mapping and end up treated as a VRAM offset. This has not been observed in real drivers but should be handled when implementing blits outside of VRAM. Signed-off-by: Chad Jablonski <[email protected]> --- hw/display/ati_2d.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c index f51ecb747a..e1cbf9efa9 100644 --- a/hw/display/ati_2d.c +++ b/hw/display/ati_2d.c @@ -135,10 +135,13 @@ static void setup_2d_blt_ctx(ATIVGAState *s, ATI2DCtx *ctx) ctx->dst_stride = s->regs.dst_pitch * ctx->bpp; ctx->dst_offset = s->regs.dst_offset; } else { + ATIMemRoute res = ati_mc_route(s, s->regs.dp_gui_master_cntl & + GMC_DST_PITCH_OFFSET_CNTL + ? s->regs.dst_offset + : s->regs.default_offset); ctx->dst_stride = s->regs.dp_gui_master_cntl & GMC_DST_PITCH_OFFSET_CNTL ? s->regs.dst_pitch : s->regs.default_pitch; - ctx->dst_offset = s->regs.dp_gui_master_cntl & GMC_DST_PITCH_OFFSET_CNTL - ? s->regs.dst_offset : s->regs.default_offset; + ctx->dst_offset = res.addr; } ctx->dst_bits = s->vga.vram_ptr + ctx->dst_offset; @@ -150,11 +153,13 @@ static void setup_2d_blt_ctx(ATIVGAState *s, ATI2DCtx *ctx) ctx->src_stride = s->regs.src_pitch * ctx->bpp; ctx->src_bits = s->vga.vram_ptr + s->regs.src_offset; } else { + uint32_t src = s->regs.dp_gui_master_cntl & GMC_SRC_PITCH_OFFSET_CNTL + ? s->regs.src_offset + : s->regs.default_offset; + ATIMemRoute res = ati_mc_route(s, src); ctx->src_stride = s->regs.dp_gui_master_cntl & GMC_SRC_PITCH_OFFSET_CNTL ? s->regs.src_pitch : s->regs.default_pitch; - ctx->src_bits = s->vga.vram_ptr + - (s->regs.dp_gui_master_cntl & GMC_SRC_PITCH_OFFSET_CNTL - ? s->regs.src_offset : s->regs.default_offset); + ctx->src_bits = s->vga.vram_ptr + res.addr; } DPRINTF("%d %d %d, %d %d %d, (%d,%d) -> (%d,%d) %dx%d %c %c\n", s->regs.src_offset, s->regs.dst_offset, s->regs.default_offset, -- 2.54.0
