How to compile hlsl shaders multiple times in visual studio? - visual-studio-2017

I have HLSL shaders added to my Visual Studio project and they're getting compiled automatically to cso files as part of the build process. The problem which I'm facing is, that I need to compile them multiple times using different Shader models because i.e. "/4_0_level_9_3" works on DirectX 11, but not on DirectX 9, while "/3_0" only works on DirectX 9 but not on DirectX 11.
Adding the same files more than once to the Visual Studio project is not working and I would like to avoid copying the HLSL source files as it increases maintenance efforts and potential error causes. I can't create separate targets/configuration in Visual Studio to achieve this either, because I need to support both DirectX versions in the executable (switchable at runtime).
Is there any way to specify multiple compilations (different shader models and different output file) for a single HLSL file in Visual Studio?

Put your shader code into an .hlsli file, add that to your project. Create for each shader and model combination an .hlsl file which does a #include of your .hlsli file. Add each .hlsl to your project and set the file settings appropriately.
File 1 (set to exclude from build)
// MyShader.hlsli
PS_INPUT VertexShader( VS_INPUT input )
{
...
}
float4 PixelShader( PS_INPUT input)
{
...
}
File 2 (set to build as a Vertex Shader, Shader Model 9_3, Entry-point VertexShader)
// MyShader_VS.hlsl
#include "MyShader.hlsl"
File 3 (set to build as a Pixel Shader, Shader Model 9_3, Entry-point PixelShader)
// MyShader_PS.hlsl
#include "MyShader.hlsl"
File 4 (set to build as a Vertex Shader, Shader Model 4.0, Entry-point VertexShader)
// MyShader_VS4.hlsl
#include "MyShader.hlsl"
File 5 (set to build as a Pixel Shader, Shader Model 4.0, Entry-point PixelShader)
// MyShader_PS4.hlsl
#include "MyShader.hlsl"
Note that you can make life a little easier by manually editing your vcxproj file with a text editor. Look for the Label="UserMacros" and then in the ItemDefinitionGroup for each configuration right after that add a section for <FXCompile> to set better defaults (rather than 4.0_level_9_1):
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Link>
...
</Link>
<ClCompile>
...
</ClCompile>
<FXCompile>
<ShaderModel>4.0_level_9_3</ShaderModel>
</FXCompile>
Unless you are specifically targeting Windows XP systems, there's not much value in using the legacy Direc3D 9 API at all. Just use DirectX 11 Feature Level 9.3+ to target Shader Model 2.0/3.0 era video cards. The main value of Shader Model 3.0 was vertex texture fetch which was never implemented by one of the major vendors anyhow. The 4_0_level_9_3 profile already builds the shader as both 2.0 and 4.0 in the same blob.

Related

gl3w and GL extensions

I am targeting GL Core Profile on Linux. When I directly use the system GL headers like so:
#include <GL/glcorearb.h>
...then everything works as expected, and I can use GL extensions too, e.g. glPushGroupMarkerEXT() calls.
But since I've integrated imgui, I have been forced to go through a GL Loader (I was not able to make imgui work without a loader.)
So I have followed the imgui examples, and now use gl3w.
Now that I go through gl3w, I can no longer use those GL extensions:
src/wld.cpp:373:2: error: use of undeclared identifier 'glPushGroupMarkerEXT'
I looked, but gl3w does not seem to come with a separate header for extension, like glew does: the glxew.h file.
Does this mean that I cannot use glPushGroupMarkerEXT() if I use gl3w as a GL loader?
Ok, so it wasn't mentioned in the README before (it is now, I created a pull rq) but there is a command line option to gl3w's generator script:
gl3w_gen.py --ext
When using the --ext flag, the extensions will be available in the generated GL/glcorearb.h header.
The gl3w packed with the imgui repository was generated without this flag, hence the extensions were not available.

Premake5: How to build HLSL shaders?

I'm struggling to figure out how to set up my hlsl shaders to work with Premake5 and Visual Studio 2017.
I have no idea how to tell Premake5 to compile my hlsl shaders, as a pre-build step.
Here are my goals for this pre-build step:
Specify shader model
Specify debug/release compilation
Only compile files that have changed
Produce dxasm files
Place resulting *.asms and *.cso in appropriate release/debug folders
Update 1:
Investigating a little further I found that Premake5 has buildaction which makes direct reference to FxCompile.
Update 2:
Thanks to mukunda. I was able to configure my project perfectly!
I had to build premake5 from source in order to get this premake script to run.
Because as of March, 2019 the binary distributed doesn't support shader model greater than 5.
hf.deactivate_filter()
files(src_dir.."shaders/*.hlsl")
shadermodel("6.3")
shaderassembler("AssemblyCode")
local shader_dir = _WORKING_DIR.."/"..src_dir.."shaders/%{cfg.buildcfg}/"
-- HLSL files that don't end with 'Extensions' will be ignored as they will be
-- used as includes
filter("files:**.hlsl")
flags("ExcludeFromBuild")
shaderobjectfileoutput(shader_dir.."%{file.basename}"..".cso")
shaderassembleroutput(shader_dir.."%{file.basename}"..".asm")
filter("files:**_ps.hlsl")
removeflags("ExcludeFromBuild")
shadertype("Pixel")
filter("files:**_vs.hlsl")
removeflags("ExcludeFromBuild")
shadertype("Vertex")
hf.deactivate_filter()
-- Warnings as errors
shaderoptions({"/WX"})
Update 3:
I figured out how to handle command line parameters.
I was just messing around with this today. For my HLSL files I have a simple naming scheme:
*-p.hlsl for pixel shader files.
*-v.hlsl for vertex shader files.
*.hlsl for generic files meant to be included by the shader programs. I just use the hlsl extension so that it shows up with proper HLSL syntax highlighting in the editor.
You don't need custom build rules to compile them. Premake seems to be able to output a proper block in the Visual Studio project for using the shader compiler, and then things like only recompiling files that have changed (with #include dependencies) are handled just fine. Here's what my configuration block looks like:
filter { "files:**.hlsl" }
flags "ExcludeFromBuild"
shadermodel "5.0"
filter { "files:**-p.hlsl" }
removeflags "ExcludeFromBuild"
shadertype "Pixel"
shaderentry "ForPixel"
filter { "files:**-v.hlsl" }
removeflags "ExcludeFromBuild"
shadertype "Vertex"
shaderentry "ForVertex"
filter {}
Basically sets up the shadermodel and entry points for my files (For DirectX 12 you probably want shadermodel "6.0"). Then I can add my shaders to the project through files:
files { "shaders/**.hlsl"; }
This is all very new stuff in premake, so you won't find much documentation on it. I saw these options here: https://github.com/premake/premake-core/blob/master/modules/vstudio/_preload.lua.
As for your question about exporting the dxasm files, there are some other options such as shaderassembleroutput and shaderassembler, the latter I believe to be the switch that exports the assembly code to the location specified, but I have not done any testing with these to give an elaborate answer.
Unfortunately I'm not really sure how to enable debugging information in the output files, as there doesn't seem to be a premake option for that yet. I was digging through the documentation to look for any way to add the /Zi (enable debug symbols) flag for shader compilation, but I'm not entirely sure if it's possible.

SFML Can't Load Image

I am trying to load an image with SFML, here is my code.
// Get the background texture
Texture bg;
if (!bg.loadFromFile("background.jpg"))
{
return EXIT_FAILURE;
}
Sprite background;
background.setTexture(bg);
background.setPosition(width / 2, height / 2);
and in the main loop:
window.draw(background);
Now I have included the background.jpg in every single folder for this solution, starting from C:/users/username/source/repos/thisSolution. However I am still getting the failed to load image error, is there some arbitrary folder where VS2017 would be looking for this file?
As #Arnav Broborah pointed, by default with Visual Studio, resources should be located into your project folder (where .vcxproj file is)
If you have created your project with "Create directory for solution", the
resulting hierarchy will be something like:
C:\Users\username\Documents\Visual Studio 2013\Projects\YourSolution\YourProject
Obviously, those names depends on the drive you installed VS, username, VS version, etc, but your resource files should go into the project folder by default.
You can change it in debug settings

Creating .fxo shader file using fxc.exe

Does anybody know how to compile a single file containing various shaders (PixelShader, VertexShader, GeometryShader) using the fxc.exe tool provided by the DirectX 11 SDK?
The shader is used to create a tesselation-effect in a C++ programmed Enviroment:
The result should be a .fxo shader File.
Thx in advance :)
You run the compiler separately for each effect source file (one source file per effect, including the various shaders and helper routines). There will be a separate shader object file for each effect, similarly. The command line depends on what you actually want to compile but something like this:
fxc.exe /T ps_2_0 /nologo /E main /Fo"Effect.fxo" "Effect.fx"
or
fxc.exe /T fx_4_0 /nologo /Fo"Effect.fxo" "Effect.fx"

Change order of display variables in Visual Studio Debugger

I've got an issue with how Visual Studio is displaying my variables during debugging. I develop on two computers, both on VS2012, and they have the same versions of the development libraries installed, and they display the order of variables in a class differently.
Seems inconsequential, but I'm using a math library (GLM) and when I break and inspect a variable, the order they are shown is different:
The type is a glm::vec3, which is defined by 3 floats x, y, z, but the library is designed to be as close syntactically to glsl, so it also contains other names for the variables (rgb, stp) which really are just references(x=r=s, y=g=t, z=b=p). On my other machine, the preview shows x y and z values, which is what I want.
Viewing these is a pain on this machine, as I have to click the drop down to inspect each individual variable, and the lists of vectors I'm working with can be 100's or 1000's of items long. I also can't print them out in the immediate window and inspect that way either because it prints in the same order.
Anything I can change?
edit:
I needed to update the autoexp.dat file, but it doesn't seem to be working for me. I opened a sample file in VS2010 which I have installed, and modified it's autoexp.dat and it worked great.
One thing I did notice is that my VS2012 is installed in C:\Program Files(x86), rather than C:\Program Files(X86)\Microsoft Visual Studio 11.0 (my 2010 is installed in the correct location), so my Common7 folder is C:\Program Files(x86)\Common7
Is that a problem?
In VS2012 and later, autoexp.dat has been superseded by the native type visualization framework (natvis).
This works with an xml file with .natvis extension, which can be put at three different locations :
%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers (requires admin access)
%USERPROFILE%\My Documents\Visual Studio 2012\Visualizers\
VS extension folders
Your .natvis file should look like this (replace TheType by the name of the class you want to visualize) :
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="TheType">
<DisplayString>x = {x} y = {y} z = {z}</DisplayString>
</Type>
</AutoVisualizer>
On MSDN :
Create custom views of native objects in the debugger