mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 21:32:50 +00:00
commit
028277bd2d
@ -684,27 +684,32 @@ s32 cellGameThemeInstallFromBuffer()
|
||||
|
||||
s32 cellDiscGameGetBootDiscInfo()
|
||||
{
|
||||
throw EXCEPTION("");
|
||||
UNIMPLEMENTED_FUNC(cellGame);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDiscGameRegisterDiscChangeCallback()
|
||||
{
|
||||
throw EXCEPTION("");
|
||||
UNIMPLEMENTED_FUNC(cellGame);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellDiscGameUnregisterDiscChangeCallback()
|
||||
{
|
||||
throw EXCEPTION("");
|
||||
UNIMPLEMENTED_FUNC(cellGame);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellGameRegisterDiscChangeCallback()
|
||||
{
|
||||
throw EXCEPTION("");
|
||||
UNIMPLEMENTED_FUNC(cellGame);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellGameUnregisterDiscChangeCallback()
|
||||
{
|
||||
throw EXCEPTION("");
|
||||
UNIMPLEMENTED_FUNC(cellGame);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,6 +78,7 @@ namespace vm
|
||||
|
||||
_var_base(_var_base&& right)
|
||||
: pointer(right)
|
||||
, m_size(right.m_size)
|
||||
{
|
||||
reinterpret_cast<u32&>(static_cast<pointer&>(right)) = 0;
|
||||
}
|
||||
|
@ -515,28 +515,51 @@ enum
|
||||
CELL_GCM_SCULL_SFUNC_GEQUAL = 6,
|
||||
CELL_GCM_SCULL_SFUNC_ALWAYS = 7,
|
||||
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE = 1 << 0,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR = 1 << 1,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE = 1 << 2,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR = 1 << 3,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_FOG = 1 << 4,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_POINTSIZE = 1 << 5,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 = 1 << 6,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 = 1 << 7,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_UC2 = 1 << 8,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 = 1 << 9,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 = 1 << 10,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 = 1 << 11,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX8 = 1 << 12,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX9 = 1 << 13,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX0 = 1 << 14,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX1 = 1 << 15,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX2 = 1 << 16,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX3 = 1 << 17,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX4 = 1 << 18,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX5 = 1 << 19,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 = 1 << 20,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 = 1 << 21,
|
||||
CELL_GCM_ATTRIB_OUTPUT_FRONTDIFFUSE = 0,
|
||||
CELL_GCM_ATTRIB_OUTPUT_FRONTSPECULAR = 1,
|
||||
CELL_GCM_ATTRIB_OUTPUT_BACKDIFFUSE = 2,
|
||||
CELL_GCM_ATTRIB_OUTPUT_BACKSPECULAR = 3,
|
||||
CELL_GCM_ATTRIB_OUTPUT_FOG = 4,
|
||||
CELL_GCM_ATTRIB_OUTPUT_POINTSIZE = 5,
|
||||
CELL_GCM_ATTRIB_OUTPUT_UC0 = 6,
|
||||
CELL_GCM_ATTRIB_OUTPUT_UC1 = 7,
|
||||
CELL_GCM_ATTRIB_OUTPUT_UC2 = 8,
|
||||
CELL_GCM_ATTRIB_OUTPUT_UC3 = 9,
|
||||
CELL_GCM_ATTRIB_OUTPUT_UC4 = 10,
|
||||
CELL_GCM_ATTRIB_OUTPUT_UC5 = 11,
|
||||
CELL_GCM_ATTRIB_OUTPUT_TEX8 = 12,
|
||||
CELL_GCM_ATTRIB_OUTPUT_TEX9 = 13,
|
||||
CELL_GCM_ATTRIB_OUTPUT_TEX0 = 14,
|
||||
CELL_GCM_ATTRIB_OUTPUT_TEX1 = 15,
|
||||
CELL_GCM_ATTRIB_OUTPUT_TEX2 = 16,
|
||||
CELL_GCM_ATTRIB_OUTPUT_TEX3 = 17,
|
||||
CELL_GCM_ATTRIB_OUTPUT_TEX4 = 18,
|
||||
CELL_GCM_ATTRIB_OUTPUT_TEX5 = 19,
|
||||
CELL_GCM_ATTRIB_OUTPUT_TEX6 = 20,
|
||||
CELL_GCM_ATTRIB_OUTPUT_TEX7 = 21,
|
||||
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE = 1 << CELL_GCM_ATTRIB_OUTPUT_FRONTDIFFUSE,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR = 1 << CELL_GCM_ATTRIB_OUTPUT_FRONTSPECULAR,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE = 1 << CELL_GCM_ATTRIB_OUTPUT_BACKDIFFUSE,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR = 1 << CELL_GCM_ATTRIB_OUTPUT_BACKSPECULAR,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_FOG = 1 << CELL_GCM_ATTRIB_OUTPUT_FOG,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_POINTSIZE = 1 << CELL_GCM_ATTRIB_OUTPUT_POINTSIZE,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 = 1 << CELL_GCM_ATTRIB_OUTPUT_UC0,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 = 1 << CELL_GCM_ATTRIB_OUTPUT_UC1,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_UC2 = 1 << CELL_GCM_ATTRIB_OUTPUT_UC2,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 = 1 << CELL_GCM_ATTRIB_OUTPUT_UC3,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 = 1 << CELL_GCM_ATTRIB_OUTPUT_UC4,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 = 1 << CELL_GCM_ATTRIB_OUTPUT_UC5,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX8 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX8,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX9 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX9,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX0 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX0,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX1 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX1,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX2 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX2,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX3 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX3,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX4 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX4,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX5 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX5,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX6,
|
||||
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX7,
|
||||
|
||||
CELL_GCM_POLYGON_MODE_POINT = 0x1B00,
|
||||
CELL_GCM_POLYGON_MODE_LINE = 0x1B01,
|
||||
|
@ -64,12 +64,6 @@ void GLGSRender::begin()
|
||||
{
|
||||
rsx::thread::begin();
|
||||
|
||||
if (!load_program())
|
||||
{
|
||||
//no program - no drawing
|
||||
return;
|
||||
}
|
||||
|
||||
init_buffers();
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> then = std::chrono::system_clock::now();
|
||||
@ -98,12 +92,6 @@ void GLGSRender::begin()
|
||||
__glcheck glDepthRange((f32&)rsx::method_registers[NV4097_SET_CLIP_MIN], (f32&)rsx::method_registers[NV4097_SET_CLIP_MAX]);
|
||||
__glcheck enable(rsx::method_registers[NV4097_SET_DITHER_ENABLE], GL_DITHER);
|
||||
|
||||
if (!!rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE])
|
||||
{
|
||||
//TODO: NV4097_SET_ALPHA_REF must be converted to f32
|
||||
//glcheck(glAlphaFunc(rsx::method_registers[NV4097_SET_ALPHA_FUNC], rsx::method_registers[NV4097_SET_ALPHA_REF]));
|
||||
}
|
||||
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_BLEND_ENABLE], GL_BLEND))
|
||||
{
|
||||
u32 sfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR];
|
||||
@ -207,6 +195,56 @@ void GLGSRender::begin()
|
||||
//NV4097_SET_FLAT_SHADE_OP
|
||||
//NV4097_SET_EDGE_FLAG
|
||||
|
||||
__glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE], GL_CULL_FACE))
|
||||
{
|
||||
__glcheck glCullFace(rsx::method_registers[NV4097_SET_CULL_FACE]);
|
||||
}
|
||||
|
||||
__glcheck glFrontFace(rsx::method_registers[NV4097_SET_FRONT_FACE] ^ 1);
|
||||
|
||||
__glcheck enable(rsx::method_registers[NV4097_SET_POLY_SMOOTH_ENABLE], GL_POLYGON_SMOOTH);
|
||||
|
||||
//NV4097_SET_COLOR_KEY_COLOR
|
||||
//NV4097_SET_SHADER_CONTROL
|
||||
//NV4097_SET_ZMIN_MAX_CONTROL
|
||||
//NV4097_SET_ANTI_ALIASING_CONTROL
|
||||
//NV4097_SET_CLIP_ID_TEST_ENABLE
|
||||
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE], GL_PRIMITIVE_RESTART))
|
||||
{
|
||||
__glcheck glPrimitiveRestartIndex(rsx::method_registers[NV4097_SET_RESTART_INDEX]);
|
||||
}
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
|
||||
m_begin_time += (u32)std::chrono::duration_cast<std::chrono::microseconds>(now - then).count();
|
||||
m_draw_calls++;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
GLenum get_gl_target_for_texture(const rsx::texture& tex)
|
||||
{
|
||||
switch (tex.get_extended_texture_dimension())
|
||||
{
|
||||
case rsx::texture_dimension_extended::texture_dimension_1d: return GL_TEXTURE_1D;
|
||||
case rsx::texture_dimension_extended::texture_dimension_2d: return GL_TEXTURE_2D;
|
||||
case rsx::texture_dimension_extended::texture_dimension_cubemap: return GL_TEXTURE_CUBE_MAP;
|
||||
case rsx::texture_dimension_extended::texture_dimension_3d: return GL_TEXTURE_3D;
|
||||
}
|
||||
throw EXCEPTION("Unknow texture target");
|
||||
}
|
||||
}
|
||||
|
||||
void GLGSRender::end()
|
||||
{
|
||||
if (!draw_fbo || !load_program())
|
||||
{
|
||||
rsx::thread::end();
|
||||
return;
|
||||
}
|
||||
|
||||
u32 clip_plane_control = rsx::method_registers[NV4097_SET_USER_CLIP_PLANE_CONTROL];
|
||||
u8 clip_plane_0 = clip_plane_control & 0xf;
|
||||
u8 clip_plane_1 = (clip_plane_control >> 4) & 0xf;
|
||||
@ -252,56 +290,6 @@ void GLGSRender::begin()
|
||||
set_clip_plane_control(4, clip_plane_4);
|
||||
set_clip_plane_control(5, clip_plane_5);
|
||||
|
||||
__glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE], GL_CULL_FACE))
|
||||
{
|
||||
__glcheck glCullFace(rsx::method_registers[NV4097_SET_CULL_FACE]);
|
||||
}
|
||||
|
||||
__glcheck glFrontFace(rsx::method_registers[NV4097_SET_FRONT_FACE] ^ 1);
|
||||
|
||||
__glcheck enable(rsx::method_registers[NV4097_SET_POLY_SMOOTH_ENABLE], GL_POLYGON_SMOOTH);
|
||||
|
||||
//NV4097_SET_COLOR_KEY_COLOR
|
||||
//NV4097_SET_SHADER_CONTROL
|
||||
//NV4097_SET_ZMIN_MAX_CONTROL
|
||||
//NV4097_SET_ANTI_ALIASING_CONTROL
|
||||
//NV4097_SET_CLIP_ID_TEST_ENABLE
|
||||
|
||||
if (__glcheck enable(rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE], GL_PRIMITIVE_RESTART))
|
||||
{
|
||||
__glcheck glPrimitiveRestartIndex(rsx::method_registers[NV4097_SET_RESTART_INDEX]);
|
||||
}
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
|
||||
m_begin_time += (u32)std::chrono::duration_cast<std::chrono::microseconds>(now - then).count();
|
||||
m_draw_calls++;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
GLenum get_gl_target_for_texture(const rsx::texture& tex)
|
||||
{
|
||||
switch (tex.get_extended_texture_dimension())
|
||||
{
|
||||
case rsx::texture_dimension_extended::texture_dimension_1d: return GL_TEXTURE_1D;
|
||||
case rsx::texture_dimension_extended::texture_dimension_2d: return GL_TEXTURE_2D;
|
||||
case rsx::texture_dimension_extended::texture_dimension_cubemap: return GL_TEXTURE_CUBE_MAP;
|
||||
case rsx::texture_dimension_extended::texture_dimension_3d: return GL_TEXTURE_3D;
|
||||
}
|
||||
throw EXCEPTION("Unknow texture target");
|
||||
}
|
||||
}
|
||||
|
||||
void GLGSRender::end()
|
||||
{
|
||||
if (!draw_fbo)
|
||||
{
|
||||
rsx::thread::end();
|
||||
return;
|
||||
}
|
||||
|
||||
draw_fbo.bind();
|
||||
m_program->use();
|
||||
|
||||
@ -311,7 +299,7 @@ void GLGSRender::end()
|
||||
for (int i = 0; i < rsx::limits::textures_count; ++i)
|
||||
{
|
||||
int location;
|
||||
if (m_program->uniforms.has_location("texture" + std::to_string(i), &location))
|
||||
if (m_program->uniforms.has_location("ftexture" + std::to_string(i), &location))
|
||||
{
|
||||
if (!textures[i].enabled())
|
||||
{
|
||||
@ -330,7 +318,7 @@ void GLGSRender::end()
|
||||
|
||||
//texture_index++;
|
||||
|
||||
if (m_program->uniforms.has_location("texture" + std::to_string(i) + "_cm", &location))
|
||||
if (m_program->uniforms.has_location("ftexture" + std::to_string(i) + "_cm", &location))
|
||||
{
|
||||
if (textures[i].format() & CELL_GCM_TEXTURE_UN)
|
||||
{
|
||||
@ -478,16 +466,24 @@ void GLGSRender::on_exit()
|
||||
programs_cache.clear();
|
||||
|
||||
if (draw_fbo)
|
||||
{
|
||||
draw_fbo.remove();
|
||||
}
|
||||
|
||||
if (m_flip_fbo)
|
||||
{
|
||||
m_flip_fbo.remove();
|
||||
}
|
||||
|
||||
if (m_flip_tex_color)
|
||||
{
|
||||
m_flip_tex_color.remove();
|
||||
}
|
||||
|
||||
if (m_vao)
|
||||
{
|
||||
m_vao.remove();
|
||||
}
|
||||
|
||||
for (gl::texture &tex : m_gl_attrib_buffers)
|
||||
{
|
||||
@ -539,7 +535,7 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer)
|
||||
mask |= GLenum(gl::buffers::depth);
|
||||
}
|
||||
|
||||
if (surface_depth_format == rsx::surface_depth_format::z24s8 && arg & 0x2)
|
||||
if (surface_depth_format == rsx::surface_depth_format::z24s8 && (arg & 0x2))
|
||||
{
|
||||
u8 clear_stencil = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] & 0xff;
|
||||
|
||||
@ -607,6 +603,15 @@ struct alignas(4) glsl_fragment_constants_buffer
|
||||
float fc[2048][4];
|
||||
};
|
||||
|
||||
//binding 3
|
||||
struct alignas(4) glsl_fragment_state_buffer
|
||||
{
|
||||
float fog_param0;
|
||||
float fog_param1;
|
||||
uint alpha_test;
|
||||
float alpha_ref;
|
||||
};
|
||||
|
||||
static void fill_matrix_buffer(glsl_matrix_buffer *buffer)
|
||||
{
|
||||
rsx::fill_viewport_matrix(buffer->viewport_matrix, true);
|
||||
@ -655,8 +660,25 @@ static void fill_matrix_buffer(glsl_matrix_buffer *buffer)
|
||||
rsx::fill_scale_offset_matrix(buffer->normalize_matrix, true, offset_x, offset_y, offset_z, scale_x, scale_y, scale_z);
|
||||
}
|
||||
|
||||
static void fill_fragment_state_buffer(glsl_fragment_state_buffer *buffer)
|
||||
{
|
||||
std::memcpy(&buffer->fog_param0, rsx::method_registers + NV4097_SET_FOG_PARAMS, sizeof(float) * 2);
|
||||
|
||||
buffer->alpha_test = rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE];
|
||||
buffer->alpha_ref = rsx::method_registers[NV4097_SET_ALPHA_REF] / 255.f;
|
||||
}
|
||||
|
||||
bool GLGSRender::load_program()
|
||||
{
|
||||
if (0)
|
||||
{
|
||||
RSXVertexProgram vertex_program = get_current_vertex_program();
|
||||
RSXFragmentProgram fragment_program = get_current_fragment_program();
|
||||
|
||||
GLProgramBuffer prog_buffer;
|
||||
__glcheck prog_buffer.getGraphicPipelineState(vertex_program, fragment_program, nullptr);
|
||||
}
|
||||
|
||||
rsx::program_info info = programs_cache.get(get_raw_program(), rsx::decompile_language::glsl);
|
||||
m_program = (gl::glsl::program*)info.program;
|
||||
m_program->use();
|
||||
@ -667,6 +689,7 @@ bool GLGSRender::load_program()
|
||||
u32 max_buffer_sz =
|
||||
align(sizeof(glsl_matrix_buffer), m_uniform_buffer_offset_align) +
|
||||
align(sizeof(glsl_vertex_constants_buffer), m_uniform_buffer_offset_align) +
|
||||
align(sizeof(glsl_fragment_state_buffer), m_uniform_buffer_offset_align) +
|
||||
align(fragment_constants_size, m_uniform_buffer_offset_align);
|
||||
|
||||
m_uniform_ring_buffer.reserve_and_map(max_buffer_sz);
|
||||
@ -674,6 +697,7 @@ bool GLGSRender::load_program()
|
||||
u32 scale_offset_offset;
|
||||
u32 vertex_constants_offset;
|
||||
u32 fragment_constants_offset;
|
||||
u32 fragment_state_offset;
|
||||
|
||||
{
|
||||
auto mapping = m_uniform_ring_buffer.alloc_from_reserve(sizeof(glsl_matrix_buffer), m_uniform_buffer_offset_align);
|
||||
@ -687,6 +711,12 @@ bool GLGSRender::load_program()
|
||||
vertex_constants_offset = mapping.second;
|
||||
}
|
||||
|
||||
{
|
||||
auto mapping = m_uniform_ring_buffer.alloc_from_reserve(sizeof(glsl_fragment_state_buffer), m_uniform_buffer_offset_align);
|
||||
fill_fragment_state_buffer((glsl_fragment_state_buffer *)mapping.first);
|
||||
fragment_state_offset = mapping.second;
|
||||
}
|
||||
|
||||
if (fragment_constants_size)
|
||||
{
|
||||
auto mapping = m_uniform_ring_buffer.alloc_from_reserve(fragment_constants_size, m_uniform_buffer_offset_align);
|
||||
@ -710,12 +740,16 @@ bool GLGSRender::load_program()
|
||||
const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask);
|
||||
_mm_stream_si128((__m128i*)dst, shuffled_vector);
|
||||
|
||||
float x = ((float*)dst)[0];
|
||||
float y = ((float*)dst)[1];
|
||||
float z = ((float*)dst)[2];
|
||||
float w = ((float*)dst)[3];
|
||||
if (0)
|
||||
{
|
||||
float x = ((float*)dst)[0];
|
||||
float y = ((float*)dst)[1];
|
||||
float z = ((float*)dst)[2];
|
||||
float w = ((float*)dst)[3];
|
||||
|
||||
LOG_WARNING(RSX, "fc%u = {%g, %g, %g, %g}", constant.id, x, y, z, w);
|
||||
}
|
||||
|
||||
//LOG_WARNING(RSX, "fc%u = {%g, %g, %g, %g}", constant.id, x, y, z, w);
|
||||
++dst;
|
||||
}
|
||||
}
|
||||
@ -730,12 +764,13 @@ bool GLGSRender::load_program()
|
||||
m_uniform_ring_buffer.bind_range(2, fragment_constants_offset, fragment_constants_size);
|
||||
}
|
||||
|
||||
m_uniform_ring_buffer.bind_range(3, fragment_state_offset, sizeof(glsl_fragment_state_buffer));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLGSRender::flip(int buffer)
|
||||
{
|
||||
//LOG_NOTICE(Log::RSX, "flip(%d)", buffer);
|
||||
u32 buffer_width = gcm_buffers[buffer].width;
|
||||
u32 buffer_height = gcm_buffers[buffer].height;
|
||||
u32 buffer_pitch = gcm_buffers[buffer].pitch;
|
||||
@ -744,33 +779,37 @@ void GLGSRender::flip(int buffer)
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
rsx::tiled_region buffer_region = get_tiled_address(gcm_buffers[buffer].offset, CELL_GCM_LOCATION_LOCAL);
|
||||
|
||||
bool skip_read = false;
|
||||
rsx::tiled_region buffer_region = get_tiled_address(gcm_buffers[buffer].offset, CELL_GCM_LOCATION_LOCAL);
|
||||
u32 absolute_address = buffer_region.address + buffer_region.base;
|
||||
|
||||
if (0)
|
||||
{
|
||||
LOG_NOTICE(RSX, "flip(%d) -> 0x%x [0x%x]", buffer, absolute_address, rsx::get_address(gcm_buffers[1 - buffer].offset, CELL_GCM_LOCATION_LOCAL));
|
||||
}
|
||||
|
||||
gl::texture *render_target_texture = m_rtts.get_texture_from_render_target_if_applicable(absolute_address);
|
||||
|
||||
/**
|
||||
* Calling read_buffers will overwrite cached content
|
||||
*/
|
||||
if (draw_fbo)
|
||||
|
||||
__glcheck m_flip_fbo.recreate();
|
||||
m_flip_fbo.bind();
|
||||
|
||||
auto *flip_fbo = &m_flip_fbo;
|
||||
|
||||
if (render_target_texture)
|
||||
{
|
||||
skip_read = true;
|
||||
/*
|
||||
for (uint i = 0; i < rsx::limits::color_buffers_count; ++i)
|
||||
{
|
||||
u32 color_address = rsx::get_address(rsx::method_registers[mr_color_offset[i]], rsx::method_registers[mr_color_dma[i]]);
|
||||
|
||||
if (color_address == buffer_address)
|
||||
{
|
||||
skip_read = true;
|
||||
__glcheck draw_fbo.draw_buffer(draw_fbo.color[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
__glcheck m_flip_fbo.color = *render_target_texture;
|
||||
__glcheck m_flip_fbo.read_buffer(m_flip_fbo.color);
|
||||
}
|
||||
|
||||
if (!skip_read)
|
||||
else if (draw_fbo)
|
||||
{
|
||||
//HACK! it's here, because textures cache isn't implemented correctly!
|
||||
flip_fbo = &draw_fbo;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_flip_tex_color || m_flip_tex_color.size() != sizei{ (int)buffer_width, (int)buffer_height })
|
||||
{
|
||||
@ -782,15 +821,8 @@ void GLGSRender::flip(int buffer)
|
||||
.format(gl::texture::format::bgra);
|
||||
|
||||
m_flip_tex_color.pixel_unpack_settings().aligment(1).row_length(buffer_pitch / 4);
|
||||
|
||||
__glcheck m_flip_fbo.recreate();
|
||||
__glcheck m_flip_fbo.color = m_flip_tex_color;
|
||||
}
|
||||
|
||||
__glcheck m_flip_fbo.draw_buffer(m_flip_fbo.color);
|
||||
|
||||
m_flip_fbo.bind();
|
||||
|
||||
if (buffer_region.tile)
|
||||
{
|
||||
std::unique_ptr<u8[]> temp(new u8[buffer_height * buffer_pitch]);
|
||||
@ -801,6 +833,9 @@ void GLGSRender::flip(int buffer)
|
||||
{
|
||||
__glcheck m_flip_tex_color.copy_from(buffer_region.ptr, gl::texture::format::bgra, gl::texture::type::uint_8_8_8_8);
|
||||
}
|
||||
|
||||
m_flip_fbo.color = m_flip_tex_color;
|
||||
__glcheck m_flip_fbo.read_buffer(m_flip_fbo.color);
|
||||
}
|
||||
|
||||
areai screen_area = coordi({}, { (int)buffer_width, (int)buffer_height });
|
||||
@ -835,14 +870,7 @@ void GLGSRender::flip(int buffer)
|
||||
|
||||
gl::screen.clear(gl::buffers::color_depth_stencil);
|
||||
|
||||
if (!skip_read)
|
||||
{
|
||||
__glcheck m_flip_fbo.blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical());
|
||||
}
|
||||
else
|
||||
{
|
||||
__glcheck draw_fbo.blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical());
|
||||
}
|
||||
__glcheck flip_fbo->blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical());
|
||||
|
||||
m_frame->flip(m_context);
|
||||
|
||||
|
@ -83,57 +83,69 @@ void GLGSRender::init_buffers(bool skip_reading)
|
||||
u32 clip_horizontal = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL];
|
||||
u32 clip_vertical = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL];
|
||||
|
||||
|
||||
set_viewport();
|
||||
|
||||
if (draw_fbo && !m_rtts_dirty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_rtts_dirty = false;
|
||||
|
||||
m_rtts.prepare_render_target(nullptr, surface_format, clip_horizontal, clip_vertical, rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]),
|
||||
if (0)
|
||||
{
|
||||
LOG_NOTICE(RSX, "render to -> 0x%x", get_color_surface_addresses()[0]);
|
||||
}
|
||||
|
||||
m_rtts.prepare_render_target(nullptr, surface_format, clip_horizontal, clip_vertical,
|
||||
rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]),
|
||||
get_color_surface_addresses(), get_zeta_surface_address());
|
||||
|
||||
draw_fbo.recreate();
|
||||
|
||||
for (int i = 0; i < rsx::limits::color_buffers_count; ++i)
|
||||
{
|
||||
if (std::get<0>(m_rtts.m_bound_render_targets[i]) != 0)
|
||||
if (std::get<0>(m_rtts.m_bound_render_targets[i]))
|
||||
{
|
||||
__glcheck draw_fbo.color[i] = *std::get<1>(m_rtts.m_bound_render_targets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (std::get<0>(m_rtts.m_bound_depth_stencil) != 0)
|
||||
if (std::get<0>(m_rtts.m_bound_depth_stencil))
|
||||
{
|
||||
__glcheck draw_fbo.depth = *std::get<1>(m_rtts.m_bound_depth_stencil);
|
||||
}
|
||||
|
||||
__glcheck draw_fbo.check();
|
||||
__glcheck draw_fbo.read_buffer(draw_fbo.color[0]);
|
||||
|
||||
|
||||
//HACK: read_buffer shouldn't be there
|
||||
switch (rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
|
||||
{
|
||||
case rsx::surface_target::none: break;
|
||||
|
||||
case rsx::surface_target::surface_a:
|
||||
__glcheck draw_fbo.draw_buffer(draw_fbo.color[0]);
|
||||
__glcheck draw_fbo.read_buffer(draw_fbo.color[0]);
|
||||
break;
|
||||
|
||||
case rsx::surface_target::surface_b:
|
||||
{
|
||||
__glcheck draw_fbo.draw_buffer(draw_fbo.color[1]);
|
||||
__glcheck draw_fbo.read_buffer(draw_fbo.color[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
case rsx::surface_target::surfaces_a_b:
|
||||
__glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1] });
|
||||
__glcheck draw_fbo.read_buffer(draw_fbo.color[0]);
|
||||
break;
|
||||
|
||||
case rsx::surface_target::surfaces_a_b_c:
|
||||
__glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1], draw_fbo.color[2] });
|
||||
__glcheck draw_fbo.read_buffer(draw_fbo.color[0]);
|
||||
break;
|
||||
|
||||
case rsx::surface_target::surfaces_a_b_c_d:
|
||||
__glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1], draw_fbo.color[2], draw_fbo.color[3] });
|
||||
__glcheck draw_fbo.read_buffer(draw_fbo.color[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,162 @@
|
||||
#include "gl_helpers.h"
|
||||
#include "../GCM.h"
|
||||
|
||||
static void insert_texture_fetch_function(std::string &dst, const rsx::decompiled_shader &shader, const rsx::program_state &state)
|
||||
{
|
||||
if (shader.textures.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dst += "vec4 texture_fetch(int index, vec4 coord)\n{\n";
|
||||
dst += "\tswitch (index)\n\t{\n";
|
||||
|
||||
for (auto &texture : shader.textures)
|
||||
{
|
||||
dst += "\tcase " + std::to_string(texture.id) + ": return ";
|
||||
|
||||
switch (state.textures[texture.id])
|
||||
{
|
||||
case rsx::texture_target::none: dst += "vec4(0.0)"; break;
|
||||
case rsx::texture_target::_1: dst += "texture(" + texture.name + ", coord.x)"; break;
|
||||
case rsx::texture_target::_2: dst += "texture(" + texture.name + ", coord.xy)"; break;
|
||||
|
||||
case rsx::texture_target::cube:
|
||||
case rsx::texture_target::_3: dst += "texture(" + texture.name + ", coord.xyz)"; break;
|
||||
}
|
||||
|
||||
dst += ";\n";
|
||||
}
|
||||
|
||||
dst += "\t}\n";
|
||||
dst += "}\n";
|
||||
}
|
||||
|
||||
static void insert_texture_bias_fetch_function(std::string &dst, const rsx::decompiled_shader &shader, const rsx::program_state &state)
|
||||
{
|
||||
if (shader.textures.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dst += "vec4 texture_bias_fetch(int index, vec4 coord, float bias)\n{\n";
|
||||
dst += "\tswitch (index)\n\t{\n";
|
||||
|
||||
for (auto &texture : shader.textures)
|
||||
{
|
||||
dst += "\tcase " + std::to_string(texture.id) + ": return ";
|
||||
|
||||
switch (state.textures[texture.id])
|
||||
{
|
||||
case rsx::texture_target::none: dst += "vec4(0.0)"; break;
|
||||
case rsx::texture_target::_1: dst += "texture(" + texture.name + ", coord.x, bias)"; break;
|
||||
case rsx::texture_target::_2: dst += "texture(" + texture.name + ", coord.xy, bias)"; break;
|
||||
|
||||
case rsx::texture_target::cube:
|
||||
case rsx::texture_target::_3: dst += "texture(" + texture.name + ", coord.xyz, bias)"; break;
|
||||
}
|
||||
|
||||
dst += ";\n";
|
||||
}
|
||||
|
||||
dst += "\t}\n";
|
||||
dst += "}\n";
|
||||
}
|
||||
|
||||
static void insert_texture_grad_fetch_function(std::string &dst, const rsx::decompiled_shader &shader, const rsx::program_state &state)
|
||||
{
|
||||
if (shader.textures.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dst += "vec4 texture_grad_fetch(int index, vec4 coord, vec4 dPdx, vec4 dPdy)\n{\n";
|
||||
dst += "\tswitch (index)\n\t{\n";
|
||||
|
||||
for (auto &texture : shader.textures)
|
||||
{
|
||||
dst += "\tcase " + std::to_string(texture.id) + ": return ";
|
||||
|
||||
switch (state.textures[texture.id])
|
||||
{
|
||||
case rsx::texture_target::none: dst += "vec4(0.0)"; break;
|
||||
case rsx::texture_target::_1: dst += "textureGrad(" + texture.name + ", coord.x, dPdx.x, dPdy.x)"; break;
|
||||
case rsx::texture_target::_2: dst += "textureGrad(" + texture.name + ", coord.xy, dPdx.xy, dPdy.xy)"; break;
|
||||
|
||||
case rsx::texture_target::cube:
|
||||
case rsx::texture_target::_3: dst += "textureGrad(" + texture.name + ", coord.xyz, dPdx.xyz, dPdy.xyz)"; break;
|
||||
}
|
||||
|
||||
dst += ";\n";
|
||||
}
|
||||
|
||||
dst += "\t}\n";
|
||||
dst += "}\n";
|
||||
}
|
||||
|
||||
static void insert_texture_lod_fetch_function(std::string &dst, const rsx::decompiled_shader &shader, const rsx::program_state &state)
|
||||
{
|
||||
if (shader.textures.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dst += "vec4 texture_lod_fetch(int index, vec4 coord, float lod)\n{\n";
|
||||
dst += "\tswitch (index)\n\t{\n";
|
||||
|
||||
for (auto &texture : shader.textures)
|
||||
{
|
||||
dst += "\tcase " + std::to_string(texture.id) + ": return ";
|
||||
|
||||
switch (state.textures[texture.id])
|
||||
{
|
||||
case rsx::texture_target::none: dst += "vec4(0.0)"; break;
|
||||
case rsx::texture_target::_1: dst += "textureLod(" + texture.name + ", coord.x, lod)"; break;
|
||||
case rsx::texture_target::_2: dst += "textureLod(" + texture.name + ", coord.xy, lod)"; break;
|
||||
|
||||
case rsx::texture_target::cube:
|
||||
case rsx::texture_target::_3: dst += "textureLod(" + texture.name + ", coord.xyz, lod)"; break;
|
||||
}
|
||||
|
||||
dst += ";\n";
|
||||
}
|
||||
|
||||
dst += "\t}\n";
|
||||
dst += "}\n";
|
||||
}
|
||||
|
||||
|
||||
static void insert_texture_proj_fetch_function(std::string &dst, const rsx::decompiled_shader &shader, const rsx::program_state &state)
|
||||
{
|
||||
if (shader.textures.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dst += "vec4 texture_proj_fetch(int index, vec4 coord, float bias)\n{\n";
|
||||
dst += "\tswitch (index)\n\t{\n";
|
||||
|
||||
for (auto &texture : shader.textures)
|
||||
{
|
||||
dst += "\tcase " + std::to_string(texture.id) + ": return ";
|
||||
|
||||
switch (state.textures[texture.id])
|
||||
{
|
||||
case rsx::texture_target::cube:
|
||||
case rsx::texture_target::none: dst += "vec4(0.0)"; break;
|
||||
case rsx::texture_target::_1: dst += "textureProj(" + texture.name + ", coord.xy, bias)"; break;
|
||||
case rsx::texture_target::_2: dst += "textureProj(" + texture.name + ", coord.xyz, bias)"; break;
|
||||
case rsx::texture_target::_3: dst += "textureProj(" + texture.name + ", coord, bias)"; break;
|
||||
}
|
||||
|
||||
dst += ";\n";
|
||||
}
|
||||
|
||||
dst += "\t}\n";
|
||||
dst += "}\n";
|
||||
}
|
||||
|
||||
|
||||
rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader, rsx::program_state state)
|
||||
{
|
||||
rsx::complete_shader result;
|
||||
@ -17,6 +173,15 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
"\tmat4 normalize_matrix;\n"
|
||||
"};\n";
|
||||
}
|
||||
else if (shader.raw->type == rsx::program_type::fragment)
|
||||
{
|
||||
result.code += "layout(std140, binding = 3) uniform StateParameters\n{\n"
|
||||
"\tfloat fog_param0;\n"
|
||||
"\tfloat fog_param1;\n"
|
||||
"\tuint alpha_test;\n"
|
||||
"\tfloat alpha_ref;\n"
|
||||
"};\n";
|
||||
}
|
||||
|
||||
if (!shader.constants.empty())
|
||||
{
|
||||
@ -75,7 +240,21 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
for (const rsx::texture_info& texture : shader.textures)
|
||||
{
|
||||
result.code += "uniform vec4 " + texture.name + "_cm = vec4(1.0);\n";
|
||||
result.code += "uniform sampler2D " + texture.name + ";\n";
|
||||
|
||||
rsx::texture_target target = state.textures[texture.id];
|
||||
|
||||
|
||||
result.code += "uniform sampler";
|
||||
|
||||
switch (target)
|
||||
{
|
||||
default:
|
||||
case rsx::texture_target::_1: result.code += "1D"; break;
|
||||
case rsx::texture_target::_2: result.code += "2D"; break;
|
||||
case rsx::texture_target::_3: result.code += "3D"; break;
|
||||
case rsx::texture_target::cube: result.code += "Cube"; break;
|
||||
}
|
||||
result.code += " " + texture.name + ";\n";
|
||||
}
|
||||
|
||||
std::string prepare;
|
||||
@ -85,6 +264,13 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
switch (shader.raw->type)
|
||||
{
|
||||
case rsx::program_type::fragment:
|
||||
insert_texture_fetch_function(result.code, shader, state);
|
||||
insert_texture_bias_fetch_function(result.code, shader, state);
|
||||
insert_texture_grad_fetch_function(result.code, shader, state);
|
||||
insert_texture_lod_fetch_function(result.code, shader, state);
|
||||
insert_texture_proj_fetch_function(result.code, shader, state);
|
||||
|
||||
result.code += "\n";
|
||||
result.code += "layout(location = 0) out vec4 ocol;\n";
|
||||
|
||||
if (state.ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS)
|
||||
@ -153,6 +339,43 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (~state.output_attributes & CELL_GCM_ATTRIB_OUTPUT_MASK_FOG)
|
||||
{
|
||||
result.code += "vec4 fog = vec4(0.0);\n";
|
||||
}
|
||||
|
||||
result.code += "vec4 fogc;\n";
|
||||
|
||||
std::string body;
|
||||
switch ((rsx::fog_mode)state.fog_mode)
|
||||
{
|
||||
case rsx::fog_mode::linear:
|
||||
body = "fog_param1 * fog.x + (fog_param0 - 1.0), fog_param1 * fog.x + (fog_param0 - 1.0)";
|
||||
break;
|
||||
case rsx::fog_mode::exponential:
|
||||
body = "11.084 * (fog_param1 * fog.x + fog_param0 - 1.5), exp(11.084 * (fog_param1 * fog.x + fog_param0 - 1.5))";
|
||||
break;
|
||||
case rsx::fog_mode::exponential2:
|
||||
body = "4.709 * (fog_param1 * fog.x + fog_param0 - 1.5), exp(-pow(4.709 * (fog_param1 * fog.x + fog_param0 - 1.5), 2.0))";
|
||||
break;
|
||||
case rsx::fog_mode::linear_abs:
|
||||
body = "fog_param1 * abs(fog.x) + (fog_param0 - 1.0), fog_param1 * abs(fog.x) + (fog_param0 - 1.0)";
|
||||
break;
|
||||
case rsx::fog_mode::exponential_abs:
|
||||
body = "11.084 * (fog_param1 * abs(fog.x) + fog_param0 - 1.5), exp(11.084 * (fog_param1 * abs(fog.x) + fog_param0 - 1.5))";
|
||||
break;
|
||||
case rsx::fog_mode::exponential2_abs:
|
||||
body = "4.709 * (fog_param1 * abs(fog.x) + fog_param0 - 1.5), exp(-pow(4.709 * (fog_param1 * abs(fog.x) + fog_param0 - 1.5), 2.0))";
|
||||
break;
|
||||
|
||||
default:
|
||||
body = "0.0, 0.0";
|
||||
}
|
||||
|
||||
prepare += "\tfogc = clamp(vec4(" + body + ", 0.0, 0.0), 0.0, 1.0);\n";
|
||||
}
|
||||
|
||||
{
|
||||
u32 diffuse_color = state.output_attributes & (CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE | CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE);
|
||||
u32 specular_color = state.output_attributes & (CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR | CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR);
|
||||
@ -240,10 +463,67 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
result.code += "in vec4 " + rsx::vertex_program::output_attrib_names[index] + ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto make_comparsion_test = [](rsx::comparaison_function compare_func, const std::string &test, const std::string &a, const std::string &b) -> std::string
|
||||
{
|
||||
if (compare_func == rsx::comparaison_function::always)
|
||||
{
|
||||
return{};
|
||||
}
|
||||
|
||||
if (compare_func == rsx::comparaison_function::never)
|
||||
{
|
||||
return "\tdiscard;\n";
|
||||
}
|
||||
|
||||
std::string compare;
|
||||
|
||||
switch (compare_func)
|
||||
{
|
||||
case rsx::comparaison_function::equal:
|
||||
compare = "==";
|
||||
break;
|
||||
|
||||
case rsx::comparaison_function::not_equal:
|
||||
compare = "!=";
|
||||
break;
|
||||
|
||||
case rsx::comparaison_function::less_or_equal:
|
||||
compare = "<=";
|
||||
break;
|
||||
|
||||
case rsx::comparaison_function::less:
|
||||
compare = "<";
|
||||
break;
|
||||
|
||||
case rsx::comparaison_function::greater:
|
||||
compare = ">";
|
||||
break;
|
||||
|
||||
case rsx::comparaison_function::greater_or_equal:
|
||||
compare = ">=";
|
||||
break;
|
||||
}
|
||||
|
||||
return "\tif (" + test + "!(" + a + " " + compare + " " + b + ")) discard;\n";
|
||||
};
|
||||
|
||||
for (u8 index = 0; index < 16; ++index)
|
||||
{
|
||||
if (state.textures_alpha_kill[index])
|
||||
{
|
||||
std::string index_string = std::to_string(index);
|
||||
std::string fetch_texture = "texture_fetch(" + index_string + ", tex" + index_string + " * ftexture" + index_string + "_cm).a";
|
||||
finalize += make_comparsion_test((rsx::comparaison_function)state.textures_zfunc[index], "", "0", fetch_texture);
|
||||
}
|
||||
}
|
||||
|
||||
finalize += make_comparsion_test((rsx::comparaison_function)state.alpha_func, "alpha_test != 0 && ", "ocol.a", "alpha_ref");
|
||||
}
|
||||
break;
|
||||
|
||||
case rsx::program_type::vertex:
|
||||
|
||||
result.code += "out vec4 wpos;\n";
|
||||
|
||||
// TODO
|
||||
@ -266,9 +546,6 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
{
|
||||
if (shader.input_attributes & (1 << index))
|
||||
{
|
||||
// result.code += "in vec4 " + rsx::vertex_program::input_attrib_names[index] + ";\n";
|
||||
|
||||
// TODO: use actual information about vertex inputs
|
||||
const std::string &attrib_name = rsx::vertex_program::input_attrib_names[index];
|
||||
|
||||
result.code += "uniform ";
|
||||
@ -290,11 +567,22 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
|
||||
std::string vertex_id;
|
||||
|
||||
if (state.is_array & (1 << index))
|
||||
if (state.frequency[index] == 1)
|
||||
{
|
||||
if (state.divider_op & (1 << index))
|
||||
{
|
||||
vertex_id += "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex_id += "gl_VertexID";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex_id = "gl_VertexID";
|
||||
|
||||
if (state.frequency[index] > 1)
|
||||
if (state.frequency[index])
|
||||
{
|
||||
if (state.divider_op & (1 << index))
|
||||
{
|
||||
@ -308,10 +596,6 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
vertex_id += std::to_string(state.frequency[index]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex_id = "0";
|
||||
}
|
||||
|
||||
prepare += '\t' + attrib_name + " = texelFetch(" + attrib_name + "_buffer, " + vertex_id + ");\n";
|
||||
}
|
||||
@ -321,6 +605,12 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
}
|
||||
|
||||
{
|
||||
if (state.output_attributes & CELL_GCM_ATTRIB_OUTPUT_MASK_FOG)
|
||||
{
|
||||
result.code += "out vec4 fog;\n";
|
||||
finalize += "\tfog = o5.xxxx;\n";
|
||||
}
|
||||
|
||||
auto map_register = [&](int to, int from)
|
||||
{
|
||||
if (shader.output_attributes & (1 << from))
|
||||
@ -332,11 +622,11 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
{
|
||||
result.code += "out vec4 " + rsx::vertex_program::output_attrib_names[to] + ";\n";
|
||||
|
||||
if ((1 << to) == CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE && shader.output_attributes & (1 << 1))
|
||||
if (to == CELL_GCM_ATTRIB_OUTPUT_BACKDIFFUSE && shader.output_attributes & (1 << 1))
|
||||
{
|
||||
finalize += "\t" + rsx::vertex_program::output_attrib_names[to] + " = o1;\n";
|
||||
}
|
||||
else if ((1 << to) == CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR && shader.output_attributes & (1 << 2))
|
||||
else if (to == CELL_GCM_ATTRIB_OUTPUT_BACKSPECULAR && shader.output_attributes & (1 << 2))
|
||||
{
|
||||
finalize += "\t" + rsx::vertex_program::output_attrib_names[to] + " = o2;\n";
|
||||
}
|
||||
@ -347,19 +637,19 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
}
|
||||
};
|
||||
|
||||
map_register(0, 1);
|
||||
map_register(1, 2);
|
||||
map_register(2, 3);
|
||||
map_register(3, 4);
|
||||
map_register(14, 7);
|
||||
map_register(15, 8);
|
||||
map_register(16, 9);
|
||||
map_register(17, 10);
|
||||
map_register(18, 11);
|
||||
map_register(19, 12);
|
||||
map_register(20, 13);
|
||||
map_register(21, 14);
|
||||
map_register(12, 15);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_FRONTDIFFUSE, 1);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_FRONTSPECULAR, 2);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_BACKDIFFUSE, 3);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_BACKSPECULAR, 4);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_TEX0, 7);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_TEX1, 8);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_TEX2, 9);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_TEX3, 10);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_TEX4, 11);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_TEX5, 12);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_TEX6, 13);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_TEX7, 14);
|
||||
map_register(CELL_GCM_ATTRIB_OUTPUT_TEX8, 15);
|
||||
|
||||
if (shader.output_attributes & (1 << 5))
|
||||
{
|
||||
@ -407,11 +697,6 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
finalize += "\tgl_ClipDistance[5] = uc_m5 * o6.w;\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (state.output_attributes & CELL_GCM_ATTRIB_OUTPUT_MASK_FOG)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -422,7 +707,7 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
|
||||
result.code += "\n";
|
||||
result.code += shader.code;
|
||||
|
||||
result.code += "void main()\n{\n" + prepare + "\t" + shader.entry_function + "();\n" + finalize + "}";
|
||||
result.code += "void main()\n{\n" + prepare + "\n\t" + shader.entry_function + "();\n\n" + finalize + "}";
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -446,7 +731,6 @@ void* glsl_make_program(const void *vertex_shader, const void *fragment_shader)
|
||||
result->attach(*(gl::glsl::shader*)fragment_shader);
|
||||
|
||||
result->link();
|
||||
result->validate();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -516,8 +516,6 @@ namespace rsx
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_T, gl_wrap(tex.wrap_t()));
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_R, gl_wrap(tex.wrap_r()));
|
||||
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.zfunc()]);
|
||||
|
||||
__glcheck glTexParameterf(m_target, GL_TEXTURE_LOD_BIAS, tex.bias());
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8));
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8));
|
||||
|
@ -176,12 +176,10 @@ u32 GLGSRender::set_vertex_buffer()
|
||||
|
||||
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
{
|
||||
if (vertex_arrays_info[index].size == 0)
|
||||
if (vertex_arrays_info[index].size || register_vertex_info[index].size)
|
||||
{
|
||||
continue;
|
||||
max_vertex_attrib_size += 16;
|
||||
}
|
||||
|
||||
max_vertex_attrib_size += 16;
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::indexed)
|
||||
@ -292,7 +290,7 @@ u32 GLGSRender::set_vertex_buffer()
|
||||
if (draw_command == rsx::draw_command::array || draw_command == rsx::draw_command::indexed)
|
||||
{
|
||||
u32 verts_allocated = std::max(vertex_draw_count, max_index + 1);
|
||||
m_attrib_ring_buffer.reserve_and_map(verts_allocated * max_vertex_attrib_size);
|
||||
__glcheck m_attrib_ring_buffer.reserve_and_map(verts_allocated * max_vertex_attrib_size);
|
||||
|
||||
for (int index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
{
|
||||
@ -365,7 +363,6 @@ u32 GLGSRender::set_vertex_buffer()
|
||||
}
|
||||
else if (register_vertex_info[index].size > 0)
|
||||
{
|
||||
//Untested!
|
||||
auto &vertex_data = register_vertex_data[index];
|
||||
auto &vertex_info = register_vertex_info[index];
|
||||
|
||||
|
@ -342,18 +342,30 @@ namespace rsx
|
||||
|
||||
void thread::begin()
|
||||
{
|
||||
draw_inline_vertex_array = false;
|
||||
inline_vertex_array.clear();
|
||||
first_count_commands.clear();
|
||||
draw_command = rsx::draw_command::none;
|
||||
draw_mode = to_primitive_type(method_registers[NV4097_SET_BEGIN_END]);
|
||||
}
|
||||
|
||||
void thread::end()
|
||||
{
|
||||
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
{
|
||||
register_vertex_info[index].size = 0;
|
||||
register_vertex_data[index].clear();
|
||||
}
|
||||
|
||||
transform_constants.clear();
|
||||
|
||||
if (capture_current_frame)
|
||||
{
|
||||
for (const auto &first_count : first_count_commands)
|
||||
{
|
||||
vertex_draw_count += first_count.second;
|
||||
}
|
||||
|
||||
capture_frame("Draw " + std::to_string(vertex_draw_count));
|
||||
vertex_draw_count = 0;
|
||||
}
|
||||
@ -747,7 +759,7 @@ namespace rsx
|
||||
|
||||
raw_program thread::get_raw_program() const
|
||||
{
|
||||
raw_program result;
|
||||
raw_program result{};
|
||||
|
||||
u32 fp_info = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
|
||||
|
||||
@ -755,8 +767,8 @@ namespace rsx
|
||||
result.state.output_attributes = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK];
|
||||
result.state.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL];
|
||||
result.state.divider_op = rsx::method_registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION];
|
||||
|
||||
result.state.is_array = 0;
|
||||
result.state.alpha_func = rsx::method_registers[NV4097_SET_ALPHA_FUNC];
|
||||
result.state.fog_mode = (u32)rsx::to_fog_mode(rsx::method_registers[NV4097_SET_FOG_MODE]);
|
||||
result.state.is_int = 0;
|
||||
|
||||
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
@ -765,7 +777,6 @@ namespace rsx
|
||||
|
||||
if (vertex_arrays_info[index].size > 0)
|
||||
{
|
||||
result.state.is_array |= 1 << index;
|
||||
is_int = is_int_type(vertex_arrays_info[index].type);
|
||||
result.state.frequency[index] = vertex_arrays_info[index].frequency;
|
||||
}
|
||||
@ -785,6 +796,32 @@ namespace rsx
|
||||
}
|
||||
}
|
||||
|
||||
for (u8 index = 0; index < rsx::limits::textures_count; ++index)
|
||||
{
|
||||
if (!textures[index].enabled())
|
||||
{
|
||||
result.state.textures_alpha_kill[index] = 0;
|
||||
result.state.textures_zfunc[index] = 0;
|
||||
result.state.textures[index] = rsx::texture_target::none;
|
||||
continue;
|
||||
}
|
||||
|
||||
result.state.textures_alpha_kill[index] = textures[index].alpha_kill_enabled() ? 1 : 0;
|
||||
result.state.textures_zfunc[index] = textures[index].zfunc();
|
||||
|
||||
switch (textures[index].get_extended_texture_dimension())
|
||||
{
|
||||
case rsx::texture_dimension_extended::texture_dimension_1d: result.state.textures[index] = rsx::texture_target::_1; break;
|
||||
case rsx::texture_dimension_extended::texture_dimension_2d: result.state.textures[index] = rsx::texture_target::_2; break;
|
||||
case rsx::texture_dimension_extended::texture_dimension_3d: result.state.textures[index] = rsx::texture_target::_3; break;
|
||||
case rsx::texture_dimension_extended::texture_dimension_cubemap: result.state.textures[index] = rsx::texture_target::cube; break;
|
||||
|
||||
default:
|
||||
result.state.textures[index] = rsx::texture_target::none;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result.vertex_shader.ucode_ptr = transform_program;
|
||||
result.vertex_shader.offset = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START];
|
||||
|
||||
|
@ -197,6 +197,7 @@ namespace rsx
|
||||
|
||||
enum class draw_command
|
||||
{
|
||||
none,
|
||||
array,
|
||||
inlined_array,
|
||||
indexed,
|
||||
|
@ -92,7 +92,7 @@ namespace rsx
|
||||
program_info result;
|
||||
|
||||
result.vertex_shader = m_vertex_shaders_cache.get(context, raw_program_.vertex_shader, raw_program_.state);
|
||||
result.fragment_shader = m_vertex_shaders_cache.get(context, raw_program_.fragment_shader, raw_program_.state);
|
||||
result.fragment_shader = m_fragment_shader_cache.get(context, raw_program_.fragment_shader, raw_program_.state);
|
||||
result.program = context.make_program(result.vertex_shader.complete->user_data, result.fragment_shader.complete->user_data);
|
||||
m_program_cache.insert({ raw_program_, result });
|
||||
|
||||
|
@ -90,7 +90,7 @@ namespace rsx
|
||||
//find begin of data
|
||||
size_t begin = id + index * element_size_in_words;
|
||||
|
||||
size_t position = 0;//entry.size();
|
||||
size_t position = entry.size();
|
||||
entry.resize(position + element_size);
|
||||
|
||||
memcpy(entry.data() + position, method_registers + begin, element_size);
|
||||
@ -226,17 +226,47 @@ namespace rsx
|
||||
}
|
||||
};
|
||||
|
||||
force_inline void set_begin_end(thread* rsx, u32 arg)
|
||||
force_inline void set_begin_end(thread* rsxthr, u32 arg)
|
||||
{
|
||||
if (arg)
|
||||
{
|
||||
rsx->draw_inline_vertex_array = false;
|
||||
rsx->inline_vertex_array.clear();
|
||||
rsx->begin();
|
||||
rsxthr->begin();
|
||||
return;
|
||||
}
|
||||
|
||||
rsx->end();
|
||||
u32 max_vertex_count = 0;
|
||||
|
||||
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
{
|
||||
auto &vertex_info = rsxthr->register_vertex_info[index];
|
||||
|
||||
if (vertex_info.size > 0)
|
||||
{
|
||||
auto &vertex_data = rsxthr->register_vertex_data[index];
|
||||
|
||||
u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size);
|
||||
u32 element_count = vertex_data.size() / element_size;
|
||||
|
||||
vertex_info.frequency = element_count;
|
||||
rsx::method_registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION] |= 1 << index;
|
||||
|
||||
if (rsxthr->draw_command == rsx::draw_command::none)
|
||||
{
|
||||
max_vertex_count = std::max<u32>(max_vertex_count, element_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rsxthr->draw_command == rsx::draw_command::none && max_vertex_count)
|
||||
{
|
||||
rsxthr->draw_command = rsx::draw_command::array;
|
||||
rsxthr->first_count_commands.push_back(std::make_pair(0, max_vertex_count));
|
||||
}
|
||||
|
||||
if (!rsxthr->first_count_commands.empty())
|
||||
{
|
||||
rsxthr->end();
|
||||
}
|
||||
}
|
||||
|
||||
force_inline void get_report(thread* rsx, u32 arg)
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 9f8814af57264c82b7e063c1df5d71dc32c7a951
|
||||
Subproject commit aa6bcbc58961356733ae1fc0742a37a0a6190f31
|
Loading…
x
Reference in New Issue
Block a user