gxm: Remove compability features for handwritten shader

This commit is contained in:
mangren 2021-02-16 13:44:41 +07:00 committed by Nicolas Jallamion
parent 2cebd902c1
commit e61594c38d
15 changed files with 50 additions and 142 deletions

View File

@ -51,8 +51,6 @@
code(bool, "discord-rich-presence", true, discord_rich_presence) \
code(bool, "wait-for-debugger", false, wait_for_debugger) \
code(bool, "color-surface-debug", false, color_surface_debug) \
code(bool, "hardware-flip", false, hardware_flip) \
code(bool, "use-ubo", false, use_ubo) \
code(bool, "performance-overlay", false, performance_overlay) \
code(std::string, "backend-renderer", "OpenGL", backend_renderer) \
code(int, "keyboard-button-select", 229, keyboard_button_select) \

View File

@ -6,8 +6,6 @@ struct FeatureState {
bool support_shader_interlock = false; ///< First option for blending. Using this with ordered execution mode.
bool support_texture_barrier = false; ///< Second option for blending. Slower but work on 3 vendors.
bool direct_fragcolor = false;
bool hardware_flip = true; ///< Allow flipping in shader.
bool use_ubo = false;
bool use_shader_binding = false;
bool is_programmable_blending_supported() const {

View File

@ -193,9 +193,6 @@ void draw_settings_dialog(GuiState &gui, HostState &host) {
ImGui::PushStyleColor(ImGuiCol_Text, GUI_COLOR_TEXT_MENUBAR);
if (ImGui::BeginTabItem("GPU")) {
ImGui::PopStyleColor();
ImGui::Checkbox("Hardware Flip", &host.cfg.hardware_flip);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Check the box to enable texture flipping from GPU side.\nIt is recommended to disable this option for homebrew.");
ImGui::EndTabItem();
} else
ImGui::PopStyleColor();

View File

@ -310,7 +310,6 @@ static ExitCode load_app_impl(Ptr<const void> &entry_point, HostState &host, con
return InitConfigFailed;
}
LOG_INFO_IF(host.cfg.hardware_flip, "{}: enabled", host.cfg[e_hardware_flip]);
LOG_INFO("ngs experimental state: {}", !host.cfg.disable_ngs);
LOG_INFO("video player state: {}", host.cfg.video_playing);
if (host.cfg.auto_lle)

View File

@ -206,7 +206,6 @@ int main(int argc, char *argv[]) {
}
gui::init_app_background(gui, host, host.io.title_id);
host.renderer->features.hardware_flip = host.cfg.hardware_flip;
app::gl_screen_renderer gl_renderer;

View File

@ -743,16 +743,8 @@ EXPORT(int, sceGxmDraw, SceGxmContext *context, SceGxmPrimitiveType primType, Sc
const SceGxmProgram &vertex_program_gxp = *gxm_vertex_program.program.get(host.mem);
const SceGxmProgram &fragment_program_gxp = *gxm_fragment_program.program.get(host.mem);
if (host.renderer->features.use_ubo) {
renderer::set_uniform_buffers(*host.renderer, context->renderer.get(), vertex_program_gxp, context->state.vertex_uniform_buffers, gxm_vertex_program.renderer_data->uniform_buffer_sizes, host.mem);
renderer::set_uniform_buffers(*host.renderer, context->renderer.get(), fragment_program_gxp, context->state.fragment_uniform_buffers, gxm_fragment_program.renderer_data->uniform_buffer_sizes, host.mem);
} else {
// Update uniforms from this side. We should pass the pointer to parameter struct, since from there it can
// find the name and other things based on the pointer in memory. The pointer should be persists until
// the fragment is done, so we are guranteed to be safe.
renderer::set_uniforms(*host.renderer, context->renderer.get(), vertex_program_gxp, context->state.vertex_uniform_buffers, host.mem);
renderer::set_uniforms(*host.renderer, context->renderer.get(), fragment_program_gxp, context->state.fragment_uniform_buffers, host.mem);
}
renderer::set_uniform_buffers(*host.renderer, context->renderer.get(), vertex_program_gxp, context->state.vertex_uniform_buffers, gxm_vertex_program.renderer_data->uniform_buffer_sizes, host.mem);
renderer::set_uniform_buffers(*host.renderer, context->renderer.get(), fragment_program_gxp, context->state.fragment_uniform_buffers, gxm_fragment_program.renderer_data->uniform_buffer_sizes, host.mem);
// Update vertex data. We should stores a copy of the data to pass it to GPU later, since another scene
// may start to overwrite stuff when this scene is being processed in our queue (in case of OpenGL).
@ -837,13 +829,8 @@ EXPORT(int, sceGxmDrawPrecomputed, SceGxmContext *context, SceGxmPrecomputedDraw
const SceGxmProgram &vertex_program_gxp = *vertex_program->program.get(host.mem);
const SceGxmProgram &fragment_program_gxp = *fragment_program->program.get(host.mem);
if (host.renderer->features.use_ubo) {
renderer::set_uniform_buffers(*host.renderer, context->renderer.get(), vertex_program_gxp, *vertex_state->uniform_buffers.get(host.mem), gxm_vertex_program.renderer_data->uniform_buffer_sizes, host.mem);
renderer::set_uniform_buffers(*host.renderer, context->renderer.get(), fragment_program_gxp, *fragment_state->uniform_buffers.get(host.mem), gxm_fragment_program.renderer_data->uniform_buffer_sizes, host.mem);
} else {
renderer::set_uniforms(*host.renderer, context->renderer.get(), vertex_program_gxp, *vertex_state->uniform_buffers.get(host.mem), host.mem);
renderer::set_uniforms(*host.renderer, context->renderer.get(), fragment_program_gxp, *fragment_state->uniform_buffers.get(host.mem), host.mem);
}
renderer::set_uniform_buffers(*host.renderer, context->renderer.get(), vertex_program_gxp, *vertex_state->uniform_buffers.get(host.mem), gxm_vertex_program.renderer_data->uniform_buffer_sizes, host.mem);
renderer::set_uniform_buffers(*host.renderer, context->renderer.get(), fragment_program_gxp, *fragment_state->uniform_buffers.get(host.mem), gxm_fragment_program.renderer_data->uniform_buffer_sizes, host.mem);
// Update vertex data. We should stores a copy of the data to pass it to GPU later, since another scene
// may start to overwrite stuff when this scene is being processed in our queue (in case of OpenGL).

View File

@ -54,18 +54,18 @@ bool create(std::unique_ptr<Context> &context);
bool create(std::unique_ptr<RenderTarget> &rt, const SceGxmRenderTargetParams &params, const FeatureState &features);
bool create(std::unique_ptr<FragmentProgram> &fp, GLState &state, const SceGxmProgram &program, const SceGxmBlendInfo *blend, GXPPtrMap &gxp_ptr_map, const char *base_path, const char *title_id);
bool create(std::unique_ptr<VertexProgram> &vp, GLState &state, const SceGxmProgram &program, GXPPtrMap &gxp_ptr_map, const char *base_path, const char *title_id);
bool sync_state(GLContext &context, const GxmContextState &state, const MemState &mem, bool enable_texture_cache, bool hardware_flip, const std::string &base_path, const std::string &title_id);
bool sync_state(GLContext &context, const GxmContextState &state, const MemState &mem, bool enable_texture_cache, const std::string &base_path, const std::string &title_id);
void sync_rendertarget(const GLRenderTarget &rt);
void set_context(GLContext &ctx, GxmContextState &state, const MemState &mem, const GLRenderTarget *rt, const FeatureState &features);
void get_surface_data(GLContext &context, size_t width, size_t height, size_t stride_in_pixels, uint32_t *pixels, SceGxmColorFormat format, const bool do_flip);
void get_surface_data(GLContext &context, size_t width, size_t height, size_t stride_in_pixels, uint32_t *pixels, SceGxmColorFormat format);
void draw(GLState &renderer, GLContext &context, GxmContextState &state, const FeatureState &features, SceGxmPrimitiveType type, SceGxmIndexFormat format,
const void *indices, size_t count, const MemState &mem, const char *base_path, const char *title_id, const Config &config);
void upload_vertex_stream(GLContext &context, const std::size_t stream_index, const std::size_t length, const void *data);
// State
void sync_viewport(GLContext &context, const GxmContextState &state, const bool hardware_flip);
void sync_clipping(GLContext &context, const GxmContextState &state, const bool hardware_flip);
void sync_viewport(GLContext &context, const GxmContextState &state);
void sync_clipping(GLContext &context, const GxmContextState &state);
void sync_cull(GLContext &context, const GxmContextState &state);
void sync_front_depth_func(const GxmContextState &state);
void sync_front_depth_write_enable(const GxmContextState &state);

View File

@ -125,39 +125,12 @@ void draw(GLState &renderer, GLContext &context, GxmContextState &state, const F
}
bind_host_texture("f_mask", shader::MASK_TEXTURE_SLOT_IMAGE, context.render_target->masktexture[0]);
if (!features.use_ubo) {
const SceGxmVertexProgram &gxm_vertex_program = *state.vertex_program.get(mem);
const FragmentProgram &fragment_program = *gxm_fragment_program.renderer_data.get();
// Try to configure the vertex shader, to output coordinates suited for GXM viewport
GLuint flip_vec_loc = glGetUniformLocation(program_id, "flip_vec");
// Set uniforms
const SceGxmProgram &vertex_program_gxp = *gxm_vertex_program.program.get(mem);
gl::GLShaderStatics &vertex_gl_statics = reinterpret_cast<gl::GLVertexProgram *>(gxm_vertex_program.renderer_data.get())->statics;
gl::GLShaderStatics &fragment_gl_statics = reinterpret_cast<gl::GLFragmentProgram *>(gxm_fragment_program.renderer_data.get())->statics;
for (auto &vertex_uniform : context.vertex_set_requests) {
gl::set_uniform(program_id, vertex_program_gxp, vertex_gl_statics, mem, vertex_uniform.parameter, vertex_uniform.data,
config.log_uniforms);
delete vertex_uniform.data;
}
for (auto &fragment_uniform : context.fragment_set_requests) {
gl::set_uniform(program_id, fragment_program_gxp, fragment_gl_statics, mem, fragment_uniform.parameter,
fragment_uniform.data, config.log_uniforms);
delete fragment_uniform.data;
}
}
if (config.hardware_flip) {
// Try to configure the vertex shader, to output coordinates suited for GXM viewport
GLuint flip_vec_loc = glGetUniformLocation(program_id, "flip_vec");
if (flip_vec_loc != -1) {
// Let's do flipping
glUniform4fv(flip_vec_loc, 1, context.viewport_flip);
}
if (flip_vec_loc != -1) {
// Let's do flipping
glUniform4fv(flip_vec_loc, 1, context.viewport_flip);
}
const auto set_uniform_if_exists = [&](const std::string &name, float val) {

View File

@ -270,8 +270,6 @@ bool create(SDL_Window *window, std::unique_ptr<State> &state) {
LOG_WARN("Consider updating your graphics drivers or upgrading your GPU.");
}
gl_state.features.use_ubo = true;
return true;
}
@ -438,20 +436,7 @@ void set_context(GLContext &context, GxmContextState &state, const MemState &mem
}
}
static void flip_vertically(uint32_t *pixels, size_t width, size_t height, size_t stride_in_pixels) {
R_PROFILE(__func__);
uint32_t *row1 = &pixels[0];
uint32_t *row2 = &pixels[(height - 1) * stride_in_pixels];
while (row1 < row2) {
std::swap_ranges(&row1[0], &row1[width], &row2[0]);
row1 += stride_in_pixels;
row2 -= stride_in_pixels;
}
}
void get_surface_data(GLContext &context, size_t width, size_t height, size_t stride_in_pixels, uint32_t *pixels, SceGxmColorFormat format, const bool do_flip) {
void get_surface_data(GLContext &context, size_t width, size_t height, size_t stride_in_pixels, uint32_t *pixels, SceGxmColorFormat format) {
R_PROFILE(__func__);
if (pixels == nullptr) {
@ -504,11 +489,6 @@ void get_surface_data(GLContext &context, size_t width, size_t height, size_t st
}
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
if (do_flip) {
flip_vertically(pixels, width, height, stride_in_pixels);
}
++context.texture_cache.timestamp;
}

View File

@ -117,7 +117,7 @@ void sync_mask(GLContext &context, const GxmContextState &state, const MemState
glBindTexture(GL_TEXTURE_2D, texId);
}
void sync_viewport(GLContext &context, const GxmContextState &state, const bool hardware_flip) {
void sync_viewport(GLContext &context, const GxmContextState &state) {
// Viewport.
const GLsizei display_w = state.color_surface.width;
const GLsizei display_h = state.color_surface.height;
@ -131,34 +131,30 @@ void sync_viewport(GLContext &context, const GxmContextState &state, const bool
const GLfloat x = viewport.offset.x - std::abs(viewport.scale.x);
const GLfloat y = std::min<GLfloat>(ymin, ymax);
if (hardware_flip) {
context.viewport_flip[0] = 1.0f;
context.viewport_flip[1] = (ymin < ymax) ? -1.0f : 1.0f;
context.viewport_flip[2] = 1.0f;
context.viewport_flip[3] = 1.0f;
}
context.viewport_flip[0] = 1.0f;
context.viewport_flip[1] = (ymin < ymax) ? -1.0f : 1.0f;
context.viewport_flip[2] = 1.0f;
context.viewport_flip[3] = 1.0f;
glViewportIndexedf(0, x, hardware_flip ? y : display_h - h - y, w, h);
glViewportIndexedf(0, x, y, w, h);
glDepthRange(viewport.offset.z - viewport.scale.z, viewport.offset.z + viewport.scale.z);
} else {
if (hardware_flip) {
context.viewport_flip[0] = 1.0f;
context.viewport_flip[1] = -1.0f;
context.viewport_flip[2] = 1.0f;
context.viewport_flip[3] = 1.0f;
}
context.viewport_flip[0] = 1.0f;
context.viewport_flip[1] = -1.0f;
context.viewport_flip[2] = 1.0f;
context.viewport_flip[3] = 1.0f;
glViewport(0, 0, display_w, display_h);
glDepthRange(0, 1);
}
}
void sync_clipping(GLContext &context, const GxmContextState &state, const bool hardware_flip) {
void sync_clipping(GLContext &context, const GxmContextState &state) {
const GLsizei display_h = state.color_surface.height;
const GLsizei scissor_x = state.region_clip_min.x;
GLsizei scissor_y = 0;
if (hardware_flip && context.viewport_flip[1] == -1.0f)
if (context.viewport_flip[1] == -1.0f)
scissor_y = state.region_clip_min.y;
else
scissor_y = display_h - state.region_clip_max.y - 1;
@ -385,8 +381,8 @@ bool sync_state(GLContext &context, const GxmContextState &state, const MemState
const GLFragmentProgram &fragment_program = *reinterpret_cast<GLFragmentProgram *>(
gxm_fragment_program.renderer_data.get());
sync_viewport(context, state, config.hardware_flip);
sync_clipping(context, state, config.hardware_flip);
sync_viewport(context, state);
sync_clipping(context, state);
sync_cull(context, state);
glEnable(GL_DEPTH_TEST);

View File

@ -65,7 +65,7 @@ COMMAND(handle_sync_surface_data) {
switch (renderer.current_backend) {
case Backend::OpenGL: {
gl::get_surface_data(*reinterpret_cast<gl::GLContext *>(render_context), width, height,
stride_in_pixels, pixels, state->color_surface.colorFormat, !config.hardware_flip);
stride_in_pixels, pixels, state->color_surface.colorFormat);
break;
}

View File

@ -28,7 +28,7 @@ COMMAND_SET_STATE(region_clip) {
switch (renderer.current_backend) {
case Backend::OpenGL: {
gl::sync_clipping(*reinterpret_cast<gl::GLContext *>(render_context), *state, config.hardware_flip);
gl::sync_clipping(*reinterpret_cast<gl::GLContext *>(render_context), *state);
break;
}
@ -134,7 +134,7 @@ COMMAND_SET_STATE(viewport) {
// Sync
switch (renderer.current_backend) {
case Backend::OpenGL: {
gl::sync_viewport(*reinterpret_cast<gl::GLContext *>(render_context), *state, config.hardware_flip);
gl::sync_viewport(*reinterpret_cast<gl::GLContext *>(render_context), *state);
break;
}

View File

@ -358,13 +358,6 @@ struct UniformBuffer {
bool rw; // TODO confirm this
};
struct UniformInputSource {
std::string name;
// resource index
uint32_t index;
bool in_mem;
};
struct AttributeInputSource {
std::string name;
@ -390,7 +383,7 @@ struct DependentSamplerInputSource {
};
// Read source field in Input struct
using InputSource = std::variant<UniformInputSource, UniformBufferInputSource, LiteralInputSource, AttributeInputSource, DependentSamplerInputSource>;
using InputSource = std::variant<UniformBufferInputSource, LiteralInputSource, AttributeInputSource, DependentSamplerInputSource>;
/**
* Input parameters that are usually copied into PA or SA

View File

@ -90,28 +90,25 @@ ProgramInput shader::get_program_input(const SceGxmProgram &program) {
const auto [store_type, param_type_name] = shader::get_parameter_type_store_and_name(parameter_type);
// Make the type
Input item;
item.type = store_type;
item.offset = offset;
item.component_count = parameter.component_count;
item.array_size = parameter.array_size;
gxp::GenericParameterType param_type = gxp::parameter_generic_type(parameter);
item.generic_type = translate_generic_type(param_type);
item.bank = is_uniform ? RegisterBank::SECATTR : RegisterBank::PRIMATTR;
if (!is_uniform) {
Input item;
item.type = store_type;
item.offset = offset;
item.component_count = parameter.component_count;
item.array_size = parameter.array_size;
item.generic_type = translate_generic_type(param_type);
item.bank = RegisterBank::PRIMATTR;
AttributeInputSource source;
source.name = var_name;
source.index = parameter.resource_index;
source.semantic = parameter.semantic;
item.source = source;
program_input.inputs.push_back(item);
} else {
UniformInputSource source;
source.name = var_name;
source.index = parameter.resource_index;
const uint32_t reg_block_size = container ? container->size_in_f32 : 0;
source.in_mem = parameter.resource_index > reg_block_size;
item.source = source;
uint32_t vector_size = parameter.component_count * get_data_type_size(store_type);
if (parameter.array_size != 1) {
if (is_float_data_type(store_type) && parameter.component_count != 1) {
@ -123,6 +120,8 @@ ProgramInput shader::get_program_input(const SceGxmProgram &program) {
const uint32_t parameter_size = parameter.array_size * vector_size;
const uint32_t parameter_size_in_f32 = (parameter_size + 3) / 4;
if (uniform_buffers.find(parameter.container_index) == uniform_buffers.end()) {
const std::uint32_t reg_block_size = container ? container->size_in_f32 : 0;
UniformBuffer buffer;
buffer.index = (parameter.container_index + 1) % SCE_GXM_REAL_MAX_UNIFORM_BUFFER;
buffer.reg_block_size = reg_block_size;
@ -136,8 +135,6 @@ ProgramInput shader::get_program_input(const SceGxmProgram &program) {
buffer.reg_start_offset = std::min(buffer.reg_start_offset, static_cast<uint32_t>(offset));
}
}
program_input.inputs.push_back(item);
break;
}

View File

@ -741,13 +741,11 @@ static SpirvShaderParameters create_parameters(spv::Builder &b, const SceGxmProg
uniform_buffers.emplace(buffer.index, block);
}
if (features.use_ubo) {
for (const auto buffer : program_input.uniform_buffers) {
if (buffer.reg_block_size > 0) {
const uint32_t reg_block_size_in_f32v = (buffer.reg_block_size + 3) / 4;
const auto spv_buffer = uniform_buffers.at(buffer.index);
copy_uniform_block_to_register(b, spv_params.uniforms, spv_buffer, ite_copy, buffer.reg_start_offset / 4, reg_block_size_in_f32v);
}
for (const auto buffer : program_input.uniform_buffers) {
if (buffer.reg_block_size > 0) {
const uint32_t reg_block_size_in_f32v = (buffer.reg_block_size + 3) / 4;
const auto spv_buffer = uniform_buffers.at(buffer.index);
copy_uniform_block_to_register(b, spv_params.uniforms, spv_buffer, ite_copy, buffer.reg_start_offset / 4, reg_block_size_in_f32v);
}
}
@ -849,12 +847,6 @@ static SpirvShaderParameters create_parameters(spv::Builder &b, const SceGxmProg
// Pair sort automatically sort offset for us
std::sort(literal_pairs.begin(), literal_pairs.end());
},
[&](const UniformInputSource &s) {
// In ubo mode we copy using default uniform buffer
if (!features.use_ubo) {
add_var_to_reg(input, s.name, 0, false, -1);
}
},
[&](const UniformBufferInputSource &s) {
Operand reg;
reg.bank = RegisterBank::SECATTR;
@ -928,7 +920,7 @@ static SpirvShaderParameters create_parameters(spv::Builder &b, const SceGxmProg
translation_state.screen_height_id = height_id;
}
if (program_type == SceGxmProgramType::Vertex && features.hardware_flip) {
if (program_type == SceGxmProgramType::Vertex) {
// Create variable that helps us do flipping
// TODO: Not emit this on Vulkan or DirectX
spv::Id f32 = b.makeFloatType(32);
@ -1486,7 +1478,6 @@ void convert_gxp_to_glsl_from_filepath(const std::string &shader_filepath) {
features.direct_fragcolor = false;
features.support_shader_interlock = true;
features.pack_unpack_half_through_ext = false;
features.use_ubo = true;
convert_gxp_to_glsl(*gxp_program, shader_filepath_str.filename().string(), features, false, true);