Direct3D12 ROV を試してみる (3) 半透明ソートと Intel HD Graphics

DirectX12 / DirectX11.3 の ROV のテストです。
前回はこちら→ 「Direct3D12 ROV を試してみる (2) Depth Test と半透明ソート

やっと Intel HD Graphics でも動くようになりました。

dx12_rov_suzanne01.png

↑Celeron N3150 Braswell Intel HD Graphics (Gen8) 使用

Intel HD Graphcis で問題だったのは PipelineState 生成時にエラーになることです。いろいろ試した結果 Shader に原因があることが判明。理由はよくわかっていませんが if 文中の代入を無くし、同等の加算に置き換えることで回避出来ました。GeForce では元のままで問題ありませんでした。

zstack_x= pz;
stack_x= color_enc;

↓ Intel HD Graphics

zstack_x*= 1e-32f;
zstack_x+= pz;
stack_x*= 0;
stack_x+= color_enc;

あとは Typed UAV を使わずに展開しています。シェーダーは下記の通り。

// hlsl
struct PS_OUT   {
    float4  Color   :   SV_Target;
};

RasterizerOrderedTexture2D    UColor  : register( u0 );
RasterizerOrderedTexture2D   UDepth  : register( u1 );
RasterizerOrderedTexture2D    UStack  : register( u2 );
RasterizerOrderedTexture2D   UZStack : register( u3 );

PS_OUT  pmain( VS_OUT pin, float4 pos : SV_Position )
{
    PS_OUT  pout;
    float3  Light= normalize( float3( 0.0f, -0.5f, -1.0f ) );
    float3  normal= normalize( pin.Normal );

    float3  cp= normalize( float3(0.0f, 0.0f, -120.0f) - pin.WPos.xyz );
    float3  hv= normalize( cp.xyz + Light.xyz );
    float3  specular= pow( saturate( dot( hv, normal ) ), 82.0f ) * saturate( Color.xyz + float3(0.6f, 0.6f, 0.6f) );
    float   diffuse= saturate( max( dot( normal, Light ), 0.0f ) + 0.2f );

    float4  color;
    color.xyz= Color.xyz * diffuse + specular;
    color.w= Color.w;
    pout.Color= color;

    float   pz= pos.z;
    uint2   addr2x= uint2( pos.xy );
    addr2x.x*= 4;
    uint2   addr2y= uint2( addr2x.x + 1, addr2x.y );
    uint2   addr2z= uint2( addr2x.x + 2, addr2x.y );
    uint2   addr2w= uint2( addr2x.x + 3, addr2x.y );

    uint    color_enc= EncodeColor( color );
    uint    stack_x= UStack[addr2x];
    uint    stack_y= UStack[addr2y];
    uint    stack_z= UStack[addr2z];
    uint    stack_w= UStack[addr2w];
    float   zstack_x= UZStack[addr2x];
    float   zstack_y= UZStack[addr2y];
    float   zstack_z= UZStack[addr2z];
    float   zstack_w= UZStack[addr2w];
    if( pz < zstack_w ){
        zstack_w*= 1e-32f;
        zstack_w+= pz;
        stack_w*= 0;
        stack_w+= color_enc;
    }
    if( pz < zstack_z ){
        zstack_w= zstack_z;
        stack_w= stack_z;
        zstack_z*= 1e-32f;
        zstack_z+= pz;
        stack_z*= 0;
        stack_z+= color_enc;
    }
    if( pz < zstack_y ){
        zstack_z= zstack_y;
        stack_z= stack_y;
        zstack_y*= 1e-32f;
        zstack_y+= pz;
        stack_y*= 0;
        stack_y+= color_enc;
    }
    if( pz < zstack_x ){
        zstack_y= zstack_x;
        stack_y= stack_x;
        zstack_x*= 1e-32f;
        zstack_x+= pz;
        stack_x*= 0;
        stack_x+= color_enc;
    }
    UStack[addr2x]= stack_x;
    UStack[addr2y]= stack_y;
    UStack[addr2z]= stack_z;
    UStack[addr2w]= stack_w;
    UZStack[addr2x]= zstack_x;
    UZStack[addr2y]= zstack_y;
    UZStack[addr2z]= zstack_z;
    UZStack[addr2w]= zstack_w;

    return  pout;
}

関連エントリ
Direct3D12 ROV を試してみる (2) Depth Test と半透明ソート
Direct3D12 ROV (Rasterizer Order View) を試してみる
3D 低レベル API の違い Direct3D 12/Metal
Direct3D 12 GeForce GTX970 は FeatureLevel 12_1 対応、Resource Bind/Heap Tier は低い
3D 低レベル API の現状 Direct3D 12/Metal