X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=plugins%2Fgpu_neon%2Fpsx_gpu%2Fpsx_gpu.c;h=cf6e2be4331c27a37856e8164190eff4da96a70b;hp=75deb3016801f8f7890dcaf063a48aadc189429a;hb=05740673341dbd61b23085c8cf1303f632e44f87;hpb=24b9bacccdb340d369f10ece217603d63aadc264 diff --git a/plugins/gpu_neon/psx_gpu/psx_gpu.c b/plugins/gpu_neon/psx_gpu/psx_gpu.c index 75deb301..cf6e2be4 100644 --- a/plugins/gpu_neon/psx_gpu/psx_gpu.c +++ b/plugins/gpu_neon/psx_gpu/psx_gpu.c @@ -244,6 +244,58 @@ u32 invalidate_texture_cache_region_viewport(psx_gpu_struct *psx_gpu, u32 x1, return mask; } +void update_texture_cache_region(psx_gpu_struct *psx_gpu, u32 x1, u32 y1, + u32 x2, u32 y2) +{ + u32 mask = texture_region_mask(x1, y1, x2, y2); + u32 texture_page; + u8 *texture_page_ptr; + u16 *vram_ptr; + u32 texel_block; + u32 sub_x, sub_y; + + psx_gpu->dirty_textures_8bpp_mask |= mask; + psx_gpu->dirty_textures_8bpp_alternate_mask |= mask; + + if ((psx_gpu->dirty_textures_4bpp_mask & mask) == 0 && + (x1 & 3) == 0 && (y1 & 15) == 0 && x2 - x1 < 4 && y2 - y1 < 16) + { + texture_page = ((x1 / 64) & 15) + (y1 / 256) * 16; + texture_page_ptr = psx_gpu->texture_4bpp_cache[texture_page]; + texture_page_ptr += (x1 / 4 & 15) * 16*16 + (y1 / 16 & 15) * 16*16*16; + vram_ptr = psx_gpu->vram_ptr + x1 + y1 * 1024; + sub_x = 4; + sub_y = 16; + + while(sub_y) + { + while(sub_x) + { + texel_block = *vram_ptr; + + texture_page_ptr[0] = texel_block & 0xF; + texture_page_ptr[1] = (texel_block >> 4) & 0xF; + texture_page_ptr[2] = (texel_block >> 8) & 0xF; + texture_page_ptr[3] = texel_block >> 12; + + vram_ptr++; + texture_page_ptr += 4; + + sub_x--; + } + + vram_ptr -= 4; + sub_x = 4; + + sub_y--; + vram_ptr += 1024; + } + } + else + { + psx_gpu->dirty_textures_4bpp_mask |= mask; + } +} void update_texture_8bpp_cache_slice(psx_gpu_struct *psx_gpu, u32 texture_page); @@ -401,6 +453,48 @@ void setup_blocks_shaded_untextured_undithered_unswizzled_indirect( void flush_render_block_buffer(psx_gpu_struct *psx_gpu) { + if((psx_gpu->interlace_mode & RENDER_INTERLACE_ENABLED) && + (psx_gpu->primitive_type == PRIMITIVE_TYPE_SPRITE)) + { + u32 num_blocks_dest = 0; + block_struct *block_src = psx_gpu->blocks; + block_struct *block_dest = psx_gpu->blocks; + + u16 *vram_ptr = psx_gpu->vram_ptr; + u32 i; + + if(psx_gpu->interlace_mode & RENDER_INTERLACE_ODD) + { + for(i = 0; i < psx_gpu->num_blocks; i++) + { + u32 fb_offset = (u32)((u8 *)block_src->fb_ptr - (u8 *)vram_ptr); + if(fb_offset & (1 << 11)) + { + *block_dest = *block_src; + num_blocks_dest++; + block_dest++; + } + block_src++; + } + } + else + { + for(i = 0; i < psx_gpu->num_blocks; i++) + { + u32 fb_offset = (u32)((u8 *)block_src->fb_ptr - (u8 *)vram_ptr); + if((fb_offset & (1 << 11)) == 0) + { + *block_dest = *block_src; + num_blocks_dest++; + block_dest++; + } + block_src++; + } + } + + psx_gpu->num_blocks = num_blocks_dest; + } + if(psx_gpu->num_blocks) { render_block_handler_struct *render_block_handler = @@ -2987,6 +3081,28 @@ void render_triangle(psx_gpu_struct *psx_gpu, vertex_struct *vertexes, spans += psx_gpu->num_spans; #endif + if(psx_gpu->interlace_mode & RENDER_INTERLACE_ENABLED) + { + u32 i; + + if(psx_gpu->interlace_mode & RENDER_INTERLACE_ODD) + { + for(i = 0; i < psx_gpu->num_spans; i++) + { + if((psx_gpu->span_edge_data[i].y & 1) == 0) + psx_gpu->span_edge_data[i].num_blocks = 0; + } + } + else + { + for(i = 0; i < psx_gpu->num_spans; i++) + { + if(psx_gpu->span_edge_data[i].y & 1) + psx_gpu->span_edge_data[i].num_blocks = 0; + } + } + } + u32 render_state = flags & (RENDER_FLAGS_MODULATE_TEXELS | RENDER_FLAGS_BLEND | RENDER_FLAGS_TEXTURE_MAP | RENDER_FLAGS_SHADE); @@ -4322,38 +4438,56 @@ void render_block_fill(psx_gpu_struct *psx_gpu, u32 color, u32 x, u32 y, flush_render_block_buffer(psx_gpu); invalidate_texture_cache_region(psx_gpu, x, y, x + width - 1, y + height - 1); -#ifndef NEON_BUILD u32 r = color & 0xFF; u32 g = (color >> 8) & 0xFF; u32 b = (color >> 16) & 0xFF; - u32 color_16bpp = (r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10); + u32 color_16bpp = (r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10) | + psx_gpu->mask_msb; + u32 color_32bpp = color_16bpp | (color_16bpp << 16); - u16 *vram_ptr = psx_gpu->vram_ptr + x + (y * 1024); - u32 draw_x, draw_y; + u32 *vram_ptr = (u32 *)(psx_gpu->vram_ptr + x + (y * 1024)); - for(draw_y = 0; draw_y < height; draw_y++) + u32 pitch = 512 - (width / 2); + u32 num_width; + + if(psx_gpu->interlace_mode & RENDER_INTERLACE_ENABLED) { - for(draw_x = 0; draw_x < width; draw_x++) + pitch += 512; + height /= 2; + + if(psx_gpu->interlace_mode & RENDER_INTERLACE_ODD) + vram_ptr += 512; + } + + while(height) + { + num_width = width; + while(num_width) { - vram_ptr[draw_x] = color_16bpp; + vram_ptr[0] = color_32bpp; + vram_ptr[1] = color_32bpp; + vram_ptr[2] = color_32bpp; + vram_ptr[3] = color_32bpp; + vram_ptr[4] = color_32bpp; + vram_ptr[5] = color_32bpp; + vram_ptr[6] = color_32bpp; + vram_ptr[7] = color_32bpp; + + vram_ptr += 8; + num_width -= 16; } - vram_ptr += 1024; + vram_ptr += pitch; + height--; } -#else - void render_block_fill_body(psx_gpu_struct *psx_gpu, u32 color, u32 x, u32 y, - u32 width, u32 height); - - render_block_fill_body(psx_gpu, color, x, y, width, height); -#endif } void render_block_copy(psx_gpu_struct *psx_gpu, u16 *source, u32 x, u32 y, u32 width, u32 height, u32 pitch) { u16 *vram_ptr = psx_gpu->vram_ptr + x + (y * 1024); - u32 mask_msb = psx_gpu->mask_msb; u32 draw_x, draw_y; + u32 mask_msb = psx_gpu->mask_msb; if((width == 0) || (height == 0)) return; @@ -4439,6 +4573,8 @@ void initialize_psx_gpu(psx_gpu_struct *psx_gpu, u16 *vram) psx_gpu->texture_mask_width = 0xFF; psx_gpu->texture_mask_height = 0xFF; + psx_gpu->interlace_mode = 0; + memset(psx_gpu->vram_ptr, 0, sizeof(u16) * 1024 * 512); initialize_reciprocal_table();