o3de / sig-simulation

Special Interest Group for Simulation
Apache License 2.0
9 stars 13 forks source link

Proposed RFC Feature : PhysX Gem 4/5 Split #85

Closed spham-amzn closed 5 months ago

spham-amzn commented 7 months ago

Summary:

The PhysX gem currently supports either the PhysX 4 or PhysX 5 library from NVIDIA. However, the version of PhysX that the gem links against is determined by a cmake switch at project generation time, meaning that only one of the versions is available. This puts a restriction on the engine to be either built with PhysX 4 or PhysX 5, and new projects generated from the Project Manager will be restricted to this fixed version as well. This RFC is a proposal to split the PhysX gem into two distinct gems: one for PhysX 4, and one for PhysX 5.

What is the relevance of this feature?

PhysX 5 is a major release from NVIDIA and brings improvements for the physics simulations space. PhysX 5 is particularly important for the ROS gem and robotics simulation due to new features that it supports. For projects that were formerly based on PhysX 4, an extensive migration is necessary. Rather than forcing an update for all projects that were formerly using PhysX 4 to PhysX 5, O3DE supports both versions. However, rather than supporting both versions concurrently, the version is determined by the CMake variable AZ_USE_PHYSX5.

The problems of having a CMake variable determine the version of PhysX at project generation are:

Splitting the single PhysX gem into version specific ones will solve these issues:

Feature design description:

Additional Gems

Currently, PhysX 5 is an opt-in flag. By default, PhysX 4 is the version of Phys X that the gem will use. Since the version is determined by this opt-in flag, the single PhysX gem will be built with either version but will not be reflected in the gem description. Not only is the PhysX gem affected by this, but also the PhysXDebug gem as well. When configuring the gems for the project, the PhysX and PhysXDebug gems are listed with their basic information, but not with any information regarding the version of PhysX they represent.

physx_4

We will split the gem into a PhysX & PhysX5 gem (and PhysXDebug & PhysX5Debug respectively). For backwards compatibility, the PhysX for version 4 gem will not be renamed to PhysX4 since all of the existing SDK were built with version 4 being the default version. Instead, the PhysX version 4 gem will only be updated with the gem description, while the PhysX/PhysXDebug gem will be named PhysX5/PhysX5Debug along with the version information in its description.

physx_split

Current Workflow

The current workflow to create a project that utilizes PhysX 4 or PhysX 5 requires that the Physx version decision to be made at the engine project generation time. The following describes the workflow based on a source build of the engine. For SDK builds, they currently only support PhysX 4, so those workflows will be omitted here.

  1. Clone o3de from github.com

  2. Register the o3de engine
    o3de.bat register --this-engine 

  3. Create a new project from the O3DE CLI (see 'Creating Projects on Windows') using the DefaultProject Template.
    scripts\o3de.bat create-project --project-path %USERPROFILE%\O3DE\Projects\MyProject 

  4. Go to the new project project folder
    cd %USERPROFILE%\O3DE\Projects\MyProject

  5. Run the cmake generation from the project folder
    cmake -B build/windows 

The DefaultProject template will have the PhysX gem enabled. And since PhysX 4 is the default, there is no special flag that needs to be set at this point.

Source Build PhysX 5

The steps to build a new project with PhysX 5 is the same as the Source Build PhysX 4 steps, except for step #5 will add the AZ_USE_PHYSX5 flag

cmake -B build/windows -DAZ_ENABLE_PHYSX5=TRUE 

Installed SDK Builds

The workflow using the O3DE Project Manager from the installation of the O3DE SDKs only support PhysX 4. There is no support for PhysX 5 due to the fact that there are no PhysX 5 specific installers currently.

Switching PhysX versions

Switching the version of PhysX requires a rebuild of the project with the AZ_ENABLE_PHYSX5  argument reversed, and then the project / engine rebuilt.

Workflow Improvements

Splitting the PhysX gem will improve workflow such that the choice of which PhysX version to use for PhysX is not made at compile time for source builds. It also allows for the creation of a single installed SDK build will support more than just one version of PhysX at the same time.

Technical design description:

PhysX version 5 argument removal and 3rd Party Updates

The AZ_USE_PHYSX5 CMake variable will be removed. This will mean that the ly_associate_package calls for PhysX4 vs PhysX5 based on this argument will no longer be gated on this condition. Both 3rd Party PhysX4 and Physx5 packages will exist simultaneously. That means that instead of a single 3rdParty:PhysX package target, there will be two:

The individual PhysX4 and PhysX5 gems will depend on their corresponding 3rdParty package equivalent. This also means that the 3rd Party package's FindPhysX.cmake will be changed to FindPhysX4.cmake and FindPhysX5.cmake respectively. The location of the ly_associate_package call to bring in PhysX will be removed from the global BuiltinPackages_<platform>.cmake  file and into each split gem's platform specific PAL cmake file, depending on the version.

CMake Target Hierarchy

The relevant CMake target dependency hierarchy currently has the single PhysX Gem that links against NVIDIA PhysX4 or PhysX5 based only on the AZ_USE_PHYSX5 flag, so it gives no indication of which version is actually built after the variable is set.

Current PhysX Hierarchy
diagram_before

Splitting the gem will require that all of the previous PhysX targets that had any dependencies on the PhysX 3rd Party package will need to be separated into a PhysX and PhysX5  version each. (See the feature design description section for why we are not renaming to PhysX4). Only PhysX.NumericalMethods and PhysX.Mocks do not need to be split since they do not have any upstream dependency to the 3rd Party PhysX, and thus can be shared across both gems.

Proposed Hierarchy
diagram_after

Additional Details

What are the advantages of the feature?

The advantages of splitting the PhysX gem are:

What are the disadvantages of the feature?

How will this be implemented or integrated into the O3DE environment?

The details of implementation are mostly described in the technical design description section. The updates will be made in the following repos

The ROS2 gem will be updated to depend on PhysX 5.

The PhysX 3rd party packages for version 4 and 5 will be updated and rebuilt for all supported platforms to support the name change for FindPhysX.cmake  to FindPhysX<ver>.cmake  as well

Are there any alternatives to this feature?

How will users learn this feature?

Are there any open questions?

adamdbrw commented 7 months ago

Great work @spham-amzn! I believe this is very much needed.

adamdbrw commented 7 months ago

Great work! It would be very useful to clarify PhysX 5 fork situation, schedule for updating to upstream etc.

nick-l-o3de commented 6 months ago

Looks good to me - it may be possible to avoid downloading both 3rd party libraries, though (at least, on a per-user basis). This is because the 3rd Party system only actually fetches a library if a target being built actually depends on that library. So if the two 3rd party libraries are separate downloads (as in, .tar.xz files in the 3p system CDN) then only actually linking to the target in your project will cause it to fetch.

The installer would have to include both binaries though, but not the entirety of both 3p sdks.

lgleim commented 6 months ago

Technically, this looks like a very nice proposal to me and it has got my support. I am however wondering about the longer-term perspective of this proposal, since this will mean maintaining both PhysX4 and PhysX5 in parallel for the foreseeable future. Does this proposal come with such a commitment?

Deprecating support for Multiplayer with PhysX5 also appears like a significant regression. I would prefer to see all core Gems updated between major releases when moving forward.

Finally, which should be the default PhysX version for newly created projects in the future? Or will this vary by template?

spham-amzn commented 6 months ago

The decision to deprecate PhysX version 4 is not part of the scope of this RFC. This RFC is meant to fix the current situation of how we handle both major versions. I would agree that it would be better not to support dual major versions, but I think that will require an in-depth analysis of PhysX5 and the gaps that it has with PhysX4, and that would be require another RFC. And also, the default version of the PhysX gem will be dictated by the template that is used to create the project.

spham-amzn commented 5 months ago

This feature has been merged into o3de and o3de-extras