Integrating latest from github/staging

Integrating up through commit 5e1bdae
This commit is contained in:
alexpete
2021-03-26 14:31:50 -07:00
parent 9c54341af8
commit 36c4e827bd
764 changed files with 11453 additions and 20251 deletions
@@ -0,0 +1,16 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
constexpr char CognitoUserPoolIdResourceMappingKey[] = "AWSClientAuth.CognitoUserPoolId";
constexpr char CognitoAppClientIdResourceMappingKey[] = "AWSClientAuth.CognitoUserPoolAppClientId";
constexpr char CognitoIdentityPoolIdResourceMappingKey[] = "AWSClientAuth.CognitoIdentityPoolId";
@@ -23,8 +23,8 @@ namespace AWSClientAuth
: public AuthenticationProviderInterface
{
public:
AWSCognitoAuthenticationProvider();
virtual ~AWSCognitoAuthenticationProvider();
AWSCognitoAuthenticationProvider() = default;
virtual ~AWSCognitoAuthenticationProvider() = default;
// AuthenticationProviderInterface overrides
bool Initialize(AZStd::weak_ptr<AZ::SettingsRegistryInterface> settingsRegistry) override;
@@ -41,8 +41,8 @@ namespace AWSClientAuth
void UpdateTokens(const Aws::CognitoIdentityProvider::Model::AuthenticationResultType& authenticationResult);
protected:
AZStd::unique_ptr<AWSCognitoProviderSetting> m_settings;
AZStd::string m_session;
AZStd::string m_cognitoAppClientId;
};
} // namespace AWSClientAuth
@@ -68,35 +68,4 @@ namespace AWSClientAuth
->Field("OAuthTokensURL", &GoogleProviderSetting::m_oAuthTokensURL);
}
};
//! Holds AWS Cognito provider serialized Settings.
class AWSCognitoProviderSetting
{
public:
AWSCognitoProviderSetting() = default;
~AWSCognitoProviderSetting() = default;
AZ_TYPE_INFO(AWSCognitoProviderSetting, "{46EF239C-D3CF-4B17-BA68-FD6B3B249305}");
AZStd::string m_appClientId;
static void Reflect(AZ::SerializeContext& context)
{
context.Class<AWSCognitoProviderSetting>()
->Field("AppClientId", &AWSCognitoProviderSetting::m_appClientId)
;
AZ::EditContext* editContext = context.GetEditContext();
if (editContext)
{
editContext->Class<AWSCognitoProviderSetting>("AWSCognitoProviderSetting", "AWSCognitoProviderSetting Settings")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "AWSClientAuth")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
->DataElement(AZ::Edit::UIHandlers::Default, &AWSCognitoProviderSetting::m_appClientId, "ClientId", "Cognito User Pool App Client Id");
}
}
};
} // namespace AWSClientAuth
@@ -14,27 +14,25 @@
namespace AWSClientAuth
{
constexpr char OAUTH_CLIENT_ID_BODY_KEY[] = "client_id";
constexpr char OAUTH_CLIENT_SECRET_BODY_KEY[] = "client_secret";
constexpr char OAUTH_DEVICE_CODE_BODY_KEY[] = "device_code";
constexpr char OAUTH_SCOPE_BODY_KEY[] = "scope";
constexpr char OAUTH_SCOPE_BODY_VALUE[] = "profile";
constexpr char OAUTH_GRANT_TYPE_BODY_KEY[] = "grant_type";
constexpr char OAUTH_REFRESH_TOKEN_BODY_KEY[] = "refresh_token";
constexpr char OAUTH_REFRESH_TOKEN_BODY_VALUE[] = "refresh_token";
constexpr char OAUTH_RESPONSE_TYPE_BODY_KEY[] = "response_type";
constexpr char OAUTH_CONTENT_TYPE_HEADER_KEY[] = "Content-Type";
constexpr char OAUTH_CONTENT_TYPE_HEADER_VALUE[] = "application/x-www-form-urlencoded";
constexpr char OAUTH_CONTENT_LENGTH_HEADER_KEY[] = "Content-Length";
constexpr char OAUTH_USER_CODE_RESPONSE_KEY[] = "user_code";
constexpr char OAUTH_ID_TOKEN_RESPONSE_KEY[] = "id_token";
constexpr char OAUTH_ACCESS_TOKEN_RESPONSE_KEY[] = "access_token";
constexpr char OAUTH_REFRESH_TOKEN_RESPONSE_KEY[] = "refresh_token";
constexpr char OAUTH_EXPIRES_IN_RESPONSE_KEY[] = "expires_in";
constexpr char OAUTH_ERROR_RESPONSE_KEY[] = "error";
constexpr char OAuthClientIdBodyKey[] = "client_id";
constexpr char OAuthClientSecretBodyKey[] = "client_secret";
constexpr char OAuthDeviceCodeBodyKey[] = "device_code";
constexpr char OAuthScopeBodyKey[] = "scope";
constexpr char OAuthScopeBodyValue[] = "profile";
constexpr char OAuthGrantTypeBodyKey[] = "grant_type";
constexpr char OAuthRefreshTokenBodyKey[] = "refresh_token";
constexpr char OAuthRefreshTokenBodyValue[] = "refresh_token";
constexpr char OAuthResponseTypeBodyKey[] = "response_type";
constexpr char OAuthContentTypeHeaderKey[] = "Content-Type";
constexpr char OAuthContentTypeHeaderValue[] = "application/x-www-form-urlencoded";
constexpr char OAuthContentLengthHeaderKey[] = "Content-Length";
constexpr char OAuthUserCodeResponseKey[] = "user_code";
constexpr char OAuthIdTokenResponseKey[] = "id_token";
constexpr char OAuthAccessTokenResponseKey[] = "access_token";
constexpr char OAuthRefreshTokenResponseKey[] = "refresh_token";
constexpr char OAuthExpiresInResponseKey[] = "expires_in";
constexpr char OAuthErrorResponseKey[] = "error";
} // namespace AWSClientAuth
@@ -12,7 +12,6 @@
#pragma once
#include <Authorization/AWSCognitoAuthorizationTypes.h>
#include <aws/identity-management/auth/PersistentCognitoIdentityProvider.h>
namespace AWSClientAuth
@@ -13,7 +13,6 @@
#pragma once
#include <Authorization/AWSCognitoAuthorizationBus.h>
#include <Authorization/AWSCognitoAuthorizationTypes.h>
#include <Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h>
#include <Authentication/AuthenticationProviderBus.h>
#include <Credential/AWSCredentialBus.h>
@@ -34,7 +33,7 @@ namespace AWSClientAuth
virtual ~AWSCognitoAuthorizationController();
// AWSCognitoAuthorizationRequestsBus interface methods
bool Initialize(const AZStd::string& settingsRegistryPath) override;
bool Initialize() override;
void Reset() override;
AZStd::string GetIdentityId() override;
bool HasPersistedLogins() override;
@@ -54,12 +53,15 @@ namespace AWSClientAuth
int GetCredentialHandlerOrder() const override;
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> GetCredentialsProvider() override;
AZStd::unique_ptr<CognitoAuthorizationSettings> m_settings;
std::shared_ptr<AWSClientAuthPersistentCognitoIdentityProvider> m_persistentCognitoIdentityProvider;
std::shared_ptr<AWSClientAuthPersistentCognitoIdentityProvider> m_persistentAnonymousCognitoIdentityProvider;
std::shared_ptr<Aws::Auth::CognitoCachingAuthenticatedCredentialsProvider> m_cognitoCachingCredentialsProvider;
std::shared_ptr<Aws::Auth::CognitoCachingAnonymousCredentialsProvider> m_cognitoCachingAnonymousCredentialsProvider;
AZStd::string m_cognitoIdentityPoolId;
AZStd::string m_formattedCognitoUserPoolId;
AZStd::string m_awsAccountId;
private:
void PersistLoginsAndRefreshAWSCredentials(const AuthenticationTokens& authenticationTokens);
@@ -1,59 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Serialization/EditContext.h>
namespace AWSClientAuth
{
//! Holds Cognito Authorization Identity pool settings.
class CognitoAuthorizationSettings
{
public:
AZ_TYPE_INFO(CognitoAuthorizationSettings, "{2F2080CD-E575-42BD-9717-E42E43C13956}");
static void Reflect(AZ::SerializeContext& context)
{
context.Class<CognitoAuthorizationSettings>()
->Field("CognitoUserPoolId", &CognitoAuthorizationSettings::m_cognitoUserPoolId)
->Field("LoginWithAmazonId", &CognitoAuthorizationSettings::m_loginWithAmazonId)
->Field("GoogleId", &CognitoAuthorizationSettings::m_googleId)
->Field("AWSAccountId", &CognitoAuthorizationSettings::m_awsAccountId)
->Field("IdentityPoolId", &CognitoAuthorizationSettings::m_cognitoIdentityPoolId);
AZ::EditContext* editContext = context.GetEditContext();
if (editContext)
{
editContext->Class<CognitoAuthorizationSettings>("CognitoAuthorizationSettings", "CognitoAuthorizationSettings")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "AWSClientAuth")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
->DataElement(AZ::Edit::UIHandlers::Default, &CognitoAuthorizationSettings::m_cognitoUserPoolId, "CognitoUserPoolId", "Cognito User pool Id")
->DataElement(AZ::Edit::UIHandlers::Default, &CognitoAuthorizationSettings::m_loginWithAmazonId, "LoginWithAmazonId", "Login with Amazon id. default: www.amazon.com")
->DataElement(AZ::Edit::UIHandlers::Default, &CognitoAuthorizationSettings::m_googleId, "Google Endpoint", "Google endpoint. default: accounts.google.com")
->DataElement(AZ::Edit::UIHandlers::Default, &CognitoAuthorizationSettings::m_cognitoUserPoolId, "AWSAccountId", "AWS account Cognito for Cognito identity pool")
->DataElement(AZ::Edit::UIHandlers::Default, &CognitoAuthorizationSettings::m_cognitoUserPoolId, "IdentityPoolId", "Cognito Identity pool Id")
;
}
}
AZStd::string m_cognitoUserPoolId;
AZStd::string m_loginWithAmazonId = "www.amazon.com";
AZStd::string m_googleId = "accounts.google.com";
AZStd::string m_awsAccountId;
AZStd::string m_cognitoIdentityPoolId;
};
} // namespace AWSClientAuth
@@ -13,7 +13,6 @@
#pragma once
#include <UserManagement/AWSCognitoUserManagementBus.h>
#include <UserManagement/AWSCognitoUserManagementTypes.h>
namespace AWSClientAuth
{
@@ -27,7 +26,7 @@ namespace AWSClientAuth
virtual ~AWSCognitoUserManagementController();
// AWSCognitoUserManagementRequestsBus interface methods
bool Initialize(const AZStd::string& settingsRegistryPath);
bool Initialize() override;
void EmailSignUpAsync(const AZStd::string& username, const AZStd::string& password, const AZStd::string& email) override;
void PhoneSignUpAsync(const AZStd::string& username, const AZStd::string& password, const AZStd::string& phoneNumber) override;
void ConfirmSignUpAsync(const AZStd::string& username, const AZStd::string& confirmationCode) override;
@@ -35,8 +34,13 @@ namespace AWSClientAuth
void ConfirmForgotPasswordAsync(const AZStd::string& userName, const AZStd::string& confirmationCode, const AZStd::string& newPassword) override;
void EnableMFAAsync(const AZStd::string& accessToken) override;
protected:
AZStd::unique_ptr<AWSCognitoUserManagementSetting> m_settings;
inline const AZStd::string& GetCognitoAppClientId() const
{
return m_cognitoAppClientId;
}
private:
AZStd::string m_cognitoAppClientId;
};
} // namespace AWSClientAuth
@@ -1,50 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Serialization/EditContext.h>
namespace AWSClientAuth
{
//! Holds AWS Cognito user management serialized Settings.
class AWSCognitoUserManagementSetting
{
public:
AWSCognitoUserManagementSetting() = default;
~AWSCognitoUserManagementSetting() = default;
AZ_TYPE_INFO(AWSCognitoUserManagementSetting, "{58FC34F1-B84B-4677-B986-45A226F0328D}");
AZStd::string m_appClientId;
static void Reflect(AZ::SerializeContext& context)
{
context.Class<AWSCognitoUserManagementSetting>()
->Field("AppClientId", &AWSCognitoUserManagementSetting::m_appClientId)
;
AZ::EditContext* editContext = context.GetEditContext();
if (editContext)
{
editContext->Class<AWSCognitoUserManagementSetting>("AWSCognitoUserManagementSetting", "AWSCognitoUserManagementSetting Settings")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "AWSClientAuth")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
->DataElement(AZ::Edit::UIHandlers::Default, &AWSCognitoUserManagementSetting::m_appClientId, "ClientId", "Cognito User Pool App Client Id")
;
}
}
};
} // namespace AWSClientAuth
@@ -27,7 +27,7 @@ namespace AWSClientAuth
//! Initializes settings for Cognito identity pool from settings registry.
//! @param settingsRegistryPath Path for the settings registry file to use.
virtual bool Initialize(const AZStd::string& settingsRegistryPath) = 0;
virtual bool Initialize() = 0;
//! Once credentials provider are set they cannot be reset. So recreates new Cognito credentials provider on reset.
//! Service clients need to be created with the new AWSCredentialsProvider after reset.
@@ -24,7 +24,7 @@ namespace AWSClientAuth
//! Initialize Cognito User pool.
//! @param settingsRegistryPath settingsRegistryPath Path for the settings registry file to use.
virtual bool Initialize(const AZStd::string& settingsRegistryPath) = 0;
virtual bool Initialize() = 0;
// Requests interface
//! Cognito user pool email sign up start.
@@ -16,7 +16,6 @@
#include <UserManagement/UserManagementNotificationBusBehaviorHandler.h>
#include <Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h>
#include <Authorization/AWSCognitoAuthorizationController.h>
#include <Authorization/AWSCognitoAuthorizationTypes.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <ResourceMapping/AWSResourceMappingBus.h>
@@ -25,7 +24,7 @@
namespace AWSClientAuth
{
constexpr char SERIALIZE_COMPONENT_NAME[] = "AWSClientAuth";
constexpr char SerializeComponentName[] = "AWSClientAuth";
void AWSClientAuthSystemComponent::Reflect(AZ::ReflectContext* context)
{
@@ -41,17 +40,14 @@ namespace AWSClientAuth
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System"))
->Attribute(AZ::Edit::Attributes::AutoExpand, true);
}
AWSClientAuth::AWSCognitoProviderSetting::Reflect(*serialize);
AWSClientAuth::LWAProviderSetting::Reflect(*serialize);
AWSClientAuth::GoogleProviderSetting::Reflect(*serialize);
AWSClientAuth::CognitoAuthorizationSettings::Reflect(*serialize);
AWSClientAuth::AWSCognitoUserManagementSetting::Reflect(*serialize);
}
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<AuthenticationProviderRequestBus>("AuthenticationProviderRequestBus")
->Attribute(AZ::Script::Attributes::Category, SERIALIZE_COMPONENT_NAME)
->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
->Event("Initialize", &AuthenticationProviderRequestBus::Events::Initialize)
->Event("IsSignedIn", &AuthenticationProviderRequestBus::Events::IsSignedIn)
->Event("GetAuthenticationTokens", &AuthenticationProviderRequestBus::Events::GetAuthenticationTokens)
@@ -64,7 +60,7 @@ namespace AWSClientAuth
->Event("SignOut", &AuthenticationProviderRequestBus::Events::SignOut);
behaviorContext->EBus<AWSCognitoAuthorizationRequestBus>("AWSCognitoAuthorizationRequestBus")
->Attribute(AZ::Script::Attributes::Category, SERIALIZE_COMPONENT_NAME)
->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
->Event("Initialize", &AWSCognitoAuthorizationRequestBus::Events::Initialize)
->Event("Reset", &AWSCognitoAuthorizationRequestBus::Events::Reset)
->Event("GetIdentityId", &AWSCognitoAuthorizationRequestBus::Events::GetIdentityId)
@@ -72,7 +68,7 @@ namespace AWSClientAuth
->Event("RequestAWSCredentialsAsync", &AWSCognitoAuthorizationRequestBus::Events::RequestAWSCredentialsAsync);
behaviorContext->EBus<AWSCognitoUserManagementRequestBus>("AWSCognitoUserManagementRequestBus")
->Attribute(AZ::Script::Attributes::Category, SERIALIZE_COMPONENT_NAME)
->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
->Event("Initialize", &AWSCognitoUserManagementRequestBus::Events::Initialize)
->Event("EmailSignUpAsync", &AWSCognitoUserManagementRequestBus::Events::EmailSignUpAsync)
->Event("PhoneSignUpAsync", &AWSCognitoUserManagementRequestBus::Events::PhoneSignUpAsync)
@@ -18,6 +18,8 @@
#include <Authentication/AuthenticationProviderBus.h>
#include <AWSClientAuthBus.h>
#include <AWSCoreBus.h>
#include <ResourceMapping/AWSResourceMappingBus.h>
#include <AWSClientAuthResourceMappingConstants.h>
#include <aws/cognito-idp/model/InitiateAuthRequest.h>
#include <aws/cognito-idp/model/InitiateAuthResult.h>
@@ -28,31 +30,18 @@
namespace AWSClientAuth
{
constexpr char COGNITO_IDP_SETTINGS_PATH[] = "/AWS/CognitoIDP";
constexpr char COGNITO_USERNAME_KEY[] = "USERNAME";
constexpr char COGNITO_PASSWORD_KEY[] = "PASSWORD";
constexpr char COGNITO_REFRESH_TOKEN_AUTHPARAM_KEY[] = "REFRESH_TOKEN";
constexpr char COGNITO_SMS_MFA_CODE_KEY[] = "SMS_MFA_CODE";
AWSCognitoAuthenticationProvider::AWSCognitoAuthenticationProvider()
{
m_settings = AZStd::make_unique<AWSCognitoProviderSetting>();
}
AWSCognitoAuthenticationProvider::~AWSCognitoAuthenticationProvider()
{
m_settings.reset();
}
constexpr char CognitoUsernameKey[] = "USERNAME";
constexpr char CognitoPasswordKey[] = "PASSWORD";
constexpr char CognitoRefreshTokenAuthParamKey[] = "REFRESH_TOKEN";
constexpr char CognitoSmsMfaCodeKey[] = "SMS_MFA_CODE";
bool AWSCognitoAuthenticationProvider::Initialize(AZStd::weak_ptr<AZ::SettingsRegistryInterface> settingsRegistry)
{
if (!settingsRegistry.lock()->GetObject(m_settings.get(), azrtti_typeid(m_settings.get()), COGNITO_IDP_SETTINGS_PATH))
{
AZ_Warning("AWSCognitoAuthenticationProvider", true, "Failed to get settings object for path %s", COGNITO_IDP_SETTINGS_PATH);
return false;
}
return true;
AZ_UNUSED(settingsRegistry);
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
m_cognitoAppClientId, &AWSCore::AWSResourceMappingRequests::GetResourceNameId, CognitoAppClientIdResourceMappingKey);
AZ_Warning("AWSCognitoAuthenticationProvider", m_cognitoAppClientId.empty(), "Missing Cognito App Client Id from resource mappings. Calls to Cognito will fail.");
return !m_cognitoAppClientId.empty();
}
@@ -128,9 +117,9 @@ namespace AWSClientAuth
// Set Request parameters for SMS Multi factor authentication.
// Note: Email MFA is no longer supported by Cognito, use SMS as MFA
Aws::CognitoIdentityProvider::Model::RespondToAuthChallengeRequest respondToAuthChallengeRequest;
respondToAuthChallengeRequest.SetClientId(m_settings->m_appClientId.c_str());
respondToAuthChallengeRequest.AddChallengeResponses(COGNITO_SMS_MFA_CODE_KEY, confirmationCode.c_str());
respondToAuthChallengeRequest.AddChallengeResponses(COGNITO_USERNAME_KEY, username.c_str());
respondToAuthChallengeRequest.SetClientId(m_cognitoAppClientId.c_str());
respondToAuthChallengeRequest.AddChallengeResponses(CognitoSmsMfaCodeKey, confirmationCode.c_str());
respondToAuthChallengeRequest.AddChallengeResponses(CognitoUsernameKey, username.c_str());
respondToAuthChallengeRequest.SetChallengeName(Aws::CognitoIdentityProvider::Model::ChallengeNameType::SMS_MFA);
respondToAuthChallengeRequest.SetSession(m_session.c_str());
@@ -177,13 +166,13 @@ namespace AWSClientAuth
{
// Set Request parameters.
Aws::CognitoIdentityProvider::Model::InitiateAuthRequest initiateAuthRequest;
initiateAuthRequest.SetClientId(m_settings->m_appClientId.c_str());
initiateAuthRequest.SetClientId(m_cognitoAppClientId.c_str());
initiateAuthRequest.SetAuthFlow(Aws::CognitoIdentityProvider::Model::AuthFlowType::REFRESH_TOKEN_AUTH);
// Set username and password for Password grant/ Initiate Auth flow.
Aws::Map<Aws::String, Aws::String> authParameters
{
{COGNITO_REFRESH_TOKEN_AUTHPARAM_KEY, GetAuthenticationTokens().GetRefreshToken().c_str()}
{CognitoRefreshTokenAuthParamKey, GetAuthenticationTokens().GetRefreshToken().c_str()}
};
initiateAuthRequest.SetAuthParameters(authParameters);
@@ -228,14 +217,14 @@ namespace AWSClientAuth
{
// Set Request parameters.
Aws::CognitoIdentityProvider::Model::InitiateAuthRequest initiateAuthRequest;
initiateAuthRequest.SetClientId(m_settings->m_appClientId.c_str());
initiateAuthRequest.SetClientId(m_cognitoAppClientId.c_str());
initiateAuthRequest.SetAuthFlow(Aws::CognitoIdentityProvider::Model::AuthFlowType::USER_PASSWORD_AUTH);
// Set username and password for Password grant/ Initiate Auth flow.
Aws::Map<Aws::String, Aws::String> authParameters
{
{COGNITO_USERNAME_KEY, username.c_str()},
{COGNITO_PASSWORD_KEY, password.c_str()}
{CognitoUsernameKey, username.c_str()},
{CognitoPasswordKey, password.c_str()}
};
initiateAuthRequest.SetAuthParameters(authParameters);
@@ -22,8 +22,8 @@
namespace AWSClientAuth
{
constexpr char GOOGLE_SETTINGS_PATH[] = "/AWS/Google";
constexpr char GOOGLE_VERIFICATION_URL_RESPONSE_KEY[] = "verification_url";
constexpr char GoogleSettingsPath[] = "/AWS/Google";
constexpr char GoogleVerificationUrlResponseKey[] = "verification_url";
GoogleAuthenticationProvider::GoogleAuthenticationProvider()
{
@@ -37,9 +37,9 @@ namespace AWSClientAuth
bool GoogleAuthenticationProvider::Initialize(AZStd::weak_ptr<AZ::SettingsRegistryInterface> settingsRegistry)
{
if (!settingsRegistry.lock()->GetObject(m_settings.get(), azrtti_typeid(m_settings.get()), GOOGLE_SETTINGS_PATH))
if (!settingsRegistry.lock()->GetObject(m_settings.get(), azrtti_typeid(m_settings.get()), GoogleSettingsPath))
{
AZ_Warning("AWSCognitoAuthenticationProvider", true, "Failed to get Google settings object for path %s", GOOGLE_SETTINGS_PATH);
AZ_Warning("AWSCognitoAuthenticationProvider", true, "Failed to get Google settings object for path %s", GoogleSettingsPath);
return false;
}
return true;
@@ -70,13 +70,13 @@ namespace AWSClientAuth
// Refer https://developers.google.com/identity/protocols/oauth2/limited-input-device#step-1:-request-device-and-user-codes.
void GoogleAuthenticationProvider::DeviceCodeGrantSignInAsync()
{
AZStd::string body = AZStd::string::format("%s=%s&%s=%s", OAUTH_CLIENT_ID_BODY_KEY, m_settings->m_appClientId.c_str()
, OAUTH_SCOPE_BODY_KEY, OAUTH_SCOPE_BODY_VALUE);
AZStd::string body = AZStd::string::format("%s=%s&%s=%s", OAuthClientIdBodyKey, m_settings->m_appClientId.c_str()
, OAuthScopeBodyKey, OAuthScopeBodyValue);
// Set headers and body for device sign in http requests.
AZStd::map<AZStd::string, AZStd::string> headers;
headers[OAUTH_CONTENT_TYPE_HEADER_KEY] = OAUTH_CONTENT_TYPE_HEADER_VALUE;
headers[OAUTH_CONTENT_LENGTH_HEADER_KEY] = AZStd::to_string(body.length());
headers[OAuthContentTypeHeaderKey] = OAuthContentTypeHeaderValue;
headers[OAuthContentLengthHeaderKey] = AZStd::to_string(body.length());
HttpRequestor::HttpRequestorRequestBus::Broadcast(&HttpRequestor::HttpRequestorRequests::AddRequestWithHeadersAndBody, m_settings->m_oAuthCodeURL
, Aws::Http::HttpMethod::HTTP_POST, headers, body
@@ -84,15 +84,15 @@ namespace AWSClientAuth
{
if (responseCode == Aws::Http::HttpResponseCode::OK)
{
m_cachedDeviceCode = jsonView.GetString(OAUTH_DEVICE_CODE_BODY_KEY).c_str();
m_cachedDeviceCode = jsonView.GetString(OAuthDeviceCodeBodyKey).c_str();
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnDeviceCodeGrantSignInSuccess
, jsonView.GetString(OAUTH_USER_CODE_RESPONSE_KEY).c_str(), jsonView.GetString(GOOGLE_VERIFICATION_URL_RESPONSE_KEY).c_str()
, jsonView.GetInteger(OAUTH_EXPIRES_IN_RESPONSE_KEY));
, jsonView.GetString(OAuthUserCodeResponseKey).c_str(), jsonView.GetString(GoogleVerificationUrlResponseKey).c_str()
, jsonView.GetInteger(OAuthExpiresInResponseKey));
}
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnDeviceCodeGrantSignInFail
, jsonView.GetString(OAUTH_ERROR_RESPONSE_KEY).c_str());
, jsonView.GetString(OAuthErrorResponseKey).c_str());
}
}
);
@@ -105,12 +105,12 @@ namespace AWSClientAuth
{
// Set headers and body for device confirm sign in http requests.
AZStd::map<AZStd::string, AZStd::string> headers;
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s&%s=%s", OAUTH_CLIENT_ID_BODY_KEY, m_settings->m_appClientId.c_str()
, OAUTH_CLIENT_SECRET_BODY_KEY, m_settings->m_clientSecret.c_str(), OAUTH_DEVICE_CODE_BODY_KEY, m_cachedDeviceCode.c_str()
, OAUTH_GRANT_TYPE_BODY_KEY, m_settings->m_grantType.c_str());
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s&%s=%s", OAuthClientIdBodyKey, m_settings->m_appClientId.c_str()
, OAuthClientSecretBodyKey, m_settings->m_clientSecret.c_str(), OAuthDeviceCodeBodyKey, m_cachedDeviceCode.c_str()
, OAuthGrantTypeBodyKey, m_settings->m_grantType.c_str());
headers[OAUTH_CONTENT_TYPE_HEADER_KEY] = OAUTH_CONTENT_TYPE_HEADER_VALUE;
headers[OAUTH_CONTENT_LENGTH_HEADER_KEY] = AZStd::to_string(body.length());
headers[OAuthContentTypeHeaderKey] = OAuthContentTypeHeaderValue;
headers[OAuthContentLengthHeaderKey] = AZStd::to_string(body.length());
HttpRequestor::HttpRequestorRequestBus::Broadcast(&HttpRequestor::HttpRequestorRequests::AddRequestWithHeadersAndBody, m_settings->m_oAuthTokensURL
, Aws::Http::HttpMethod::HTTP_POST, headers, body
@@ -125,7 +125,7 @@ namespace AWSClientAuth
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnDeviceCodeGrantConfirmSignInFail
, jsonView.GetString(OAUTH_ERROR_RESPONSE_KEY).c_str());
, jsonView.GetString(OAuthErrorResponseKey).c_str());
}
}
);
@@ -136,12 +136,12 @@ namespace AWSClientAuth
void GoogleAuthenticationProvider::RefreshTokensAsync()
{
AZStd::map<AZStd::string, AZStd::string> headers;
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s&%s=%s", OAUTH_CLIENT_ID_BODY_KEY, m_settings->m_appClientId.c_str()
, OAUTH_CLIENT_SECRET_BODY_KEY, m_settings->m_clientSecret.c_str()
, OAUTH_GRANT_TYPE_BODY_KEY, OAUTH_REFRESH_TOKEN_BODY_VALUE, OAUTH_REFRESH_TOKEN_BODY_KEY, m_authenticationTokens.GetRefreshToken().c_str());
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s&%s=%s", OAuthClientIdBodyKey, m_settings->m_appClientId.c_str()
, OAuthClientSecretBodyKey, m_settings->m_clientSecret.c_str()
, OAuthGrantTypeBodyKey, OAuthRefreshTokenBodyValue, OAuthRefreshTokenBodyKey, m_authenticationTokens.GetRefreshToken().c_str());
headers[OAUTH_CONTENT_TYPE_HEADER_KEY] = OAUTH_CONTENT_TYPE_HEADER_VALUE;
headers[OAUTH_CONTENT_LENGTH_HEADER_KEY] = AZStd::to_string(body.length());
headers[OAuthContentTypeHeaderKey] = OAuthContentTypeHeaderValue;
headers[OAuthContentLengthHeaderKey] = AZStd::to_string(body.length());
HttpRequestor::HttpRequestorRequestBus::Broadcast(&HttpRequestor::HttpRequestorRequests::AddRequestWithHeadersAndBody, m_settings->m_oAuthTokensURL
, Aws::Http::HttpMethod::HTTP_POST, headers, body
@@ -156,7 +156,7 @@ namespace AWSClientAuth
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnRefreshTokensFail
, jsonView.GetString(OAUTH_ERROR_RESPONSE_KEY).c_str());
, jsonView.GetString(OAuthErrorResponseKey).c_str());
}
}
);
@@ -164,9 +164,9 @@ namespace AWSClientAuth
void GoogleAuthenticationProvider::UpdateTokens(const Aws::Utils::Json::JsonView& jsonView)
{
m_authenticationTokens = AuthenticationTokens(jsonView.GetString(OAUTH_ACCESS_TOKEN_RESPONSE_KEY).c_str(),
jsonView.GetString(OAUTH_REFRESH_TOKEN_RESPONSE_KEY).c_str() ,jsonView.GetString(OAUTH_ID_TOKEN_RESPONSE_KEY).c_str(), ProviderNameEnum::Google
, jsonView.GetInteger(OAUTH_EXPIRES_IN_RESPONSE_KEY));
m_authenticationTokens = AuthenticationTokens(jsonView.GetString(OAuthAccessTokenResponseKey).c_str(),
jsonView.GetString(OAuthRefreshTokenResponseKey).c_str() ,jsonView.GetString(OAuthIdTokenResponseKey).c_str(), ProviderNameEnum::Google
, jsonView.GetInteger(OAuthExpiresInResponseKey));
}
} // namespace AWSClientAuth
@@ -21,8 +21,8 @@
namespace AWSClientAuth
{
constexpr char LWA_SETTINGS_PATH[] = "/AWS/LoginWithAmazon";
constexpr char LWA_VERIFICATION_URL_RESPONSE_KEY[] = "verification_uri";
constexpr char LwaSettingsPath[] = "/AWS/LoginWithAmazon";
constexpr char LwaVerificationUrlResponseKey[] = "verification_uri";
LWAAuthenticationProvider::LWAAuthenticationProvider()
{
@@ -36,9 +36,9 @@ namespace AWSClientAuth
bool LWAAuthenticationProvider::Initialize(AZStd::weak_ptr<AZ::SettingsRegistryInterface> settingsRegistry)
{
if (!settingsRegistry.lock()->GetObject(m_settings.get(), azrtti_typeid(m_settings.get()), LWA_SETTINGS_PATH))
if (!settingsRegistry.lock()->GetObject(m_settings.get(), azrtti_typeid(m_settings.get()), LwaSettingsPath))
{
AZ_Warning("AWSCognitoAuthenticationProvider", true, "Failed to get login with Amazon settings object for path %s", LWA_SETTINGS_PATH);
AZ_Warning("AWSCognitoAuthenticationProvider", true, "Failed to get login with Amazon settings object for path %s", LwaSettingsPath);
return false;
}
return true;
@@ -70,12 +70,12 @@ namespace AWSClientAuth
void LWAAuthenticationProvider::DeviceCodeGrantSignInAsync()
{
// Set headers and body for device sign in http requests.
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s", OAUTH_RESPONSE_TYPE_BODY_KEY, m_settings->m_responseType.c_str()
, OAUTH_CLIENT_ID_BODY_KEY, m_settings->m_appClientId.c_str(), OAUTH_SCOPE_BODY_KEY, OAUTH_SCOPE_BODY_VALUE);
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s", OAuthResponseTypeBodyKey, m_settings->m_responseType.c_str()
, OAuthClientIdBodyKey, m_settings->m_appClientId.c_str(), OAuthScopeBodyKey, OAuthScopeBodyValue);
AZStd::map<AZStd::string, AZStd::string> headers;
headers[OAUTH_CONTENT_TYPE_HEADER_KEY] = OAUTH_CONTENT_TYPE_HEADER_VALUE;
headers[OAUTH_CONTENT_LENGTH_HEADER_KEY] = AZStd::to_string(body.length());
headers[OAuthContentTypeHeaderKey] = OAuthContentTypeHeaderValue;
headers[OAuthContentLengthHeaderKey] = AZStd::to_string(body.length());
HttpRequestor::HttpRequestorRequestBus::Broadcast(&HttpRequestor::HttpRequestorRequests::AddRequestWithHeadersAndBody, m_settings->m_oAuthCodeURL
, Aws::Http::HttpMethod::HTTP_POST, headers, body
@@ -83,17 +83,17 @@ namespace AWSClientAuth
{
if (responseCode == Aws::Http::HttpResponseCode::OK)
{
m_cachedUserCode = jsonView.GetString(OAUTH_USER_CODE_RESPONSE_KEY).c_str();
m_cachedDeviceCode = jsonView.GetString(OAUTH_DEVICE_CODE_BODY_KEY).c_str();
m_cachedUserCode = jsonView.GetString(OAuthUserCodeResponseKey).c_str();
m_cachedDeviceCode = jsonView.GetString(OAuthDeviceCodeBodyKey).c_str();
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnDeviceCodeGrantSignInSuccess
, jsonView.GetString(OAUTH_USER_CODE_RESPONSE_KEY).c_str()
, jsonView.GetString(LWA_VERIFICATION_URL_RESPONSE_KEY).c_str()
, jsonView.GetInteger(OAUTH_EXPIRES_IN_RESPONSE_KEY));
, jsonView.GetString(OAuthUserCodeResponseKey).c_str()
, jsonView.GetString(LwaVerificationUrlResponseKey).c_str()
, jsonView.GetInteger(OAuthExpiresInResponseKey));
}
else
{
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnDeviceCodeGrantSignInFail
, jsonView.GetString(OAUTH_ERROR_RESPONSE_KEY).c_str());
, jsonView.GetString(OAuthErrorResponseKey).c_str());
}
}
);
@@ -104,12 +104,12 @@ namespace AWSClientAuth
void LWAAuthenticationProvider::DeviceCodeGrantConfirmSignInAsync()
{
// Set headers and body for device confirm sign in http requests.
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s", OAUTH_USER_CODE_RESPONSE_KEY, m_cachedUserCode.c_str()
, OAUTH_GRANT_TYPE_BODY_KEY, m_settings->m_grantType.c_str(), OAUTH_DEVICE_CODE_BODY_KEY, m_cachedDeviceCode.c_str());
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s", OAuthUserCodeResponseKey, m_cachedUserCode.c_str()
, OAuthGrantTypeBodyKey, m_settings->m_grantType.c_str(), OAuthDeviceCodeBodyKey, m_cachedDeviceCode.c_str());
AZStd::map<AZStd::string, AZStd::string> headers;
headers[OAUTH_CONTENT_TYPE_HEADER_KEY] = OAUTH_CONTENT_TYPE_HEADER_VALUE;
headers[OAUTH_CONTENT_LENGTH_HEADER_KEY] = AZStd::to_string(body.length());
headers[OAuthContentTypeHeaderKey] = OAuthContentTypeHeaderValue;
headers[OAuthContentLengthHeaderKey] = AZStd::to_string(body.length());
HttpRequestor::HttpRequestorRequestBus::Broadcast(&HttpRequestor::HttpRequestorRequests::AddRequestWithHeadersAndBody, m_settings->m_oAuthTokensURL
, Aws::Http::HttpMethod::HTTP_POST, headers, body
@@ -136,12 +136,12 @@ namespace AWSClientAuth
void LWAAuthenticationProvider::RefreshTokensAsync()
{
// Set headers and body for device confirm sign in http requests.
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s", OAUTH_CLIENT_ID_BODY_KEY, m_settings->m_appClientId.c_str(), OAUTH_GRANT_TYPE_BODY_KEY,
OAUTH_REFRESH_TOKEN_BODY_VALUE, OAUTH_REFRESH_TOKEN_BODY_KEY, m_authenticationTokens.GetRefreshToken().c_str());
AZStd::string body = AZStd::string::format("%s=%s&%s=%s&%s=%s", OAuthClientIdBodyKey, m_settings->m_appClientId.c_str(), OAuthGrantTypeBodyKey,
OAuthRefreshTokenBodyValue, OAuthRefreshTokenBodyKey, m_authenticationTokens.GetRefreshToken().c_str());
AZStd::map<AZStd::string, AZStd::string> headers;
headers[OAUTH_CONTENT_TYPE_HEADER_KEY] = OAUTH_CONTENT_TYPE_HEADER_VALUE;
headers[OAUTH_CONTENT_LENGTH_HEADER_KEY] = AZStd::to_string(body.length());
headers[OAuthContentTypeHeaderKey] = OAuthContentTypeHeaderValue;
headers[OAuthContentLengthHeaderKey] = AZStd::to_string(body.length());
HttpRequestor::HttpRequestorRequestBus::Broadcast(&HttpRequestor::HttpRequestorRequests::AddRequestWithHeadersAndBody, m_settings->m_oAuthTokensURL
, Aws::Http::HttpMethod::HTTP_POST, headers, body
@@ -165,9 +165,9 @@ namespace AWSClientAuth
void LWAAuthenticationProvider::UpdateTokens(const Aws::Utils::Json::JsonView& jsonView)
{
// For Login with Amazon openId and access tokens are the same.
m_authenticationTokens = AuthenticationTokens(jsonView.GetString(OAUTH_ACCESS_TOKEN_RESPONSE_KEY).c_str(), jsonView.GetString(OAUTH_REFRESH_TOKEN_RESPONSE_KEY).c_str(),
jsonView.GetString(OAUTH_ACCESS_TOKEN_RESPONSE_KEY).c_str(), ProviderNameEnum::LoginWithAmazon
, jsonView.GetInteger(OAUTH_EXPIRES_IN_RESPONSE_KEY));
m_authenticationTokens = AuthenticationTokens(jsonView.GetString(OAuthAccessTokenResponseKey).c_str(), jsonView.GetString(OAuthRefreshTokenResponseKey).c_str(),
jsonView.GetString(OAuthAccessTokenResponseKey).c_str(), ProviderNameEnum::LoginWithAmazon
, jsonView.GetInteger(OAuthExpiresInResponseKey));
}
} // namespace AWSClientAuth
@@ -13,6 +13,9 @@
#include <AWSClientAuthBus.h>
#include <AWSCoreBus.h>
#include <Authorization/AWSCognitoAuthorizationController.h>
#include <ResourceMapping/AWSResourceMappingBus.h>
#include <AWSClientAuthResourceMappingConstants.h>
#include <AzCore/EBus/Internal/BusContainer.h>
#include <AzCore/Jobs/JobFunction.h>
#include <AzCore/Interface/Interface.h>
@@ -22,7 +25,9 @@
namespace AWSClientAuth
{
constexpr char COGNITO_AUTHORIZATION_SETTINGS_PATH[] = "/AWS/CognitoIdentityPool";
constexpr char CognitoAmazonLoginsId[] = "www.amazon.com";
constexpr char CognitoGoogleLoginsId[] = "accounts.google.com";
constexpr char CognitoUserPoolIdFormat[] = "cognito-idp.%s.amazonaws.com/%s";
AWSCognitoAuthorizationController::AWSCognitoAuthorizationController()
{
@@ -31,8 +36,6 @@ namespace AWSClientAuth
AuthenticationProviderNotificationBus::Handler::BusConnect();
AWSCore::AWSCredentialRequestBus::Handler::BusConnect();
m_settings = AZStd::make_unique<CognitoAuthorizationSettings>();
m_persistentCognitoIdentityProvider = std::make_shared<AWSClientAuthPersistentCognitoIdentityProvider>();
m_persistentAnonymousCognitoIdentityProvider = std::make_shared<AWSClientAuthPersistentCognitoIdentityProvider>();
@@ -52,32 +55,39 @@ namespace AWSClientAuth
m_persistentCognitoIdentityProvider.reset();
m_persistentAnonymousCognitoIdentityProvider.reset();
m_settings.reset();
AWSCore::AWSCredentialRequestBus::Handler::BusDisconnect();
AuthenticationProviderNotificationBus::Handler::BusDisconnect();
AWSCognitoAuthorizationRequestBus::Handler::BusDisconnect();
AZ::Interface<IAWSCognitoAuthorizationRequests>::Unregister(this);
}
bool AWSCognitoAuthorizationController::Initialize(const AZStd::string& settingsRegistryPath)
bool AWSCognitoAuthorizationController::Initialize()
{
AZStd::unique_ptr<AZ::SettingsRegistryInterface> settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
m_awsAccountId, &AWSCore::AWSResourceMappingRequests::GetDefaultAccountId);
if (!settingsRegistry->MergeSettingsFile(settingsRegistryPath, AZ::SettingsRegistryInterface::Format::JsonMergePatch))
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
m_cognitoIdentityPoolId, &AWSCore::AWSResourceMappingRequests::GetResourceNameId, CognitoIdentityPoolIdResourceMappingKey);
if (m_awsAccountId.empty() || m_cognitoIdentityPoolId.empty())
{
AZ_Error("AWSCognitoAuthorizationController", true, "Failed to merge settings file for path %s", settingsRegistryPath.c_str());
AZ_Warning("AWSCognitoUserManagementController", m_awsAccountId.empty(), "Missing AWS account id in resource mappings.");
AZ_Warning("AWSCognitoUserManagementController", m_cognitoIdentityPoolId.empty(), "Missing Cognito Identity pool id in resource mappings.");
return false;
}
if (!settingsRegistry->GetObject(m_settings.get(), azrtti_typeid(m_settings.get()), COGNITO_AUTHORIZATION_SETTINGS_PATH))
{
AZ_Error("AWSCognitoAuthorizationController", true, "Failed to get settings object for path %s", COGNITO_AUTHORIZATION_SETTINGS_PATH);
return false;
}
AZStd::string userPoolId;
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
userPoolId, &AWSCore::AWSResourceMappingRequests::GetResourceNameId, CognitoUserPoolIdResourceMappingKey);
AZ_Warning("AWSCognitoUserManagementController", userPoolId.empty(), "Missing Cognito USer pool id in resource mappings. Cognito IDP authenticated identities will no work.");
m_persistentCognitoIdentityProvider->Initialize(m_settings->m_awsAccountId.c_str(), m_settings->m_cognitoIdentityPoolId.c_str());
m_persistentAnonymousCognitoIdentityProvider->Initialize(m_settings->m_awsAccountId.c_str(), m_settings->m_cognitoIdentityPoolId.c_str());
AZStd::string defaultRegion;
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
defaultRegion, &AWSCore::AWSResourceMappingRequests::GetDefaultRegion);
m_formattedCognitoUserPoolId = AZStd::string::format(CognitoUserPoolIdFormat, defaultRegion.c_str(), userPoolId.c_str());
m_persistentCognitoIdentityProvider->Initialize(m_awsAccountId.c_str(), m_cognitoIdentityPoolId.c_str());
m_persistentAnonymousCognitoIdentityProvider->Initialize(m_awsAccountId.c_str(), m_cognitoIdentityPoolId.c_str());
return true;
}
@@ -182,15 +192,15 @@ namespace AWSClientAuth
{
case ProviderNameEnum::AWSCognitoIDP:
{
return m_settings->m_cognitoUserPoolId;
return m_formattedCognitoUserPoolId;
}
case ProviderNameEnum::LoginWithAmazon:
{
return m_settings->m_loginWithAmazonId;
return CognitoAmazonLoginsId;
}
case ProviderNameEnum::Google:
{
return m_settings->m_googleId;
return CognitoGoogleLoginsId;
}
default:
{
@@ -14,7 +14,9 @@
#include <UserManagement/AWSCognitoUserManagementController.h>
#include <AWSClientAuthBus.h>
#include <AWSClientAuthResourceMappingConstants.h>
#include <AWSCoreBus.h>
#include <ResourceMapping/AWSResourceMappingBus.h>
#include <aws/core/utils/Outcome.h>
#include <aws/core/utils/memory/stl/AWSVector.h>
@@ -35,41 +37,25 @@
namespace AWSClientAuth
{
constexpr char COGNITO_USER_POOL[] = "/AWS/CognitoUserPool";
AWSCognitoUserManagementController::AWSCognitoUserManagementController()
{
AZ::Interface<IAWSCognitoUserManagementRequests>::Register(this);
AWSCognitoUserManagementRequestBus::Handler::BusConnect();
m_settings = AZStd::make_unique<AWSCognitoUserManagementSetting>();
}
AWSCognitoUserManagementController::~AWSCognitoUserManagementController()
{
m_settings.reset();
AWSCognitoUserManagementRequestBus::Handler::BusDisconnect();
AZ::Interface<IAWSCognitoUserManagementRequests>::Unregister(this);
}
bool AWSCognitoUserManagementController::Initialize(const AZStd::string& settingsRegistryPath)
bool AWSCognitoUserManagementController::Initialize()
{
AZStd::unique_ptr<AZ::SettingsRegistryInterface> settingsRegistry = AZStd::make_unique<AZ::SettingsRegistryImpl>();
if (!settingsRegistry->MergeSettingsFile(settingsRegistryPath, AZ::SettingsRegistryInterface::Format::JsonMergePatch))
{
AZ_Error("AWSCognitoUserManagementController", true, "Failed to merge settings file for path %s", settingsRegistryPath.c_str());
return false;
}
if (!settingsRegistry->GetObject(m_settings.get(), azrtti_typeid(m_settings.get()), COGNITO_USER_POOL))
{
AZ_Error("AWSCognitoUserManagementController", true, "Failed to get settings object for path %s", COGNITO_USER_POOL);
return false;
}
return true;
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
m_cognitoAppClientId, &AWSCore::AWSResourceMappingRequests::GetResourceNameId, CognitoAppClientIdResourceMappingKey);
AZ_Warning(
"AWSCognitoUserManagementController", m_cognitoAppClientId.empty(), "Missing Cognito App Client Id from resource mappings. Calls to Cognito will fail.");
return !m_cognitoAppClientId.empty();
}
// Call Cognito user pool sign up using email. Confirmation code sent to the email set.
@@ -85,7 +71,7 @@ namespace AWSClientAuth
AZ::Job* emailSignUpJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, password, email]()
{
Aws::CognitoIdentityProvider::Model::SignUpRequest signUpRequest;
signUpRequest.SetClientId(m_settings->m_appClientId.c_str());
signUpRequest.SetClientId(m_cognitoAppClientId.c_str());
signUpRequest.SetUsername(username.c_str());
signUpRequest.SetPassword(password.c_str());
@@ -123,7 +109,7 @@ namespace AWSClientAuth
AZ::Job* phoneSignUpJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, password, phoneNumber]()
{
Aws::CognitoIdentityProvider::Model::SignUpRequest signUpRequest;
signUpRequest.SetClientId(m_settings->m_appClientId.c_str());
signUpRequest.SetClientId(m_cognitoAppClientId.c_str());
signUpRequest.SetUsername(username.c_str());
signUpRequest.SetPassword(password.c_str());
@@ -163,7 +149,7 @@ namespace AWSClientAuth
AZ::Job* confirmSignUpJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, confirmationCode]()
{
Aws::CognitoIdentityProvider::Model::ConfirmSignUpRequest confirmSignupRequest;
confirmSignupRequest.SetClientId(m_settings->m_appClientId.c_str());
confirmSignupRequest.SetClientId(m_cognitoAppClientId.c_str());
confirmSignupRequest.SetUsername(username.c_str());
confirmSignupRequest.SetConfirmationCode(confirmationCode.c_str());
@@ -192,7 +178,7 @@ namespace AWSClientAuth
AZ::Job* forgotPasswordJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username]()
{
Aws::CognitoIdentityProvider::Model::ForgotPasswordRequest forgotPasswordRequest;
forgotPasswordRequest.SetClientId(m_settings->m_appClientId.c_str());
forgotPasswordRequest.SetClientId(m_cognitoAppClientId.c_str());
forgotPasswordRequest.SetUsername(username.c_str());
Aws::CognitoIdentityProvider::Model::ForgotPasswordOutcome forgotPasswordOutcome{ cognitoIdentityProviderClient->ForgotPassword(forgotPasswordRequest) };
@@ -220,7 +206,7 @@ namespace AWSClientAuth
AZ::Job* confirmForgotPasswordJob = AZ::CreateJobFunction([this, cognitoIdentityProviderClient, username, confirmationCode, newPassword]()
{
Aws::CognitoIdentityProvider::Model::ConfirmForgotPasswordRequest confirmForgotPasswordRequest;
confirmForgotPasswordRequest.SetClientId(m_settings->m_appClientId.c_str());
confirmForgotPasswordRequest.SetClientId(m_cognitoAppClientId.c_str());
confirmForgotPasswordRequest.SetUsername(username.c_str());
confirmForgotPasswordRequest.SetConfirmationCode(confirmationCode.c_str());
confirmForgotPasswordRequest.SetPassword(newPassword.c_str());
@@ -32,6 +32,7 @@
#include <Authorization/AWSCognitoAuthorizationBus.h>
#include <UserManagement/AWSCognitoUserManagementBus.h>
#include <AWSCoreBus.h>
#include <ResourceMapping/AWSResourceMappingBus.h>
#include <AWSClientAuthBus.h>
#include <AWSNativeSDKInit/AWSNativeSDKInit.h>
#include <HttpRequestor/HttpRequestorBus.h>
@@ -68,13 +69,14 @@ namespace AWSClientAuthUnitTest
constexpr char TEST_PASSWORD[] = "TestPassword";
constexpr char TEST_NEW_PASSWORD[] = "TestNewPassword";
constexpr char TEST_CODE[] = "TestCode";
constexpr char TEST_REGION[] = "us-east-1";
constexpr char TEST_EMAIL[] = "test@test.com";
constexpr char TEST_PHONE[] = "+11234567890";
constexpr char TEST_COGNITO_CLIENTID[] = "TestCognitoClientId";
constexpr char TEST_EXCEPTION[] = "TestException";
constexpr char TEST_SESSION[] = "TestSession";
constexpr char TEST_TOKEN[] = "TestToken";
constexpr char TEST_ACCOUNT_ID[] = "1234567890";
constexpr char TEST_ACCOUNT_ID[] = "TestAccountId";
constexpr char TEST_IDENTITY_POOL_ID[] = "TestIdenitityPoolId";
constexpr char TEST_IDENTITY_ID[] = "TestIdenitityId";
constexpr char TEST_ACCESS_TOKEN[] = "TestAccessToken";
@@ -82,6 +84,39 @@ namespace AWSClientAuthUnitTest
constexpr char TEST_ID_TOKEN[] = "TestIdToken";
constexpr char TEST_ACCESS_KEY_ID[] = "TestAccessKeyId";
constexpr char TEST_SECRET_KEY_ID[] = "TestSecretKeyId";
constexpr char TEST_RESOURCE_NAME_ID[] = "TestResourceNameId";
class AWSResourceMappingRequestBusMock
: public AWSCore::AWSResourceMappingRequestBus::Handler
{
public:
AWSResourceMappingRequestBusMock()
{
AWSCore::AWSResourceMappingRequestBus::Handler::BusConnect();
ON_CALL(*this, GetResourceRegion).WillByDefault(testing::Return(TEST_REGION));
ON_CALL(*this, GetDefaultAccountId).WillByDefault(testing::Return(TEST_ACCOUNT_ID));
ON_CALL(*this, GetResourceAccountId).WillByDefault(testing::Return(TEST_ACCOUNT_ID));
ON_CALL(*this, GetResourceNameId).WillByDefault(testing::Return(TEST_RESOURCE_NAME_ID));
ON_CALL(*this, GetDefaultRegion).WillByDefault(testing::Return(TEST_REGION));
}
~AWSResourceMappingRequestBusMock()
{
AWSCore::AWSResourceMappingRequestBus::Handler::BusDisconnect();
}
MOCK_CONST_METHOD0(GetDefaultAccountId, AZStd::string());
MOCK_CONST_METHOD0(GetDefaultRegion, AZStd::string());
MOCK_CONST_METHOD1(GetResourceAccountId, AZStd::string(const AZStd::string& resourceKeyName));
MOCK_CONST_METHOD1(GetResourceNameId, AZStd::string(const AZStd::string& resourceKeyName));
MOCK_CONST_METHOD1(GetResourceRegion, AZStd::string(const AZStd::string& resourceKeyName));
MOCK_CONST_METHOD1(GetResourceType, AZStd::string(const AZStd::string& resourceKeyName));
MOCK_CONST_METHOD1(GetServiceUrlByServiceName, AZStd::string(const AZStd::string& serviceName));
MOCK_CONST_METHOD2(
GetServiceUrlByRESTApiIdAndStage,
AZStd::string(const AZStd::string& restApiIdKeyName, const AZStd::string& restApiStageKeyName));
MOCK_METHOD1(ReloadConfigFile, void(bool isReloadingConfigFileName));
};
class HttpRequestorRequestBusMock
: public HttpRequestor::HttpRequestorRequestBus::Handler
@@ -545,6 +580,7 @@ namespace AWSClientAuthUnitTest
AZ::BehaviorContext* GetBehaviorContext() override { return nullptr; }
const char* GetExecutableFolder() const override { return nullptr; }
const char* GetAppRoot() const override { return nullptr; }
const char* GetEngineRoot() const override { return nullptr; }
AZ::Debug::DrillerManager* GetDrillerManager() override { return nullptr; }
void EnumerateEntities(const EntityCallback& /*callback*/) override {}
void QueryApplicationType(AZ::ApplicationTypeQuery& /*appType*/) const override {}
@@ -14,7 +14,6 @@
#include <AzTest/Utils.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AWSClientAuthSystemComponent.h>
#include <ResourceMapping/AWSResourceMappingBus.h>
#include <AzCore/Component/Entity.h>
#include <AzFramework/IO/LocalFileIO.h>
#include <AWSClientAuthGemMock.h>
@@ -119,33 +118,6 @@ namespace AWSClientAuthUnitTest
};
}
class AWSResourceMappingRequestBusMock
: public AWSCore::AWSResourceMappingRequestBus::Handler
{
public:
AWSResourceMappingRequestBusMock()
{
AWSCore::AWSResourceMappingRequestBus::Handler::BusConnect();
ON_CALL(*this, GetResourceRegion).WillByDefault(testing::Return("us-east-1"));
}
~AWSResourceMappingRequestBusMock()
{
AWSCore::AWSResourceMappingRequestBus::Handler::BusDisconnect();
}
MOCK_CONST_METHOD0(GetDefaultAccountId, AZStd::string());
MOCK_CONST_METHOD0(GetDefaultRegion, AZStd::string());
MOCK_CONST_METHOD1(GetResourceAccountId, AZStd::string(const AZStd::string& resourceKeyName));
MOCK_CONST_METHOD1(GetResourceNameId, AZStd::string(const AZStd::string& resourceKeyName));
MOCK_CONST_METHOD1(GetResourceRegion, AZStd::string(const AZStd::string& resourceKeyName));
MOCK_CONST_METHOD1(GetResourceType, AZStd::string(const AZStd::string& resourceKeyName));
MOCK_CONST_METHOD1(GetServiceUrlByServiceName, AZStd::string(const AZStd::string& serviceName));
MOCK_CONST_METHOD2(
GetServiceUrlByRESTApiIdAndStage, AZStd::string(const AZStd::string& restApiIdKeyName, const AZStd::string& restApiStageKeyName));
MOCK_METHOD1(ReloadConfigFile, void(bool isReloadingConfigFileName));
};
class AWSClientAuthSystemComponentTest
: public AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture
{
@@ -193,7 +165,7 @@ protected:
public:
testing::NiceMock<AWSClientAuthUnitTest::AWSClientAuthSystemComponentMock> *m_awsClientAuthSystemsComponent;
testing::NiceMock<AWSClientAuthUnitTest::AWSCoreSystemComponentMock> *m_awsCoreSystemsComponent;
testing::NiceMock<AWSResourceMappingRequestBusMock> m_awsResourceMappingRequestBusMock;
testing::NiceMock<AWSClientAuthUnitTest::AWSResourceMappingRequestBusMock> m_awsResourceMappingRequestBusMock;
AZ::Entity* m_entity = nullptr;
};
@@ -24,7 +24,7 @@ namespace AWSClientAuthUnitTest
: public AWSClientAuth::AWSCognitoAuthenticationProvider
{
public:
using AWSClientAuth::AWSCognitoAuthenticationProvider::m_settings;
using AWSClientAuth::AWSCognitoAuthenticationProvider::m_cognitoAppClientId;
};
}
@@ -36,22 +36,6 @@ class AWSCognitoAuthenticationProviderTest
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
AWSClientAuth::AWSCognitoProviderSetting::Reflect(*m_serializeContext);
AZStd::string path = AZStd::string::format("%s/%s/authenticationProvider.setreg",
m_testFolder->c_str(), AZ::SettingsRegistryInterface::RegistryFolder);
CreateTestFile("authenticationProvider.setreg"
, R"({
"AWS":
{
"CognitoIDP":
{
"AppClientId": "TestCognitoClientId"
}
}
})");
m_settingsRegistry->MergeSettingsFile(path, AZ::SettingsRegistryInterface::Format::JsonMergePatch, {});
m_cognitoAuthenticationProviderMock.Initialize(m_settingsRegistry);
AWSCore::AWSCoreRequestBus::Handler::BusConnect();
@@ -78,6 +62,7 @@ class AWSCognitoAuthenticationProviderTest
public:
AWSClientAuthUnitTest::AWSCognitoAuthenticationProviderrLocalMock m_cognitoAuthenticationProviderMock;
testing::NiceMock<AWSClientAuthUnitTest::AWSResourceMappingRequestBusMock> m_awsResourceMappingRequestBusMock;
void AssertAuthenticationTokensPopulated()
{
@@ -116,9 +101,10 @@ public:
TEST_F(AWSCognitoAuthenticationProviderTest, Initialize_Success)
{
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetResourceNameId(testing::_)).Times(1);
AWSClientAuthUnitTest::AWSCognitoAuthenticationProviderrLocalMock mock;
ASSERT_TRUE(mock.Initialize(m_settingsRegistry));
ASSERT_EQ(mock.m_settings->m_appClientId, AWSClientAuthUnitTest::TEST_COGNITO_CLIENTID);
ASSERT_EQ(mock.m_cognitoAppClientId, AWSClientAuthUnitTest::TEST_RESOURCE_NAME_ID);
}
TEST_F(AWSCognitoAuthenticationProviderTest, PasswordGrantSingleFactorSignInAsync_Success)
@@ -275,15 +261,9 @@ TEST_F(AWSCognitoAuthenticationProviderTest, SignOut_Success)
AssertAuthenticationTokensEmpty();
}
TEST_F(AWSCognitoAuthenticationProviderTest, Initialize_Fail_EmptyRegistry)
TEST_F(AWSCognitoAuthenticationProviderTest, Initialize_Fail_EmptyResourceName)
{
AWSClientAuthUnitTest::AWSCognitoAuthenticationProviderrLocalMock mock;
AZStd::shared_ptr<AZ::SettingsRegistryImpl> registry = AZStd::make_shared<AZ::SettingsRegistryImpl>();
registry->SetContext(m_serializeContext.get());
ASSERT_FALSE(mock.Initialize(registry));
ASSERT_EQ(mock.m_settings->m_appClientId, "");
registry.reset();
// Restore
mock.Initialize(m_settingsRegistry);
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetResourceNameId(testing::_)).Times(1).WillOnce(testing::Return(""));
ASSERT_FALSE(mock.Initialize(m_settingsRegistry));
}
@@ -66,7 +66,6 @@ protected:
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
AWSClientAuth::AWSCognitoProviderSetting::Reflect(*m_serializeContext);
AWSClientAuth::LWAProviderSetting::Reflect(*m_serializeContext);
AWSClientAuth::GoogleProviderSetting::Reflect(*m_serializeContext);
@@ -93,10 +92,6 @@ protected:
"Scope": "profile",
"OAuthCodeURL": "https://oauth2.googleapis.com/device/code",
"OAuthTokensURL": "https://oauth2.googleapis.com/token"
},
"CognitoIDP":
{
"AppClientId": "TestCognitoClientId"
}
}
})");
@@ -24,11 +24,13 @@ namespace AWSClientAuthUnitTest
{
public:
using AWSClientAuth::AWSCognitoAuthorizationController::m_settings;
using AWSClientAuth::AWSCognitoAuthorizationController::m_persistentCognitoIdentityProvider;
using AWSClientAuth::AWSCognitoAuthorizationController::m_persistentAnonymousCognitoIdentityProvider;
using AWSClientAuth::AWSCognitoAuthorizationController::m_cognitoCachingCredentialsProvider;
using AWSClientAuth::AWSCognitoAuthorizationController::m_cognitoCachingAnonymousCredentialsProvider;
using AWSClientAuth::AWSCognitoAuthorizationController::m_cognitoIdentityPoolId;
using AWSClientAuth::AWSCognitoAuthorizationController::m_formattedCognitoUserPoolId;
using AWSClientAuth::AWSCognitoAuthorizationController::m_awsAccountId;
};
}
@@ -39,9 +41,6 @@ protected:
void SetUp() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
AWSClientAuth::CognitoAuthorizationSettings::Reflect(*m_serializeContext);
m_mockController = AZStd::make_unique<AWSClientAuthUnitTest::AWSCognitoAuthorizationControllerTestLocalMock>();
}
@@ -53,26 +52,18 @@ protected:
public:
AZStd::unique_ptr<AWSClientAuthUnitTest::AWSCognitoAuthorizationControllerTestLocalMock> m_mockController;
testing::NiceMock<AWSClientAuthUnitTest::AWSResourceMappingRequestBusMock> m_awsResourceMappingRequestBusMock;
};
TEST_F(AWSCognitoAuthorizationControllerTest, Initialize_Success)
{
AZStd::string path = AZStd::string::format("%s/%s/awsCognitoAuthorization.setreg",
m_testFolder->c_str(), AZ::SettingsRegistryInterface::RegistryFolder);
CreateTestFile("awsCognitoAuthorization.setreg"
, R"({
"AWS": {
"CognitoIdentityPool": {
"CognitoUserPoolId": "TestUserPoolId",
"LoginWithAmazonId": "www.amazon.com",
"AWSAccountId": "1234567890",
"IdentityPoolId": "TestIdentityPoolId"
}
}
})");
ASSERT_TRUE(m_mockController->Initialize(path));
ASSERT_TRUE(m_mockController->m_settings->m_cognitoUserPoolId == "TestUserPoolId");
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetResourceNameId(testing::_)).Times(2);
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultAccountId()).Times(1);
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultRegion()).Times(1);
ASSERT_TRUE(m_mockController->Initialize());
ASSERT_TRUE(m_mockController->m_formattedCognitoUserPoolId.find(AWSClientAuthUnitTest::TEST_RESOURCE_NAME_ID) != AZStd::string::npos);
ASSERT_TRUE(m_mockController->m_awsAccountId == AWSClientAuthUnitTest::TEST_ACCOUNT_ID);
ASSERT_TRUE(m_mockController->m_cognitoIdentityPoolId == AWSClientAuthUnitTest::TEST_RESOURCE_NAME_ID);
}
TEST_F(AWSCognitoAuthorizationControllerTest, RequestAWSCredentials_WithLogins_Success)
@@ -438,9 +429,17 @@ TEST_F(AWSCognitoAuthorizationControllerTest, GetCredentialHandlerOrder_Call_Alw
EXPECT_EQ(order, AWSCore::CredentialHandlerOrder::COGNITO_IDENITY_POOL_CREDENTIAL_HANDLER);
}
TEST_F(AWSCognitoAuthorizationControllerTest, Initialize_Fail_InvalidPath)
TEST_F(AWSCognitoAuthorizationControllerTest, Initialize_Fail_GetResourceNameEmpty)
{
AZ_TEST_START_TRACE_SUPPRESSION;
ASSERT_FALSE(m_mockController->Initialize(""));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetResourceNameId(testing::_)).Times(1).WillOnce(testing::Return(""));
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultAccountId()).Times(1);
ASSERT_FALSE(m_mockController->Initialize());
}
TEST_F(AWSCognitoAuthorizationControllerTest, Initialize_Fail_GetAWSAccountEmpty)
{
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetResourceNameId(testing::_)).Times(1);
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultAccountId()).Times(1).WillOnce(testing::Return(""));
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultRegion()).Times(0);
ASSERT_FALSE(m_mockController->Initialize());
}
@@ -16,17 +16,6 @@
#include <AWSClientAuthGemMock.h>
#include <aws/cognito-idp/CognitoIdentityProviderErrors.h>
namespace AWSClientAuthUnitTest
{
class AWSCognitoUserManagementControllerLocalMock
: public AWSClientAuth::AWSCognitoUserManagementController
{
public:
using AWSClientAuth::AWSCognitoUserManagementController::m_settings;
};
}
class AWSCognitoUserManagementControllerTest
: public AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture
, public AWSCore::AWSCoreRequestBus::Handler
@@ -35,8 +24,7 @@ protected:
void SetUp() override
{
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
AWSClientAuth::AWSCognitoUserManagementSetting::Reflect(*m_serializeContext);
m_mockController = AZStd::make_unique<AWSClientAuthUnitTest::AWSCognitoUserManagementControllerLocalMock>();
m_mockController = AZStd::make_unique<AWSClientAuth::AWSCognitoUserManagementController>();
AWSCore::AWSCoreRequestBus::Handler::BusConnect();
}
@@ -61,26 +49,15 @@ protected:
}
public:
AZStd::unique_ptr<AWSClientAuthUnitTest::AWSCognitoUserManagementControllerLocalMock> m_mockController;
AZStd::unique_ptr<AWSClientAuth::AWSCognitoUserManagementController> m_mockController;
testing::NiceMock<AWSClientAuthUnitTest::AWSResourceMappingRequestBusMock> m_awsResourceMappingRequestBusMock;
};
TEST_F(AWSCognitoUserManagementControllerTest, Initialize_Success)
{
AZStd::string path = AZStd::string::format("%s/%s/awsCognitoUserManagement.setreg",
m_testFolder->c_str(), AZ::SettingsRegistryInterface::RegistryFolder);
CreateTestFile("awsCognitoUserManagement.setreg"
, R"({"AWS":
{
"CognitoUserPool":
{
"AppClientId": "TestClientId",
"SignUpConfirmationType": "email"
}
}
})");
ASSERT_TRUE(m_mockController->Initialize(path));
ASSERT_EQ(m_mockController->m_settings->m_appClientId, "TestClientId");
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetResourceNameId(testing::_)).Times(1);
ASSERT_TRUE(m_mockController->Initialize());
ASSERT_EQ(m_mockController->GetCognitoAppClientId(), AWSClientAuthUnitTest::TEST_RESOURCE_NAME_ID);
}
TEST_F(AWSCognitoUserManagementControllerTest, EmailSignUp_Success)
@@ -203,9 +180,8 @@ TEST_F(AWSCognitoUserManagementControllerTest, ConfirmForgotPassword_Fail_Confir
m_mockController->ConfirmForgotPasswordAsync(AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_CODE, AWSClientAuthUnitTest::TEST_NEW_PASSWORD);
}
TEST_F(AWSCognitoUserManagementControllerTest, Initialize_Fail_InvalidPath)
TEST_F(AWSCognitoUserManagementControllerTest, Initialize_Fail_GetResourceNameEmpty)
{
AZ_TEST_START_TRACE_SUPPRESSION;
ASSERT_FALSE(m_mockController->Initialize(""));
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetResourceNameId(testing::_)).Times(1).WillOnce(testing::Return(""));
ASSERT_FALSE(m_mockController->Initialize());
}
@@ -18,16 +18,15 @@ set(FILES
Include/Private/AWSClientAuthSystemComponent.h
Include/Private/AWSClientAuthBus.h
Include/Private/AWSClientAuthResourceMappingConstants.h
Include/Private/Authentication/AuthenticationProviderTypes.h
Include/Private/Authentication/AuthenticationProviderManager.h
Include/Private/Authentication/AuthenticationNotificationBusBehaviorHandler.h
Include/Private/Authorization/AWSCognitoAuthorizationTypes.h
Include/Private/Authorization/AWSCognitoAuthorizationController.h
Include/Private/Authorization/AWSClientAuthPersistentCognitoIdentityProvider.h
Include/Private/Authorization/AWSCognitoAuthorizationNotificationBusBehaviorHandler.h
Include/Private/UserManagement/AWSCognitoUserManagementTypes.h
Include/Private/UserManagement/AWSCognitoUserManagementController.h
Include/Private/UserManagement/UserManagementNotificationBusBehaviorHandler.h
+3 -3
View File
@@ -1,3 +1,3 @@
aws-cdk.core
aws-cdk.aws_cognito
aws-cdk.aws_iam
aws-cdk.core>=1.91.0
aws-cdk.aws_iam>=1.91.0
aws-cdk.aws_cognito>=1.91.0
-2
View File
@@ -33,7 +33,6 @@ ly_add_target(
ly_add_target(
NAME AWSCore ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.AWSCore.c3710872891c4401b0cbdabfca066cb5.0.1.0
FILES_CMAKE
awscore_shared_files.cmake
INCLUDE_DIRECTORIES
@@ -71,7 +70,6 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_target(
NAME AWSCore.Editor MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.AWSCore.Editor.45818501e4b24cb3b09848740ace9fac.0.1.0
FILES_CMAKE
awscore_editor_shared_files.cmake
INCLUDE_DIRECTORIES
@@ -93,6 +93,11 @@ namespace AWSMetrics
//! @return Path to the local metrics file.
const char* GetMetricsFilePath() const;
//! Get the total number of requests for sending metrics events.
//! This value could be different to the number of submitted metrics events since metrics events could be sent in batch.
//! @return Total number of requests for sending metrics events.
int GetNumTotalRequests() const;
private:
//! Job management
void SetupJobContext();
@@ -145,11 +145,11 @@ namespace AWSMetrics
const GlobalStatistics& stats = m_metricsManager->GetGlobalStatistics();
AZ_Printf("AWSMetrics", " - Total number of metrics events sent to the backend: %u", stats.m_numEvents.load());
AZ_Printf("AWSMetrics", " - Total number of metrics events sent to the backend successfully: %u", stats.m_numSuccesses.load());
AZ_Printf("AWSMetrics", " - Total size of metrics events sent to the backend successfully: %u bytes", stats.m_sendSizeInBytes.load());
AZ_Printf("AWSMetrics", " - Total number of metrics events failed to be processed by the backend: %u", stats.m_numErrors.load());
AZ_Printf("AWSMetrics", " - Total number of metrics events which failed the JSON schema validation or reached the maximum number of retries : %u", stats.m_numDropped.load());
AZ_Printf("AWSMetrics", "Total number of metrics events sent to the backend: %u", stats.m_numEvents.load());
AZ_Printf("AWSMetrics", "Total number of metrics events sent to the backend successfully: %u", stats.m_numSuccesses.load());
AZ_Printf("AWSMetrics", "Total size of metrics events sent to the backend successfully: %u bytes", stats.m_sendSizeInBytes.load());
AZ_Printf("AWSMetrics", "Total number of metrics events failed to be processed by the backend: %u", stats.m_numErrors.load());
AZ_Printf("AWSMetrics", "Total number of metrics events which failed the JSON schema validation or reached the maximum number of retries : %u", stats.m_numDropped.load());
}
void AWSMetricsSystemComponent::EnableOfflineRecording(const AZ::ConsoleCommandContainer& arguments)
+29 -6
View File
@@ -60,6 +60,8 @@ namespace AWSMetrics
}
m_consumerTerminated = false;
AZStd::lock_guard<AZStd::mutex> lock(m_metricsMutex);
m_lastSendMetricsTime = AZStd::chrono::system_clock::now();
// Start a separate thread to monitor and consume the metrics queue.
@@ -138,8 +140,6 @@ namespace AWSMetrics
void MetricsManager::SendMetricsAsync(AZStd::shared_ptr<MetricsQueue> metricsQueue)
{
m_lastSendMetricsTime = AZStd::chrono::system_clock::now();
if (m_clientConfiguration->OfflineRecordingEnabled())
{
SendMetricsToLocalFileAsync(metricsQueue);
@@ -186,13 +186,20 @@ namespace AWSMetrics
OnResponseReceived(*metricsQueue, responseRecords);
AWSMetricsNotificationBus::Broadcast(&AWSMetricsNotifications::OnSendMetricsSuccess, requestId);
AZ::TickBus::QueueFunction([requestId]()
{
AWSMetricsNotificationBus::Broadcast(&AWSMetricsNotifications::OnSendMetricsSuccess, requestId);
});
}
else
{
OnResponseReceived(*metricsQueue);
AWSMetricsNotificationBus::Broadcast(&AWSMetricsNotifications::OnSendMetricsFailure, requestId, outcome.GetError());
AZStd::string errorMessage = outcome.GetError();
AZ::TickBus::QueueFunction([requestId, errorMessage]()
{
AWSMetricsNotificationBus::Broadcast(&AWSMetricsNotifications::OnSendMetricsFailure, requestId, errorMessage);
});
}
},
true, m_jobContext.get());
@@ -209,13 +216,20 @@ namespace AWSMetrics
{
OnResponseReceived(successJob->parameters.data, successJob->result.events);
AWSMetricsNotificationBus::Broadcast(&AWSMetricsNotifications::OnSendMetricsSuccess, requestId);
AZ::TickBus::QueueFunction([requestId]()
{
AWSMetricsNotificationBus::Broadcast(&AWSMetricsNotifications::OnSendMetricsSuccess, requestId);
});
},
[this, requestId](ServiceAPI::PostProducerEventsRequestJob* failedJob)
{
OnResponseReceived(failedJob->parameters.data);
AWSMetricsNotificationBus::Broadcast(&AWSMetricsNotifications::OnSendMetricsFailure, requestId, failedJob->error.message);
AZStd::string errorMessage = failedJob->error.message;
AZ::TickBus::QueueFunction([requestId, errorMessage]()
{
AWSMetricsNotificationBus::Broadcast(&AWSMetricsNotifications::OnSendMetricsFailure, requestId, errorMessage);
});
});
requestJob->parameters.data = AZStd::move(metricsQueue);
@@ -332,6 +346,10 @@ namespace AWSMetrics
void MetricsManager::FlushMetricsAsync()
{
AZStd::lock_guard<AZStd::mutex> lock(m_metricsMutex);
m_lastSendMetricsTime = AZStd::chrono::system_clock::now();
if (m_metricsQueue.GetNumMetrics() == 0)
{
return;
@@ -452,4 +470,9 @@ namespace AWSMetrics
{
return m_clientConfiguration->GetMetricsFileFullPath();
}
int MetricsManager::GetNumTotalRequests() const
{
return m_sendMetricsId.load();
}
}
@@ -212,17 +212,29 @@ namespace AWSMetrics
int currentNumProcessedEvents = originalStats.m_numEvents;
int processingTime = 0;
while (processingTime < TIMEOUT_FOR_PROCESSING_IN_MS && currentNumProcessedEvents < expectedNumProcessedEvents)
int numTotalRequests = 0;
while (processingTime < TIMEOUT_FOR_PROCESSING_IN_MS)
{
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(SLEEP_TIME_FOR_PROCESSING_IN_MS));
processingTime += SLEEP_TIME_FOR_PROCESSING_IN_MS;
const GlobalStatistics& currentStats = m_metricsManager->GetGlobalStatistics();
currentNumProcessedEvents = currentStats.m_numEvents;
}
numTotalRequests = m_metricsManager->GetNumTotalRequests();
if (currentNumProcessedEvents == expectedNumProcessedEvents)
{
// All the expectd metrics events has been sent. Flush the tick bus queue until we get all the notifications.
AZ::TickBus::ExecuteQueuedEvents();
if (numTotalRequests ==
m_notifications.m_numSuccessNotification + m_notifications.m_numFailureNotification)
{
break;
}
}
}
}
testing::NiceMock<AWSMetricsNotificationBusMock> m_awsMetricsNotificationBusMock;
AZStd::unique_ptr<MetricsManager> m_metricsManager;
AWSMetricsNotificationBusMock m_notifications;
@@ -356,7 +368,7 @@ namespace AWSMetrics
AWSMetricsRequestBus::Broadcast(&AWSMetricsRequests::FlushMetrics);
WaitForProcessing(1);
WaitForProcessing(MAX_NUM_METRICS_EVENTS);
ASSERT_EQ(m_notifications.m_numSuccessNotification, 1);
ASSERT_EQ(m_notifications.m_numFailureNotification, 0);
ASSERT_EQ(m_metricsManager->GetNumBufferedMetrics(), 0);
+26 -2
View File
@@ -52,7 +52,7 @@ to use for environment variables.
## Bootstrap the environment
An environment needs to be bootstrapped since this CDK application uses assets like a local directory that contains the handler code for the AWS Lambda functions.
Use the following cdk bootstrap command to bootstrap one or more AWS environments.
Use the following CDK bootstrap command to bootstrap one or more AWS environments.
```
cdk bootstrap aws://ACCOUNT-NUMBER-1/REGION-1 aws://ACCOUNT-NUMBER-2/REGION-2 ...
@@ -68,9 +68,33 @@ $ cdk synth
```
To add additional dependencies, for example other CDK libraries, just add
them to your `setup.py` file and rerun the `pip install -r requirements.txt`
them to your `requirements.txt` file and rerun the `pip install -r requirements.txt`
command.
## Deploy the project
To deploy the CDK application, use the following CLI command:
```
$ cdk deploy
```
## Enable the optional batch processing feature
You can optionally enable the batch processing feature by specifying the context variable like below:
```
$ cdk synth -c batch_processing=true
$ cdk deploy -c batch_processing=true
```
This will deploy the AWS resources required by the batch processing feature and bring additional cost.
To disable the feature and remove related AWS resources, you need to empty the deployed S3 bucket manually and run the normal CDK CLI commands for updating the CDK application:
```
$ cdk synth
$ cdk deploy
```
## Useful commands
* `cdk ls` list all stacks in the app
+1 -1
View File
@@ -68,6 +68,6 @@ class AuthPolicy:
policy_output = core.CfnOutput(
self._stack,
id=f'{policy_id}Output',
description='User policy arn to call service',
description=f'{role_name} policy arn to call service',
export_name=f"{self._application_name}:{policy_id}",
value=policy.managed_policy_arn)
@@ -121,7 +121,7 @@ DASHBOARD_GLOBAL_DESCRIPTION = "# Metrics Dashboard \n"\
"This dashboard contains near-real-time metrics sent from your client"\
" or dedicated server. \n You can edit the widgets using the AWS console"\
" or modify your CDK application code. Please note that redeploying"\
" the CDK application will not overwrite any changes you made directly"\
" the CDK application will overwrite any changes you made directly"\
" via the AWS console. \n For more information about using the AWS Metrics Gem"\
" and CDK application, please check the AWSMetrics gem document."
# The description for the operational health shown on the CloudWatch dashboard
-1
View File
@@ -33,7 +33,6 @@ ly_add_target(
ly_add_target(
NAME Achievements ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.Achievements.6f8d953dd4fc4bb6ad34c9118a7b789f.v0.1.0
FILES_CMAKE
achievements_shared_files.cmake
INCLUDE_DIRECTORIES
+2 -1
View File
@@ -30,7 +30,6 @@ ly_add_target(
ly_add_target(
NAME AssetMemoryAnalyzer ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.AssetMemoryAnalyzer.35414634480a4d4c8412c60fe62f4c81.v0.1.0
FILES_CMAKE
assetmemoryanalyzer_shared_files.cmake
INCLUDE_DIRECTORIES
@@ -41,6 +40,8 @@ ly_add_target(
BUILD_DEPENDENCIES
PRIVATE
Gem::AssetMemoryAnalyzer.Static
RUNTIME_DEPENDENCIES
Gem::ImGui
)
################################################################################
-2
View File
@@ -23,14 +23,12 @@ ly_add_target(
PUBLIC
AZ::AzCore
AZ::AzFramework
AZ::GemRegistry
Legacy::CryCommon
)
ly_add_target(
NAME AssetValidation ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.AssetValidation.5a5c3c10b91d4b4ea8baef474c5b5d49.v0.1.0
FILES_CMAKE
assetvalidation_shared_files.cmake
INCLUDE_DIRECTORIES
@@ -11,20 +11,11 @@
*/
#include "AssetSeedUtil.h"
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
namespace AssetValidation::AssetSeed
{
GemInfo::GemInfo(AZStd::string name, AZStd::string relativeFilePath, AZStd::string absoluteFilePath, AZStd::string identifier, bool isGameGem, bool assetOnlyGem)
: m_gemName(AZStd::move(name))
, m_relativeFilePath(AZStd::move(relativeFilePath))
, m_absoluteFilePath(AZStd::move(absoluteFilePath))
, m_identifier(AZStd::move(identifier))
, m_isGameGem(isGameGem)
, m_assetOnly(assetOnlyGem)
{
}
void AddPlatformSeeds(const AZStd::string& rootFolder, AZStd::vector<AZStd::string>& defaultSeedLists, AzFramework::PlatformFlags platformFlags)
{
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
@@ -69,193 +60,82 @@ namespace AssetValidation::AssetSeed
fileIO->FindFiles(platformsDirectory.c_str(),
AZStd::string::format("*.%s", SeedFileExtension).c_str(),
[&](const char* fileName)
{
AZStd::string normalizedFilePath = fileName;
AZ::StringFunc::Path::Normalize(normalizedFilePath);
defaultSeedLists.emplace_back(normalizedFilePath);
return true;
});
{
AZStd::string normalizedFilePath = fileName;
AZ::StringFunc::Path::Normalize(normalizedFilePath);
defaultSeedLists.emplace_back(normalizedFilePath);
return true;
});
}
AddPlatformSeeds(platformsDirectory, defaultSeedLists, platformFlags);
}
bool GetGemsInfo(const char* root, const char* assetRoot, const char* gameName, AZStd::vector<GemInfo>& gemInfoList)
{
Gems::IGemRegistry* registry = nullptr;
Gems::IProjectSettings* projectSettings = nullptr;
AZ::ModuleManagerRequests::LoadModuleOutcome result = AZ::Failure(AZStd::string("Failed to connect to ModuleManagerRequestBus.\n"));
AZ::ModuleManagerRequestBus::BroadcastResult(result, &AZ::ModuleManagerRequestBus::Events::LoadDynamicModule, "GemRegistry", AZ::ModuleInitializationSteps::Load, false);
if (!result.IsSuccess())
{
AZ_Error("AzToolsFramework::AssetUtils", false, "Could not load the GemRegistry module - %s.\n", result.GetError().c_str());
return false;
}
// Use shared_ptr aliasing ctor to use the refcount/deleter from the moduledata pointer, but we only need to store the dynamic module handle.
auto registryModule = AZStd::shared_ptr<AZ::DynamicModuleHandle>(result.GetValue(), result.GetValue()->GetDynamicModuleHandle());
auto CreateGemRegistry = registryModule->GetFunction<Gems::RegistryCreatorFunction>(GEMS_REGISTRY_CREATOR_FUNCTION_NAME);
Gems::RegistryDestroyerFunction registryDestroyerFunc = registryModule->GetFunction<Gems::RegistryDestroyerFunction>(GEMS_REGISTRY_DESTROYER_FUNCTION_NAME);
if (!CreateGemRegistry || !registryDestroyerFunc)
{
AZ_Error("AzToolsFramework::AssetUtils", false, "Failed to load GemRegistry functions.\n");
return false;
}
registry = CreateGemRegistry();
if (!registry)
{
AZ_Error("AzToolsFramework::AssetUtils", false, "Failed to create Gems::GemRegistry.\n");
return false;
}
registry->AddSearchPath({ root, GemsDirectoryName }, false);
registry->AddSearchPath({ assetRoot, GemsDirectoryName }, false);
const char* engineRootPath = nullptr;
AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRootPath, &AzFramework::ApplicationRequests::GetEngineRoot);
if (engineRootPath && azstricmp(engineRootPath, root))
{
registry->AddSearchPath({ engineRootPath, GemsDirectoryName }, false);
}
projectSettings = registry->CreateProjectSettings();
if (!projectSettings)
{
registryDestroyerFunc(registry);
AZ_Error("AzToolsFramework::AssetUtils", false, "Failed to create Gems::ProjectSettings.\n");
return false;
}
if (!projectSettings->Initialize(assetRoot, gameName))
{
registry->DestroyProjectSettings(projectSettings);
registryDestroyerFunc(registry);
AZ_Error("AzToolsFramework::AssetUtils", false, "Failed to initialize Gems::ProjectSettings.\n");
return false;
}
auto loadProjectOutcome = registry->LoadProject(*projectSettings, true);
if (!loadProjectOutcome.IsSuccess())
{
registry->DestroyProjectSettings(projectSettings);
registryDestroyerFunc(registry);
AZ_Error("AzToolsFramework::AssetUtils", false, "Failed to load Gems project: %s.\n", loadProjectOutcome.GetError().c_str());
return false;
}
// Populating the gem info list
for (const auto& pair : projectSettings->GetGems())
{
Gems::IGemDescriptionConstPtr desc = registry->GetGemDescription(pair.second);
if (!desc)
{
Gems::ProjectGemSpecifier gemSpecifier = pair.second;
AZStd::string errorStr = AZStd::string::format("Failed to load Gem with ID %s and Version %s (from path %s).\n",
gemSpecifier.m_id.ToString<AZStd::string>().c_str(), gemSpecifier.m_version.ToString().c_str(), gemSpecifier.m_path.c_str());
if (Gems::IGemDescriptionConstPtr latestVersion = registry->GetLatestGem(pair.first))
{
errorStr += AZStd::string::format(" Found version %s, you may want to use that instead.\n", latestVersion->GetVersion().ToString().c_str());
}
AZ_Error("AzToolsFramework::AssetUtils", false, errorStr.c_str());
return false;
}
// Note: the two 'false' parameters in the ToString call below ToString(false, false)
// eliminates brackets and dashes in the formatting of the UUID.
// this keeps it compatible with legacy formatting which also omitted the curly braces and the dashes in the UUID.
AZStd::string gemId = desc->GetID().ToString<AZStd::string>(false, false).c_str();
AZStd::to_lower(gemId.begin(), gemId.end());
bool assetOnlyGem = true;
Gems::ModuleDefinitionVector moduleList = desc->GetModules();
for (Gems::ModuleDefinitionConstPtr moduleDef : moduleList)
{
if (moduleDef->m_linkType != Gems::LinkType::NoCode)
{
assetOnlyGem = false;
break;
}
}
gemInfoList.emplace_back(GemInfo(desc->GetName(), desc->GetPath(), desc->GetAbsolutePath(), gemId, desc->IsGameGem(), assetOnlyGem));
}
registry->DestroyProjectSettings(projectSettings);
registryDestroyerFunc(registry);
return true;
}
AZStd::vector<AZStd::string> GetGemSeedListFiles(const AZStd::vector<GemInfo>& gemInfoList, AzFramework::PlatformFlags platformFlags)
AZStd::vector<AZStd::string> GetGemSeedListFiles(const AZStd::vector<AzFramework::GemInfo>& gemInfoList, AzFramework::PlatformFlags platformFlags)
{
AZStd::vector<AZStd::string> gemSeedListFiles;
for (const GemInfo& gemInfo : gemInfoList)
for (const AzFramework::GemInfo& gemInfo : gemInfoList)
{
AZStd::string absoluteGemSeedFilePath;
AZ::StringFunc::Path::ConstructFull(gemInfo.m_absoluteFilePath.c_str(), GemsSeedFileName, SeedFileExtension, absoluteGemSeedFilePath, true);
if (AZ::IO::FileIOBase::GetInstance()->Exists(absoluteGemSeedFilePath.c_str()))
for (AZ::IO::Path absoluteGemAssetPath : gemInfo.m_absoluteSourcePaths)
{
gemSeedListFiles.emplace_back(absoluteGemSeedFilePath);
}
absoluteGemAssetPath /= AzFramework::GemInfo::GetGemAssetFolder();
AddPlatformsDirectorySeeds(gemInfo.m_absoluteFilePath, gemSeedListFiles, platformFlags);
AZ::IO::Path absoluteGemSeedFilePath = absoluteGemAssetPath / GemsSeedFileName;
absoluteGemSeedFilePath.ReplaceExtension(SeedFileExtension);
if (AZ::IO::FileIOBase::GetInstance()->Exists(absoluteGemSeedFilePath.c_str()))
{
gemSeedListFiles.emplace_back(absoluteGemSeedFilePath);
}
AddPlatformsDirectorySeeds(absoluteGemAssetPath.Native(), gemSeedListFiles, platformFlags);
}
}
return gemSeedListFiles;
}
AZStd::vector<AZStd::string> GetDefaultSeedListFiles(const AZStd::vector<GemInfo>& gemInfoList, AzFramework::PlatformFlags platformFlag)
AZStd::vector<AZStd::string> GetDefaultSeedListFiles(const AZStd::vector<AzFramework::GemInfo>& gemInfoList, AzFramework::PlatformFlags platformFlag)
{
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
AZ_Assert(fileIO, "AZ::IO::FileIOBase must be ready for use.\n");
const char* root = nullptr;
AzFramework::ApplicationRequests::Bus::BroadcastResult(root, &AzFramework::ApplicationRequests::GetEngineRoot);
auto settingsRegistry = AZ::SettingsRegistry::Get();
AZ_Assert(settingsRegistry, "Global Settings registry must be available to retrieve default seed list");
AZ::IO::Path engineRoot;
settingsRegistry->Get(engineRoot.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
// Add all seed list files of enabled gems for the given project
AZStd::vector<AZStd::string> defaultSeedLists = GetGemSeedListFiles(gemInfoList, platformFlag);
// Add the engine seed list file
AZStd::string engineDirectory;
AZ::StringFunc::Path::Join(root, EngineDirectoryName, engineDirectory);
AZStd::string absoluteEngineSeedFilePath;
AZ::StringFunc::Path::ConstructFull(engineDirectory.c_str(), EngineSeedFileName, SeedFileExtension, absoluteEngineSeedFilePath, true);
AZ::IO::Path engineSourceAssetsDirectory = engineRoot / EngineDirectoryName;
AZ::IO::Path absoluteEngineSeedFilePath = engineSourceAssetsDirectory;
absoluteEngineSeedFilePath /= EngineSeedFileName;
absoluteEngineSeedFilePath.ReplaceExtension(SeedFileExtension);
if (fileIO->Exists(absoluteEngineSeedFilePath.c_str()))
{
defaultSeedLists.emplace_back(absoluteEngineSeedFilePath);
defaultSeedLists.emplace_back(AZStd::move(absoluteEngineSeedFilePath.LexicallyNormal().Native()));
}
AddPlatformsDirectorySeeds(engineDirectory, defaultSeedLists, platformFlag);
AddPlatformsDirectorySeeds(engineSourceAssetsDirectory.Native(), defaultSeedLists, platformFlag);
// Add the current project default seed list file
AZStd::string projectName;
bool checkPlatform = false;
auto settingsRegistry = AZ::SettingsRegistry::Get();
if (settingsRegistry)
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
if (!projectPath.empty())
{
AZ::SettingsRegistryInterface::FixedValueString bootstrapProjectName;
auto projectKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/sys_game_folder", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey);
settingsRegistry->Get(bootstrapProjectName, projectKey);
if (!bootstrapProjectName.empty())
AZ::IO::FixedMaxPath absoluteProjectDefaultSeedFilePath{ engineRoot };
absoluteProjectDefaultSeedFilePath /= projectPath;
absoluteProjectDefaultSeedFilePath /= EngineSeedFileName;
absoluteProjectDefaultSeedFilePath.ReplaceExtension(SeedFileExtension);
if (fileIO->Exists(absoluteProjectDefaultSeedFilePath.c_str()))
{
AZStd::string absoluteProjectDefaultSeedFilePath;
AZ::StringFunc::Path::ConstructFull(root, bootstrapProjectName.c_str(), EngineSeedFileName, SeedFileExtension, absoluteProjectDefaultSeedFilePath, true);
if (fileIO->Exists(absoluteProjectDefaultSeedFilePath.c_str()))
{
defaultSeedLists.emplace_back(move(absoluteProjectDefaultSeedFilePath));
}
defaultSeedLists.emplace_back(absoluteProjectDefaultSeedFilePath.LexicallyNormal().String());
}
}
return defaultSeedLists;
@@ -17,11 +17,11 @@
#include <AzCore/Module/ModuleManager.h>
#include <AzCore/Outcome/Outcome.h>
#include <AzCore/std/string/string.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzFramework/Application/Application.h>
#include <AzFramework/FileFunc/FileFunc.h>
#include <AzFramework/Gem/GemInfo.h>
#include <AzFramework/Platform/PlatformDefaults.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <GemRegistry/IGemRegistry.h>
namespace AssetValidation::AssetSeed
{
@@ -32,31 +32,12 @@ namespace AssetValidation::AssetSeed
constexpr char EngineSeedFileName[] = "SeedAssetList";
constexpr char EngineDirectoryName[] = "Engine";
//! This struct stores gem related information
struct GemInfo
{
AZ_CLASS_ALLOCATOR(GemInfo, AZ::SystemAllocator, 0);
GemInfo(AZStd::string name, AZStd::string relativeFilePath, AZStd::string absoluteFilePath, AZStd::string identifier, bool isGameGem, bool assetOnlyGem);
GemInfo() = default;
AZStd::string m_gemName; ///< A friendly display name, not to be used for any pathing stuff.
AZStd::string m_relativeFilePath; ///< Where the gem's folder is (relative to the gems search path(s))
AZStd::string m_absoluteFilePath; ///< Where the gem's folder is (as an absolute path)
AZStd::string m_identifier; ///< The UUID of the gem.
bool m_isGameGem = false; //< True if its a 'game project' gem. Only one such gem can exist for any game project.
bool m_assetOnly = false; ///< True if it is an asset only gems.
static constexpr AZStd::string_view GetGemAssetFolder() { return AZStd::string_view("Assets"); }
};
void AddPlatformSeeds(const AZStd::string& rootFolder, AZStd::vector<AZStd::string>& defaultSeedLists, AzFramework::PlatformFlags platformFlags);
void AddPlatformsDirectorySeeds(const AZStd::string& rootFolder, AZStd::vector<AZStd::string>& defaultSeedLists, AzFramework::PlatformFlags platformFlags);
bool GetGemsInfo(const char* root, const char* assetRoot, const char* gameName, AZStd::vector<GemInfo>& gemInfoList);
AZStd::vector<AZStd::string> GetGemSeedListFiles(const AZStd::vector<GemInfo>& gemInfoList, AzFramework::PlatformFlags platformFlags);
AZStd::vector<AZStd::string> GetGemSeedListFiles(const AZStd::vector<AzFramework::GemInfo>& gemInfoList, AzFramework::PlatformFlags platformFlags);
AZStd::vector<AZStd::string> GetDefaultSeedListFiles(const AZStd::vector<GemInfo>& gemInfoList, AzFramework::PlatformFlags platformFlag);
AZStd::vector<AZStd::string> GetDefaultSeedListFiles(const AZStd::vector<AzFramework::GemInfo>& gemInfoList, AzFramework::PlatformFlags platformFlag);
}
@@ -452,7 +452,7 @@ namespace AssetValidation
auto settingsRegistry = AZ::SettingsRegistry::Get();
AZ::SettingsRegistryInterface::FixedValueString gameFolder;
auto projectKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/sys_game_folder", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey);
auto projectKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/project_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey);
settingsRegistry->Get(gameFolder, projectKey);
if (gameFolder.empty())
@@ -461,9 +461,9 @@ namespace AssetValidation
return false;
}
AZStd::vector<AssetSeed::GemInfo> gemInfoList;
AZStd::vector<AzFramework::GemInfo> gemInfoList;
if (!AssetSeed::GetGemsInfo(engineRoot, appRoot, gameFolder.c_str(), gemInfoList))
if (!AzFramework::GetGemsInfo(gemInfoList, *settingsRegistry))
{
AZ_Warning("AssetValidation", false, "Unable to get gem information.");
return false;
@@ -15,6 +15,7 @@
#include "AssetValidationTestShared.h"
#include <AzFramework/Platform/PlatformDefaults.h>
#include <AzFramework/Asset/AssetSeedList.h>
#include <AzFramework/Gem/GemInfo.h>
// Needs SPEC-2324
#if !AZ_TRAIT_USE_POSIX_TEMP_FOLDER
@@ -29,25 +30,22 @@ bool AssetValidationTest::CreateDummyFile(const char* path, const char* seedFile
TEST_F(AssetValidationTest, DefaultSeedList_ReturnsExpectedSeedLists)
{
AZStd::vector<AssetValidation::AssetSeed::GemInfo> gemInfo;
AZStd::vector<AzFramework::GemInfo> gemInfo;
AZStd::string gemSeedList, engineSeedList, projectSeedList;
ASSERT_TRUE(CreateDummyFile("mockGem", "seedList", "Mock Gem Seed List", gemSeedList));
ASSERT_TRUE(CreateDummyFile((AZ::IO::Path("mockGem") / AzFramework::GemInfo::GetGemAssetFolder()).c_str(), "seedList", "Mock Gem Seed List", gemSeedList));
ASSERT_TRUE(CreateDummyFile("Engine", "SeedAssetList", "Engine Seed List", engineSeedList));
auto settingsRegistry = AZ::SettingsRegistry::Get();
ASSERT_NE(settingsRegistry, nullptr);
AZ::SettingsRegistryInterface::FixedValueString bootstrapProjectName;
auto projectKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/sys_game_folder", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey);
settingsRegistry->Get(bootstrapProjectName, projectKey);
ASSERT_FALSE(bootstrapProjectName.empty());
ASSERT_TRUE(CreateDummyFile(bootstrapProjectName.c_str(), "SeedAssetList", "Project Seed List", projectSeedList));
AZ::SettingsRegistryInterface::FixedValueString projectName = AZ::Utils::GetProjectName();
ASSERT_FALSE(projectName.empty());
ASSERT_TRUE(CreateDummyFile(projectName.c_str(), "SeedAssetList", "Project Seed List", projectSeedList));
AssetValidation::AssetSeed::GemInfo mockGem("MockGem", "mockGem", (m_tempDir / "mockGem").string().c_str(), "mockGem", true, false);
AzFramework::GemInfo mockGem("MockGem");
mockGem.m_absoluteSourcePaths.push_back((m_tempDir / "mockGem").string().c_str());
gemInfo.push_back(mockGem);
AZStd::vector<AZStd::string> defaultSeedLists = GetDefaultSeedListFiles(gemInfo, AzFramework::PlatformFlags::Platform_PC);
AZStd::vector<AZStd::string> defaultSeedLists = AssetValidation::AssetSeed::GetDefaultSeedListFiles(gemInfo, AzFramework::PlatformFlags::Platform_PC);
ASSERT_THAT(defaultSeedLists, ::testing::UnorderedElementsAre(gemSeedList, engineSeedList, projectSeedList));
}
@@ -150,8 +150,15 @@ struct AssetValidationTest
{
if (!AZ::SettingsRegistry::Get())
{
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(m_registry);
AZ::SettingsRegistry::Register(&m_registry);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(m_registry);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
// Set the engine root to the temporary directory and re-update the runtime file paths
auto enginePathKey = AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)
+ "/engine_path";
m_registry.Set(enginePathKey, GetEngineRoot());
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
}
}
@@ -165,7 +172,7 @@ struct AssetValidationTest
AZ_Assert(false, "Not implemented");
}
void CalculateBranchTokenForAppRoot([[maybe_unused]] AZStd::string& token) const override
void CalculateBranchTokenForEngineRoot([[maybe_unused]] AZStd::string& token) const override
{
AZ_Assert(false, "Not implemented");
}
@@ -1,15 +0,0 @@
; ---- add any metadata file type here that needs to be monitored by the AssetProcessor.
; Modifying these meta file will cause the source asset to re-compile again.
; They are specified in the following format
; metadata extension=original extension to replace
; if the metadata extension does not replace the original, then the original can be blank
; so for example if your normal file is blah.tif and your metafile for that file is blah.tif.exportsettings
; then your declaration would be exportsettings= ; ie, it would be blank
; however if your metafile REPLACES the extension (for example, if you have the file blah.i_caf and its metafile is blah.exportsettings)
; then you specify the original extension here to narrow the scope.
; If a relative path to a specific file is provided instead of an extension, a change to the file will change all files
; with the associated extension (e.g. Animations/SkeletonList.xml=i_caf will cause all i_caf files to recompile when
; Animations/SkeletonList.xml within the current game project changes)
[MetaDataTypes]
assetinfo=
@@ -0,0 +1,7 @@
{
"Amazon": {
"AssetProcessor": {
"Settings": {}
}
}
}
@@ -93,9 +93,9 @@ ly_add_source_properties(
)
ly_add_target(
NAME ImageProcessingAtom.Editor MODULE
NAME ImageProcessingAtom.Editor GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.ImageProcessingAtom.Editor.9d10b00be96045caa64c705e5772cb64.v0.1.0
FILES_CMAKE
imageprocessingatom_shared_files.cmake
INCLUDE_DIRECTORIES
@@ -22,6 +22,7 @@
#include <ImageLoader/ImageLoaders.h>
#include <Processing/ImageAssetProducer.h>
#include <Processing/ImageConvert.h>
#include <Processing/ImageToProcess.h>
#include <Processing/PixelFormatInfo.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzCore/Serialization/EditContextConstants.inl>
@@ -85,10 +86,13 @@ namespace ImageProcessingAtom
m_assetHandlers.emplace_back(AZ::RPI::MakeAssetHandler<AZ::RPI::ImageMipChainAssetHandler>());
m_assetHandlers.emplace_back(AZ::RPI::MakeAssetHandler<AZ::RPI::StreamingImageAssetHandler>());
ImageProcessingRequestBus::Handler::BusConnect();
}
void BuilderPluginComponent::Deactivate()
{
ImageProcessingRequestBus::Handler::BusDisconnect();
m_imageBuilder.BusDisconnect();
BuilderSettingManager::DestroyInstance();
CPixelFormats::DestroyInstance();
@@ -125,6 +129,23 @@ namespace ImageProcessingAtom
incompatible.push_back(AZ_CRC("ImagerBuilderPluginService", 0x6dc0db6e));
}
IImageObjectPtr BuilderPluginComponent::LoadImage(const AZStd::string& filePath)
{
return IImageObjectPtr(LoadImageFromFile(filePath));
}
IImageObjectPtr BuilderPluginComponent::LoadImagePreview(const AZStd::string& filePath)
{
IImageObjectPtr image(LoadImageFromFile(filePath));
if (image)
{
ImageToProcess imageToProcess(image);
imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8);
return imageToProcess.Get();
}
return image;
}
void ImageBuilderWorker::ShutDown()
{
// it is important to note that this will be called on a different thread than your process job thread
@@ -16,6 +16,7 @@
#include <AssetBuilderSDK/AssetBuilderBusses.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
#include <AzCore/Asset/AssetManager.h>
#include <Atom/ImageProcessing/ImageProcessingBus.h>
namespace ImageProcessingAtom
{
@@ -45,6 +46,7 @@ namespace ImageProcessingAtom
//! BuilderPluginComponent is to handle the lifecycle of ImageBuilder module.
class BuilderPluginComponent
: public AZ::Component
, protected ImageProcessingRequestBus::Handler
{
public:
AZ_COMPONENT(BuilderPluginComponent, "{A227F803-D2E4-406E-93EC-121EF45A64A1}")
@@ -63,6 +65,12 @@ namespace ImageProcessingAtom
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
//////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// AtomImageProcessingRequestBus interface implementation
IImageObjectPtr LoadImage(const AZStd::string& filePath) override;
IImageObjectPtr LoadImagePreview(const AZStd::string& filePath) override;
////////////////////////////////////////////////////////////////////////
private:
BuilderPluginComponent(const BuilderPluginComponent&) = delete;
@@ -53,7 +53,6 @@ namespace ImageProcessingAtom
IImageObjectPtr LoadImagePreview(const AZStd::string& filePath) override;
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// AZ::Component interface implementation
void Init() override;
@@ -110,8 +110,9 @@ namespace UnitTest
SerializeContext* GetSerializeContext() override { return m_context.get(); }
BehaviorContext* GetBehaviorContext() override { return nullptr; }
AZ::JsonRegistrationContext* GetJsonRegistrationContext() override { return m_jsonRegistrationContext.get(); }
const char* GetExecutableFolder() const override { return nullptr; }
const char* GetAppRoot() const override { return nullptr; }
const char* GetEngineRoot() const override { return nullptr; }
const char* GetExecutableFolder() const override { return nullptr; }
Debug::DrillerManager* GetDrillerManager() override { return nullptr; }
void EnumerateEntities(const EntityCallback& /*callback*/) override {}
void QueryApplicationType(AZ::ApplicationTypeQuery& /*appType*/) const override {}
@@ -159,7 +160,7 @@ namespace UnitTest
m_jsonSystemComponent = AZStd::make_unique<AZ::JsonSystemComponent>();
m_jsonSystemComponent->Reflect(m_jsonRegistrationContext.get());
BuilderPluginComponent::Reflect(m_jsonRegistrationContext.get());
// Startup default local FileIO (hits OSAllocator) if not already setup.
if (AZ::IO::FileIOBase::GetInstance() == nullptr)
{
@@ -171,7 +172,7 @@ namespace UnitTest
m_gemFolder = AZ::Test::GetEngineRootPath() + "/Gems/Atom/Asset/ImageProcessingAtom/";
s_gemFolder = m_gemFolder.c_str();
m_defaultSettingFolder = m_gemFolder + AZStd::string("Config/");
m_testFileFolder = m_gemFolder + AZStd::string("Code/Tests/TestAssets/");
@@ -192,7 +193,7 @@ namespace UnitTest
delete AZ::IO::FileIOBase::GetInstance();
AZ::IO::FileIOBase::SetInstance(nullptr);
m_jsonRegistrationContext->EnableRemoveReflection();
m_jsonSystemComponent->Reflect(m_jsonRegistrationContext.get());
BuilderPluginComponent::Reflect(m_jsonRegistrationContext.get());
@@ -916,7 +917,7 @@ namespace UnitTest
imageToProcess.LinearToGamma();
SaveImageToFile(imageToProcess.Get(), "LinearToGamma_DeGamma", 1);
}
TEST_F(ImageProcessingTest, VerifyRestrictedPlatform)
{
auto outcome = BuilderSettingManager::Instance()->LoadConfigFromFolder(m_defaultSettingFolder);
@@ -1005,7 +1006,7 @@ namespace UnitTest
TEST_F(ImageProcessingTest, DISABLED_TestLoadDdsImage)
{
IImageObjectPtr originImage, alphaImage;
AZStd::string inputFolder = "../Cache/SamplesProject/pc/samplesproject/engineassets/texturemsg/";
AZStd::string inputFolder = "../SamplesProject/Cache/pc/engineassets/texturemsg/";
AZStd::string inputFile;
inputFile = "E:/Javelin_NWLYDev/dev/Cache/Assets/pc/assets/textures/blend_maps/moss/jav_moss_ddn.dds";
@@ -1074,7 +1075,7 @@ namespace UnitTest
}
f.close();
}
TEST_F(ImageProcessingTest, TextureSettingReflect_SerializingModernDataInAndOut_WritesAndParsesFileAccurately)
{
AZStd::string filepath = "test.xml";
+4 -4
View File
@@ -22,9 +22,9 @@ if(NOT PAL_TRAIT_BUILD_ATOM_ASSET_SHADER_SUPPORTED)
# Create a stub
ly_add_target(
NAME Atom_Asset_Shader.Builders MODULE
NAME Atom_Asset_Shader.Builders GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_Asset_Shader.Builders.d32452026dae4b7dba2ad89dbde9c48f.v0.1.0
FILES_CMAKE
atom_asset_shader_builders_stub_files.cmake
INCLUDE_DIRECTORIES
@@ -83,9 +83,9 @@ foreach(enabled_platform ${LY_PAL_TOOLS_ENABLED})
endforeach()
ly_add_target(
NAME Atom_Asset_Shader.Builders MODULE
NAME Atom_Asset_Shader.Builders GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_Asset_Shader.Builders.d32452026dae4b7dba2ad89dbde9c48f.v0.1.0
FILES_CMAKE
atom_asset_shader_builders_shared_files.cmake
PLATFORM_INCLUDE_FILES
@@ -167,7 +167,12 @@ namespace AZ
// execute azsl prepending here, before preprocess, in order to support macros in AzslcHeader.azsli
AZStd::string prependedAzslSourceCode;
RHI::PrependArguments args{ fullPath.c_str(), shaderPlatformInterface->GetAzslHeader(info), shaderPlatformInterface->GetAPIName().GetCStr(), nullptr, &prependedAzslSourceCode };
RHI::PrependArguments args;
args.m_sourceFile = fullPath.c_str();
args.m_prependFile = shaderPlatformInterface->GetAzslHeader(info);
args.m_addSuffixToFileName = shaderPlatformInterface->GetAPIName().GetCStr();
args.m_destinationStringOpt = &prependedAzslSourceCode;
if (RHI::PrependFile(args) == fullPath) // error case. it returns the combined-file's name on success, or original path on failure, but here we use the "direct to string" mode so we don't need to store the returned name.
{
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Failed;
@@ -345,14 +350,11 @@ namespace AZ
return;
}
// pass it to the shader platform interface:
platformInterface->SetExternalArguments(buildOptions.m_compilerArguments);
// compiler setup
ShaderBuilder::AzslCompiler azslc(preprocessedPath);
AZStd::string compilerParameters = platformInterface->GetAzslCompilerParameters();
AZStd::string compilerParameters = platformInterface->GetAzslCompilerParameters(buildOptions.m_compilerArguments);
compilerParameters += " ";
compilerParameters += platformInterface->GetAzslCompilerWarningParameters();
compilerParameters += platformInterface->GetAzslCompilerWarningParameters(buildOptions.m_compilerArguments);
AtomShaderConfig::AddParametersFromConfigFile(compilerParameters, request.m_platformInfo);
if (isSrgi || isAzsli)
{
@@ -28,8 +28,8 @@
#include <AzFramework/IO/LocalFileIO.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/Process/ProcessCommunicator.h>
#include <AzToolsFramework/Process/ProcessWatcher.h>
#include <AzFramework/Process/ProcessCommunicator.h>
#include <AzFramework/Process/ProcessWatcher.h>
#include <AzslCompiler.h>
#include <CommonFiles/CommonTypes.h>
@@ -86,7 +86,7 @@ namespace AZ
// Register AZSL's compilation products Builder
AssetBuilderSDK::AssetBuilderDesc azslBuilderDescriptor;
azslBuilderDescriptor.m_name = "AZSL Builder";
azslBuilderDescriptor.m_version = 5; // ATOM-13204
azslBuilderDescriptor.m_version = 7; // LKG Merge
// register all extensions thay may carry azsl code. header. main shader. or SRG
azslBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
azslBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.azsl", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
@@ -102,7 +102,7 @@ namespace AZ
// Register Shader Resource Group Layout Builder
AssetBuilderSDK::AssetBuilderDesc srgLayoutBuilderDescriptor;
srgLayoutBuilderDescriptor.m_name = "Shader Resource Group Layout Builder";
srgLayoutBuilderDescriptor.m_version = 48; // ATOM-14428
srgLayoutBuilderDescriptor.m_version = 50; // ATOM-14918 (probably don't need to bump this one but just playing it safe)
srgLayoutBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.azsl", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
srgLayoutBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.azsli", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
srgLayoutBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", SrgLayoutBuilder::MergedPartialSrgsExtension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
@@ -117,7 +117,7 @@ namespace AZ
// Register Shader Asset Builder
AssetBuilderSDK::AssetBuilderDesc shaderAssetBuilderDescriptor;
shaderAssetBuilderDescriptor.m_name = "Shader Asset Builder";
shaderAssetBuilderDescriptor.m_version = 93; // ATOM-13204
shaderAssetBuilderDescriptor.m_version = 95; // LKG Merge
// .shader file changes trigger rebuilds
shaderAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern( AZStd::string::format("*.%s", RPI::ShaderSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
shaderAssetBuilderDescriptor.m_busId = azrtti_typeid<ShaderAssetBuilder>();
@@ -132,7 +132,7 @@ namespace AZ
shaderVariantAssetBuilderDescriptor.m_name = "Shader Variant Asset Builder";
// Both "Shader Variant Asset Builder" and "Shader Asset Builder" produce ShaderVariantAsset products. If you update
// ShaderVariantAsset you will need to update BOTH version numbers, not just "Shader Variant Asset Builder".
shaderVariantAssetBuilderDescriptor.m_version = 14; // ATOM-13204
shaderVariantAssetBuilderDescriptor.m_version = 16; // LKG Merge
shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
shaderVariantAssetBuilderDescriptor.m_busId = azrtti_typeid<ShaderVariantAssetBuilder>();
shaderVariantAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::CreateJobs, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
@@ -144,7 +144,7 @@ namespace AZ
// Register Precompiled Shader Builder
AssetBuilderSDK::AssetBuilderDesc precompiledShaderBuilderDescriptor;
precompiledShaderBuilderDescriptor.m_name = "Precompiled Shader Builder";
precompiledShaderBuilderDescriptor.m_version = 4; // ATOM-14428
precompiledShaderBuilderDescriptor.m_version = 6; // ATOM-14918
precompiledShaderBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", AZ::PrecompiledShaderBuilder::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
precompiledShaderBuilderDescriptor.m_busId = azrtti_typeid<PrecompiledShaderBuilder>();
precompiledShaderBuilderDescriptor.m_createJobFunction = AZStd::bind(&PrecompiledShaderBuilder::CreateJobs, &m_precompiledShaderBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
@@ -65,12 +65,6 @@ namespace AZ
GlobalBuildOptions ReadBuildOptions(const char* builderName)
{
GlobalBuildOptions output;
// get the application root:
AZStd::string devFolder;
AzFramework::ApplicationRequests::Bus::BroadcastResult(devFolder, &AzFramework::ApplicationRequests::GetAppRoot);
AzFramework::StringFunc::Path::Normalize(devFolder);
// additionally,
// try to parse some config file for eventual additional options
AZStd::string globalBuildOption = "Config/shader_global_build_options.json";
bool found = MutateToAbsolutePathIfFound(globalBuildOption);
@@ -309,22 +309,22 @@ namespace AZ
}
} // the folders constructed this fashion constitute the base of automatic include search paths
// get the application root:
AZStd::string devFolder;
AzFramework::ApplicationRequests::Bus::BroadcastResult(devFolder, &AzFramework::ApplicationRequests::GetAppRoot);
AzFramework::StringFunc::Path::Normalize(devFolder);
// get the engine root:
AZStd::string engineRoot;
AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRoot, &AzFramework::ApplicationRequests::GetEngineRoot);
AzFramework::StringFunc::Path::Normalize(engineRoot);
// add optional additional options
for (AZStd::string& path : options.m_projectIncludePaths)
{
AzFramework::StringFunc::Path::Join(devFolder.c_str(), path.c_str(), path);
AzFramework::StringFunc::Path::Join(engineRoot.c_str(), path.c_str(), path);
DeleteFromSet(path, scanFoldersSet); // no need to add a path two times.
}
// back-insert the default paths (after the config-read paths we just read)
TransferContent(/*to:*/options.m_projectIncludePaths, /*from:*/scanFoldersSet);
// finally the dev/Gems fallback
// finally the <engineroot>/Gems fallback
AZStd::string gemsFolder;
AzFramework::StringFunc::Path::Join(devFolder.c_str(), "Gems", gemsFolder);
AzFramework::StringFunc::Path::Join(engineRoot.c_str(), "Gems", gemsFolder);
options.m_projectIncludePaths.push_back(gemsFolder);
}
@@ -128,7 +128,12 @@ namespace AZ
{// *** block (remove all this when [ATOM-4225] addressed)
// this is the same code as in AzslBuilder.cpp's CreateJobs. This is not supposed to be repeated here (temporary hack), so not factorized. refer to AzslBuilder.cpp for code comments
AZStd::string prependedAzslSourceCode;
RHI::PrependArguments args{ fullPath.c_str(), shaderPlatformInterface->GetAzslHeader(platformInfo), shaderPlatformInterface->GetAPIName().GetCStr(), nullptr, &prependedAzslSourceCode };
RHI::PrependArguments args;
args.m_sourceFile = fullPath.c_str();
args.m_prependFile = shaderPlatformInterface->GetAzslHeader(platformInfo);
args.m_addSuffixToFileName = shaderPlatformInterface->GetAPIName().GetCStr();
args.m_destinationStringOpt = &prependedAzslSourceCode;
if (RHI::PrependFile(args) == fullPath)
{
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Failed;
@@ -179,6 +184,7 @@ namespace AZ
RHI::ShaderPlatformInterface* shaderPlatformInterface,
AssetBuilderSDK::ProcessJobResponse& response,
AzslData& azslData,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
RPI::Ptr<RPI::ShaderOptionGroupLayout> shaderOptionGroupLayout,
const RPI::ShaderSourceData& shaderSourceDataDescriptor,
AZStd::sys_time_t shaderAssetBuildTimestamp,
@@ -217,7 +223,7 @@ namespace AZ
// Signal the begin of shader data for an RHI API.
shaderAssetCreator.BeginAPI(shaderPlatformInterface->GetAPIType());
RHI::Ptr<RHI::PipelineLayoutDescriptor> pipelineLayoutDescriptor = ShaderBuilderUtility::BuildPipelineLayoutDescriptorForApi(
ShaderAssetBuilderName, shaderPlatformInterface, bindingDependencies, srgAssets, shaderEntryPoints, &rootConstantData);
ShaderAssetBuilderName, shaderPlatformInterface, bindingDependencies, srgAssets, shaderEntryPoints, shaderCompilerArguments, &rootConstantData);
if (!pipelineLayoutDescriptor)
{
AZ_Error(ShaderAssetBuilderName, false, "Failed to build pipeline layout descriptor for api=[%s]",
@@ -257,6 +263,7 @@ namespace AZ
variantCreationContext,
*shaderPlatformInterface,
azslData,
shaderCompilerArguments,
pathOfProductFiles[ShaderBuilderUtility::AzslSubProducts::om],
pathOfProductFiles[ShaderBuilderUtility::AzslSubProducts::ia]);
if (!outcomeForShaderVariantAsset.IsSuccess())
@@ -483,8 +490,6 @@ namespace AZ
// We define a merge behavior that is: ".shader wins if set"
RHI::ShaderCompilerArguments mergedArguments = buildOptions.m_compilerArguments;
mergedArguments.Merge(shaderAssetSource.m_compiler);
// pass it to the shader platform interface:
shaderPlatformInterface->SetExternalArguments(mergedArguments);
AssetBuilderSDK::ProcessJobResultCode compileResult =
CompileForAPI(
@@ -493,6 +498,7 @@ namespace AZ
shaderPlatformInterface,
response,
azslData,
mergedArguments,
shaderOptionGroupLayout,
shaderAssetSource,
shaderAssetBuildTimestamp,
@@ -23,6 +23,7 @@
#include <AzCore/IO/IOUtils.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AtomCore/Serialization/Json/JsonUtils.h>
@@ -316,6 +317,7 @@ namespace AZ
BindingDependencies& bindingDependencies /*inout*/,
const ShaderResourceGroupAssets& srgAssets,
const MapOfStringToStageType& shaderEntryPoints,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
const RootConstantData* rootConstantData /*= nullptr*/)
{
PruneNonEntryFunctions(bindingDependencies, shaderEntryPoints);
@@ -415,7 +417,7 @@ namespace AZ
rootConstantInfo.m_totalSizeInBytes = rootConstantsLayout->GetDataSize();
// Build platform-specific PipelineLayoutDescriptor data, and finalize
if (!shaderPlatformInterface->BuildPipelineLayoutDescriptor(pipelineLayoutDescriptor, srgInfos, rootConstantInfo))
if (!shaderPlatformInterface->BuildPipelineLayoutDescriptor(pipelineLayoutDescriptor, srgInfos, rootConstantInfo, shaderCompilerArguments))
{
AZ_Error(BuilderName, false, "Failed to build pipeline layout descriptor");
return nullptr;
@@ -87,6 +87,7 @@ namespace AZ
BindingDependencies& bindingDependencies /*inout*/,
const ShaderResourceGroupAssets& srgAssets,
const MapOfStringToStageType& shaderEntryPoints,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
const RootConstantData* rootConstantData = nullptr
);
@@ -68,7 +68,7 @@ namespace AZ
static constexpr char ShaderVariantAssetBuilderName[] = "ShaderVariantAssetBuilder";
static constexpr uint32_t ShaderVariantLoadErrorParam = 0;
static constexpr uint32_t ShaderPathJobParam = 2;
static constexpr uint32_t ShaderSourceFilePathJobParam = 2;
static constexpr uint32_t ShaderVariantJobVariantParam = 3;
static constexpr uint32_t ShouldExitEarlyFromProcessJobParam = 4;
@@ -234,7 +234,7 @@ namespace AZ
AZStd::string m_deferredMessage; // Only used when m_code == DeferredError
};
static LoadResult LoadShaderVariantList(const AZStd::string& variantListFullPath, RPI::ShaderVariantListSourceData& shaderVariantList, AZStd::string& shaderFullPath,
static LoadResult LoadShaderVariantList(const AZStd::string& variantListFullPath, RPI::ShaderVariantListSourceData& shaderVariantList, AZStd::string& shaderSourceFileFullPath,
bool& shouldExitEarlyFromProcessJob)
{
// Need to get the name of the shader file from the template so that we can preprocess the shader data and setup
@@ -251,9 +251,9 @@ namespace AZ
return LoadResult{LoadResult::Code::DeferredError, AZStd::string::format("The shader path [%s] was not found.", resolvedShaderPath.c_str())};
}
shaderFullPath = resolvedShaderPath;
shaderSourceFileFullPath = resolvedShaderPath;
if (!ValidateShaderVariantListLocation(variantListFullPath, shaderFullPath, shouldExitEarlyFromProcessJob))
if (!ValidateShaderVariantListLocation(variantListFullPath, shaderSourceFileFullPath, shouldExitEarlyFromProcessJob))
{
return LoadResult{LoadResult::Code::Error};
}
@@ -270,13 +270,13 @@ namespace AZ
return LoadResult{LoadResult::Code::Error};
}
if (!IO::FileIOBase::GetInstance()->Exists(shaderFullPath.c_str()))
if (!IO::FileIOBase::GetInstance()->Exists(shaderSourceFileFullPath.c_str()))
{
return LoadResult{LoadResult::Code::DeferredError, AZStd::string::format("ShaderSourceData file does not exist: %s.", shaderFullPath.c_str())};
return LoadResult{LoadResult::Code::DeferredError, AZStd::string::format("ShaderSourceData file does not exist: %s.", shaderSourceFileFullPath.c_str())};
}
// Let's open the shader source, because We need the source code of its AZSL file
auto outcomeShaderData = ShaderBuilderUtility::LoadShaderDataJson(shaderFullPath);
auto outcomeShaderData = ShaderBuilderUtility::LoadShaderDataJson(shaderSourceFileFullPath);
if (!outcomeShaderData.IsSuccess())
{
return LoadResult{LoadResult::Code::DeferredError, AZStd::string::format("Failed to parse Shader Descriptor JSON: %s", outcomeShaderData.GetError().c_str())};
@@ -292,9 +292,9 @@ namespace AZ
AZ_TracePrintf(ShaderVariantAssetBuilderName, "CreateJobs for Shader Variant List \"%s\"\n", variantListFullPath.data());
RPI::ShaderVariantListSourceData shaderVariantList;
AZStd::string shaderFullPath;
AZStd::string shaderSourceFileFullPath;
bool shouldExitEarlyFromProcessJob = false;
const LoadResult loadResult = LoadShaderVariantList(variantListFullPath, shaderVariantList, shaderFullPath, shouldExitEarlyFromProcessJob);
const LoadResult loadResult = LoadShaderVariantList(variantListFullPath, shaderVariantList, shaderSourceFileFullPath, shouldExitEarlyFromProcessJob);
if (loadResult.m_code == LoadResult::Code::Error)
{
@@ -318,7 +318,7 @@ namespace AZ
AZStd::vector<RHI::ShaderPlatformInterface*> platformInterfaces = ShaderBuilderUtility::DiscoverValidShaderPlatformInterfaces(info);
for (RHI::ShaderPlatformInterface* shaderPlatformInterface : platformInterfaces)
{
AddAzslBuilderJobDependency(jobDescriptor, info.m_identifier, shaderPlatformInterface->GetAPIName().GetCStr(), shaderFullPath);
AddAzslBuilderJobDependency(jobDescriptor, info.m_identifier, shaderPlatformInterface->GetAPIName().GetCStr(), shaderSourceFileFullPath);
}
if (loadResult.m_code == LoadResult::Code::DeferredError)
@@ -357,7 +357,7 @@ namespace AZ
AddShaderAssetJobDependency(jobDescriptor, info, variantListFullPath, shaderVariantList.m_shaderFilePath);
jobDescriptor.m_jobParameters.emplace(ShaderPathJobParam, shaderFullPath);
jobDescriptor.m_jobParameters.emplace(ShaderSourceFilePathJobParam, shaderSourceFileFullPath);
response.m_createJobOutputs.push_back(jobDescriptor);
}
@@ -392,7 +392,7 @@ namespace AZ
jobDescriptor.m_jobDependencyList.emplace_back(variantTreeJobDependency);
jobDescriptor.m_jobParameters.emplace(ShaderVariantJobVariantParam, variantInfoAsJsonString);
jobDescriptor.m_jobParameters.emplace(ShaderPathJobParam, shaderFullPath);
jobDescriptor.m_jobParameters.emplace(ShaderSourceFilePathJobParam, shaderSourceFileFullPath);
response.m_createJobOutputs.push_back(jobDescriptor);
}
@@ -449,14 +449,14 @@ namespace AZ
return;
}
const AZStd::string& shaderFullPath = request.m_jobDescription.m_jobParameters.at(ShaderPathJobParam);
const AZStd::string& shaderSourceFileFullPath = request.m_jobDescription.m_jobParameters.at(ShaderSourceFilePathJobParam);
//For debugging purposes will create a dummy azshadervarianttree file.
AZStd::string shaderName;
AzFramework::StringFunc::Path::Split(shaderFullPath.c_str(), nullptr /*drive*/, nullptr /*path*/, & shaderName, nullptr /*extension*/);
AzFramework::StringFunc::Path::Split(shaderSourceFileFullPath.c_str(), nullptr /*drive*/, nullptr /*path*/, & shaderName, nullptr /*extension*/);
RPI::ShaderSourceData shaderSourceDescriptor;
AZStd::shared_ptr<ShaderFiles> azslSources = ShaderBuilderUtility::PrepareSourceInput(ShaderVariantAssetBuilderName, shaderFullPath, shaderSourceDescriptor);
AZStd::shared_ptr<ShaderFiles> azslSources = ShaderBuilderUtility::PrepareSourceInput(ShaderVariantAssetBuilderName, shaderSourceFileFullPath, shaderSourceDescriptor);
if (!azslSources)
{
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
@@ -474,7 +474,7 @@ namespace AZ
// Gracefully do nothing and continue with the next shaderPlatformInterface.
AZ_TracePrintf(
ShaderVariantAssetBuilderName, "Skipping shader variant tree compilation of [%s] for API [%s]\n",
shaderFullPath.c_str(),
shaderSourceFileFullPath.c_str(),
shaderPlatformInterface->GetAPIName().GetCStr());
continue;
}
@@ -551,6 +551,7 @@ namespace AZ
Data::Asset<RPI::ShaderVariantAsset>& shaderVariantAsset,
RHI::ShaderPlatformInterface* shaderPlatformInterface,
AzslData& azslData,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
const RPI::ShaderOptionGroupLayout& shaderOptionGroupLayout,
const RPI::ShaderSourceData& shaderSourceDataDescriptor,
AZStd::sys_time_t shaderAssetBuildTimestamp,
@@ -583,7 +584,7 @@ namespace AZ
}
if (!ShaderBuilderUtility::BuildPipelineLayoutDescriptorForApi(
ShaderVariantAssetBuilderName, shaderPlatformInterface, bindingDependencies, srgAssets, shaderEntryPoints, &rootConstantData))
ShaderVariantAssetBuilderName, shaderPlatformInterface, bindingDependencies, srgAssets, shaderEntryPoints, shaderCompilerArguments, &rootConstantData))
{
AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to build pipeline layout descriptor for api=[%s]",
shaderPlatformInterface->GetAPIName().GetCStr());
@@ -597,6 +598,7 @@ namespace AZ
variantCreationContext,
*shaderPlatformInterface,
azslData,
shaderCompilerArguments,
pathToOmJson,
pathToIaJson);
if (!outcomeForShaderVariantAsset.IsSuccess())
@@ -621,23 +623,23 @@ namespace AZ
AzFramework::StringFunc::Path::ConstructFull(request.m_watchFolder.data(), request.m_sourceFile.data(), fullPath, true);
const auto& jobParameters = request.m_jobDescription.m_jobParameters;
const AZStd::string& shaderFullPath = jobParameters.at(ShaderPathJobParam);
const AZStd::string& shaderSourceFileFullPath = jobParameters.at(ShaderSourceFilePathJobParam);
const AZStd::string& variantJsonString = jobParameters.at(ShaderVariantJobVariantParam);
RPI::ShaderVariantListSourceData::VariantInfo variantInfo;
const bool toJsonStringSuccess = AZ::RPI::JsonUtils::LoadObjectFromJsonString(variantJsonString, variantInfo);
AZ_Assert(toJsonStringSuccess, "Failed to convert json string to VariantInfo");
auto shaderAssetOutcome = RPI::AssetUtils::LoadAsset<RPI::ShaderAsset>(shaderFullPath);
auto shaderAssetOutcome = RPI::AssetUtils::LoadAsset<RPI::ShaderAsset>(shaderSourceFileFullPath);
if (!shaderAssetOutcome.IsSuccess())
{
AZ_Error(ShaderVariantAssetBuilderName, false, "The shader path [%s] could not be loaded.", shaderFullPath.c_str());
AZ_Error(ShaderVariantAssetBuilderName, false, "The shader path [%s] could not be loaded.", shaderSourceFileFullPath.c_str());
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
return;
}
Data::Asset<RPI::ShaderAsset> shaderAsset = shaderAssetOutcome.TakeValue();
RPI::ShaderSourceData shaderSourceDescriptor;
AZStd::shared_ptr<ShaderFiles> sources = ShaderBuilderUtility::PrepareSourceInput(ShaderVariantAssetBuilderName, shaderFullPath, shaderSourceDescriptor);
AZStd::shared_ptr<ShaderFiles> sources = ShaderBuilderUtility::PrepareSourceInput(ShaderVariantAssetBuilderName, shaderSourceFileFullPath, shaderSourceDescriptor);
// Request the list of valid shader platform interfaces for the target platform.
AZStd::vector<RHI::ShaderPlatformInterface*> platformInterfaces;
@@ -652,13 +654,13 @@ namespace AZ
// Gracefully do nothing and continue with the next shaderPlatformInterface.
AZ_TracePrintf(
ShaderVariantAssetBuilderName, "Skipping shader variant compilation of [%s] with StableId [%u] for API [%s]\n",
shaderFullPath.c_str(), variantInfo.m_stableId, shaderPlatformInterface->GetAPIName().GetCStr());
shaderSourceFileFullPath.c_str(), variantInfo.m_stableId, shaderPlatformInterface->GetAPIName().GetCStr());
continue;
}
if (!shaderPlatformInterface)
{
AZ_Error(ShaderVariantAssetBuilderName, false, "ShaderPlatformInterface for [%s] is not registered, can't compile [%s]", request.m_platformInfo.m_identifier.c_str(), shaderFullPath.c_str());
AZ_Error(ShaderVariantAssetBuilderName, false, "ShaderPlatformInterface for [%s] is not registered, can't compile [%s]", request.m_platformInfo.m_identifier.c_str(), shaderSourceFileFullPath.c_str());
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
return;
}
@@ -714,11 +716,27 @@ namespace AZ
return;
}
GlobalBuildOptions buildOptions = ReadBuildOptions(ShaderVariantAssetBuilderName);
auto shaderSourceLoadResult = ShaderBuilderUtility::LoadShaderDataJson(shaderSourceFileFullPath);
if (!shaderSourceLoadResult.IsSuccess())
{
AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to load/parse Shader Descriptor JSON: %s", shaderSourceLoadResult.GetError().c_str());
return;
}
// The idea of this merge is that we have compiler options coming from 2 source:
// global options (from project Config/), and .shader options.
// We define a merge behavior that is: ".shader wins if set"
RHI::ShaderCompilerArguments mergedArguments = buildOptions.m_compilerArguments;
mergedArguments.Merge(shaderSourceLoadResult.GetValue().m_compiler);
Data::Asset<RPI::ShaderVariantAsset> shaderVariantAsset;
auto [success, byproducts] = CompileShaderVariantForAPI(
shaderVariantAsset,
shaderPlatformInterface,
azslData,
mergedArguments,
*shaderOptionGroupLayout,
shaderSourceDescriptor,
shaderAsset->GetShaderAssetBuildTimestamp(),
@@ -740,7 +758,7 @@ namespace AZ
// Time to save the asset in the cache tmp folder.
const uint32_t productSubID = RPI::ShaderVariantAsset::GetAssetSubId(shaderPlatformInterface->GetAPIUniqueIndex(), shaderVariantAsset->GetStableId());
AssetBuilderSDK::JobProduct assetProduct;
if (!SerializeOutShaderVariantAsset(shaderVariantAsset, shaderFullPath, request.m_tempDirPath, *shaderPlatformInterface, productSubID, assetProduct))
if (!SerializeOutShaderVariantAsset(shaderVariantAsset, shaderSourceFileFullPath, request.m_tempDirPath, *shaderPlatformInterface, productSubID, assetProduct))
{
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
return;
@@ -811,6 +829,7 @@ namespace AZ
static bool CreateShaderVariant(
ShaderVariantCreationContext& variantCreationContext,
const AzslData& azslData,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
RHI::ShaderPlatformInterface& shaderPlatformInterface,
const size_t colorAttachmentCount,
const RPI::ShaderVariantStableId variantStableId,
@@ -834,7 +853,6 @@ namespace AZ
auto assetBuilderShaderType = ShaderBuilderUtility::ToAssetBuilderShaderType(shaderStageType);
AZStd::string variantShaderSourcePath;
auto crc = AZ::Crc32(azslData.m_shaderCodePrefix.data(), azslData.m_shaderCodePrefix.size());
// Check if we need to prepend any code prefix
if (!azslData.m_shaderCodePrefix.empty())
@@ -868,7 +886,8 @@ namespace AZ
shaderEntryName,
assetBuilderShaderType,
variantCreationContext.m_tempDirPath,
descriptor);
descriptor,
shaderCompilerArguments);
if (!shaderWasCompiled)
{
@@ -1147,6 +1166,7 @@ namespace AZ
ShaderVariantCreationContext& variantCreationContext,
RHI::ShaderPlatformInterface& shaderPlatformInterface,
AzslData& azslData,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
const AZStd::string& pathToOmJson,
const AZStd::string& pathToIaJson)
{
@@ -1191,14 +1211,6 @@ namespace AZ
optionList.push_back(OptionCache{ optionName, optionValue, optionIndex, value });
}
// The user might supply the option values in any order. Sort them now:
AZStd::sort(optionList.begin(), optionList.end(), [](const OptionCache& left, const OptionCache& right)
{
// m_optionIndex is the cached index in the m_options vector (stored in the ShaderOptionGroupLayout)
// m_options has already been sorted so the index *is* the option priority:
return left.m_optionIndex < right.m_optionIndex;
});
// Create one instance of the shader variant
RPI::ShaderOptionGroup optionGroup(&shaderOptionGroupLayout);
@@ -1236,6 +1248,7 @@ namespace AZ
if (!CreateShaderVariant(
variantCreationContext,
azslData,
shaderCompilerArguments,
shaderPlatformInterface,
colorAttachmentCount,
shaderVariantStableId,
@@ -1268,11 +1281,11 @@ namespace AZ
}
}
bool ShaderVariantAssetBuilder::SerializeOutShaderVariantAsset(const Data::Asset<RPI::ShaderVariantAsset> shaderVariantAsset, const AZStd::string& shaderFullPath, const AZStd::string& tempDirPath,
bool ShaderVariantAssetBuilder::SerializeOutShaderVariantAsset(const Data::Asset<RPI::ShaderVariantAsset> shaderVariantAsset, const AZStd::string& shaderSourceFileFullPath, const AZStd::string& tempDirPath,
const RHI::ShaderPlatformInterface& shaderPlatformInterface, const uint32_t productSubID, AssetBuilderSDK::JobProduct& assetProduct)
{
AZStd::string shaderName;
AzFramework::StringFunc::Path::Split(shaderFullPath.c_str(), nullptr /*drive*/, nullptr /*path*/, &shaderName, nullptr /*extension*/);
AzFramework::StringFunc::Path::Split(shaderSourceFileFullPath.c_str(), nullptr /*drive*/, nullptr /*path*/, &shaderName, nullptr /*extension*/);
AZStd::string filename = AZStd::string::format("%s_%s_%u.%s", shaderName.c_str(), shaderPlatformInterface.GetAPIName().GetCStr(), shaderVariantAsset->GetStableId().GetIndex(), RPI::ShaderVariantAsset::Extension);
AZStd::string assetPath;
@@ -66,6 +66,7 @@ namespace AZ
ShaderVariantCreationContext& context,
RHI::ShaderPlatformInterface& shaderPlatformInterface,
AzslData& azslData,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
const AZStd::string& pathToOmJson,
const AZStd::string& pathToIaJson);
@@ -352,9 +352,9 @@ namespace AZ
// The register number only makes sense if the platform uses "spaces",
// since the register Id of the resource will not change even if the pipeline layout changes.
AZStd::string compilerParameters = shaderPlatformInterface->GetAzslCompilerParameters();
bool useRegisterId = (AzFramework::StringFunc::Find(compilerParameters, "--use-spaces") != AZStd::string::npos);
AtomShaderConfig::AddParametersFromConfigFile(compilerParameters, request.m_platformInfo);
// We can pass in a default ShaderCompilerArguments because all we care about is whether the shaderPlatformInterface appends the "--use-spaces" flag.
AZStd::string azslCompilerParameters = shaderPlatformInterface->GetAzslCompilerParameters(RHI::ShaderCompilerArguments{});
bool useRegisterId = (AzFramework::StringFunc::Find(azslCompilerParameters, "--use-spaces") != AZStd::string::npos);
// Samplers
for (const SamplerSrgData& samplerData : srgData.m_samplers)
-1
View File
@@ -22,7 +22,6 @@ ly_add_target(
ly_add_target(
NAME Atom_Bootstrap ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_Bootstrap.c7ff89ad6e8b4b45b2fadef2bcf12d6e.v0.1.0
FILES_CMAKE
bootstrap_files.cmake
INCLUDE_DIRECTORIES
@@ -30,7 +30,6 @@ ly_add_target(
ly_add_target(
NAME Atom_Component_DebugCamera ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_Component_DebugCamera.013d1b42ad314c929b292c143bcbf045.v0.1.0
FILES_CMAKE
atom_component_debugcamera_shared_files.cmake
INCLUDE_DIRECTORIES
@@ -14,6 +14,13 @@
"ReadMask" : "0x00",
"WriteMask" : "0xFF",
"FrontFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Replace"
},
"BackFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
@@ -14,6 +14,13 @@
"ReadMask" : "0x00",
"WriteMask" : "0xFF",
"FrontFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Replace"
},
"BackFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
@@ -70,7 +70,7 @@ VertexOutput MainVS(VertexInput IN)
struct PSDepthOutput
{
float m_depth : SV_DepthLessEqual;
float m_depth : SV_DepthGreaterEqual;
};
PSDepthOutput MainPS(VertexOutput IN, bool isFrontFace : SV_IsFrontFace)
@@ -14,6 +14,13 @@
"ReadMask" : "0x00",
"WriteMask" : "0xFF",
"FrontFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Replace"
},
"BackFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
@@ -14,6 +14,13 @@
"ReadMask" : "0x00",
"WriteMask" : "0xFF",
"FrontFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Replace"
},
"BackFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
@@ -14,6 +14,13 @@
"ReadMask" : "0x00",
"WriteMask" : "0xFF",
"FrontFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Replace"
},
"BackFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
@@ -14,6 +14,13 @@
"ReadMask" : "0x00",
"WriteMask" : "0xFF",
"FrontFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
"FailOp" : "Keep",
"PassOp" : "Replace"
},
"BackFace" :
{
"Func" : "Always",
"DepthFailOp" : "Keep",
@@ -70,7 +70,7 @@ VertexOutput MainVS(VertexInput IN)
struct PSDepthOutput
{
float m_depth : SV_DepthLessEqual;
float m_depth : SV_DepthGreaterEqual;
};
PSDepthOutput MainPS(VertexOutput IN, bool isFrontFace : SV_IsFrontFace)
+4 -5
View File
@@ -73,7 +73,6 @@ ly_add_target(
ly_add_target(
NAME Atom_Feature_Common ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_Feature_Common.b58e5eed0901428ca78544b04dbd61bd.v0.1.0
FILES_CMAKE
atom_feature_common_shared_files.cmake
../Assets/atom_feature_common_asset_files.cmake
@@ -95,9 +94,9 @@ ly_add_target(
if(PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_target(
NAME Atom_Feature_Common.Editor MODULE
NAME Atom_Feature_Common.Editor GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_Feature_Common.Editor.b58e5eed0901428ca78544b04dbd61bd.v0.1.0
FILES_CMAKE
atom_feature_common_editor_files.cmake
INCLUDE_DIRECTORIES
@@ -126,9 +125,9 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
)
ly_add_target(
NAME Atom_Feature_Common.Builders MODULE
NAME Atom_Feature_Common.Builders GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_Feature_Common.Builders.b58e5eed0901428ca78544b04dbd61bd.v0.1.0
FILES_CMAKE
atom_feature_common_builders_files.cmake
INCLUDE_DIRECTORIES
@@ -76,6 +76,18 @@ namespace AZ
};
using FrameCaptureNotificationBus = EBus<FrameCaptureNotifications>;
//! Stores the result of a frame capture request.
//! Includes the result type along with an optional error message if the request did not complete successfully.
struct FrameCaptureOutputResult
{
FrameCaptureResult m_result; //!< Outcome after attempting to capture a frame.
AZStd::optional<AZStd::string> m_errorMessage; //!< If the capture did not succeed, an optional diagnostic message is set.
};
//! Writes out content of ReadbackResult in the Dds image format.
FrameCaptureOutputResult DdsFrameCaptureOutput(
const AZStd::string& outputFilePath, const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult);
} // namespace Render
AZ_TYPE_INFO_SPECIALIZE(Render::FrameCaptureResult, "{F0B013CE-DFAE-4743-B123-EB1EE1705E03}");
@@ -80,9 +80,10 @@ namespace AZ
bool m_autoSelect = false;
AZStd::string m_displayName;
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> m_skyboxImageAsset;
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> m_iblSpecularImageAsset;
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> m_iblDiffuseImageAsset;
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> m_iblSpecularImageAsset;
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> m_skyboxImageAsset;
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> m_alternateSkyboxImageAsset;
float m_iblExposure = 0.0f;
float m_skyboxExposure = 0.0f;
ExposureControlConfig m_exposure;
@@ -99,7 +100,8 @@ namespace AZ
const Camera::Configuration& cameraConfig,
AZStd::vector<DirectionalLightFeatureProcessorInterface::LightHandle>& lightHandles,
Data::Instance<AZ::RPI::Material> shadowCatcherMaterial = nullptr,
RPI::MaterialPropertyIndex shadowCatcherOpacityPropertyIndex = RPI::MaterialPropertyIndex()) const;
RPI::MaterialPropertyIndex shadowCatcherOpacityPropertyIndex = RPI::MaterialPropertyIndex(),
bool enableAlternateSkybox = false) const;
};
using LightingPresetPtr = AZStd::shared_ptr<LightingPreset>;
@@ -19,6 +19,7 @@
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzCore/std/string/string.h>
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
#include <Atom/RPI.Reflect/Image/StreamingImageAsset.h>
namespace AZ
{
@@ -34,6 +35,7 @@ namespace AZ
bool m_autoSelect = false;
AZStd::string m_displayName;
AZ::Data::Asset<AZ::RPI::ModelAsset> m_modelAsset;
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> m_previewImageAsset;
};
using ModelPresetPtr = AZStd::shared_ptr<ModelPreset>;
@@ -38,6 +38,18 @@ namespace AZ
{
AZ_ENUM_DEFINE_REFLECT_UTILITIES(FrameCaptureResult);
FrameCaptureOutputResult DdsFrameCaptureOutput(
const AZStd::string& outputFilePath, const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
{
// write the read back result of the image attachment to a dds file
const auto outcome = AZ::DdsFile::WriteFile(
outputFilePath,
{readbackResult.m_imageDescriptor.m_size, readbackResult.m_imageDescriptor.m_format, readbackResult.m_dataBuffer.get()});
return outcome.IsSuccess() ? FrameCaptureOutputResult{FrameCaptureResult::Success, AZStd::nullopt}
: FrameCaptureOutputResult{FrameCaptureResult::InternalError, outcome.GetError().m_message};
}
class FrameCaptureNotificationBusHandler final
: public FrameCaptureNotificationBus::Handler
, public AZ::BehaviorEBusHandler
@@ -392,18 +404,9 @@ namespace AZ
}
else if (extension == "dds")
{
// write the read back result of the image attachment to a dds file
auto outcome = AZ::DdsFile::WriteFile(m_outputFilePath, { readbackResult.m_imageDescriptor.m_size,
readbackResult.m_imageDescriptor.m_format, readbackResult.m_dataBuffer.get() });
if (outcome.IsSuccess())
{
m_result = FrameCaptureResult::Success;
}
else
{
m_latestCaptureInfo = outcome.GetError().m_message;
m_result = FrameCaptureResult::InternalError;
}
const auto ddsFrameCapture = DdsFrameCaptureOutput(m_outputFilePath, readbackResult);
m_result = ddsFrameCapture.m_result;
m_latestCaptureInfo = ddsFrameCapture.m_errorMessage.value_or("");
}
else
{
@@ -42,10 +42,10 @@ namespace AZ
uint32_t m_ev100Index;
uint32_t m_nitIndex;
float m_ev100Min;
float m_ev100Max;
float m_nitMin;
float m_nitMax;
float m_ev100Min = 0.0f;
float m_ev100Max = 0.0f;
float m_nitMin = 0.0f;
float m_nitMax = 0.0f;
};
}
}
@@ -27,7 +27,7 @@ namespace AZ
if (auto* serialize = azrtti_cast<SerializeContext*>(context))
{
serialize->Class<MaterialConverterSystemComponent, Component>()
->Version(2)
->Version(3)
->Attribute(Edit::Attributes::SystemComponentTags, AZStd::vector<Crc32>({ AssetBuilderSDK::ComponentTags::AssetBuilder }));
}
}
@@ -42,15 +42,16 @@ namespace AZ
RPI::MaterialConverterBus::Handler::BusDisconnect();
}
bool MaterialConverterSystemComponent::ConvertMaterial(const AZ::SceneAPI::DataTypes::IMaterialData& materialData, RPI::MaterialSourceData& sourceData)
bool MaterialConverterSystemComponent::ConvertMaterial(
const AZ::SceneAPI::DataTypes::IMaterialData& materialData, RPI::MaterialSourceData& sourceData)
{
using namespace AZ::RPI;
// The source data for generating material asset
sourceData.m_materialType = GetMaterialTypePath();
auto handleTexture = [&materialData, &sourceData](const char* propertyTextureGroup, SceneAPI::DataTypes::IMaterialData::TextureMapType textureType)
{
auto handleTexture = [&materialData, &sourceData](
const char* propertyTextureGroup, SceneAPI::DataTypes::IMaterialData::TextureMapType textureType) {
MaterialSourceData::PropertyMap& properties = sourceData.m_properties[propertyTextureGroup];
const AZStd::string& texturePath = materialData.GetTexture(textureType);
@@ -61,14 +62,16 @@ namespace AZ
using namespace AzToolsFramework;
AZ::Data::AssetInfo sourceInfo;
AZStd::string watchFolder;
AssetSystemRequestBus::BroadcastResult(assetFound, &AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, texturePath.c_str(), sourceInfo, watchFolder);
AssetSystemRequestBus::BroadcastResult(
assetFound, &AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, texturePath.c_str(), sourceInfo,
watchFolder);
}
if (assetFound)
{
properties["textureMap"].m_value = texturePath;
}
else if(!texturePath.empty())
else if (!texturePath.empty())
{
AZ_Warning("AtomFeatureCommon", false, "Could not find asset '%s' for '%s'", texturePath.c_str(), propertyTextureGroup);
}
@@ -76,29 +79,54 @@ namespace AZ
handleTexture("specularF0", SceneAPI::DataTypes::IMaterialData::TextureMapType::Specular);
handleTexture("normal", SceneAPI::DataTypes::IMaterialData::TextureMapType::Normal);
handleTexture("baseColor", SceneAPI::DataTypes::IMaterialData::TextureMapType::BaseColor);
AZStd::optional<bool> useColorMap = materialData.GetUseColorMap();
// If the useColorMap property exists, this is a PBR material and the color should be set to baseColor.
if (useColorMap.has_value())
{
handleTexture("baseColor", SceneAPI::DataTypes::IMaterialData::TextureMapType::BaseColor);
}
else
{
// If it doesn't have the useColorMap property, then it's a non-PBR material and the baseColor
// texture needs to be set to the diffuse texture.
handleTexture("baseColor", SceneAPI::DataTypes::IMaterialData::TextureMapType::Diffuse);
}
auto toColor = [](const AZ::Vector3& v) { return AZ::Color::CreateFromVector3AndFloat(v, 1.0f); };
sourceData.m_properties["baseColor"]["color"].m_value = toColor(materialData.GetBaseColor());
AZStd::optional<AZ::Vector3> baseColor = materialData.GetBaseColor();
if (baseColor.has_value())
{
sourceData.m_properties["baseColor"]["color"].m_value = toColor(baseColor.value());
}
sourceData.m_properties["opacity"]["factor"].m_value = materialData.GetOpacity();
auto applyOptionalPropertiesFunc = [&sourceData](const auto& propertyGroup, const auto& propertyName, const auto& propertyOptional)
{
// Only set PBR settings if they were specifically set in the scene's data.
// Otherwise, leave them unset so the data driven default properties are used.
if (propertyOptional.has_value())
{
sourceData.m_properties[propertyGroup][propertyName].m_value = propertyOptional.value();
}
};
handleTexture("metallic", SceneAPI::DataTypes::IMaterialData::TextureMapType::Metallic);
sourceData.m_properties["metallic"]["factor"].m_value = materialData.GetMetallicFactor();
sourceData.m_properties["metallic"]["useTexture"].m_value = materialData.GetUseMetallicMap();
applyOptionalPropertiesFunc("metallic", "factor", materialData.GetMetallicFactor());
applyOptionalPropertiesFunc("metallic", "useTexture", materialData.GetUseMetallicMap());
handleTexture("roughness", SceneAPI::DataTypes::IMaterialData::TextureMapType::Roughness);
sourceData.m_properties["roughness"]["factor"].m_value = materialData.GetRoughnessFactor();
sourceData.m_properties["roughness"]["useTexture"].m_value = materialData.GetUseRoughnessMap();
applyOptionalPropertiesFunc("roughness", "factor", materialData.GetRoughnessFactor());
applyOptionalPropertiesFunc("roughness", "useTexture", materialData.GetUseRoughnessMap());
handleTexture("emissive", SceneAPI::DataTypes::IMaterialData::TextureMapType::Emissive);
sourceData.m_properties["emissive"]["intensity"].m_value = materialData.GetEmissiveIntensity();
sourceData.m_properties["emissive"]["color"].m_value = toColor(materialData.GetEmissiveColor());
sourceData.m_properties["emissive"]["useTexture"].m_value = materialData.GetUseEmissiveMap();
applyOptionalPropertiesFunc("emissive", "intensity", materialData.GetEmissiveIntensity());
applyOptionalPropertiesFunc("emissive", "useTexture", materialData.GetUseEmissiveMap());
handleTexture("ambientOcclusion", SceneAPI::DataTypes::IMaterialData::TextureMapType::AmbientOcclusion);
sourceData.m_properties["ambientOcclusion"]["useTexture"].m_value = materialData.GetUseAOMap();
applyOptionalPropertiesFunc("ambientOcclusion", "useTexture", materialData.GetUseAOMap());
return true;
}
@@ -113,9 +113,10 @@ namespace AZ
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_displayName, "Display Name", "Identifier used for display and selection")
->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_autoSelect, "Auto Select", "When true, the configuration is automatically selected when loaded")
->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_skyboxImageAsset, "Skybox Image Asset", "Skybox image asset reference")
->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_iblDiffuseImageAsset, "IBL Diffuse Image Asset", "IBL diffuse image asset reference")
->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_iblSpecularImageAsset, "IBL Specular Image Asset", "IBL specular image asset reference")
->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_skyboxImageAsset, "Skybox Image Asset", "Skybox image asset reference")
->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_alternateSkyboxImageAsset, "Skybox Image Asset (Alt)", "Alternate skybox image asset reference")
->DataElement(AZ::Edit::UIHandlers::Slider, &LightingPreset::m_skyboxExposure, "Skybox Exposure", "Skybox exposure")
->Attribute(AZ::Edit::Attributes::SoftMin, -5.0f)
->Attribute(AZ::Edit::Attributes::SoftMax, 5.0f)
@@ -34,6 +34,7 @@ namespace AZ
->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_displayName, "Display Name", "Identifier used for display and selection")
->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_autoSelect, "Auto Select", "When true, the configuration is automatically selected when loaded")
->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_modelAsset, "Model Asset", "Model asset reference")
->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_previewImageAsset, "Preview Image Asset", "Preview image asset reference")
;
}
}
@@ -107,12 +107,13 @@ namespace AZ
serializeContext->RegisterGenericType<AZStd::vector<LightConfig>>();
serializeContext->Class<LightingPreset>()
->Version(3)
->Version(4)
->Field("autoSelect", &LightingPreset::m_autoSelect)
->Field("displayName", &LightingPreset::m_displayName)
->Field("skyboxImageAsset", &LightingPreset::m_skyboxImageAsset)
->Field("iblSpecularImageAsset", &LightingPreset::m_iblSpecularImageAsset)
->Field("iblDiffuseImageAsset", &LightingPreset::m_iblDiffuseImageAsset)
->Field("iblSpecularImageAsset", &LightingPreset::m_iblSpecularImageAsset)
->Field("skyboxImageAsset", &LightingPreset::m_skyboxImageAsset)
->Field("alternateSkyboxImageAsset", &LightingPreset::m_alternateSkyboxImageAsset)
->Field("iblExposure", &LightingPreset::m_iblExposure)
->Field("skyboxExposure", &LightingPreset::m_skyboxExposure)
->Field("shadowCatcherOpacity", &LightingPreset::m_shadowCatcherOpacity)
@@ -132,6 +133,7 @@ namespace AZ
->Constructor<const LightingPreset&>()
->Property("autoSelect", BehaviorValueProperty(&LightingPreset::m_autoSelect))
->Property("displayName", BehaviorValueProperty(&LightingPreset::m_displayName))
->Property("alternateSkyboxImageAsset", BehaviorValueProperty(&LightingPreset::m_alternateSkyboxImageAsset))
->Property("skyboxImageAsset", BehaviorValueProperty(&LightingPreset::m_skyboxImageAsset))
->Property("iblSpecularImageAsset", BehaviorValueProperty(&LightingPreset::m_iblSpecularImageAsset))
->Property("iblDiffuseImageAsset", BehaviorValueProperty(&LightingPreset::m_iblDiffuseImageAsset))
@@ -152,7 +154,8 @@ namespace AZ
const Camera::Configuration& cameraConfig,
AZStd::vector<DirectionalLightFeatureProcessorInterface::LightHandle>& lightHandles,
Data::Instance<RPI::Material> shadowCatcherMaterial,
RPI::MaterialPropertyIndex shadowCatcherOpacityPropertyIndex) const
RPI::MaterialPropertyIndex shadowCatcherOpacityPropertyIndex,
bool enableAlternateSkybox) const
{
if (iblFeatureProcessor)
{
@@ -163,7 +166,8 @@ namespace AZ
if (skyboxFeatureProcessor)
{
skyboxFeatureProcessor->SetCubemap(RPI::StreamingImage::FindOrCreate(m_skyboxImageAsset));
auto skyboxAsset = (enableAlternateSkybox && m_alternateSkyboxImageAsset.GetId().IsValid()) ? m_alternateSkyboxImageAsset : m_skyboxImageAsset;
skyboxFeatureProcessor->SetCubemap(RPI::StreamingImage::FindOrCreate(skyboxAsset));
skyboxFeatureProcessor->SetCubemapExposure(m_skyboxExposure);
}
@@ -25,10 +25,11 @@ namespace AZ
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<ModelPreset>()
->Version(1)
->Version(2)
->Field("autoSelect", &ModelPreset::m_autoSelect)
->Field("displayName", &ModelPreset::m_displayName)
->Field("modelAsset", &ModelPreset::m_modelAsset)
->Field("previewImageAsset", &ModelPreset::m_previewImageAsset)
;
}
@@ -44,6 +45,7 @@ namespace AZ
->Property("autoSelect", BehaviorValueProperty(&ModelPreset::m_autoSelect))
->Property("displayName", BehaviorValueProperty(&ModelPreset::m_displayName))
->Property("modelAsset", BehaviorValueProperty(&ModelPreset::m_modelAsset))
->Property("previewImageAsset", BehaviorValueProperty(&ModelPreset::m_previewImageAsset))
;
}
}
-1
View File
@@ -68,7 +68,6 @@ ly_add_target(
ly_add_target(
NAME Atom_RHI.Private ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RHI.Private.fb7f322c8bdb42228d9e155c954f98bd.v0.1.0
FILES_CMAKE
atom_rhi_private_shared_files.cmake
INCLUDE_DIRECTORIES
@@ -51,6 +51,9 @@ namespace AZ
//! This class provides a platform agnostic interface for the creation
//! and manipulation of platform shader objects.
//! WARNING: The ShaderPlatformInterface objects are singletons and will be used to process multiple shader compilation jobs.
//! Do not store per-job configuration data in any ShaderPlatformInterface classes, as it may get stomped. Instead, pass
//! any per-job configuration on the call stack.
class ShaderPlatformInterface
{
public:
@@ -123,16 +126,17 @@ namespace AZ
const AZStd::string& functionName,
ShaderHardwareStage shaderStage,
const AZStd::string& tempFolderPath,
StageDescriptor& outputDescriptor) const = 0;
StageDescriptor& outputDescriptor,
const RHI::ShaderCompilerArguments& shaderCompilerArguments) const = 0;
//! Get the parameters (except warning related) from that platform interface, and the configuration files.
virtual AZStd::string GetAzslCompilerParameters() const = 0;
virtual AZStd::string GetAzslCompilerParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const = 0;
//! Get only the warning-related parameters from that platform interface.
virtual AZStd::string GetAzslCompilerWarningParameters() const = 0;
virtual AZStd::string GetAzslCompilerWarningParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const = 0;
//! Query whether the shaders are set to build with debug information
virtual bool BuildHasDebugInfo() const = 0;
virtual bool BuildHasDebugInfo(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const = 0;
//! Get the filename of include file to prefix shader programs with
virtual const char* GetAzslHeader(const AssetBuilderSDK::PlatformInfo& platform) const = 0;
@@ -142,23 +146,20 @@ namespace AZ
virtual bool BuildPipelineLayoutDescriptor(
RHI::Ptr<RHI::PipelineLayoutDescriptor> pipelineLayoutDescriptor,
const ShaderResourceGroupInfoList& srgInfoList,
const RootConstantsInfo& rootConstantsInfo) = 0;
const RootConstantsInfo& rootConstantsInfo,
const ShaderCompilerArguments& shaderCompilerArguments) = 0;
//! See AZ::RHI::Factory::GetAPIUniqueIndex() for details.
//! See AZ::RHI::Limits::APIType::PerPlatformApiUniqueIndexMax.
uint32_t GetAPIUniqueIndex() const { return m_apiUniqueIndex; }
//! To set when you can read from a config file: additional arguments or compiler settings
void SetExternalArguments(const ShaderCompilerArguments& arguments)
{
m_settings = arguments;
}
protected:
ShaderCompilerArguments m_settings;
private:
ShaderPlatformInterface() = delete;
//! WARNING: The ShaderPlatformInterface objects are singletons and will be used to process multiple shader compilation jobs.
//! Do not store per-job configuration data in any ShaderPlatformInterface classes, as it may get stomped. Instead, pass
//! any per-job configuration on the call stack.
const uint32_t m_apiUniqueIndex;
};
}
@@ -52,7 +52,7 @@ namespace AZ
{
const char* m_sourceFile;
const char* m_prependFile;
const char* m_addSuffixToFileName;
const char* m_addSuffixToFileName = nullptr; //!< optional
const char* m_destinationFolder = nullptr; //!< optional. if not set, will just use sourceFile's folder
AZStd::string* m_destinationStringOpt = nullptr; //!< when not null, PrependFile() will dump the result in that string rather than on disk.
ArrayOfCharForMd5* m_digest = nullptr; //! optionally run a hash
@@ -133,6 +133,7 @@ namespace AZ
P8,
A8P8,
B4G4R4A4_UNORM,
R4G4B4A4_UNORM,
R10G10B10_7E3_A2_FLOAT,
R10G10B10_6E4_A2_FLOAT,
D16_UNORM_S8_UINT,
+16 -7
View File
@@ -14,8 +14,8 @@
#include <AtomCore/Serialization/Json/JsonUtils.h>
#include <AzToolsFramework/Process/ProcessCommunicator.h>
#include <AzToolsFramework/Process/ProcessWatcher.h>
#include <AzFramework/Process/ProcessCommunicator.h>
#include <AzFramework/Process/ProcessWatcher.h>
#include <AzToolsFramework/Debug/TraceContext.h>
#include <AzCore/Component/ComponentApplicationBus.h>
@@ -176,7 +176,16 @@ namespace AZ
AZStd::string combinedFile;
if (arguments.m_destinationFolder)
{
combinedFile = arguments.m_destinationFolder;
AZStd::string filename;
if(AzFramework::StringFunc::Path::GetFullFileName(sourceFileAbsolutePath->c_str(), filename))
{
combinedFile = AZStd::string::format("%s/%s", arguments.m_destinationFolder, filename.c_str());
}
else
{
AZ_Error(ShaderPlatformInterfaceName, false, "GetFullFileName('%s') failed", sourceFileAbsolutePath->c_str());
return *sourceFileAbsolutePath;
}
}
else
{
@@ -248,10 +257,10 @@ namespace AZ
return false;
}
AzToolsFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
processLaunchInfo.m_commandlineParameters = AZStd::string::format("\"%s\" %s", executableAbsolutePath.c_str(), parameters.c_str());
processLaunchInfo.m_showWindow = true;
processLaunchInfo.m_processPriority = AzToolsFramework::PROCESSPRIORITY_NORMAL;
processLaunchInfo.m_processPriority = AzFramework::ProcessPriority::PROCESSPRIORITY_NORMAL;
{
AZStd::string contextKey = toolNameForLog + AZStd::string(" Input File");
@@ -263,14 +272,14 @@ namespace AZ
}
AZ_TracePrintf(ShaderPlatformInterfaceName, "Executing '%s' ...", processLaunchInfo.m_commandlineParameters.c_str());
AzToolsFramework::ProcessWatcher* watcher = AzToolsFramework::ProcessWatcher::LaunchProcess(processLaunchInfo, AzToolsFramework::COMMUNICATOR_TYPE_STDINOUT);
AzFramework::ProcessWatcher* watcher = AzFramework::ProcessWatcher::LaunchProcess(processLaunchInfo, AzFramework::COMMUNICATOR_TYPE_STDINOUT);
if (!watcher)
{
AZ_Error(ShaderPlatformInterfaceName, false, "Shader compiler could not be launched");
return false;
}
AZStd::unique_ptr<AzToolsFramework::ProcessWatcher> watcherPtr = AZStd::unique_ptr<AzToolsFramework::ProcessWatcher>(watcher);
AZStd::unique_ptr<AzFramework::ProcessWatcher> watcherPtr = AZStd::unique_ptr<AzFramework::ProcessWatcher>(watcher);
AZStd::string errorMessages;
auto pumpOuputStreams = [&watcherPtr, &errorMessages]()
+4 -6
View File
@@ -46,7 +46,6 @@ if(NOT PAL_TRAIT_ATOM_RHI_DX12_SUPPORTED)
ly_add_target(
NAME Atom_RHI_DX12.Private ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RHI_DX12.Private.e011969cf32442fdaac2443a960ab5ff.v0.1.0
FILES_CMAKE
atom_rhi_dx12_stub_module.cmake
BUILD_DEPENDENCIES
@@ -56,9 +55,9 @@ if(NOT PAL_TRAIT_ATOM_RHI_DX12_SUPPORTED)
if(PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_target(
NAME Atom_RHI_DX12.Builders MODULE
NAME Atom_RHI_DX12.Builders GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RHI_DX12.Builders.e011969cf32442fdaac2443a960ab5ff.v0.1.0
FILES_CMAKE
Source/Platform/${PAL_PLATFORM_NAME}/platform_builders_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
atom_rhi_dx12_reflect_common_files.cmake
@@ -136,7 +135,6 @@ ly_add_target(
ly_add_target(
NAME Atom_RHI_DX12.Private ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RHI_DX12.Private.e011969cf32442fdaac2443a960ab5ff.v0.1.0
FILES_CMAKE
atom_rhi_dx12_private_common_shared_files.cmake
INCLUDE_DIRECTORIES
@@ -182,9 +180,9 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
)
ly_add_target(
NAME Atom_RHI_DX12.Builders MODULE
NAME Atom_RHI_DX12.Builders GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RHI_DX12.Builders.e011969cf32442fdaac2443a960ab5ff.v0.1.0
FILES_CMAKE
atom_rhi_dx12_builders_common_shared_files.cmake
INCLUDE_DIRECTORIES
@@ -15,6 +15,7 @@
#include <RHI/NsightAftermathGpuCrashTracker_Windows.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/Utils/Utils.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzCore/Debug/EventTrace.h>
@@ -91,16 +92,8 @@ void GpuCrashTracker::OnDescription(PFN_GFSDK_Aftermath_AddGpuCrashDumpDescripti
// Add some basic description about the crash. This is called after the GPU crash happens, but before
// the actual GPU crash dump callback. The provided data is included in the crash dump and can be
// retrieved using GFSDK_Aftermath_GpuCrashDump_GetDescription().
AZ::SettingsRegistryInterface::FixedValueString projectName;
auto settingsRegistry = AZ::Interface<AZ::SettingsRegistryInterface>::Get();
auto projectKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/sys_game_folder", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey);
settingsRegistry->Get(projectName, projectKey);
static const char* executableFolder = nullptr;
AZStd::string fileAbsolutePath;
AZ::ComponentApplicationBus::BroadcastResult(executableFolder, &AZ::ComponentApplicationBus::Events::GetExecutableFolder);
AzFramework::StringFunc::Path::Join(executableFolder, projectName.c_str(), fileAbsolutePath);
fileAbsolutePath /= AZ::Utils::GetProjectName();
addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationName, fileAbsolutePath.c_str());
addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationVersion, "v1.0");
@@ -88,7 +88,8 @@ namespace AZ
bool ShaderPlatformInterface::BuildPipelineLayoutDescriptor(
RHI::Ptr<RHI::PipelineLayoutDescriptor> pipelineLayoutDescriptorBase,
const ShaderResourceGroupInfoList& srgInfoList,
const RootConstantsInfo& rootConstantsInfo)
const RootConstantsInfo& rootConstantsInfo,
const RHI::ShaderCompilerArguments& shaderCompilerArguments)
{
PipelineLayoutDescriptor* pipelineLayoutDescriptor = azrtti_cast<PipelineLayoutDescriptor*>(pipelineLayoutDescriptorBase.get());
AZ_Assert(pipelineLayoutDescriptor, "PipelineLayoutDescriptor should have been created by now");
@@ -116,7 +117,7 @@ namespace AZ
}
}
if (m_settings.m_dxcDisableOptimizations)
if (shaderCompilerArguments.m_dxcDisableOptimizations)
{
// When optimizations are disabled (-Od), all resources declared in the source file are available to all stages
// (when enabled only the resources which are referenced in a stage are bound to the stage)
@@ -148,7 +149,8 @@ namespace AZ
const AZStd::string& functionName,
RHI::ShaderHardwareStage shaderStage,
const AZStd::string& tempFolderPath,
StageDescriptor& outputDescriptor) const
StageDescriptor& outputDescriptor,
const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
AZStd::vector<uint8_t> shaderByteCode;
@@ -158,6 +160,7 @@ namespace AZ
tempFolderPath, // AP job temp folder
functionName, // name of function that is the entry point
shaderStage, // shader stage (vertex shader, pixel shader, ...)
shaderCompilerArguments,
shaderByteCode, // compiled shader output
outputDescriptor.m_byProducts); // dynamic branch count output & byproduct files
@@ -182,20 +185,20 @@ namespace AZ
return true;
}
AZStd::string ShaderPlatformInterface::GetAzslCompilerParameters() const
AZStd::string ShaderPlatformInterface::GetAzslCompilerParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
return m_settings.MakeAdditionalAzslcCommandLineString() +
return shaderCompilerArguments.MakeAdditionalAzslcCommandLineString() +
" --use-spaces --namespace=dx --root-const=128";
}
AZStd::string ShaderPlatformInterface::GetAzslCompilerWarningParameters() const
AZStd::string ShaderPlatformInterface::GetAzslCompilerWarningParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
return m_settings.MakeAdditionalAzslcWarningCommandLineString();
return shaderCompilerArguments.MakeAdditionalAzslcWarningCommandLineString();
}
bool ShaderPlatformInterface::BuildHasDebugInfo() const
bool ShaderPlatformInterface::BuildHasDebugInfo(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
return m_settings.m_dxcGenerateDebugInfo;
return shaderCompilerArguments.m_dxcGenerateDebugInfo;
}
const char* ShaderPlatformInterface::GetAzslHeader(const AssetBuilderSDK::PlatformInfo& platform) const
@@ -209,6 +212,7 @@ namespace AZ
const AZStd::string& tempFolder,
const AZStd::string& entryPoint,
const RHI::ShaderHardwareStage shaderStageType,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
AZStd::vector<uint8_t>& compiledShader,
ByProducts& byProducts) const
{
@@ -253,7 +257,7 @@ namespace AZ
}
// Compilation parameters
AZStd::string params = m_settings.MakeAdditionalDxcCommandLineString();
AZStd::string params = shaderCompilerArguments.MakeAdditionalDxcCommandLineString();
// Enable half precision types when shader model >= 6.2
int shaderModelMajor = 0;
@@ -267,13 +271,18 @@ namespace AZ
AZ::StringFunc::TrimWhiteSpace(params, true, false); // we don't need the extra leading spaces that tend to build up
unsigned char md5[RHI::Md5NumBytes];
RHI::PrependArguments args{ shaderSourceFile.c_str(), PlatformShaderHeader, "", tempFolder.c_str(), nullptr, &md5 };
RHI::PrependArguments args;
args.m_sourceFile = shaderSourceFile.c_str();
args.m_prependFile = PlatformShaderHeader;
args.m_destinationFolder = tempFolder.c_str();
args.m_digest = &md5;
const auto dxcInputFile = RHI::PrependFile(args); // Prepend PAL header & obtain hash
// -Fd "Write debug information to the given file, or automatically named file in directory when ending in '\\'"
// If we use the auto-name (hash), there is no way we can retrieve that name apart from listing the directory.
// Instead, let's just generate that hash ourselves.
AZStd::string symbolDatabaseFileCliArgument{" "}; // when not debug: still insert a space between 5.dxil and 7.hlsl-in
if (BuildHasDebugInfo())
if (BuildHasDebugInfo(shaderCompilerArguments))
{
// prepare .ldd filename:
AZStd::string md5hex = RHI::ByteToHexString(md5);
@@ -343,7 +352,7 @@ namespace AZ
byProducts.m_dynamicBranchCount = ByProducts::UnknownDynamicBranchCount;
}
if (BuildHasDebugInfo())
if (BuildHasDebugInfo(shaderCompilerArguments))
{
byProducts.m_intermediatePaths.emplace(AZStd::move(objectCodeOutputFile));
}
@@ -38,7 +38,8 @@ namespace AZ
bool BuildPipelineLayoutDescriptor(
RHI::Ptr<RHI::PipelineLayoutDescriptor> pipelineLayoutDescriptor,
const ShaderResourceGroupInfoList& srgInfoList,
const RootConstantsInfo& rootConstantsInfo) override;
const RootConstantsInfo& rootConstantsInfo,
const RHI::ShaderCompilerArguments& shaderCompilerArguments) override;
bool CompilePlatformInternal(
const AssetBuilderSDK::PlatformInfo& platform,
@@ -46,13 +47,14 @@ namespace AZ
const AZStd::string& functionName,
RHI::ShaderHardwareStage shaderStage,
const AZStd::string& tempFolderPath,
StageDescriptor& outputDescriptor) const override;
StageDescriptor& outputDescriptor,
const RHI::ShaderCompilerArguments& shaderCompilerArguments) const override;
AZStd::string GetAzslCompilerParameters() const override;
AZStd::string GetAzslCompilerParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const override;
AZStd::string GetAzslCompilerWarningParameters() const override;
AZStd::string GetAzslCompilerWarningParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const override;
bool BuildHasDebugInfo() const override;
bool BuildHasDebugInfo(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const override;
const char* GetAzslHeader(const AssetBuilderSDK::PlatformInfo& platform) const override;
@@ -64,6 +66,7 @@ namespace AZ
const AZStd::string& tempFolder,
const AZStd::string& entryPoint,
const RHI::ShaderHardwareStage shaderStageType,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
AZStd::vector<uint8_t>& m_byteCode,
ByProducts& products) const;
+4 -6
View File
@@ -17,7 +17,6 @@ include(${pal_source_dir}/PAL2_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
if(NOT PAL_TRAIT_ATOM_RHI_METAL_SUPPORTED)
ly_add_target(
NAME Atom_RHI_Metal.Private ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
OUTPUT_NAME Gem.Atom_RHI_Metal.Private.5f27cdc951e64fe0be9d823dc7acbc28.v0.1.0
NAMESPACE Gem
FILES_CMAKE
atom_rhi_metal_stub_module.cmake
@@ -35,8 +34,8 @@ if(NOT PAL_TRAIT_ATOM_RHI_METAL_SUPPORTED)
if(PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_target(
NAME Atom_RHI_Metal.Builders MODULE
OUTPUT_NAME Gem.Atom_RHI_Metal.Builders.5f27cdc951e64fe0be9d823dc7acbc28.v0.1.0
NAME Atom_RHI_Metal.Builders GEM_MODULE
NAMESPACE Gem
FILES_CMAKE
Source/Platform/${PAL_PLATFORM_NAME}/platform_builders_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
@@ -101,7 +100,6 @@ ly_add_target(
ly_add_target(
NAME Atom_RHI_Metal.Private ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RHI_Metal.Private.5f27cdc951e64fe0be9d823dc7acbc28.v0.1.0
FILES_CMAKE
atom_rhi_metal_private_common_shared_files.cmake
PLATFORM_INCLUDE_FILES
@@ -146,9 +144,9 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
)
ly_add_target(
NAME Atom_RHI_Metal.Builders MODULE
NAME Atom_RHI_Metal.Builders GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RHI_Metal.Builders.5f27cdc951e64fe0be9d823dc7acbc28.v0.1.0
FILES_CMAKE
atom_rhi_metal_builders_shared_files.cmake
PLATFORM_INCLUDE_FILES
@@ -60,7 +60,8 @@ namespace AZ
bool ShaderPlatformInterface::BuildPipelineLayoutDescriptor(
RHI::Ptr<RHI::PipelineLayoutDescriptor> pipelineLayoutDescriptor,
const ShaderResourceGroupInfoList& srgInfoList,
const RootConstantsInfo& rootConstantsInfo)
const RootConstantsInfo& rootConstantsInfo,
const RHI::ShaderCompilerArguments& shaderCompilerArguments)
{
AZ::Metal::PipelineLayoutDescriptor* metalDescriptor = azrtti_cast<AZ::Metal::PipelineLayoutDescriptor*>(pipelineLayoutDescriptor.get());
AZ_Assert(metalDescriptor, "PipelineLayoutDescriptor should have been created by now");
@@ -154,22 +155,22 @@ namespace AZ
return (shaderStageType == RHI::ShaderHardwareStage::RayTracing);
}
AZStd::string ShaderPlatformInterface::GetAzslCompilerParameters() const
AZStd::string ShaderPlatformInterface::GetAzslCompilerParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
// Note: all platforms use DirectX packing rules. We enable vk namespace as well to allow
// for vk syntax to carry through from dxc to spirv-cross.
return m_settings.MakeAdditionalAzslcCommandLineString() +
return shaderCompilerArguments.MakeAdditionalAzslcCommandLineString() +
" --use-spaces --unique-idx --namespace=mt,vk --root-const=128";
}
AZStd::string ShaderPlatformInterface::GetAzslCompilerWarningParameters() const
AZStd::string ShaderPlatformInterface::GetAzslCompilerWarningParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
return m_settings.MakeAdditionalAzslcWarningCommandLineString();
return shaderCompilerArguments.MakeAdditionalAzslcWarningCommandLineString();
}
bool ShaderPlatformInterface::BuildHasDebugInfo() const
bool ShaderPlatformInterface::BuildHasDebugInfo(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
return m_settings.m_dxcGenerateDebugInfo;
return shaderCompilerArguments.m_dxcGenerateDebugInfo;
}
const char* ShaderPlatformInterface::GetAzslHeader(const AssetBuilderSDK::PlatformInfo& platform) const
@@ -190,7 +191,8 @@ namespace AZ
const AZStd::string& functionName,
RHI::ShaderHardwareStage shaderStage,
const AZStd::string& tempFolderPath,
StageDescriptor& outputDescriptor) const
StageDescriptor& outputDescriptor,
const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
for (auto srgLayout : m_srgLayouts)
{
@@ -206,6 +208,7 @@ namespace AZ
tempFolderPath, // AP temp folder for the job
functionName, // name of function that is the entry point
shaderStage, // shader stage (vertex shader, pixel shader, ...)
shaderCompilerArguments,
shaderSourceCode, // cross-compiled shader output
shaderByteCode, // compiled byte code
platform, // target platform
@@ -241,6 +244,7 @@ namespace AZ
const AZStd::string& tempFolder,
const AZStd::string& entryPoint,
const RHI::ShaderHardwareStage shaderType,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
AZStd::vector<char>& sourceMetalShader,
AZStd::vector<uint8_t>& compiledByteCode,
const AssetBuilderSDK::PlatformInfo& platform,
@@ -275,7 +279,7 @@ namespace AZ
AZStd::string shaderSpirvOutputFile = RHI::BuildFileNameWithExtension(shaderSourceFile, tempFolder, "spirv");
// Compilation parameters
AZStd::string params = m_settings.MakeAdditionalDxcCommandLineString();
AZStd::string params = shaderCompilerArguments.MakeAdditionalDxcCommandLineString();
params += " -spirv"; // Generate SPIRV shader
// Enable half precision types when shader model >= 6.2
@@ -299,7 +303,10 @@ namespace AZ
prependFile = MacPlatformShaderHeader;
}
RHI::PrependArguments args{ shaderSourceFile.c_str(), prependFile.c_str(), "", tempFolder.c_str() };
RHI::PrependArguments args;
args.m_sourceFile = shaderSourceFile.c_str();
args.m_prependFile = prependFile.c_str();
args.m_destinationFolder = tempFolder.c_str();
const auto dxcInputFile = RHI::PrependFile(args);
if (BuildHasDebugInfo())
@@ -42,7 +42,8 @@ namespace AZ
bool BuildPipelineLayoutDescriptor(
RHI::Ptr<RHI::PipelineLayoutDescriptor> pipelineLayoutDescriptor,
const ShaderResourceGroupInfoList& srgInfoList,
const RootConstantsInfo& rootConstantsInfo) override;
const RootConstantsInfo& rootConstantsInfo,
const RHI::ShaderCompilerArguments& shaderCompilerArguments) override;
bool CompilePlatformInternal(
const AssetBuilderSDK::PlatformInfo& platform,
@@ -50,11 +51,12 @@ namespace AZ
const AZStd::string& functionName,
RHI::ShaderHardwareStage shaderStage,
const AZStd::string& tempFolderPath,
StageDescriptor& outputDescriptor) const override;
StageDescriptor& outputDescriptor,
const RHI::ShaderCompilerArguments& shaderCompilerArguments) const override;
AZStd::string GetAzslCompilerParameters() const;
AZStd::string GetAzslCompilerWarningParameters() const;
bool BuildHasDebugInfo() const override;
AZStd::string GetAzslCompilerParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const;
AZStd::string GetAzslCompilerWarningParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const;
bool BuildHasDebugInfo(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const override;
const char* GetAzslHeader(const AssetBuilderSDK::PlatformInfo& platform) const override;
@@ -66,6 +68,7 @@ namespace AZ
const AZStd::string& tempFolder,
const AZStd::string& entryPoint,
const RHI::ShaderHardwareStage shaderAssetType,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
AZStd::vector<char>& compiledShader,
AZStd::vector<uint8_t>& compiledByteCode,
const AssetBuilderSDK::PlatformInfo& platform,
+4 -6
View File
@@ -20,7 +20,6 @@ if(NOT PAL_TRAIT_ATOM_RHI_VULKAN_SUPPORTED)
ly_add_target(
NAME Atom_RHI_Vulkan.Private ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RHI_Vulkan.Private.150d40d376124d98a388dfe890551c03.v0.1.0
FILES_CMAKE
atom_rhi_vulkan_stub_module.cmake
INCLUDE_DIRECTORIES
@@ -36,9 +35,9 @@ if(NOT PAL_TRAIT_ATOM_RHI_VULKAN_SUPPORTED)
if(PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_target(
NAME Atom_RHI_Vulkan.Builders MODULE
NAME Atom_RHI_Vulkan.Builders GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RHI_Vulkan.Builders.150d40d376124d98a388dfe890551c03.v0.1.0
FILES_CMAKE
${pal_source_dir}/platform_builders_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
atom_rhi_vulkan_reflect_common_files.cmake
@@ -117,7 +116,6 @@ ly_add_target(
ly_add_target(
NAME Atom_RHI_Vulkan.Private ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RHI_Vulkan.Private.150d40d376124d98a388dfe890551c03.v0.1.0
FILES_CMAKE
atom_rhi_vulkan_private_common_shared_files.cmake
INCLUDE_DIRECTORIES
@@ -176,9 +174,9 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
)
ly_add_target(
NAME Atom_RHI_Vulkan.Builders MODULE
NAME Atom_RHI_Vulkan.Builders GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RHI_Vulkan.Builders.150d40d376124d98a388dfe890551c03.v0.1.0
FILES_CMAKE
${pal_source_dir}/platform_builders_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES
@@ -87,30 +87,32 @@ namespace AZ
bool ShaderPlatformInterface::BuildPipelineLayoutDescriptor(
RHI::Ptr<RHI::PipelineLayoutDescriptor> pipelineLayoutDescriptor,
const ShaderResourceGroupInfoList& srgInfoList,
const RootConstantsInfo& rootConstantsInfo)
const RootConstantsInfo& rootConstantsInfo,
const RHI::ShaderCompilerArguments& shaderCompilerArguments)
{
AZ_UNUSED(srgInfoList);
AZ_UNUSED(rootConstantsInfo);
AZ_UNUSED(shaderCompilerArguments);
// Nothing to do, so we just finalize the layout descriptor.
return pipelineLayoutDescriptor->Finalize() == RHI::ResultCode::Success;
}
AZStd::string ShaderPlatformInterface::GetAzslCompilerParameters() const
AZStd::string ShaderPlatformInterface::GetAzslCompilerParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
// Note: all platforms use DirectX packing rules.
return m_settings.MakeAdditionalAzslcCommandLineString() +
return shaderCompilerArguments.MakeAdditionalAzslcCommandLineString() +
" --use-spaces --unique-idx --namespace=vk --root-const=128";
}
AZStd::string ShaderPlatformInterface::GetAzslCompilerWarningParameters() const
AZStd::string ShaderPlatformInterface::GetAzslCompilerWarningParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
return m_settings.MakeAdditionalAzslcWarningCommandLineString();
return shaderCompilerArguments.MakeAdditionalAzslcWarningCommandLineString();
}
bool ShaderPlatformInterface::BuildHasDebugInfo() const
bool ShaderPlatformInterface::BuildHasDebugInfo(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
return m_settings.m_dxcGenerateDebugInfo;
return shaderCompilerArguments.m_dxcGenerateDebugInfo;
}
const char* ShaderPlatformInterface::GetAzslHeader(const AssetBuilderSDK::PlatformInfo& platform) const
@@ -133,7 +135,8 @@ namespace AZ
const AZStd::string& functionName,
RHI::ShaderHardwareStage shaderAssetType,
const AZStd::string& tempFolderPath,
StageDescriptor& outputDescriptor) const
StageDescriptor& outputDescriptor,
const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
AZStd::vector<uint8_t> shaderByteCode;
@@ -143,6 +146,7 @@ namespace AZ
tempFolderPath, // AP temp folder for the job
functionName, // name of function that is the entry point
shaderAssetType, // shader stage (vertex shader, pixel shader, ...)
shaderCompilerArguments,
shaderByteCode, // compiled shader output
platform, // target platform
outputDescriptor.m_byProducts); // dynamic branch count output & debug dumps
@@ -174,6 +178,7 @@ namespace AZ
const AZStd::string& tempFolder,
const AZStd::string& entryPoint,
const RHI::ShaderHardwareStage shaderStageType,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
AZStd::vector<uint8_t>& compiledShader,
const AssetBuilderSDK::PlatformInfo& platform,
ByProducts& byProducts) const
@@ -215,7 +220,7 @@ namespace AZ
}
// Compilation parameters
AZStd::string params = m_settings.MakeAdditionalDxcCommandLineString();
AZStd::string params = shaderCompilerArguments.MakeAdditionalDxcCommandLineString();
params += " -spirv"; // Generate SPIRV shader
switch (shaderStageType)
@@ -273,10 +278,13 @@ namespace AZ
prependFile = WindowsPlatformShaderHeader;
}
RHI::PrependArguments args{ shaderSourceFile.c_str(), prependFile.c_str(), "", tempFolder.c_str() };
RHI::PrependArguments args;
args.m_sourceFile = shaderSourceFile.c_str();
args.m_prependFile = prependFile.c_str();
args.m_destinationFolder = tempFolder.c_str();
const auto dxcInputFile = RHI::PrependFile(args); // Prepend header
if (BuildHasDebugInfo())
if (BuildHasDebugInfo(shaderCompilerArguments))
{
// dump intermediate "true final HLSL" file (shadername.vulkan.shadersource.prepend)
byProducts.m_intermediatePaths.insert(dxcInputFile);
@@ -329,7 +337,7 @@ namespace AZ
byProducts.m_dynamicBranchCount = ByProducts::UnknownDynamicBranchCount;
}
if (BuildHasDebugInfo())
if (BuildHasDebugInfo(shaderCompilerArguments))
{
byProducts.m_intermediatePaths.emplace(AZStd::move(objectCodeOutputFile));
}
@@ -42,7 +42,8 @@ namespace AZ
bool BuildPipelineLayoutDescriptor(
RHI::Ptr<RHI::PipelineLayoutDescriptor> pipelineLayoutDescriptor,
const ShaderResourceGroupInfoList& srgInfoList,
const RootConstantsInfo& rootConstantsInfo) override;
const RootConstantsInfo& rootConstantsInfo,
const RHI::ShaderCompilerArguments& shaderCompilerArguments) override;
bool CompilePlatformInternal(
const AssetBuilderSDK::PlatformInfo& platform,
@@ -50,11 +51,12 @@ namespace AZ
const AZStd::string& functionName,
RHI::ShaderHardwareStage shaderStage,
const AZStd::string& tempFolderPath,
StageDescriptor& outputDescriptor) const override;
StageDescriptor& outputDescriptor,
const RHI::ShaderCompilerArguments& shaderCompilerArguments) const override;
AZStd::string GetAzslCompilerParameters() const override;
AZStd::string GetAzslCompilerWarningParameters() const override;
bool BuildHasDebugInfo() const override;
AZStd::string GetAzslCompilerParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const override;
AZStd::string GetAzslCompilerWarningParameters(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const override;
bool BuildHasDebugInfo(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const override;
const char* GetAzslHeader(const AssetBuilderSDK::PlatformInfo& platform) const override;
@@ -66,6 +68,7 @@ namespace AZ
const AZStd::string& tempFolder,
const AZStd::string& entryPoint,
const RHI::ShaderHardwareStage shaderAssetType,
const RHI::ShaderCompilerArguments& shaderCompilerArguments,
AZStd::vector<uint8_t>& compiledShader,
const AssetBuilderSDK::PlatformInfo& platform,
ByProducts& byProducts) const;
@@ -91,6 +91,7 @@
_Func(P010, VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, 1, 0, 0) \
_Func(P016, VK_FORMAT_G16_B16R16_2PLANE_420_UNORM, 1, 0, 0) \
_Func(B4G4R4A4_UNORM, VK_FORMAT_B4G4R4A4_UNORM_PACK16, 1, 0, 0) \
_Func(R4G4B4A4_UNORM, VK_FORMAT_R4G4B4A4_UNORM_PACK16, 1, 0, 0) \
_Func(D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, 0, 1, 1) \
_Func(EAC_R11_UNORM, VK_FORMAT_EAC_R11_UNORM_BLOCK, 1, 0, 0) \
_Func(EAC_R11_SNORM, VK_FORMAT_EAC_R11_SNORM_BLOCK, 1, 0, 0) \
+6 -7
View File
@@ -36,7 +36,6 @@ ly_add_target(
ly_add_target(
NAME Atom_RPI.Private ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RPI.Private.a218db9eb2114477b46600fea4441a6c.v0.1.0
FILES_CMAKE
atom_rpi_private_files.cmake
INCLUDE_DIRECTORIES
@@ -96,9 +95,9 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
)
ly_add_target(
NAME Atom_RPI.Editor MODULE
NAME Atom_RPI.Editor GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RPI.Editor.a218db9eb2114477b46600fea4441a6c.v0.1.0
FILES_CMAKE
atom_rpi_editor_files.cmake
INCLUDE_DIRECTORIES
@@ -165,9 +164,9 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
# Create a stub
ly_add_target(
NAME Atom_RPI.Builders MODULE
NAME Atom_RPI.Builders GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RPI.Builders.a218db9eb2114477b46600fea4441a6c.v0.1.0
FILES_CMAKE
atom_rpi_builders_stub_files.cmake
INCLUDE_DIRECTORIES
@@ -209,9 +208,9 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
)
ly_add_target(
NAME Atom_RPI.Builders MODULE
NAME Atom_RPI.Builders GEM_MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.Atom_RPI.Builders.a218db9eb2114477b46600fea4441a6c.v0.1.0
FILES_CMAKE
atom_rpi_builders_shared_files.cmake
INCLUDE_DIRECTORIES
@@ -50,7 +50,7 @@ namespace AZ
{
AssetBuilderSDK::AssetBuilderDesc materialBuilderDescriptor;
materialBuilderDescriptor.m_name = JobKey;
materialBuilderDescriptor.m_version = 105; // ATOM-6239
materialBuilderDescriptor.m_version = 107; // ATOM-14918
materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.material", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.materialtype", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
materialBuilderDescriptor.m_busId = azrtti_typeid<MaterialBuilder>();
@@ -91,7 +91,7 @@ namespace AZ
if (auto* serialize = azrtti_cast<SerializeContext*>(context))
{
serialize->Class<MaterialAssetBuilderComponent, SceneAPI::SceneCore::ExportingComponent>()
->Version(13); // [ATOM-13410]
->Version(14); // [ATOM-13410]
}
}

Some files were not shown because too many files have changed in this diff Show More