u32 texture_cache_loads = 0;
u32 false_modulated_blocks = 0;
-u32 reciprocal_table[512];
+/* double size for enhancement */
+u32 reciprocal_table[512 * 2];
typedef s32 fixed_type;
void flush_render_block_buffer(psx_gpu_struct *psx_gpu)
{
- if((psx_gpu->interlace_mode & RENDER_INTERLACE_ENABLED) &&
+ if((psx_gpu->render_mode & RENDER_INTERLACE_ENABLED) &&
(psx_gpu->primitive_type == PRIMITIVE_TYPE_SPRITE))
{
u32 num_blocks_dest = 0;
u16 *vram_ptr = psx_gpu->vram_ptr;
u32 i;
- if(psx_gpu->interlace_mode & RENDER_INTERLACE_ODD)
+ if(psx_gpu->render_mode & RENDER_INTERLACE_ODD)
{
for(i = 0; i < psx_gpu->num_blocks; i++)
{
vec_4x32u uvrg_base;
vec_4x32u b_base;
- vec_4x32u const_0x8000;
+ vec_4x32u uvrgb_phase;
vec_4x16s d0_a_d3_c, d0_b, d0_c;
vec_4x16s d1_a, d1_b, d1_c_d2_a;
setup_gradient_calculation_input(1, b);
setup_gradient_calculation_input(2, c);
- dup_4x32b(const_0x8000, 0x8000);
+ dup_4x32b(uvrgb_phase, psx_gpu->uvrgb_phase);
shl_long_4x16b(uvrg_base, x0_a_y0_c, 16);
shl_long_4x16b(b_base, x0_b, 16);
- add_4x32b(uvrg_base, uvrg_base, const_0x8000);
- add_4x32b(b_base, b_base, const_0x8000);
+ add_4x32b(uvrg_base, uvrg_base, uvrgb_phase);
+ add_4x32b(b_base, b_base, uvrgb_phase);
// Can probably pair these, but it'll require careful register allocation
sub_4x16b(d0_a_d3_c, x1_a_y1_c, x0_a_y0_c);
if(span_num_blocks) \
{ \
y = span_edge_data->y; \
- fb_ptr = psx_gpu->vram_ptr + span_edge_data->left_x + (y * 1024); \
+ fb_ptr = psx_gpu->vram_out_ptr + span_edge_data->left_x + (y * 1024); \
\
setup_blocks_span_initialize_##shading##_##texturing(); \
setup_blocks_span_initialize_##dithering(texturing); \
(triangle_y_direction_##direction_c << 4) | \
(triangle_winding_##winding << 6)) \
-void render_triangle(psx_gpu_struct *psx_gpu, vertex_struct *vertexes,
- u32 flags)
+static int prepare_triangle(psx_gpu_struct *psx_gpu, vertex_struct *vertexes,
+ vertex_struct *vertexes_out[3])
{
s32 y_top, y_bottom;
s32 triangle_area;
#ifdef PROFILE
trivial_rejects++;
#endif
- return;
+ return 0;
}
if(b->y < a->y)
#ifdef PROFILE
trivial_rejects++;
#endif
- return;
+ return 0;
}
if(triangle_area < 0)
#ifdef PROFILE
trivial_rejects++;
#endif
- return;
+ return 0;
}
if(invalidate_texture_cache_region_viewport(psx_gpu, a->x, y_top, c->x,
#ifdef PROFILE
trivial_rejects++;
#endif
- return;
+ return 0;
}
- psx_gpu->num_spans = 0;
psx_gpu->triangle_area = triangle_area;
psx_gpu->triangle_winding = triangle_winding;
+ vertexes_out[0] = a;
+ vertexes_out[1] = b;
+ vertexes_out[2] = c;
+
+ return 1;
+}
+
+static void render_triangle_p(psx_gpu_struct *psx_gpu,
+ vertex_struct *vertex_ptrs[3], u32 flags)
+{
+ psx_gpu->num_spans = 0;
+
+ vertex_struct *a = vertex_ptrs[0];
+ vertex_struct *b = vertex_ptrs[1];
+ vertex_struct *c = vertex_ptrs[2];
+
s32 y_delta_a = b->y - a->y;
s32 y_delta_b = c->y - b->y;
s32 y_delta_c = c->y - a->y;
compute_all_gradients(psx_gpu, a, b, c);
switch(y_direction_a | (y_direction_b << 2) | (y_direction_c << 4) |
- (triangle_winding << 6))
+ (psx_gpu->triangle_winding << 6))
{
triangle_case(up, up, up, negative):
triangle_case(up, up, flat, negative):
spans += psx_gpu->num_spans;
#endif
- if(psx_gpu->interlace_mode & RENDER_INTERLACE_ENABLED)
+ if(unlikely(psx_gpu->render_mode & RENDER_INTERLACE_ENABLED))
{
u32 i;
- if(psx_gpu->interlace_mode & RENDER_INTERLACE_ODD)
+ if(psx_gpu->render_mode & RENDER_INTERLACE_ODD)
{
for(i = 0; i < psx_gpu->num_spans; i++)
{
(psx_gpu);
}
+void render_triangle(psx_gpu_struct *psx_gpu, vertex_struct *vertexes,
+ u32 flags)
+{
+ vertex_struct *vertex_ptrs[3];
+ if (prepare_triangle(psx_gpu, vertexes, vertex_ptrs))
+ render_triangle_p(psx_gpu, vertex_ptrs, flags);
+}
+
void texture_sprite_blocks_8bpp(psx_gpu_struct *psx_gpu);
{ \
delta_y *= -1; \
\
- if(delta_y >= 512) \
- return; \
- \
if(delta_x > delta_y) \
{ \
draw_line_span_horizontal(decrement, shading, blending, dithering, \
} \
else \
{ \
- if(delta_y >= 512) \
- return; \
- \
if(delta_x > delta_y) \
{ \
draw_line_span_horizontal(increment, shading, blending, dithering, \
void render_line(psx_gpu_struct *psx_gpu, vertex_struct *vertexes, u32 flags,
- u32 color)
+ u32 color, int double_resolution)
{
s32 color_r, color_g, color_b;
u32 triangle_winding = 0;
delta_x = x_b - x_a;
delta_y = y_b - y_a;
- if(delta_x >= 1024)
+ if(delta_x >= 1024 || delta_y >= 512 || delta_y <= -512)
return;
+ if(double_resolution)
+ {
+ x_a *= 2;
+ x_b *= 2;
+ y_a *= 2;
+ y_b *= 2;
+ delta_x *= 2;
+ delta_y *= 2;
+ }
+
flags &= ~RENDER_FLAGS_TEXTURE_MAP;
- vram_ptr = psx_gpu->vram_ptr + (y_a * 1024) + x_a;
+ vram_ptr = psx_gpu->vram_out_ptr + (y_a * 1024) + x_a;
control_mask = 0x0;
if((width == 0) || (height == 0))
return;
- flush_render_block_buffer(psx_gpu);
invalidate_texture_cache_region(psx_gpu, x, y, x + width - 1, y + height - 1);
u32 r = color & 0xFF;
psx_gpu->mask_msb;
u32 color_32bpp = color_16bpp | (color_16bpp << 16);
- u32 *vram_ptr = (u32 *)(psx_gpu->vram_ptr + x + (y * 1024));
+ u32 *vram_ptr = (u32 *)(psx_gpu->vram_out_ptr + x + (y * 1024));
u32 pitch = 512 - (width / 2);
u32 num_width;
- if(psx_gpu->interlace_mode & RENDER_INTERLACE_ENABLED)
+ if(psx_gpu->render_mode & RENDER_INTERLACE_ENABLED)
{
pitch += 512;
height /= 2;
- if(psx_gpu->interlace_mode & RENDER_INTERLACE_ODD)
+ if(psx_gpu->render_mode & RENDER_INTERLACE_ODD)
vram_ptr += 512;
}
}
}
+void render_block_fill_enh(psx_gpu_struct *psx_gpu, u32 color, u32 x, u32 y,
+ u32 width, u32 height)
+{
+ if((width == 0) || (height == 0))
+ return;
+
+ if(width > 1024)
+ width = 1024;
+
+ 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) |
+ psx_gpu->mask_msb;
+ u32 color_32bpp = color_16bpp | (color_16bpp << 16);
+
+ u32 *vram_ptr = (u32 *)(psx_gpu->vram_out_ptr + x + (y * 1024));
+
+ u32 pitch = 1024 / 2 - (width / 2);
+ u32 num_width;
+
+ while(height)
+ {
+ num_width = width;
+ while(num_width)
+ {
+ 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 += pitch;
+ height--;
+ }
+}
+
void render_block_copy(psx_gpu_struct *psx_gpu, u16 *source, u32 x, u32 y,
u32 width, u32 height, u32 pitch)
{
u32 height_reciprocal;
s32 shift;
- for(height = 1; height < 512; height++)
+ for(height = 1; height < sizeof(reciprocal_table)
+ / sizeof(reciprocal_table[0]); height++)
{
shift = __builtin_clz(height);
height_normalized = height << shift;
psx_gpu->render_state = 0;
psx_gpu->render_state_base = 0;
psx_gpu->num_blocks = 0;
+ psx_gpu->uvrgb_phase = 0x8000;
psx_gpu->vram_ptr = vram;
+ psx_gpu->vram_out_ptr = vram;
psx_gpu->texture_page_base = psx_gpu->vram_ptr;
psx_gpu->texture_page_ptr = psx_gpu->vram_ptr;
psx_gpu->texture_mask_width = 0xFF;
psx_gpu->texture_mask_height = 0xFF;
- psx_gpu->interlace_mode = 0;
+ psx_gpu->render_mode = 0;
memset(psx_gpu->vram_ptr, 0, sizeof(u16) * 1024 * 512);
psx_gpu->dither_table[3] = dither_table_row(3, -1, 2, -2);
psx_gpu->primitive_type = PRIMITIVE_TYPE_UNKNOWN;
+
+ psx_gpu->enhancement_x_threshold = 256;
}
u64 get_us(void)