void ShaderCache::LoadAndSetActiveShaders(DSTALPHA_MODE ps_dst_alpha_mode, u32 gs_primitive_type) { SetCurrentPrimitiveTopology(gs_primitive_type); GeometryShaderUid gs_uid = GetGeometryShaderUid(gs_primitive_type); PixelShaderUid ps_uid = GetPixelShaderUid(ps_dst_alpha_mode); VertexShaderUid vs_uid = GetVertexShaderUid(); bool gs_changed = gs_uid != s_last_geometry_shader_uid; bool ps_changed = ps_uid != s_last_pixel_shader_uid; bool vs_changed = vs_uid != s_last_vertex_shader_uid; if (!gs_changed && !ps_changed && !vs_changed) { return; } if (gs_changed) { HandleGSUIDChange(gs_uid, gs_primitive_type); } if (ps_changed) { HandlePSUIDChange(ps_uid, ps_dst_alpha_mode); } if (vs_changed) { HandleVSUIDChange(vs_uid); } // A Uid has changed, so the PSO will need to be reset at next ApplyState. D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PSO, true); }
void ShaderCache::PrepareShaders(PIXEL_SHADER_RENDER_MODE render_mode, u32 gs_primitive_type, u32 components, const XFMemory &xfr, const BPMemory &bpm, bool on_gpu_thread) { SetCurrentPrimitiveTopology(gs_primitive_type); GeometryShaderUid gs_uid; GetGeometryShaderUid(gs_uid, gs_primitive_type, xfr, components); PixelShaderUid ps_uid; GetPixelShaderUID(ps_uid, render_mode, components, xfr, bpm); VertexShaderUid vs_uid; GetVertexShaderUID(vs_uid, components, xfr, bpm); TessellationShaderUid ts_uid; bool tessellationenabled = false; if (gs_primitive_type == PrimitiveType::PRIMITIVE_TRIANGLES && g_ActiveConfig.TessellationEnabled() && xfr.projection.type == GX_PERSPECTIVE && (g_ActiveConfig.bForcedLighting || g_ActiveConfig.PixelLightingEnabled(xfr, components))) { GetTessellationShaderUID(ts_uid, xfr, bpm, components); tessellationenabled = true; } bool gs_changed = false; bool ps_changed = false; bool vs_changed = false; bool ts_changed = false; if (on_gpu_thread) { s_compiler->ProcCompilationResults(); gs_changed = gs_uid != s_last_geometry_shader_uid; ps_changed = ps_uid != s_last_pixel_shader_uid; vs_changed = vs_uid != s_last_vertex_shader_uid; ts_changed = tessellationenabled && ts_uid != s_last_tessellation_shader_uid; } else { gs_changed = gs_uid != s_last_cpu_geometry_shader_uid; ps_changed = ps_uid != s_last_cpu_pixel_shader_uid; vs_changed = vs_uid != s_last_cpu_vertex_shader_uid; ts_changed = tessellationenabled && ts_uid != s_last_cpu_tessellation_shader_uid; } if (!gs_changed && !ps_changed && !vs_changed && !ts_changed) { return; } if (on_gpu_thread) { if (gs_changed) { s_last_geometry_shader_uid = gs_uid; } if (ps_changed) { s_last_pixel_shader_uid = ps_uid; } if (vs_changed) { s_last_vertex_shader_uid = vs_uid; } if (ts_changed) { s_last_tessellation_shader_uid = ts_uid; } // A Uid has changed, so the PSO will need to be reset at next ApplyState. D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PSO, true); } else { if (gs_changed) { s_last_cpu_geometry_shader_uid = gs_uid; } if (ps_changed) { s_last_cpu_pixel_shader_uid = ps_uid; } if (vs_changed) { s_last_cpu_vertex_shader_uid = vs_uid; } if (ts_changed) { s_last_cpu_tessellation_shader_uid = ts_uid; } } if (vs_changed) { HandleVSUIDChange(vs_uid, on_gpu_thread); } if (ts_changed) { HandleTSUIDChange(ts_uid, on_gpu_thread); } else { if (on_gpu_thread) { s_last_domain_shader_bytecode = &s_pass_entry; s_last_hull_shader_bytecode = &s_pass_entry; } } if (gs_changed) { HandleGSUIDChange(gs_uid, on_gpu_thread); } if (ps_changed) { HandlePSUIDChange(ps_uid, on_gpu_thread); } }