#
# Copyright (c) 2019, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
#

# shader source files (extension is .hlsl)

set (SHADER_SOURCE_FILES
    FullscreenVS
    ImGUIPS
    ImGUIVS
    MarkerPS
    MarkerVS
    MipmapGenerationPS
    OceanSurfaceDS
    OceanSurfaceHS
    OceanSurfacePS
    OceanSurfaceVS
    SkyRenderingPS
    SkyRenderingVS
    SkyUpdatePS
)

set(bytecode_dir "${CMAKE_CURRENT_BINARY_DIR}/bytecode/")

file(MAKE_DIRECTORY "${bytecode_dir}")

#
# DX11 - DX12
#

if (WIN32 AND NOT (NO_DX11 AND NO_DX12))

    find_package(FXC REQUIRED)

    add_custom_target(shaders_bytecode_dx)
	set_target_properties(shaders_bytecode_dx PROPERTIES FOLDER "WaveWorks_example")

    foreach(shader ${SHADER_SOURCE_FILES})

        set(infile "${CMAKE_CURRENT_SOURCE_DIR}/${shader}.hlsl")
        set(varname "${shader}_bytecode_dx" )
        set(fheader "${bytecode_dir}/${shader}_dx.h" )

        set (smodel "")
        set (types "VS" "HS" "DS" "PS" "CS")
        foreach (type ${types})
            string(FIND "${infile}" "${type}.hlsl" loc)
            if (${loc} GREATER -1)
                string(TOLOWER ${type} smodel)
                string(APPEND smodel "_5_0")
                break()
            endif()
        endforeach()

        add_custom_command(
            TARGET shaders_bytecode_dx PRE_BUILD
            COMMAND "${FXC_EXECUTABLE}" "${infile}" -E "main" -Vn "${varname}" -T "${smodel}" -Fh "${fheader}" -nologo
            BYPRODUCTS "${fheader}"
            DEPENDS "${FXC_EXECUTABLE}" "${infile}"
            VERBATIM
        )
    endforeach()
endif()

#
# Vulkan
#

if ((VULKAN_FOUND OR Vulkan_FOUND) AND NOT NO_VULKAN)

    find_package(DXCspirv REQUIRED)

    add_custom_target(shaders_bytecode_vk)
    set_target_properties(shaders_bytecode_vk PROPERTIES FOLDER "WaveWorks_example")

    foreach(shader ${SHADER_SOURCE_FILES})
        
        set(infile "${CMAKE_CURRENT_SOURCE_DIR}/${shader}.hlsl")
        set(varname "${shader}_bytecode_vk" )
        set(fheader "${bytecode_dir}/${shader}_vk.h" )
        set(objfile "${bytecode_dir}/${shader}_vk.spv")

		set(smodel "")
        set(types "VS" "HS" "DS" "GS" "PS" "CS")
		set(stage_offset 0)
        foreach (type ${types})
            string(FIND "${infile}" "${type}.hlsl" loc)
            if (${loc} GREATER -1)
                string(TOLOWER ${type} smodel)
                string(APPEND smodel "_5_0")
                break()
            endif()
			math(EXPR stage_offset "${stage_offset} + 512")
        endforeach()

		math(EXPR t_shift "0 + ${stage_offset}")
		math(EXPR s_shift "128 + ${stage_offset}")
		math(EXPR b_shift "256 + ${stage_offset}")
		math(EXPR u_shift "384 + ${stage_offset}")
		set(register_shifts -fvk-t-shift ${t_shift} 0 -fvk-s-shift ${s_shift} 0 -fvk-b-shift ${b_shift} 0 -fvk-u-shift ${u_shift} 0)
		string(JOIN " " register_shifts_string ${register_shifts})

        add_custom_command(
            TARGET shaders_bytecode_vk PRE_BUILD

            COMMAND "${DXC_SPIRV_EXECUTABLE}" "${infile}" -E "main" -T "${smodel}" -spirv -Vn "${varname}" -Fh "${fheader}" ${register_shifts} -nologo
			COMMAND ${CMAKE_COMMAND} -E echo "${DXC_SPIRV_EXECUTABLE} \"${infile}\" -E \"main\" -T \"${smodel}\" -spirv -Vn \"${varname}\" -Fh \"${fheader}\" ${register_shifts} -nologo"

            COMMAND "${DXC_SPIRV_EXECUTABLE}" "${infile}" -E "main" -T "${smodel}" -spirv -Fc "${objfile}" ${register_shifts} -nologo
			COMMAND ${CMAKE_COMMAND} -E echo "${DXC_SPIRV_EXECUTABLE} \"${infile}\" -E \"main\" -T \"${smodel}\" -spirv -Fc \"${objfile}\" ${register_shifts_string} -nologo"

            BYPRODUCTS "${fheader}" "${objfile}"
            DEPENDS "${DXC_SPIRV_EXECUTABLE}" "${infile}"
            VERBATIM
        )
    endforeach()
endif()
