PowerVR GE8320 GPUScene 문제

PowerVR GE8320 GPU 사용 기기만 Point Light 계산이 정상적이지 않고 깨지는 현상이 있습니다.

<br/>

RenderDoc 에서 확인 결과 LocalLight 계산 시 사용하는 LightingChannelMask 값을 PrimitiveData.Flags 에서 추출하는데 이 Flags 값이 쓰레기 값이 들어 있는 것으로 보여집니다.

GPUScene 을 끄면 렌더링 문제가 없습니다.

<br/>

해당 GPU 에서 GPUScene 사용 시 SSBO 사이즈 문제가 있다는 것은 알고 있지만 해당 문제는 그 문제와 별개로 보여 문의 드립니다.

<br/>

해당 기기에서 캡쳐한 rdc 파일 첨부합니다.

안녕하세요.

문의 주신 이슈에 대해 확인 후 답변드리겠습니다.

감사합니다.

안녕하세요.

제보해 주신 PowerVR GE8xxx 환경에서의 Point Light 렌더링 이상 건에 대해 확인한 내용을 공유드립니다.

현재로서 가장 가능성이 높은 원인은, 픽셀 셰이더가 프리미티브 채널 마스크(LightingChannelMask) 를 만들기 위해 참조하는 PrimitiveData.Flags 를 잘못된 레이아웃/인덱스로 읽는 경우입니다.

PowerVR에서는 픽셀 셰이더가 UBO(배치) 레이아웃을 가정해 PrimitiveData.Flags를 읽는데, 런타임으로 전달된 PrimitiveId가 GPUScene ‘전역 ID’여서 UBO를 잘못 인덱싱했고, 그 결과 LightingChannelMask가 0처럼 나와 Point/Local Light가 스킵된 것으로 추측됩니다.

정확한 원인 규명을 위해 담당 엔지니어에게 공식 버그 리포트를 제출했습니다. 추후 관련 내용이 있다면 전달드리겠습니다.

감사합니다.

안녕하세요.

공유해 주신 사례는 내부에 버그 리포트(Unreal Engine Issues and Bug Tracker (UE\-328252\))로 등록했고, 저희 쪽에서도 별도로 추가 테스트를 진행해 보고자 합니다.

현재 이슈가 전체 렌더링의 색상이 이상한 것인지, 특정 픽셀에서만 값이 비정상적으로 나오는 것인지를 구체적으로 알려주시면 큰 도움이 되겠습니다.

또한 RenderDoc 캡처에서 문제가 드러나는 프레임 번호와 픽셀 좌표, 그리고 해당 픽셀을 그리는 드로우 호출의 EID를 부탁드립니다.

그리고 이번 테스트가 RenderDoc에서 셰이더를 편집하여 리플레이하신 것인지, 아니면 엔진의 usf/ush를 수정 후 재빌드하신 것인지 알려주시면 감사하겠습니다. 후자의 경우에는 실제 실행 중인 셰이더 퍼뮤테이션이 맞는지 확인이 필요하므로, 문제 픽셀 셰이더 초반에 임시로 고정 색(return float4(1,0,1,1);)을 출력해 화면이 즉시 변하는지로 검증을 부탁드립니다.

가능하시다면, 정확한 원인 파악을 위한 짧은 두 가지 진단도 부탁드립니다.

1. 프리미티브 마스크 경로가 원인인지 정확하게 판단하기 위해 primitiveMask = 7u 를 채널 판정 직전에 임시로 강제하여 로컬 라이트가 즉시 복구되는지 확인 부탁드립니다.

2. UBO 경로라면 일시적으로 base = 0u; flags = floatBitsToUint(BatchedPrimitive[0].w); 처럼 slot[0]만 읽도록 고정했을 때 픽셀 전반에 동일 값이 나오는지 보고, 이후 다시 base = PrimitiveId * 32u 로 되돌렸을 때 증상이 재현되는지 비교해 주세요. 이 테스트는 전역 ID가 배치 UBO 인덱싱에 쓰였는지 확인하려는 목적입니다.

위 정보와 캡처를 공유해 주시면 문제 원인 파악에 큰 도움이 될 것 같습니다.

감사합니다.

안녕하세요. 해당 이슈는 모든 픽셀에 대해 문제가 발생합니다. RenderDoc 쉐이더 편집 및 usf, ush 파일 편집 모두 동일하게 이슈가 발생합니다. 말씀하신대로 초반에 임시로 고정된 색상 출력은 문제 없이 출력됩니다. (후자의 경우 쉐이더 수정 후 빌드 과정이 필요한데 즉시 변한다는 표현이 잘 이해가 가지 않습니다.)

BatchedPrimitive[0] 을 강제로 읽게 해도 문제가 발생했습니다.

감사합니다.

안녕하세요.

추가 정보 공유 감사합니다. 말씀해 주신 것처럼 “모든 픽셀에서 동일하게” 문제가 발생하고, RenderDoc 셰이더 편집과 usf/ush 수정 후 빌드 모두에서 동일 증상이 보였으며, 픽셀 셰이더 초반의 고정 색 출력은 정상적으로 적용되는 점 확인했습니다. 참고로 제가 앞서 말씀드린 “즉시 변한다”는 표현은 RenderDoc 편집 리플레이 상황을 의미했습니다.

원인을 정확히 특정하려면, 이전에 공유해 주신 RenderDoc 캡처에서 문제가 발생하는 드로우 호출의 EID를 지정해 주시면 도움이 될 것 같습니다. 만약 EID 지정이 어렵다면, 문제가 보이는 화면의 스크린샷을 알려주시면 캡처 파일과 대조하여 동일 지점을 검토하겠습니다.

또한 BatchedPrimitive[0] 고정 읽기에도 동일 증상이라고 하셨으므로, 인덱싱만의 문제로 보긴 어렵습니다. 같은 EID 기준으로 아래 간단한 두 가지만 추가 확인 부탁드립니다.

  1. 채널 판정 우회: 채널 판정 직전에 primitiveMask = 7u; 를 임시로 강제했을 때 로컬 라이트가 복구되는지 여부
  2. 값 확인 스냅샷: 같은 픽셀에서 Flags 원시값(16진수면 더 좋습니다) 과 거기서 계산된 primitiveMask 값을 화면에 출력하거나(후처리/블렌딩은 잠시 비활성화), RenderDoc의 UBO/SSBO 뷰에서 해당 인덱스의 슬롯 값을 캡처해 보내주시면 분석에 큰 도움이 됩니다.

요청드린 EID와 함께 스크린 샷을 보내주시면 도움이 될 것 같습니다.

감사합니다.

안녕하세요.

확인 후 답변드리겠습니다.

감사합니다.

안녕하세요.

첨부해주신 모든 패키지들을 갤럭시 A12에서 테스트 했지만 동일한 이슈를 동일하게 재현하기 어려웠습니다.

또한 첨부해주신 렌더독에서는 함께 첨부하신 이미지와 다른 결과가 보여집니다.

[Image Removed]현재 발생하는 이슈는 PowerVR + GPUScene 조합에서 PrimitiveId 인덱싱이 꼬이면서 LightingChannelMask가 잘못 읽히는 드라이버/엔진 상호작용 문제로 추측됩니다.

해당 이슈가 최신 렌더독 버전에서도 동일하게 발생하는지 확인 부탁드리겠습니다.

감사합니다.

안녕하세요.

문의 주신 이슈는 테스트 중이신 기기가 비교적 오래된 PowerVR 기반 디바이스라, 기기의 드라이버 이슈로 인해서 렌더링 이슈가 발생할 가능성이 있습니다.

GPUScene은 렌더링에 필요한 프리미티브 데이터를 큰 GPU 버퍼에 미리 올려두고, CPU가 매 드로우마다 해당 데이터를 다시 세팅하고 업로드하지 않도록 해서 변경된 프리미티브만 선택적으로 업데이트하게 만들어 렌더 스레드와 드라이버 호출을 줄여 주는 최적화 기능입니다.

다만 저사양 모바일 기기의 경우에는 GPU 성능이 낮아 보통 GPU가 먼저 병목이 되는 경우가 많고, 모바일 콘텐츠 자체도 이미 많이 단순화되어 있는 경우가 많아서, GPUScene이 가져다주는 CPU 측 성능 이득은 상대적으로 크지 않은 반면, 셰이더에서 한 번 더 테이블을 인덱싱해서 데이터를 읽어야 하는 오버헤드는 그대로 존재하게 됩니다.

이러한 이유로, 현재로서는 해당 기기에서 GPUScene을 비활성화하여 우회하시는 방법을 우선 권장드립니다. 모바일에서는 콘솔 명령어 r.Mobile.SupportGPUScene 0 을 사용하여 GPUScene을 비활성화하실 수 있습니다.

다만 GPUScene을 끄면 드로우 콜과 CPU 부하가 다소 늘어날 수 있으니, 비활성화 후 해당 기기에서 한 번 성능을 점검해 보시면 좋겠습니다.

SceneDepth는 별도의 케이스로 다시 올려주시면 감사하겠습니다.

감사합니다.

안녕하세요 확인 감사합니다. 말씀하신 내용을 보면 BatchedPrimitive 정보는 정상적으로 기록됐지만 PrimitiveID 가 잘못된 값으로 읽히고 있어 문제가 스킵되는거 같다고 하셨는데요. 임의로 쉐이더 코드를 수정해보면서 테스트 했을 때 명시적으로 BatchedPrimtive.Flags 값을 모두 1u 로 설정하고 PrimitiveID 0번 째 데이터만 사용하게 변경해도 일관된 값이 아닌 픽셀마다 서로 다른 값이 출력됐는데 이것도 말씀하신 내용과 연관이 있을까요?

추후 관련 내용 전달 기다리고 있겠습니다. 감사합니다.

준비되는 대로 첨부하겠습니다.

테스트 케이스 더 자세히 전달 드리겠습니다.

Case 1

MobileLightingCommon.ush, 617

#if !MOBILE_DEFERRED_LIGHTING

// Check lighting channels for mobile forward

//if ((UnpackLightingChannelMask(LocalLight) & LightingChannelMask) == 0)

//{

// continue;

//}

#endif

해당 부분 제거 (LightingChannelMask 사용하지 않음)

- LightingChannelMask 부분이 렌더링 오류를 유발

- 해당 빌드 정상적으로 출력

Case 2

LightData.ush, 219

uint UnpackLightingChannelMask(FLocalLightData In)

{

uint Mask = LIGHTING_CHANNEL_MASK << 8;

//uint Mask = 1792;

const uint LightTypeAndPackedShadowMapChannelMask = asuint(Mask);

return UnpackLightingChannelMask(LightTypeAndPackedShadowMapChannelMask);

}

In.LightDirectionAndShadowMask.w = 7u; 로 고정

- asuint() 의심

- 해당 빌드 렌더링 이슈 발생

Case 3

MobileLightingCommon.ush, 617

#if !MOBILE_DEFERRED_LIGHTING

// Check lighting channels for mobile forward

if ((UnpackLightingChannelMask(LocalLight) & 0x7) == 0)

{

continue;

}

#endif

LightingChannelMask 를 0x7로 변경

- LightingChannelMask 값 이상 의심

- 해당 빌드 렌더링 이슈 없음

- LightingChannelMask 문제로 확인됨

Case 4

MobileBasePassPixelShader.usf, 986

//uint LightingChannelMask = GetPrimitive_LightingChannelMask(MaterialParameters.PrimitiveId);

uint LightingChannelMask = GetPrimitive_LightingChannelMask(0);

AccumulateLightGridLocalLighting(CulledLightGridHeader, GBuffer, MaterialParameters.WorldPosition_CamRelative, CameraVector, EyeIndex, 0, LocalLightDynamicShadowFactors, LightingChannelMask, DirectLighting);

- MaterialParameters.PrimitiveId 를 0 으로 강제 설정

- 해당 빌드에서 정상적으로 출력

- MaterialParameters.PrimitiveId 가 문제인 것으로 보임

Case 5

LocalVertexFactory.ush, 1175

//SetPrimitiveId(Interpolants, Intermediates.Common.SceneData.PrimitiveId);

SetPrimitiveId(Interpolants, 0);

- VS 에서 전달되는 PrimitiveId 를 강제로 0 설정

- 해당 빌드 렌더링 이슈 발생

VertexInterpolants 로 넘어오는 PrimitiveId 값이 뭔가 잘못되는 것으로 보여집니다.

안녕하세요.

저희는 현재 Realme, OPPO 같은 중국 제조사 디바이스에서 해당 현상을 확인 했습니다.

지금 테스트 기기로는 Realme C2 기기를 사용 중입니다.

언급해주신 Galaxy A12 에서도 추가로 확인해보겠습니다.

직전에 첨부한 렌더독은 v1.40 에서 확인 했었고 지금 현재 최신인 v1.41 에서도 확인 결과 동일한 문제가 확인됩니다.

Realme C2, Android_ASTC_Default 패키지, RenderDoc v1.41 버전입니다. [Image Removed]

추가로 이전 Case5 에서 LocalVertexFactory 에서 PrimitiveId 를 강제로 0으로 설정하면 0번 PrimitiveId 의 LightingChannelMask 값만 읽을거 같은데도 문제가 발생한 것 보면 PrimtiveId 가 꼬이지 않더라도 문제가 발생할 수 있을거 같습니다.

안녕하세요. Galaxy A12 에서 확인 결과 Lighting Channel 및 GPUScene 관련 문제는 없어보입니다.

기존에 테스트 했던 Realme C2 가 OpenGL ES 3.2 build 1.10@5130912. 이고 Galaxy A12 가 OpenGL ES 3.2 build 1.13@5776728. 로 버전업 되면서 문제가 해결된 것으로 보입니다.

다만 A12 기기에선 SceneDepth 사용 시 깨지는 문제가 발생하고 있는데 해당 부분도 같이 확인 가능할까요?