@@ -72,8 +72,7 @@ namespace {
7272
7373 // Standard shading rates
7474 enum ShadingRates {
75- SHADING_RATE_CULL,
76- SHADING_RATE_x16,
75+ SHADING_RATE_x16 = 0 ,
7776 SHADING_RATE_x8,
7877 SHADING_RATE_x4,
7978 SHADING_RATE_x2,
@@ -84,6 +83,7 @@ namespace {
8483 SHADING_RATE_4x2,
8584 SHADING_RATE_2x4,
8685 SHADING_RATE_4x4,
86+ SHADING_RATE_CULL,
8787 SHADING_RATE_COUNT
8888 };
8989
@@ -105,7 +105,7 @@ namespace {
105105 // The number of frames since the mask was last used during a rendering pass.
106106 uint16_t age;
107107
108- std::shared_ptr<IShaderBuffer> cbShading[ViewCount + 1 ];
108+ std::shared_ptr<IShaderBuffer> cbShading[ViewCount + 2 ];
109109 std::shared_ptr<ITexture> mask[ViewCount + 1 ];
110110 std::shared_ptr<ITexture> maskDoubleWide;
111111 std::shared_ptr<ITexture> maskTextureArray;
@@ -871,17 +871,24 @@ namespace {
871871 // Draw the rings into the mask.
872872 const auto dispatchX = xr::math::DivideRoundingUp (mask.widthInTiles , 8 );
873873 const auto dispatchY = xr::math::DivideRoundingUp (mask.heightInTiles , 8 );
874- for (size_t i = 0 ; i < std::size (mask.mask ); i++) {
875- const auto constants = makeShadingConstants (i, mask.widthInTiles , mask.heightInTiles );
874+ for (size_t i = 0 ; i < std::size (mask.mask ) + 1 ; i++) {
875+ size_t target = std::min (i, std::size (mask.mask ) - 1 );
876+ size_t eye = i;
877+ ShadingConstants constants;
878+ if (m_usingEyeTracking) {
879+ // The combined mask has both eyes.
880+ eye = eye % 2 ;
881+ }
882+ constants = makeShadingConstants (eye, mask.widthInTiles , mask.heightInTiles );
876883 mask.cbShading [i]->uploadData (&constants, sizeof (constants));
877884
878885 m_csShading->updateThreadGroups ({dispatchX, dispatchY, 1 });
879886 m_device->setShader (m_csShading, SamplerType::NearestClamp);
880887 m_device->setShaderInput (0 , mask.cbShading [i]);
881- mask.mask [i ]->setState (D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
882- m_device->setShaderOutput (0 , mask.mask [i ]);
888+ mask.mask [target ]->setState (D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
889+ m_device->setShaderOutput (0 , mask.mask [target ]);
883890 m_device->dispatchShader ();
884- mask.mask [i ]->setState (D3D12_RESOURCE_STATE_COPY_SOURCE);
891+ mask.mask [target ]->setState (D3D12_RESOURCE_STATE_COPY_SOURCE);
885892 }
886893
887894 // Copy to the double wide/texture arrays mask.
@@ -929,31 +936,39 @@ namespace {
929936 if (api == Api::D3D11) {
930937 // Implementation uses a constant table with a varying shading rate texture
931938 // We set VRS on 2 viewports in case the stereo view renders in parallel.
932- m_shadingRates[SHADING_RATE_CULL] = NV_PIXEL_X0_CULL_RASTER_PIXELS;
933- m_shadingRates[SHADING_RATE_x16] = NV_PIXEL_X16_PER_RASTER_PIXEL;
934- m_shadingRates[SHADING_RATE_x8] = NV_PIXEL_X8_PER_RASTER_PIXEL;
935- m_shadingRates[SHADING_RATE_x4] = NV_PIXEL_X4_PER_RASTER_PIXEL;
936- m_shadingRates[SHADING_RATE_x2] = NV_PIXEL_X2_PER_RASTER_PIXEL;
937- m_shadingRates[SHADING_RATE_x1] = NV_PIXEL_X1_PER_RASTER_PIXEL;
938- m_shadingRates[SHADING_RATE_2x1] = NV_PIXEL_X1_PER_2X1_RASTER_PIXELS;
939- m_shadingRates[SHADING_RATE_1x2] = NV_PIXEL_X1_PER_1X2_RASTER_PIXELS;
940- m_shadingRates[SHADING_RATE_2x2] = NV_PIXEL_X1_PER_2X2_RASTER_PIXELS;
941- m_shadingRates[SHADING_RATE_4x2] = NV_PIXEL_X1_PER_4X2_RASTER_PIXELS;
942- m_shadingRates[SHADING_RATE_2x4] = NV_PIXEL_X1_PER_2X4_RASTER_PIXELS;
943- m_shadingRates[SHADING_RATE_4x4] = NV_PIXEL_X1_PER_4X4_RASTER_PIXELS;
944-
945- for (size_t i = 0 ; i < std::size (m_shadingRates); i++) {
946- m_nvRates[0 ].shadingRateTable [i] = static_cast <NV_PIXEL_SHADING_RATE>(m_shadingRates[i]);
947- }
939+ m_nvRates[0 ].shadingRateTable [0 ] = NV_PIXEL_X16_PER_RASTER_PIXEL;
940+ m_shadingRates[SHADING_RATE_x16] = 0 ;
941+ m_nvRates[0 ].shadingRateTable [1 ] = NV_PIXEL_X8_PER_RASTER_PIXEL;
942+ m_shadingRates[SHADING_RATE_x8] = 1 ;
943+ m_nvRates[0 ].shadingRateTable [2 ] = NV_PIXEL_X4_PER_RASTER_PIXEL;
944+ m_shadingRates[SHADING_RATE_x4] = 2 ;
945+ m_nvRates[0 ].shadingRateTable [3 ] = NV_PIXEL_X2_PER_RASTER_PIXEL;
946+ m_shadingRates[SHADING_RATE_x2] = 3 ;
947+ m_nvRates[0 ].shadingRateTable [4 ] = NV_PIXEL_X1_PER_RASTER_PIXEL;
948+ m_shadingRates[SHADING_RATE_x1] = 4 ;
949+ m_nvRates[0 ].shadingRateTable [5 ] = NV_PIXEL_X1_PER_2X1_RASTER_PIXELS;
950+ m_shadingRates[SHADING_RATE_2x1] = 5 ;
951+ m_nvRates[0 ].shadingRateTable [6 ] = NV_PIXEL_X1_PER_1X2_RASTER_PIXELS;
952+ m_shadingRates[SHADING_RATE_1x2] = 6 ;
953+ m_nvRates[0 ].shadingRateTable [7 ] = NV_PIXEL_X1_PER_2X2_RASTER_PIXELS;
954+ m_shadingRates[SHADING_RATE_2x2] = 7 ;
955+ m_nvRates[0 ].shadingRateTable [8 ] = NV_PIXEL_X1_PER_4X2_RASTER_PIXELS;
956+ m_shadingRates[SHADING_RATE_4x2] = 8 ;
957+ m_nvRates[0 ].shadingRateTable [9 ] = NV_PIXEL_X1_PER_2X4_RASTER_PIXELS;
958+ m_shadingRates[SHADING_RATE_2x4] = 9 ;
959+ m_nvRates[0 ].shadingRateTable [10 ] = NV_PIXEL_X1_PER_4X4_RASTER_PIXELS;
960+ m_shadingRates[SHADING_RATE_4x4] = 10 ;
961+ m_nvRates[0 ].shadingRateTable [11 ] = NV_PIXEL_X0_CULL_RASTER_PIXELS;
962+ m_shadingRates[SHADING_RATE_CULL] = 11 ;
948963 m_nvRates[0 ].enableVariablePixelShadingRate = true ;
964+
949965 for (size_t i = 1 ; i < std::size (m_nvRates); i++) {
950966 m_nvRates[i] = m_nvRates[0 ];
951967 }
952968 }
953969 if (api == Api::D3D12) {
954970 // Implementation uses a varying shading rate texture.
955971 // We use a constant table to lookup the shader constants only
956- m_shadingRates[SHADING_RATE_CULL] = D3D12_SHADING_RATE_4X4;
957972 m_shadingRates[SHADING_RATE_x16] = D3D12_SHADING_RATE_1X1;
958973 m_shadingRates[SHADING_RATE_x8] = D3D12_SHADING_RATE_1X1;
959974 m_shadingRates[SHADING_RATE_x4] = D3D12_SHADING_RATE_1X1;
@@ -965,6 +980,7 @@ namespace {
965980 m_shadingRates[SHADING_RATE_4x2] = D3D12_SHADING_RATE_4X2;
966981 m_shadingRates[SHADING_RATE_2x4] = D3D12_SHADING_RATE_2X4;
967982 m_shadingRates[SHADING_RATE_4x4] = D3D12_SHADING_RATE_4X4;
983+ m_shadingRates[SHADING_RATE_CULL] = D3D12_SHADING_RATE_4X4;
968984 }
969985 }
970986
0 commit comments