Skip to content

Commit

Permalink
Add foveation benchmark (#491)
Browse files Browse the repository at this point in the history
The third of a series of CL that integrates the commits from:

https://github.com/bjoeris/bigwheels/tree/experimental-foveation

into BW main's branch.

The series will have 4 CL, this is the third one that integrates the
following commit

Add foveation benchmark

Beside the foveation sample app, it also
* Adds ImmutableSamplers member to DescrptorBinding struct
* Refactor code from TakeScreenshot and adds a SaveImage member in
Application class
* Adds a cmake function to add a GLSL shader target

---------

Co-authored-by: Benson Joeris <[email protected]>
  • Loading branch information
jorgeag-google and bjoeris authored Jul 18, 2024
1 parent 850b143 commit 923280e
Show file tree
Hide file tree
Showing 21 changed files with 1,154 additions and 27 deletions.
24 changes: 24 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,30 @@ endif ()

message(STATUS "DXC_PATH: ${DXC_PATH}")

# ------------------------------------------------------------------------------
# Detect glslc presence. Required to compile GLSL shaders.
# ------------------------------------------------------------------------------

message(CHECK_START "Looking for GLSLC")
if (NOT GLSLC_PATH)
message(STATUS "GLSLC_PATH not set. Looking for Vulkan SDK path in ENV")
if (DEFINED ENV{VULKAN_SDK})
if (CMAKE_HOST_WIN32)
set(GLSLC_PATH "$ENV{VULKAN_SDK}\\Bin\\glslc.exe")
else ()
set(GLSLC_PATH "$ENV{VULKAN_SDK}/bin/glslc")
endif ()
endif ()
endif ()

if ((NOT GLSLC_PATH) OR (NOT EXISTS "${GLSLC_PATH}"))
message(CHECK_FAIL "Cannot open GLSLC at ${GLSLC_PATH}")
else ()
message(CHECK_PASS "found")
endif ()

message(STATUS "GLSLC_PATH: ${GLSLC_PATH}")

# ------------------------------------------------------------------------------
# Configure target platform.
# ------------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions assets/basic/shaders/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ generate_rules_for_shader("shader_diffuse_shadow" SOURCE "${PPX_DIR}/assets/basi
generate_rules_for_shader("shader_normal_map" SOURCE "${PPX_DIR}/assets/basic/shaders/NormalMap.hlsl" STAGES "vs" "ps")
generate_rules_for_shader("shader_pbr_metallic_roughness" SOURCE "${PPX_DIR}/assets/basic/shaders/PbrMetallicRoughness.hlsl" STAGES "vs" "ps")
generate_rules_for_shader("shader_fullscreen_triangle" SOURCE "${PPX_DIR}/assets/basic/shaders/FullScreenTriangle.hlsl" STAGES "vs" "ps")
generate_rules_for_shader("shader_fullscreen_triangle_combined" SOURCE "${PPX_DIR}/assets/basic/shaders/FullScreenTriangleCombined.hlsl" STAGES "vs" "ps")
generate_rules_for_shader("shader_text_draw" SOURCE "${PPX_DIR}/assets/basic/shaders/TextDraw.hlsl" STAGES "vs" "ps")
generate_rules_for_shader("shader_image_filter" SOURCE "${PPX_DIR}/assets/basic/shaders/ImageFilter.hlsl" STAGES "cs")
generate_rules_for_shader("shader_static_texture" SOURCE "${PPX_DIR}/assets/basic/shaders/StaticTexture.hlsl" STAGES "vs" "ps")
Expand Down
49 changes: 49 additions & 0 deletions assets/basic/shaders/FullScreenTriangleCombined.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//
// https://www.slideshare.net/DevCentralAMD/vertex-shader-tricks-bill-bilodeau
//

[[vk::combinedImageSampler]]
Texture2D Tex0 : register(t0);
[[vk::combinedImageSampler]]
SamplerState Sampler0 : register(s0);

struct VSOutput {
float4 Position : SV_POSITION;
float2 TexCoord : TEXCOORD;
};

VSOutput vsmain(uint id : SV_VertexID)
{
VSOutput result;

// Clip space position
result.Position.x = (float)(id / 2) * 4.0 - 1.0;
result.Position.y = (float)(id % 2) * 4.0 - 1.0;
result.Position.z = 0.0;
result.Position.w = 1.0;

// Texture coordinates
result.TexCoord.x = (float)(id / 2) * 2.0;
result.TexCoord.y = 1.0 - (float)(id % 2) * 2.0;

return result;
}

float4 psmain(VSOutput input) : SV_TARGET
{
return Tex0.Sample(Sampler0, input.TexCoord);
}
18 changes: 18 additions & 0 deletions assets/benchmarks/shaders/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,21 @@ generate_rules_for_shader("shader_benchmark_texture"
SOURCE "${PPX_DIR}/assets/benchmarks/shaders/Benchmark_Texture.hlsl"
INCLUDES "${PPX_DIR}/assets/benchmarks/shaders/VsOutput.hlsli"
STAGES "ps")

generate_rules_for_shader("shader_foveation_benchmark"
SOURCE "${PPX_DIR}/assets/benchmarks/shaders/FoveationBenchmark.hlsl"
INCLUDES "${PPX_DIR}/assets/benchmarks/shaders/VsOutput.hlsli"
STAGES "vs" "ps")

generate_rules_for_shader("shader_foveation_benchmark_shading_rate_khr"
SOURCE "${PPX_DIR}/assets/benchmarks/shaders/FoveationBenchmarkShadingRateKHR.hlsl"
INCLUDES "${PPX_DIR}/assets/benchmarks/shaders/VsOutput.hlsli"
STAGES "ps")

generate_rules_for_glsl_shader("shader_foveation_benchmark_frag_size_ext_vs"
SOURCE "${PPX_DIR}/assets/benchmarks/shaders/FoveationBenchmarkFragSizeEXT.vert"
STAGE "vs")

generate_rules_for_glsl_shader("shader_foveation_benchmark_frag_size_ext_ps"
SOURCE "${PPX_DIR}/assets/benchmarks/shaders/FoveationBenchmarkFragSizeEXT.frag"
STAGE "ps")
19 changes: 19 additions & 0 deletions assets/benchmarks/shaders/FoveationBenchmark.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "FoveationBenchmark.hlsli"

float4 psmain(VSOutputPos Input) : SV_TARGET {
return getColor(paramsUniform, Input.position.xy);
}
65 changes: 65 additions & 0 deletions assets/benchmarks/shaders/FoveationBenchmark.hlsli
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "VsOutput.hlsli"

struct Params {
// Seed for pseudo-random noise generator.
// This is combined with the fragment location to generate the color.
uint seed;

// Number of additional hash computations to perform for each fragment.
uint extraHashRounds;

// Per-channel weights of the noise in the output color.
float3 noiseWeights;

// Color to mix with the noise.
float3 color;
};

ConstantBuffer<Params> paramsUniform : register(b0);

// Computes a pseudo-random hash.
uint pcg_hash(uint input) {
uint state = input * 747796405u + 2891336453u;
uint word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
return (word >> 22u) ^ word;
}

// Get the output color, which is a mix of pseudo-random noise and a constant
// color.
float4 getColor(Params params, float2 position) {
uint hashWord = params.seed;
hashWord = pcg_hash(hashWord ^ uint(position.x));
hashWord = pcg_hash(hashWord ^ uint(position.y));
for (int i = 0; i < params.extraHashRounds; ++i) {
hashWord = pcg_hash(hashWord);
}
float3 noise = float3(float(hashWord & 0xFF) / 255.0,
float((hashWord >> 8) & 0xFF) / 255.0,
float((hashWord >> 16) & 0xFF) / 255.0);
float3 color = lerp(params.color, noise, params.noiseWeights);
return float4(color, 1.0);
}

VSOutputPos vsmain(uint vid : SV_VertexID) {
VSOutputPos result;
// Position of a triangle covering the entire viewport:
// {{-1,-1}, {3,-1}, {-1,3}}
float2 pos = float2(-1.0, -1.0) + float(vid & 1) * float2(4.0, 0.0) +
float((vid >> 1) & 1) * float2(0.0, 4.0);
result.position = float4(pos, 0, 1);
return result;
}
73 changes: 73 additions & 0 deletions assets/benchmarks/shaders/FoveationBenchmarkFragSizeEXT.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#version 450
// I am using GLSL here because for FDM we need to use the following extension
// that to my knowledge has no equivalent in HLSL
#extension GL_EXT_fragment_invocation_density : enable

layout(location = 0) out vec4 outColor;

layout(binding = 0) uniform Params
{
// Seed for pseudo-random noise generator.
// This is combined with the fragment location to generate the color.
uint seed;

// Number of additional hash computations to perform for each fragment.
uint extraHashRounds;

// Per-channel weights of the noise in the output color.
vec3 noiseWeights;

// Color to mix with the noise.
vec3 color;
}
params;

// Computes a pseudo-random hash.
uint pcg_hash(uint value)
{
uint state = value * 747796405u + 2891336453u;
uint word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
return (word >> 22u) ^ word;
}

// Get the output color, which is a mix of pseudo-random noise and a constant
// color.
vec4 getColor(uint seed, uint extraHashRounds, vec3 noiseWeights, vec3 color, vec2 position)
{
uint hashWord = seed;
hashWord = pcg_hash(hashWord ^ uint(position.x));
hashWord = pcg_hash(hashWord ^ uint(position.y));
for (int i = 0; i < extraHashRounds; ++i) {
hashWord = pcg_hash(hashWord);
}
vec3 noise = vec3(
float(hashWord & 0xFF) / 255.0,
float((hashWord >> 8) & 0xFF) / 255.0,
float((hashWord >> 16) & 0xFF) / 255.0);
return vec4(mix(color, noise, noiseWeights), 1.0);
}

void main()
{
// Adjust params so that color G&B channels are shading density, and noise
// is removed from these channels.
ivec2 fragSize = gl_FragSizeEXT;
vec2 shadingDensity = vec2(1.0 / float(fragSize.x), 1.0 / float(fragSize.y));
vec3 color = vec3(params.color.x, shadingDensity);
vec3 noiseWeights = vec3(params.noiseWeights.x, 0.001, 0.001);
outColor = getColor(params.seed, params.extraHashRounds, noiseWeights, color, gl_FragCoord.xy);
}
21 changes: 21 additions & 0 deletions assets/benchmarks/shaders/FoveationBenchmarkFragSizeEXT.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#version 450

void main()
{
vec2 pos = vec2(-1.0, -1.0) + float(gl_VertexIndex & 1) * vec2(4.0, 0.0) + float((gl_VertexIndex >> 1) & 1) * vec2(0.0, 4.0);
gl_Position = vec4(pos, 0, 1);
}
30 changes: 30 additions & 0 deletions assets/benchmarks/shaders/FoveationBenchmarkShadingRateKHR.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "FoveationBenchmark.hlsli"

float4 psmain(VSOutputPos Input, uint shading_rate
: SV_ShadingRate)
: SV_TARGET {
// Decode the shading rate into shading densities.
float2 shading_density = float2(1.0 / (1U << (shading_rate & 3)),
1.0 / (1U << ((shading_rate >> 2) & 3)));

// Adjust params so that color G&B channels are shading density, and noise
// is removed from these channels.
Params params = paramsUniform;
params.color.yz = float2(shading_density);
params.noiseWeights.yz = float2(0.001, 0.001);
return getColor(params, Input.position.xy);
}
1 change: 1 addition & 0 deletions benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ add_subdirectory(texture_sample)
add_subdirectory(texture_transfer_cpu_to_gpu)
add_subdirectory(overdraw)
add_subdirectory(graphics_pipeline)
add_subdirectory(foveation)
28 changes: 28 additions & 0 deletions benchmarks/foveation/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

project(foveation)

add_vk_sample(
NAME ${PROJECT_NAME}
SOURCES
"main.cpp"
"FoveationBenchmarkApp.h"
"FoveationBenchmarkApp.cpp"
DEPENDENCIES
"shader_foveation_benchmark"
"shader_foveation_benchmark_shading_rate_khr"
"shader_foveation_benchmark_frag_size_ext_vs"
"shader_foveation_benchmark_frag_size_ext_ps"
"shader_fullscreen_triangle_combined")
Loading

0 comments on commit 923280e

Please sign in to comment.