mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-22 07:21:34 +00:00
Refactor custom shaders to abstract binding differences. Closes #2458
* Newly written shaders and any updated shaders can now use pre-defined macros to abstract away binding differences between APIs, so custom shaders will be more portable in particular shaders written in HLSL for D3D or GLSL on OpenGL won't break on vulkan because they refer to incorrect binds.
This commit is contained in:
@@ -8,9 +8,9 @@ Introduction
|
||||
|
||||
The basic process of setting up the custom shader involves writing a shader file that will be compiled and used by RenderDoc. Note that you can use any language that is either natively accepted by the graphics API used, or any language that can be compiled to an accepted shader.
|
||||
|
||||
For example on D3D11 or D3D12, hlsl is the only language usable by default, but on Vulkan you can use hlsl or glsl as long as a compiler is available.
|
||||
For example on D3D11 or D3D12, hlsl is the only language usable by default. On OpenGL only glsl can be used, but on Vulkan you can use glsl or use hlsl as long as a compiler is available.
|
||||
|
||||
There are several special global variables that can be specified and will be filled in with values by RenderDoc.
|
||||
There are several special global helpers that can be declared and used, which will be implemented and return values by RenderDoc. In addition there are automatic macros that can be used to bind resources and still write shaders which work on different APIs with different bindings.
|
||||
|
||||
Your pixel shader defines an operation that transforms the raw value from the input texture into a value that will then be displayed by the texture viewer. The usual texture viewer controls for range adaption and channels will still be available on the resulting texture.
|
||||
|
||||
@@ -18,7 +18,11 @@ To set up your shader, it's recommended that you use the UI defined in the docum
|
||||
|
||||
.. note::
|
||||
|
||||
Since ``.glsl`` is used for both Vulkan and OpenGL shaders, you can differentiate by the pre-defined macro ``VULKAN`` if you are writing a shader to be used for both.
|
||||
Since ``.glsl`` is used for both Vulkan and OpenGL shaders, you can differentiate by the pre-defined macro ``VULKAN`` if you are writing a shader to be used for both.
|
||||
|
||||
.. warning::
|
||||
|
||||
Previously the custom shaders allowed more direct binding without helper functions or binding macros. These shaders will continue to work as backwards compatibility is maintained, however be aware that these bindings are API specific and so e.g. a shader written for OpenGL in glsl will not work on Vulkan unless care has been taken, or an HLSL shader between Vulkan and D3D. If portability is desired please update and use the new helpers and binding macros, or else be careful only to use custom shaders with the API they were written for.
|
||||
|
||||
Predefined inputs
|
||||
-----------------
|
||||
@@ -27,7 +31,7 @@ There are several pre-defined inputs that can either be taken as parameters to t
|
||||
|
||||
.. warning::
|
||||
|
||||
Type and capitalisation is important for these variables, so ensure you use the right declaration!
|
||||
Type and capitalisation is important for these variables, so ensure you use the right declaration!
|
||||
|
||||
The shader editor when using the UI can be used to insert these snippets for you, with the right type and spelling. For GLSL these snippets are inserted at the top of the file just after any ``#version`` statement.
|
||||
|
||||
@@ -37,19 +41,19 @@ UV co-ordinates
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
/* HLSL */
|
||||
float4 main(float4 pos : SV_Position, float4 uv : TEXCOORD0) : SV_Target0
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
/* HLSL */
|
||||
float4 main(float4 pos : SV_Position, float4 uv : TEXCOORD0) : SV_Target0
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* GLSL */
|
||||
layout (location = 0) in vec2 uv;
|
||||
/* GLSL */
|
||||
layout (location = 0) in vec2 uv;
|
||||
|
||||
void main()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
void main()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
This input is defined in HLSL as a second parameter to the shader entry point. The first defines the usual ``SV_Position`` system semantic, and the first two components of the second ``TEXCOORD0`` parameter gives UV co-ordinates from 0 to 1 in each dimension over the size of the texture (or texture slice).
|
||||
|
||||
@@ -59,31 +63,12 @@ You can also use the auto-generated system co-ordinates - ``SV_Position`` or ``g
|
||||
|
||||
.. note::
|
||||
|
||||
You must bind these parameters like this in this order to ensure the linkage with the vertex shader matches.
|
||||
You must bind these parameters like this in this order to ensure the linkage with the vertex shader matches.
|
||||
|
||||
Constant Parameters
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are several constant parameters available, each detailed below with the values they contain. Where possible these are bound by name as globals for convenience, but in Vulkan all variables must be contained within a single uniform buffer. The parameters correspond with the GLSL documentation but are contained within a uniform buffer at binding 0, with a structure given as so:
|
||||
|
||||
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
layout(binding = 0, std140) uniform RENDERDOC_Uniforms
|
||||
{
|
||||
uvec4 TexDim;
|
||||
uint SelectedMip;
|
||||
uint TextureType;
|
||||
uint SelectedSliceFace;
|
||||
int SelectedSample;
|
||||
uvec4 YUVDownsampleRate;
|
||||
uvec4 YUVAChannels;
|
||||
float SelectedRangeMin;
|
||||
float SelectedRangeMax;
|
||||
} RENDERDOC;
|
||||
|
||||
In this way you can access the properties as ``RENDERDOC.TexDim`` instead of ``RENDERDOC_TexDim``.
|
||||
There are several constant parameters available, each available via a helper function. They are detailed below with the values they contain.
|
||||
|
||||
Texture dimensions
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
@@ -91,14 +76,16 @@ Texture dimensions
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
uint4 RENDERDOC_TexDim; // hlsl
|
||||
uniform uvec4 RENDERDOC_TexDim; // glsl
|
||||
uint4 RD_TexDim(); // hlsl
|
||||
uvec4 RD_TexDim(); // glsl
|
||||
|
||||
uint4 RENDERDOC_YUVDownsampleRate; // hlsl / vulkan glsl only
|
||||
uint4 RENDERDOC_YUVAChannels; // hlsl / vulkan glsl only
|
||||
uint4 RD_YUVDownsampleRate(); // hlsl
|
||||
uvec4 RD_YUVDownsampleRate(); // vulkan glsl only
|
||||
uint4 RD_YUVAChannels(); // hlsl
|
||||
uvec4 RD_YUVAChannels(); // vulkan glsl only
|
||||
|
||||
|
||||
``RENDERDOC_TexDim`` will be filled out with the following values:
|
||||
``RD_TexDim`` will return the following values:
|
||||
|
||||
* ``.x`` Width
|
||||
* ``.y`` Height (if 2D or 3D)
|
||||
@@ -106,7 +93,7 @@ Texture dimensions
|
||||
* ``.w`` Number of mip levels
|
||||
|
||||
|
||||
``RENDERDOC_YUVDownsampleRate`` will be filled out with the following values:
|
||||
``RD_YUVDownsampleRate`` will return the following values:
|
||||
|
||||
* ``.x`` Horizontal downsample rate. 1 for equal luma and chroma width, 2 for half rate.
|
||||
* ``.y`` Vertical downsample rate. 1 for equal luma and chroma height, 2 for half rate.
|
||||
@@ -114,7 +101,7 @@ Texture dimensions
|
||||
* ``.w`` Number of bits per component, e.g. 8, 10 or 16.
|
||||
|
||||
|
||||
``RENDERDOC_YUVAChannels`` will be filled out an index indicating where each channel comes from in the source textures. The order is ``.x`` for ``Y``, ``.y`` for ``U``, ``.z`` for ``V`` and ``.w`` for ``A``.
|
||||
``RD_YUVAChannels`` will return an index indicating where each channel comes from in the source textures. The order is ``.x`` for ``Y``, ``.y`` for ``U``, ``.z`` for ``V`` and ``.w`` for ``A``.
|
||||
|
||||
The indices for channels in the first texture in the normal 2D slot are ``0, 1, 2, 3``. Indices from ``4`` to ``7`` indicate channels in the second texture, and so on.
|
||||
|
||||
@@ -126,11 +113,10 @@ Selected Mip level
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
uint RENDERDOC_SelectedMip; // hlsl
|
||||
uniform uint RENDERDOC_SelectedMip; // glsl
|
||||
uint RD_SelectedMip(); // hlsl or glsl
|
||||
|
||||
|
||||
This variable will be filled out with the selected mip level in the UI.
|
||||
This will return the selected mip level in the UI.
|
||||
|
||||
Selected Slice/Face
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
@@ -138,8 +124,7 @@ Selected Slice/Face
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
uint RENDERDOC_SelectedSliceFace; // hlsl
|
||||
uniform uint RENDERDOC_SelectedSliceFace; // glsl
|
||||
uint RD_SelectedSliceFace(); // hlsl or glsl
|
||||
|
||||
|
||||
This variable will be filled out with the selected texture array slice (or cubemap face) in the UI.
|
||||
@@ -150,8 +135,7 @@ Selected Multisample sample
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
int RENDERDOC_SelectedSample; // hlsl
|
||||
uniform int RENDERDOC_SelectedSample; // glsl
|
||||
int RD_SelectedSample(); // hlsl or glsl
|
||||
|
||||
|
||||
This variable will be filled out with the selected multisample sample index as chosen in the UI. If the UI has 'average value' selected, this variable will be negative and with an absolute value equal to the number of samples.
|
||||
@@ -165,14 +149,11 @@ Selected RangeMin, RangeMax
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
float RENDERDOC_SelectedRangeMin; // hlsl
|
||||
float RENDERDOC_SelectedRangeMax; // hlsl
|
||||
|
||||
uniform int RENDERDOC_SelectedRangeMin; // glsl
|
||||
uniform int RENDERDOC_SelectedRangeMax; // glsl
|
||||
float2 RD_SelectedRange(); // hlsl
|
||||
vec2 RD_SelectedRange(); // glsl
|
||||
|
||||
|
||||
These variables will be filled out with the current Minimum and Maximum values for the Range-selector in the Texture Viewer.
|
||||
This function will return a pair, with the current Minimum and Maximum values for the Range-selector in the Texture Viewer.
|
||||
|
||||
|
||||
Current texture type
|
||||
@@ -181,166 +162,170 @@ Current texture type
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
uint RENDERDOC_TextureType; // hlsl
|
||||
uniform uint RENDERDOC_TextureType; // glsl
|
||||
uint RD_TextureType(); // hlsl or glsl
|
||||
|
||||
|
||||
This variable will be set to a given integer value, depending on the type of the current texture being displayed. This can be used to sample from the correct resource.
|
||||
|
||||
.. note::
|
||||
|
||||
The value varies depending on the API this shader will be used for, as each has different resource bindings.
|
||||
The value varies depending on the API this shader will be used for, as each has different resource bindings. You should use the defines below to check, which will be portable across APIs
|
||||
|
||||
D3D11 or D3D12 / HLSL
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
D3D11 or D3D12
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
#. 1D texture
|
||||
#. 2D texture
|
||||
#. 3D texture
|
||||
#. Depth
|
||||
#. Depth + Stencil
|
||||
#. Depth (Multisampled)
|
||||
#. Depth + Stencil (Multisampled)
|
||||
#. Legacy: used to be cubemap, removed as it's unused
|
||||
#. 2D texture (Multisampled)
|
||||
* ``RD_TextureType_1D`` - 1D texture
|
||||
* ``RD_TextureType_2D`` - 2D texture
|
||||
* ``RD_TextureType_3D`` - 3D texture
|
||||
* ``RD_TextureType_Depth`` - Depth
|
||||
* ``RD_TextureType_DepthStencil`` - Depth + Stencil
|
||||
* ``RD_TextureType_DepthMS`` - Depth (Multisampled)
|
||||
* ``RD_TextureType_DepthStencilMS`` - Depth + Stencil (Multisampled)
|
||||
* ``RD_TextureType_2DMS`` - 2D texture (Multisampled)
|
||||
|
||||
OpenGL / GLSL
|
||||
^^^^^^^^^^^^^
|
||||
In all cases on D3D the bindings can be used for arrays or not, interchangeably.
|
||||
|
||||
#. 1D texture
|
||||
#. 2D texture
|
||||
#. 3D texture
|
||||
#. Cubemap
|
||||
#. 1D array texture
|
||||
#. 2D array texture
|
||||
#. Cubemap array
|
||||
#. Rectangle
|
||||
#. Buffer texture
|
||||
#. 2D texture (Multisampled)
|
||||
OpenGL
|
||||
^^^^^^
|
||||
|
||||
Vulkan / GLSL
|
||||
^^^^^^^^^^^^^
|
||||
* ``RD_TextureType_1D`` - 1D texture
|
||||
* ``RD_TextureType_2D`` - 2D texture
|
||||
* ``RD_TextureType_3D`` - 3D texture
|
||||
* ``RD_TextureType_Cube`` - Cubemap
|
||||
* ``RD_TextureType_1D_Array`` - 1D array texture
|
||||
* ``RD_TextureType_2D_Array`` - 2D array texture
|
||||
* ``RD_TextureType_Cube_Array`` - Cube array texture
|
||||
* ``RD_TextureType_Rect`` - Rectangle texture
|
||||
* ``RD_TextureType_Buffer`` - Buffer texture
|
||||
* ``RD_TextureType_2DMS`` - 2D texture (Multisampled)
|
||||
* ``RD_TextureType_2DMS_Array`` - 2D array texture (Multisampled)
|
||||
|
||||
#. 1D texture
|
||||
#. 2D texture
|
||||
#. 3D texture
|
||||
#. 2D texture (Multisampled)
|
||||
OpenGL has separate types and bindings for arrayed and non-arrayed textures.
|
||||
|
||||
Samplers (D3D11/D3D12 only)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Vulkan
|
||||
^^^^^^
|
||||
|
||||
* ``RD_TextureType_1D`` - 1D texture
|
||||
* ``RD_TextureType_2D`` - 2D texture
|
||||
* ``RD_TextureType_3D`` - 3D texture
|
||||
* ``RD_TextureType_2DMS`` - 2D texture (Multisampled)
|
||||
|
||||
In all cases on Vulkan the bindings can be used for arrays or not, interchangeably.
|
||||
|
||||
Samplers
|
||||
~~~~~~~~
|
||||
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
SamplerState pointSampler : register(s0);
|
||||
SamplerState linearSampler : register(s1);
|
||||
|
||||
These samplers are provided to allow you to sample from the resource as opposed to doing straight loads. They are bound by slot and not by variable name - so this means you can name them as you wish but you must specify the register binding explicitly.
|
||||
/* HLSL */
|
||||
SamplerState pointSampler : register(RD_POINT_SAMPLER_BINDING);
|
||||
SamplerState linearSampler : register(RD_LINEAR_SAMPLER_BINDING);
|
||||
|
||||
|
||||
/* GLSL */
|
||||
#ifdef VULKAN
|
||||
|
||||
layout(binding = RD_POINT_SAMPLER_BINDING) uniform sampler pointSampler;
|
||||
layout(binding = RD_LINEAR_SAMPLER_BINDING) uniform sampler linearSampler;
|
||||
|
||||
#endif
|
||||
|
||||
These samplers are provided to allow you to sample from the resource as opposed to doing straight loads. Samplers are not available on OpenGL, so it is recommended to protect the glsl definitions with ``#ifdef VULKAN`` as shown.
|
||||
|
||||
Resources
|
||||
~~~~~~~~~
|
||||
|
||||
D3D11 or D3D12 / HLSL
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
HLSL
|
||||
^^^^
|
||||
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
Texture1DArray<float4> texDisplayTex1DArray : register(t1);
|
||||
Texture2DArray<float4> texDisplayTex2DArray : register(t2);
|
||||
Texture3D<float4> texDisplayTex3D : register(t3);
|
||||
Texture2DArray<float2> texDisplayTexDepthArray : register(t4);
|
||||
Texture2DArray<uint2> texDisplayTexStencilArray : register(t5);
|
||||
Texture2DMSArray<float2> texDisplayTexDepthMSArray : register(t6);
|
||||
Texture2DMSArray<uint2> texDisplayTexStencilMSArray : register(t7);
|
||||
Texture2DMSArray<float4> texDisplayTex2DMSArray : register(t9);
|
||||
Texture2DArray<float4> texDisplayYUVArray : register(t10);
|
||||
// Float Textures
|
||||
Texture1DArray<float4> texDisplayTex1DArray : register(RD_FLOAT_1D_ARRAY_BINDING);
|
||||
Texture2DArray<float4> texDisplayTex2DArray : register(RD_FLOAT_2D_ARRAY_BINDING);
|
||||
Texture3D<float4> texDisplayTex3D : register(RD_FLOAT_3D_BINDING);
|
||||
Texture2DMSArray<float4> texDisplayTex2DMSArray : register(RD_FLOAT_2DMS_ARRAY_BINDING);
|
||||
Texture2DArray<float4> texDisplayYUVArray : register(RD_FLOAT_YUV_ARRAY_BINDING);
|
||||
|
||||
Texture1DArray<uint4> texDisplayUIntTex1DArray : register(t11);
|
||||
Texture2DArray<uint4> texDisplayUIntTex2DArray : register(t12);
|
||||
Texture3D<uint4> texDisplayUIntTex3D : register(t13);
|
||||
Texture2DMSArray<uint4> texDisplayUIntTex2DMSArray : register(t19);
|
||||
// only used on D3D
|
||||
Texture2DArray<float2> texDisplayTexDepthArray : register(RD_FLOAT_DEPTH_ARRAY_BINDING);
|
||||
Texture2DArray<uint2> texDisplayTexStencilArray : register(RD_FLOAT_STENCIL_ARRAY_BINDING);
|
||||
Texture2DMSArray<float2> texDisplayTexDepthMSArray : register(RD_FLOAT_DEPTHMS_ARRAY_BINDING);
|
||||
Texture2DMSArray<uint2> texDisplayTexStencilMSArray : register(RD_FLOAT_STENCILMS_ARRAY_BINDING);
|
||||
|
||||
Texture1DArray<int4> texDisplayIntTex1DArray : register(t21);
|
||||
Texture2DArray<int4> texDisplayIntTex2DArray : register(t22);
|
||||
Texture3D<int4> texDisplayIntTex3D : register(t23);
|
||||
Texture2DMSArray<int4> texDisplayIntTex2DMSArray : register(t29);
|
||||
// Int Textures
|
||||
Texture1DArray<int4> texDisplayIntTex1DArray : register(RD_INT_1D_ARRAY_BINDING);
|
||||
Texture2DArray<int4> texDisplayIntTex2DArray : register(RD_INT_2D_ARRAY_BINDING);
|
||||
Texture3D<int4> texDisplayIntTex3D : register(RD_INT_3D_BINDING);
|
||||
Texture2DMSArray<int4> texDisplayIntTex2DMSArray : register(RD_INT_2DMS_ARRAY_BINDING);
|
||||
|
||||
OpenGL / GLSL
|
||||
^^^^^^^^^^^^^
|
||||
// Unsigned int Textures
|
||||
Texture1DArray<uint4> texDisplayUIntTex1DArray : register(RD_UINT_1D_ARRAY_BINDING);
|
||||
Texture2DArray<uint4> texDisplayUIntTex2DArray : register(RD_UINT_2D_ARRAY_BINDING);
|
||||
Texture3D<uint4> texDisplayUIntTex3D : register(RD_UINT_3D_BINDING);
|
||||
Texture2DMSArray<uint4> texDisplayUIntTex2DMSArray : register(RD_UINT_2DMS_ARRAY_BINDING);
|
||||
|
||||
GLSL
|
||||
^^^^
|
||||
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
// Unsigned int samplers
|
||||
layout (binding = 1) uniform usampler1D texUInt1D;
|
||||
layout (binding = 2) uniform usampler2D texUInt2D;
|
||||
layout (binding = 3) uniform usampler3D texUInt3D;
|
||||
// skip cube = 4
|
||||
layout (binding = 5) uniform usampler1DArray texUInt1DArray;
|
||||
layout (binding = 6) uniform usampler2DArray texUInt2DArray;
|
||||
// skip cube array = 7
|
||||
layout (binding = 8) uniform usampler2DRect texUInt2DRect;
|
||||
layout (binding = 9) uniform usamplerBuffer texUIntBuffer;
|
||||
layout (binding = 10) uniform usampler2DMS texUInt2DMS;
|
||||
// Float Textures
|
||||
layout (binding = RD_FLOAT_1D_ARRAY_BINDING) uniform sampler1DArray tex1DArray;
|
||||
layout (binding = RD_FLOAT_2D_ARRAY_BINDING) uniform sampler2DArray tex2DArray;
|
||||
layout (binding = RD_FLOAT_3D_BINDING) uniform sampler3D tex3D;
|
||||
layout (binding = RD_FLOAT_2DMS_ARRAY_BINDING) uniform sampler2DMSArray tex2DMSArray;
|
||||
|
||||
// Int samplers
|
||||
layout (binding = 1) uniform isampler1D texSInt1D;
|
||||
layout (binding = 2) uniform isampler2D texSInt2D;
|
||||
layout (binding = 3) uniform isampler3D texSInt3D;
|
||||
// skip cube = 4
|
||||
layout (binding = 5) uniform isampler1DArray texSInt1DArray;
|
||||
layout (binding = 6) uniform isampler2DArray texSInt2DArray;
|
||||
// skip cube array = 7
|
||||
layout (binding = 8) uniform isampler2DRect texSInt2DRect;
|
||||
layout (binding = 9) uniform isamplerBuffer texSIntBuffer;
|
||||
layout (binding = 10) uniform isampler2DMS texSInt2DMS;
|
||||
// YUV textures only supported on vulkan
|
||||
#ifdef VULKAN
|
||||
layout(binding = RD_FLOAT_YUV_ARRAY_BINDING) uniform sampler2DArray texYUVArray[2];
|
||||
#endif
|
||||
|
||||
// Floating point samplers
|
||||
layout (binding = 1) uniform sampler1D tex1D;
|
||||
layout (binding = 2) uniform sampler2D tex2D;
|
||||
layout (binding = 3) uniform sampler3D tex3D;
|
||||
layout (binding = 4) uniform samplerCube texCube;
|
||||
layout (binding = 5) uniform sampler1DArray tex1DArray;
|
||||
layout (binding = 6) uniform sampler2DArray tex2DArray;
|
||||
layout (binding = 7) uniform samplerCubeArray texCubeArray;
|
||||
layout (binding = 8) uniform sampler2DRect tex2DRect;
|
||||
layout (binding = 9) uniform samplerBuffer texBuffer;
|
||||
layout (binding = 10) uniform sampler2DMS tex2DMS;
|
||||
// OpenGL has more texture types to match
|
||||
#ifndef VULKAN
|
||||
layout (binding = RD_FLOAT_1D_BINDING) uniform sampler1D tex1D;
|
||||
layout (binding = RD_FLOAT_2D_BINDING) uniform sampler2D tex2D;
|
||||
layout (binding = RD_FLOAT_CUBE_BINDING) uniform samplerCube texCube;
|
||||
layout (binding = RD_FLOAT_CUBE_ARRAY_BINDING) uniform samplerCubeArray texCubeArray;
|
||||
layout (binding = RD_FLOAT_RECT_BINDING) uniform sampler2DRect tex2DRect;
|
||||
layout (binding = RD_FLOAT_BUFFER_BINDING) uniform samplerBuffer texBuffer;
|
||||
layout (binding = RD_FLOAT_2DMS_BINDING) uniform sampler2DMS tex2DMS;
|
||||
#endif
|
||||
|
||||
Vulkan / GLSL
|
||||
^^^^^^^^^^^^^
|
||||
// Int Textures
|
||||
layout (binding = RD_INT_1D_ARRAY_BINDING) uniform isampler1DArray texSInt1DArray;
|
||||
layout (binding = RD_INT_2D_ARRAY_BINDING) uniform isampler2DArray texSInt2DArray;
|
||||
layout (binding = RD_INT_3D_BINDING) uniform isampler3D texSInt3D;
|
||||
layout (binding = RD_INT_2DMS_ARRAY_BINDING) uniform isampler2DMSArray texSInt2DMSArray;
|
||||
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
#ifndef VULKAN
|
||||
layout (binding = RD_INT_1D_BINDING) uniform isampler1D texSInt1D;
|
||||
layout (binding = RD_INT_2D_BINDING) uniform isampler2D texSInt2D;
|
||||
layout (binding = RD_INT_RECT_BINDING) uniform isampler2DRect texSInt2DRect;
|
||||
layout (binding = RD_INT_BUFFER_BINDING) uniform isamplerBuffer texSIntBuffer;
|
||||
layout (binding = RD_INT_2DMS_BINDING) uniform isampler2DMS texSInt2DMS;
|
||||
#endif
|
||||
|
||||
// Floating point samplers
|
||||
// Unsigned int Textures
|
||||
layout (binding = RD_UINT_1D_ARRAY_BINDING) uniform usampler1DArray texSInt1DArray;
|
||||
layout (binding = RD_UINT_2D_ARRAY_BINDING) uniform usampler2DArray texSInt2DArray;
|
||||
layout (binding = RD_UINT_3D_BINDING) uniform usampler3D texSInt3D;
|
||||
layout (binding = RD_UINT_2DMS_ARRAY_BINDING) uniform usampler2DMSArray texSInt2DMSArray;
|
||||
|
||||
// binding = 5 + RENDERDOC_TextureType
|
||||
layout(binding = 6) uniform sampler1DArray tex1DArray;
|
||||
layout(binding = 7) uniform sampler2DArray tex2DArray;
|
||||
layout(binding = 8) uniform sampler3D tex3D;
|
||||
layout(binding = 9) uniform sampler2DMS tex2DMS;
|
||||
layout(binding = 10) uniform sampler2DArray texYUV;
|
||||
|
||||
// Unsigned int samplers
|
||||
|
||||
// binding = 10 + RENDERDOC_TextureType
|
||||
layout(binding = 11) uniform usampler1DArray texUInt1DArray;
|
||||
layout(binding = 12) uniform usampler2DArray texUInt2DArray;
|
||||
layout(binding = 13) uniform usampler3D texUInt3D;
|
||||
layout(binding = 14) uniform usampler2DMS texUInt2DMS;
|
||||
|
||||
// Int samplers
|
||||
|
||||
// binding = 15 + RENDERDOC_TextureType
|
||||
layout(binding = 16) uniform isampler1DArray texSInt1DArray;
|
||||
layout(binding = 17) uniform isampler2DArray texSInt2DArray;
|
||||
layout(binding = 18) uniform isampler3D texSInt3D;
|
||||
layout(binding = 19) uniform isampler2DMS texSInt2DMS;
|
||||
#ifndef VULKAN
|
||||
layout (binding = RD_UINT_1D_BINDING) uniform usampler1D texSInt1D;
|
||||
layout (binding = RD_UINT_2D_BINDING) uniform usampler2D texSInt2D;
|
||||
layout (binding = RD_UINT_RECT_BINDING) uniform usampler2DRect texSInt2DRect;
|
||||
layout (binding = RD_UINT_BUFFER_BINDING) uniform usamplerBuffer texSIntBuffer;
|
||||
layout (binding = RD_UINT_2DMS_BINDING) uniform usampler2DMS texSInt2DMS;
|
||||
#endif
|
||||
|
||||
|
||||
These resources are bound sparsely with the appropriate type for the current texture. With a couple of exceptions there will only be one texture bound at any one time.
|
||||
These resources are bound sparsely with the appropriate type for the current texture. With a couple of exceptions there will only be one texture bound at any one time. Different APIs have different texture type matching requirements, so e.g. OpenGL has separate bindings for array and non-array texures, which will be reflected in the different ``RD_TextureType`` return values.
|
||||
|
||||
When a cubemap texture is bound, it is bound both to the 2D Array as well as the Cube Array. If a depth-stencil texture has both components, the relevant depth and stencil resources will both be bound at once.
|
||||
|
||||
@@ -351,7 +336,7 @@ Usually the float textures are used, but for unsigned and signed integer formats
|
||||
As with the samplers, these textures are bound by slot and not by name, so while you are free to name the variables as you wish, you must bind them explicitly to the slots listed here.
|
||||
|
||||
.. note::
|
||||
YUV textures may have additional planes bound as separate textures - for D3D this is ``texDisplayYUVArray`` and for Vulkan it's ``texYUV`` above. Whether to use these planes or not is specified in the texture dimension variables.
|
||||
YUV textures may have additional planes bound as separate textures - for D3D this is ``texDisplayYUVArray`` and for Vulkan it's ``texYUVArray`` above. Whether to use these planes or not is specified in the texture dimension variables.
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
@@ -981,6 +981,7 @@ void CaptureContext::LoadCaptureThreaded(const QString &captureFile, const Repla
|
||||
m_APIProps = r->GetAPIProperties();
|
||||
|
||||
m_CustomEncodings = r->GetCustomShaderEncodings();
|
||||
m_CustomPrefixes = r->GetCustomShaderSourcePrefixes();
|
||||
m_TargetEncodings = r->GetTargetShaderEncodings();
|
||||
|
||||
m_PostloadProgress = 0.2f;
|
||||
|
||||
@@ -155,6 +155,7 @@ public:
|
||||
const FrameDescription &FrameInfo() override { return m_FrameInfo; }
|
||||
const APIProperties &APIProps() override { return m_APIProps; }
|
||||
rdcarray<ShaderEncoding> CustomShaderEncodings() override { return m_CustomEncodings; }
|
||||
rdcarray<ShaderSourcePrefix> CustomShaderSourcePrefixes() override { return m_CustomPrefixes; }
|
||||
rdcarray<ShaderEncoding> TargetShaderEncodings() override { return m_TargetEncodings; }
|
||||
uint32_t CurSelectedEvent() override { return m_SelectedEventID; }
|
||||
uint32_t CurEvent() override { return m_EventID; }
|
||||
@@ -362,6 +363,7 @@ private:
|
||||
rdcarray<ActionDescription> m_EmptyActions;
|
||||
|
||||
rdcarray<ShaderEncoding> m_CustomEncodings, m_TargetEncodings;
|
||||
rdcarray<ShaderSourcePrefix> m_CustomPrefixes;
|
||||
APIProperties m_APIProps;
|
||||
FrameDescription m_FrameInfo;
|
||||
const ActionDescription *m_FirstAction = NULL;
|
||||
|
||||
@@ -1945,6 +1945,15 @@ building custom shaders for the currently loaded capture. See
|
||||
)");
|
||||
virtual rdcarray<ShaderEncoding> CustomShaderEncodings() = 0;
|
||||
|
||||
DOCUMENT(R"(Retrieve the list of prefixes for each :class:`~renderdoc.ShaderEncoding` that should
|
||||
be added to custom compiled shaders. See
|
||||
:meth:`~renderdoc.ReplayController.GetCustomShaderSourcePrefixes`.
|
||||
|
||||
:return: A list of pairs, listing a prefix for each shader encoding referenced.
|
||||
:rtype: List[Tuple[ShaderEncoding,str]]
|
||||
)");
|
||||
virtual rdcarray<ShaderSourcePrefix> CustomShaderSourcePrefixes() = 0;
|
||||
|
||||
DOCUMENT(R"(Retrieve the currently selected :data:`eventId <renderdoc.APIEvent.eventId>`.
|
||||
|
||||
In most cases, prefer using :meth:`CurEvent`. See :meth:`CaptureViewer.OnSelectedEventChanged` for more
|
||||
|
||||
@@ -373,6 +373,7 @@ TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderMessage)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderResource)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderSampler)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderSourceFile)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderSourcePrefix)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderVariable)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderEncoding)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderVariableChange)
|
||||
|
||||
@@ -430,6 +430,10 @@ struct CaptureContextInvoker : ObjectForwarder<ICaptureContext>
|
||||
{
|
||||
return m_Obj.CustomShaderEncodings();
|
||||
}
|
||||
virtual rdcarray<ShaderSourcePrefix> CustomShaderSourcePrefixes() override
|
||||
{
|
||||
return m_Obj.CustomShaderSourcePrefixes();
|
||||
}
|
||||
virtual uint32_t CurSelectedEvent() override { return m_Obj.CurSelectedEvent(); }
|
||||
virtual uint32_t CurEvent() override { return m_Obj.CurEvent(); }
|
||||
virtual const ActionDescription *CurSelectedAction() override
|
||||
|
||||
+202
-398
@@ -181,34 +181,17 @@ ShaderViewer::ShaderViewer(ICaptureContext &ctx, QWidget *parent)
|
||||
{
|
||||
QMenu *snippetsMenu = new QMenu(this);
|
||||
|
||||
QAction *dim = new QAction(tr("Texture Dimensions Global"), this);
|
||||
QAction *mip = new QAction(tr("Selected Mip Global"), this);
|
||||
QAction *slice = new QAction(tr("Selected Array Slice / Cubemap Face Global"), this);
|
||||
QAction *sample = new QAction(tr("Selected Sample Global"), this);
|
||||
QAction *range = new QAction(tr("Selected TextureViewer Range Global"), this);
|
||||
QAction *type = new QAction(tr("Texture Type Global"), this);
|
||||
QAction *constants = new QAction(tr("Per-texture constants"), this);
|
||||
QAction *samplers = new QAction(tr("Point && Linear Samplers"), this);
|
||||
QAction *resources = new QAction(tr("Texture Resources"), this);
|
||||
|
||||
snippetsMenu->addAction(dim);
|
||||
snippetsMenu->addAction(mip);
|
||||
snippetsMenu->addAction(slice);
|
||||
snippetsMenu->addAction(sample);
|
||||
snippetsMenu->addAction(range);
|
||||
snippetsMenu->addAction(type);
|
||||
snippetsMenu->addSeparator();
|
||||
snippetsMenu->addAction(constants);
|
||||
snippetsMenu->addAction(samplers);
|
||||
snippetsMenu->addAction(resources);
|
||||
|
||||
QObject::connect(dim, &QAction::triggered, this, &ShaderViewer::snippet_textureDimensions);
|
||||
QObject::connect(mip, &QAction::triggered, this, &ShaderViewer::snippet_selectedMip);
|
||||
QObject::connect(slice, &QAction::triggered, this, &ShaderViewer::snippet_selectedSlice);
|
||||
QObject::connect(sample, &QAction::triggered, this, &ShaderViewer::snippet_selectedSample);
|
||||
QObject::connect(range, &QAction::triggered, this, &ShaderViewer::snippet_selectedRange);
|
||||
QObject::connect(type, &QAction::triggered, this, &ShaderViewer::snippet_selectedType);
|
||||
QObject::connect(constants, &QAction::triggered, this, &ShaderViewer::snippet_constants);
|
||||
QObject::connect(samplers, &QAction::triggered, this, &ShaderViewer::snippet_samplers);
|
||||
QObject::connect(resources, &QAction::triggered, this, &ShaderViewer::snippet_resources);
|
||||
QObject::connect(resources, &QAction::triggered, this, &ShaderViewer::snippet_resources);
|
||||
|
||||
ui->snippets->setMenu(snippetsMenu);
|
||||
}
|
||||
@@ -282,7 +265,18 @@ void ShaderViewer::editShader(ResourceId id, ShaderStage stage, const QString &e
|
||||
ui->callstack->hide();
|
||||
ui->sourceVars->hide();
|
||||
|
||||
ui->snippets->setVisible(m_CustomShader);
|
||||
if(m_CustomShader)
|
||||
{
|
||||
ui->snippets->show();
|
||||
ui->refresh->setText(tr("Refresh"));
|
||||
ui->resetEdits->hide();
|
||||
ui->unrefresh->hide();
|
||||
ui->editStatusLabel->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->snippets->hide();
|
||||
}
|
||||
|
||||
// hide debugging toolbar buttons
|
||||
ui->editSep->hide();
|
||||
@@ -4351,270 +4345,105 @@ void ShaderViewer::insertSnippet(const QString &text)
|
||||
m_Scintillas[0]->setSelection(0, 0);
|
||||
}
|
||||
|
||||
QString ShaderViewer::vulkanUBO()
|
||||
void ShaderViewer::snippet_constants()
|
||||
{
|
||||
ShaderEncoding encoding = currentEncoding();
|
||||
|
||||
QString text;
|
||||
|
||||
if(encoding == ShaderEncoding::GLSL)
|
||||
{
|
||||
return lit(R"(
|
||||
layout(binding = 0, std140) uniform RENDERDOC_Uniforms
|
||||
{
|
||||
uvec4 TexDim;
|
||||
uint SelectedMip;
|
||||
int TextureType; // 1 = 1D, 2 = 2D, 3 = 3D, 4 = 2DMS
|
||||
uint SelectedSliceFace;
|
||||
int SelectedSample;
|
||||
uvec4 YUVDownsampleRate;
|
||||
uvec4 YUVAChannels;
|
||||
float SelectedRangeMin;
|
||||
float SelectedRangeMax;
|
||||
} RENDERDOC;
|
||||
text = lit(R"(
|
||||
// possible values (these are only return values from this function, NOT texture binding points):
|
||||
// RD_TextureType_1D
|
||||
// RD_TextureType_2D
|
||||
// RD_TextureType_3D
|
||||
// RD_TextureType_Cube (OpenGL only)
|
||||
// RD_TextureType_1D_Array (OpenGL only)
|
||||
// RD_TextureType_2D_Array (OpenGL only)
|
||||
// RD_TextureType_Cube_Array (OpenGL only)
|
||||
// RD_TextureType_Rect (OpenGL only)
|
||||
// RD_TextureType_Buffer (OpenGL only)
|
||||
// RD_TextureType_2DMS
|
||||
// RD_TextureType_2DMS_Array (OpenGL only)
|
||||
uint RD_TextureType();
|
||||
|
||||
#define RENDERDOC_TexDim RENDERDOC.TexDim
|
||||
#define RENDERDOC_SelectedMip RENDERDOC.SelectedMip
|
||||
#define RENDERDOC_TextureType RENDERDOC.TextureType
|
||||
#define RENDERDOC_SelectedSliceFace RENDERDOC.SelectedSliceFace
|
||||
#define RENDERDOC_SelectedSample RENDERDOC.SelectedSample
|
||||
#define RENDERDOC_YUVDownsampleRate RENDERDOC.YUVDownsampleRate
|
||||
#define RENDERDOC_YUVAChannels RENDERDOC.YUVAChannels
|
||||
#define RENDERDOC_SelectedRangeMin RENDERDOC.SelectedRangeMin
|
||||
#define RENDERDOC_SelectedRangeMax RENDERDOC.SelectedRangeMax
|
||||
// selected sample, or -numSamples for resolve
|
||||
int RD_SelectedSample();
|
||||
|
||||
uint RD_SelectedSliceFace();
|
||||
|
||||
uint RD_SelectedMip();
|
||||
|
||||
// xyz = width, height, depth (or array size). w = # mips
|
||||
uvec4 RD_TexDim();
|
||||
|
||||
// x = horizontal downsample rate (1 full rate, 2 half rate)
|
||||
// y = vertical downsample rate
|
||||
// z = number of planes in input texture
|
||||
// w = number of bits per component (8, 10, 16)
|
||||
uvec4 RD_YUVDownsampleRate();
|
||||
|
||||
// x = where Y channel comes from
|
||||
// y = where U channel comes from
|
||||
// z = where V channel comes from
|
||||
// w = where A channel comes from
|
||||
// each index will be [0,1,2,3] for xyzw in first plane,
|
||||
// [4,5,6,7] for xyzw in second plane texture, etc.
|
||||
// it will be 0xff = 255 if the channel does not exist.
|
||||
uvec4 RD_YUVAChannels();
|
||||
|
||||
// a pair with minimum and maximum selected range values
|
||||
vec2 RD_SelectedRange();
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::HLSL)
|
||||
{
|
||||
return lit(R"(
|
||||
cbuffer RENDERDOC_Constants : register(b0)
|
||||
{
|
||||
uint4 RENDERDOC_TexDim;
|
||||
uint RENDERDOC_SelectedMip;
|
||||
int RENDERDOC_TextureType; // 1 = 1D, 2 = 2D, 3 = 3D, 4 = 2DMS
|
||||
uint RENDERDOC_SelectedSliceFace;
|
||||
int RENDERDOC_SelectedSample;
|
||||
uint4 RENDERDOC_YUVDownsampleRate;
|
||||
uint4 RENDERDOC_YUVAChannels;
|
||||
float RENDERDOC_SelectedRangeMin;
|
||||
float RENDERDOC_SelectedRangeMax;
|
||||
};
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::SPIRVAsm)
|
||||
{
|
||||
return lit("; Can't insert snippets for SPIR-V ASM");
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
void ShaderViewer::snippet_textureDimensions()
|
||||
{
|
||||
ShaderEncoding encoding = currentEncoding();
|
||||
GraphicsAPI api = m_Ctx.APIProps().localRenderer;
|
||||
|
||||
QString text;
|
||||
|
||||
if(api == GraphicsAPI::Vulkan)
|
||||
{
|
||||
text = vulkanUBO();
|
||||
}
|
||||
else if(encoding == ShaderEncoding::HLSL)
|
||||
{
|
||||
text = lit(R"(
|
||||
// xyz == width, height, depth. w == # mips
|
||||
uint4 RENDERDOC_TexDim;
|
||||
uint4 RENDERDOC_YUVDownsampleRate;
|
||||
uint4 RENDERDOC_YUVAChannels;
|
||||
/////////////////////////////////////
|
||||
// Constants //
|
||||
/////////////////////////////////////
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::GLSL)
|
||||
{
|
||||
text = lit(R"(
|
||||
// xyz == width, height, depth. w == # mips
|
||||
uniform uvec4 RENDERDOC_TexDim;
|
||||
// possible values (these are only return values from this function, NOT texture binding points):
|
||||
// RD_TextureType_1D
|
||||
// RD_TextureType_2D
|
||||
// RD_TextureType_3D
|
||||
// RD_TextureType_Depth
|
||||
// RD_TextureType_DepthStencil
|
||||
// RD_TextureType_DepthMS
|
||||
// RD_TextureType_DepthStencilMS
|
||||
uint RD_TextureType();
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::SPIRVAsm)
|
||||
{
|
||||
text = lit("; Can't insert snippets for SPIR-V ASM");
|
||||
}
|
||||
// selected sample, or -numSamples for resolve
|
||||
int RD_SelectedSample();
|
||||
|
||||
insertSnippet(text);
|
||||
}
|
||||
uint RD_SelectedSliceFace();
|
||||
|
||||
void ShaderViewer::snippet_selectedMip()
|
||||
{
|
||||
ShaderEncoding encoding = currentEncoding();
|
||||
GraphicsAPI api = m_Ctx.APIProps().localRenderer;
|
||||
uint RD_SelectedMip();
|
||||
|
||||
QString text;
|
||||
// xyz = width, height, depth. w = # mips
|
||||
uint4 RD_TexDim();
|
||||
|
||||
if(api == GraphicsAPI::Vulkan)
|
||||
{
|
||||
text = vulkanUBO();
|
||||
}
|
||||
else if(encoding == ShaderEncoding::HLSL)
|
||||
{
|
||||
text = lit(R"(
|
||||
// selected mip in UI
|
||||
uint RENDERDOC_SelectedMip;
|
||||
// x = horizontal downsample rate (1 full rate, 2 half rate)
|
||||
// y = vertical downsample rate
|
||||
// z = number of planes in input texture
|
||||
// w = number of bits per component (8, 10, 16)
|
||||
uint4 RD_YUVDownsampleRate();
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::GLSL)
|
||||
{
|
||||
text = lit(R"(
|
||||
// selected mip in UI
|
||||
uniform uint RENDERDOC_SelectedMip;
|
||||
// x = where Y channel comes from
|
||||
// y = where U channel comes from
|
||||
// z = where V channel comes from
|
||||
// w = where A channel comes from
|
||||
// each index will be [0,1,2,3] for xyzw in first plane,
|
||||
// [4,5,6,7] for xyzw in second plane texture, etc.
|
||||
// it will be 0xff = 255 if the channel does not exist.
|
||||
uint4 RD_YUVAChannels();
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::SPIRVAsm)
|
||||
{
|
||||
text = lit("; Can't insert snippets for SPIR-V ASM");
|
||||
}
|
||||
// a pair with minimum and maximum selected range values
|
||||
float2 RD_SelectedRange();
|
||||
|
||||
insertSnippet(text);
|
||||
}
|
||||
|
||||
void ShaderViewer::snippet_selectedSlice()
|
||||
{
|
||||
ShaderEncoding encoding = currentEncoding();
|
||||
GraphicsAPI api = m_Ctx.APIProps().localRenderer;
|
||||
|
||||
QString text;
|
||||
|
||||
if(api == GraphicsAPI::Vulkan)
|
||||
{
|
||||
text = vulkanUBO();
|
||||
}
|
||||
else if(encoding == ShaderEncoding::HLSL)
|
||||
{
|
||||
text = lit(R"(
|
||||
// selected array slice or cubemap face in UI
|
||||
uint RENDERDOC_SelectedSliceFace;
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::GLSL)
|
||||
{
|
||||
text = lit(R"(
|
||||
// selected array slice or cubemap face in UI
|
||||
uniform uint RENDERDOC_SelectedSliceFace;
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::SPIRVAsm)
|
||||
{
|
||||
text = lit("; Can't insert snippets for SPIR-V ASM");
|
||||
}
|
||||
|
||||
insertSnippet(text);
|
||||
}
|
||||
|
||||
void ShaderViewer::snippet_selectedSample()
|
||||
{
|
||||
ShaderEncoding encoding = currentEncoding();
|
||||
GraphicsAPI api = m_Ctx.APIProps().localRenderer;
|
||||
|
||||
QString text;
|
||||
|
||||
if(api == GraphicsAPI::Vulkan)
|
||||
{
|
||||
text = vulkanUBO();
|
||||
}
|
||||
else if(encoding == ShaderEncoding::HLSL)
|
||||
{
|
||||
text = lit(R"(
|
||||
// selected MSAA sample or -numSamples for resolve. See docs
|
||||
int RENDERDOC_SelectedSample;
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::GLSL)
|
||||
{
|
||||
text = lit(R"(
|
||||
// selected MSAA sample or -numSamples for resolve. See docs
|
||||
uniform int RENDERDOC_SelectedSample;
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::SPIRVAsm)
|
||||
{
|
||||
text = lit("; Can't insert snippets for SPIR-V ASM");
|
||||
}
|
||||
|
||||
insertSnippet(text);
|
||||
}
|
||||
|
||||
void ShaderViewer::snippet_selectedRange()
|
||||
{
|
||||
ShaderEncoding encoding = currentEncoding();
|
||||
GraphicsAPI api = m_Ctx.APIProps().localRenderer;
|
||||
|
||||
QString text;
|
||||
|
||||
if(api == GraphicsAPI::Vulkan)
|
||||
{
|
||||
text = vulkanUBO();
|
||||
}
|
||||
else if(encoding == ShaderEncoding::HLSL)
|
||||
{
|
||||
text = lit(R"(
|
||||
// selected range min/max in UI
|
||||
float RENDERDOC_SelectedRangeMin;
|
||||
float RENDERDOC_SelectedRangeMax;
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::GLSL)
|
||||
{
|
||||
text = lit(R"(
|
||||
// selected range minmax in UI
|
||||
float RENDERDOC_SelectedRangeMin;
|
||||
float RENDERDOC_SelectedRangeMax;
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::SPIRVAsm)
|
||||
{
|
||||
text = lit("; Can't insert snippets for SPIR-V ASM");
|
||||
}
|
||||
|
||||
insertSnippet(text);
|
||||
}
|
||||
|
||||
void ShaderViewer::snippet_selectedType()
|
||||
{
|
||||
ShaderEncoding encoding = currentEncoding();
|
||||
GraphicsAPI api = m_Ctx.APIProps().localRenderer;
|
||||
|
||||
QString text;
|
||||
|
||||
if(api == GraphicsAPI::Vulkan)
|
||||
{
|
||||
text = vulkanUBO();
|
||||
}
|
||||
else if(encoding == ShaderEncoding::HLSL)
|
||||
{
|
||||
text = lit(R"(
|
||||
// 1 = 1D, 2 = 2D, 3 = 3D, 4 = Depth, 5 = Depth + Stencil
|
||||
// 6 = Depth (MS), 7 = Depth + Stencil (MS), 9 = 2DMS
|
||||
uint RENDERDOC_TextureType;
|
||||
|
||||
)");
|
||||
}
|
||||
else if(encoding == ShaderEncoding::GLSL)
|
||||
{
|
||||
text = lit(R"(
|
||||
// 1 = 1D, 2 = 2D, 3 = 3D, 4 = Cube
|
||||
// 5 = 1DArray, 6 = 2DArray, 7 = CubeArray
|
||||
// 8 = Rect, 9 = Buffer, 10 = 2DMS, 11 = 2DMSArray
|
||||
uniform uint RENDERDOC_TextureType;
|
||||
/////////////////////////////////////
|
||||
|
||||
)");
|
||||
}
|
||||
@@ -4629,28 +4458,38 @@ uniform uint RENDERDOC_TextureType;
|
||||
void ShaderViewer::snippet_samplers()
|
||||
{
|
||||
ShaderEncoding encoding = currentEncoding();
|
||||
GraphicsAPI api = m_Ctx.APIProps().localRenderer;
|
||||
|
||||
if(encoding == ShaderEncoding::HLSL)
|
||||
{
|
||||
if(api == GraphicsAPI::Vulkan)
|
||||
{
|
||||
insertSnippet(lit(R"(
|
||||
// Samplers
|
||||
SamplerState pointSampler : register(s50);
|
||||
SamplerState linearSampler : register(s51);
|
||||
// End Samplers
|
||||
insertSnippet(lit(R"(
|
||||
/////////////////////////////////////
|
||||
// Samplers //
|
||||
/////////////////////////////////////
|
||||
|
||||
SamplerState pointSampler : register(RD_POINT_SAMPLER_BINDING);
|
||||
SamplerState linearSampler : register(RD_LINEAR_SAMPLER_BINDING);
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
insertSnippet(lit(R"(
|
||||
// Samplers
|
||||
SamplerState pointSampler : register(s0);
|
||||
SamplerState linearSampler : register(s1);
|
||||
// End Samplers
|
||||
}
|
||||
else
|
||||
{
|
||||
insertSnippet(lit(R"(
|
||||
|
||||
/////////////////////////////////////
|
||||
// Samplers //
|
||||
/////////////////////////////////////
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
layout(binding = RD_POINT_SAMPLER_BINDING) uniform sampler pointSampler;
|
||||
layout(binding = RD_LINEAR_SAMPLER_BINDING) uniform sampler linearSampler;
|
||||
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////
|
||||
)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4661,132 +4500,97 @@ void ShaderViewer::snippet_resources()
|
||||
|
||||
if(encoding == ShaderEncoding::HLSL)
|
||||
{
|
||||
if(api == GraphicsAPI::Vulkan)
|
||||
{
|
||||
insertSnippet(lit(R"(
|
||||
// Textures
|
||||
// Floating point
|
||||
Texture1DArray<float4> texDisplayTex1DArray : register(t6);
|
||||
Texture2DArray<float4> texDisplayTex2DArray : register(t7);
|
||||
Texture3D<float4> texDisplayTex3D : register(t8);
|
||||
Texture2DMSArray<float4> texDisplayTex2DMSArray : register(t9);
|
||||
Texture2DArray<float4> texDisplayYUVArray : register(t10);
|
||||
insertSnippet(lit(R"(
|
||||
/////////////////////////////////////
|
||||
// Resources //
|
||||
/////////////////////////////////////
|
||||
|
||||
// Unsigned int
|
||||
Texture1DArray<uint4> texDisplayUIntTex1DArray : register(t11);
|
||||
Texture2DArray<uint4> texDisplayUIntTex2DArray : register(t12);
|
||||
Texture3D<uint4> texDisplayUIntTex3D : register(t13);
|
||||
Texture2DMSArray<uint4> texDisplayUIntTex2DMSArray : register(t14);
|
||||
// Float Textures
|
||||
Texture1DArray<float4> texDisplayTex1DArray : register(RD_FLOAT_1D_ARRAY_BINDING);
|
||||
Texture2DArray<float4> texDisplayTex2DArray : register(RD_FLOAT_2D_ARRAY_BINDING);
|
||||
Texture3D<float4> texDisplayTex3D : register(RD_FLOAT_3D_BINDING);
|
||||
Texture2DMSArray<float4> texDisplayTex2DMSArray : register(RD_FLOAT_2DMS_ARRAY_BINDING);
|
||||
Texture2DArray<float4> texDisplayYUVArray : register(RD_FLOAT_YUV_ARRAY_BINDING);
|
||||
|
||||
// only used on D3D
|
||||
Texture2DArray<float2> texDisplayTexDepthArray : register(RD_FLOAT_DEPTH_ARRAY_BINDING);
|
||||
Texture2DArray<uint2> texDisplayTexStencilArray : register(RD_FLOAT_STENCIL_ARRAY_BINDING);
|
||||
Texture2DMSArray<float2> texDisplayTexDepthMSArray : register(RD_FLOAT_DEPTHMS_ARRAY_BINDING);
|
||||
Texture2DMSArray<uint2> texDisplayTexStencilMSArray : register(RD_FLOAT_STENCILMS_ARRAY_BINDING);
|
||||
|
||||
// Int Textures
|
||||
Texture1DArray<int4> texDisplayIntTex1DArray : register(RD_INT_1D_ARRAY_BINDING);
|
||||
Texture2DArray<int4> texDisplayIntTex2DArray : register(RD_INT_2D_ARRAY_BINDING);
|
||||
Texture3D<int4> texDisplayIntTex3D : register(RD_INT_3D_BINDING);
|
||||
Texture2DMSArray<int4> texDisplayIntTex2DMSArray : register(RD_INT_2DMS_ARRAY_BINDING);
|
||||
|
||||
// Unsigned int Textures
|
||||
Texture1DArray<uint4> texDisplayUIntTex1DArray : register(RD_UINT_1D_ARRAY_BINDING);
|
||||
Texture2DArray<uint4> texDisplayUIntTex2DArray : register(RD_UINT_2D_ARRAY_BINDING);
|
||||
Texture3D<uint4> texDisplayUIntTex3D : register(RD_UINT_3D_BINDING);
|
||||
Texture2DMSArray<uint4> texDisplayUIntTex2DMSArray : register(RD_UINT_2DMS_ARRAY_BINDING);
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
// Int
|
||||
Texture1DArray<int4> texDisplayIntTex1DArray : register(t16);
|
||||
Texture2DArray<int4> texDisplayIntTex2DArray : register(t17);
|
||||
Texture3D<int4> texDisplayIntTex3D : register(t18);
|
||||
Texture2DMSArray<int4> texDisplayIntTex2DMSArray : register(t19);
|
||||
// End Textures
|
||||
)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
insertSnippet(lit(R"(
|
||||
// Textures
|
||||
Texture1DArray<float4> texDisplayTex1DArray : register(t1);
|
||||
Texture2DArray<float4> texDisplayTex2DArray : register(t2);
|
||||
Texture3D<float4> texDisplayTex3D : register(t3);
|
||||
Texture2DArray<float2> texDisplayTexDepthArray : register(t4);
|
||||
Texture2DArray<uint2> texDisplayTexStencilArray : register(t5);
|
||||
Texture2DMSArray<float2> texDisplayTexDepthMSArray : register(t6);
|
||||
Texture2DMSArray<uint2> texDisplayTexStencilMSArray : register(t7);
|
||||
Texture2DMSArray<float4> texDisplayTex2DMSArray : register(t9);
|
||||
Texture2DArray<float4> texDisplayYUVArray : register(t10);
|
||||
|
||||
// Unsigned int
|
||||
Texture1DArray<uint4> texDisplayUIntTex1DArray : register(t11);
|
||||
Texture2DArray<uint4> texDisplayUIntTex2DArray : register(t12);
|
||||
Texture3D<uint4> texDisplayUIntTex3D : register(t13);
|
||||
Texture2DMSArray<uint4> texDisplayUIntTex2DMSArray : register(t19);
|
||||
|
||||
// Int
|
||||
Texture1DArray<int4> texDisplayIntTex1DArray : register(t21);
|
||||
Texture2DArray<int4> texDisplayIntTex2DArray : register(t22);
|
||||
Texture3D<int4> texDisplayIntTex3D : register(t23);
|
||||
Texture2DMSArray<int4> texDisplayIntTex2DMSArray : register(t29);
|
||||
// End Textures
|
||||
)"));
|
||||
}
|
||||
}
|
||||
else if(encoding == ShaderEncoding::GLSL)
|
||||
{
|
||||
if(api == GraphicsAPI::Vulkan)
|
||||
{
|
||||
insertSnippet(lit(R"(
|
||||
// Textures
|
||||
// Floating point samplers
|
||||
layout(binding = 6) uniform sampler1DArray tex1DArray;
|
||||
layout(binding = 7) uniform sampler2DArray tex2DArray;
|
||||
layout(binding = 8) uniform sampler3D tex3D;
|
||||
layout(binding = 9) uniform sampler2DMS tex2DMS;
|
||||
layout(binding = 10) uniform sampler2DArray texYUVArray[2];
|
||||
insertSnippet(lit(R"(
|
||||
/////////////////////////////////////
|
||||
// Resources //
|
||||
/////////////////////////////////////
|
||||
|
||||
// Unsigned int samplers
|
||||
layout(binding = 11) uniform usampler1DArray texUInt1DArray;
|
||||
layout(binding = 12) uniform usampler2DArray texUInt2DArray;
|
||||
layout(binding = 13) uniform usampler3D texUInt3D;
|
||||
layout(binding = 14) uniform usampler2DMS texUInt2DMS;
|
||||
// Float Textures
|
||||
layout (binding = RD_FLOAT_1D_ARRAY_BINDING) uniform sampler1DArray tex1DArray;
|
||||
layout (binding = RD_FLOAT_2D_ARRAY_BINDING) uniform sampler2DArray tex2DArray;
|
||||
layout (binding = RD_FLOAT_3D_BINDING) uniform sampler3D tex3D;
|
||||
layout (binding = RD_FLOAT_2DMS_ARRAY_BINDING) uniform sampler2DMSArray tex2DMSArray;
|
||||
|
||||
// Int samplers
|
||||
layout(binding = 16) uniform isampler1DArray texSInt1DArray;
|
||||
layout(binding = 17) uniform isampler2DArray texSInt2DArray;
|
||||
layout(binding = 18) uniform isampler3D texSInt3D;
|
||||
layout(binding = 19) uniform isampler2DMS texSInt2DMS;
|
||||
// End Textures
|
||||
// YUV textures only supported on vulkan
|
||||
#ifdef VULKAN
|
||||
layout(binding = RD_FLOAT_YUV_ARRAY_BINDING) uniform sampler2DArray texYUVArray[2];
|
||||
#endif
|
||||
|
||||
// OpenGL has more texture types to match
|
||||
#ifndef VULKAN
|
||||
layout (binding = RD_FLOAT_1D_BINDING) uniform sampler1D tex1D;
|
||||
layout (binding = RD_FLOAT_2D_BINDING) uniform sampler2D tex2D;
|
||||
layout (binding = RD_FLOAT_CUBE_BINDING) uniform samplerCube texCube;
|
||||
layout (binding = RD_FLOAT_CUBE_ARRAY_BINDING) uniform samplerCubeArray texCubeArray;
|
||||
layout (binding = RD_FLOAT_RECT_BINDING) uniform sampler2DRect tex2DRect;
|
||||
layout (binding = RD_FLOAT_BUFFER_BINDING) uniform samplerBuffer texBuffer;
|
||||
layout (binding = RD_FLOAT_2DMS_BINDING) uniform sampler2DMS tex2DMS;
|
||||
#endif
|
||||
|
||||
// Int Textures
|
||||
layout (binding = RD_INT_1D_ARRAY_BINDING) uniform isampler1DArray texSInt1DArray;
|
||||
layout (binding = RD_INT_2D_ARRAY_BINDING) uniform isampler2DArray texSInt2DArray;
|
||||
layout (binding = RD_INT_3D_BINDING) uniform isampler3D texSInt3D;
|
||||
layout (binding = RD_INT_2DMS_ARRAY_BINDING) uniform isampler2DMSArray texSInt2DMSArray;
|
||||
|
||||
#ifndef VULKAN
|
||||
layout (binding = RD_INT_1D_BINDING) uniform isampler1D texSInt1D;
|
||||
layout (binding = RD_INT_2D_BINDING) uniform isampler2D texSInt2D;
|
||||
layout (binding = RD_INT_RECT_BINDING) uniform isampler2DRect texSInt2DRect;
|
||||
layout (binding = RD_INT_BUFFER_BINDING) uniform isamplerBuffer texSIntBuffer;
|
||||
layout (binding = RD_INT_2DMS_BINDING) uniform isampler2DMS texSInt2DMS;
|
||||
#endif
|
||||
|
||||
// Unsigned int Textures
|
||||
layout (binding = RD_UINT_1D_ARRAY_BINDING) uniform usampler1DArray texSInt1DArray;
|
||||
layout (binding = RD_UINT_2D_ARRAY_BINDING) uniform usampler2DArray texSInt2DArray;
|
||||
layout (binding = RD_UINT_3D_BINDING) uniform usampler3D texSInt3D;
|
||||
layout (binding = RD_UINT_2DMS_ARRAY_BINDING) uniform usampler2DMSArray texSInt2DMSArray;
|
||||
|
||||
#ifndef VULKAN
|
||||
layout (binding = RD_UINT_1D_BINDING) uniform usampler1D texSInt1D;
|
||||
layout (binding = RD_UINT_2D_BINDING) uniform usampler2D texSInt2D;
|
||||
layout (binding = RD_UINT_RECT_BINDING) uniform usampler2DRect texSInt2DRect;
|
||||
layout (binding = RD_UINT_BUFFER_BINDING) uniform usamplerBuffer texSIntBuffer;
|
||||
layout (binding = RD_UINT_2DMS_BINDING) uniform usampler2DMS texSInt2DMS;
|
||||
#endif
|
||||
)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
insertSnippet(lit(R"(
|
||||
// Textures
|
||||
// Unsigned int samplers
|
||||
layout (binding = 1) uniform usampler1D texUInt1D;
|
||||
layout (binding = 2) uniform usampler2D texUInt2D;
|
||||
layout (binding = 3) uniform usampler3D texUInt3D;
|
||||
// cube = 4
|
||||
layout (binding = 5) uniform usampler1DArray texUInt1DArray;
|
||||
layout (binding = 6) uniform usampler2DArray texUInt2DArray;
|
||||
// cube array = 7
|
||||
layout (binding = 8) uniform usampler2DRect texUInt2DRect;
|
||||
layout (binding = 9) uniform usamplerBuffer texUIntBuffer;
|
||||
layout (binding = 10) uniform usampler2DMS texUInt2DMS;
|
||||
layout (binding = 11) uniform usampler2DMSArray texUInt2DMSArray;
|
||||
|
||||
// Int samplers
|
||||
layout (binding = 1) uniform isampler1D texSInt1D;
|
||||
layout (binding = 2) uniform isampler2D texSInt2D;
|
||||
layout (binding = 3) uniform isampler3D texSInt3D;
|
||||
// cube = 4
|
||||
layout (binding = 5) uniform isampler1DArray texSInt1DArray;
|
||||
layout (binding = 6) uniform isampler2DArray texSInt2DArray;
|
||||
// cube array = 7
|
||||
layout (binding = 8) uniform isampler2DRect texSInt2DRect;
|
||||
layout (binding = 9) uniform isamplerBuffer texSIntBuffer;
|
||||
layout (binding = 10) uniform isampler2DMS texSInt2DMS;
|
||||
layout (binding = 11) uniform isampler2DMSArray texSInt2DMSArray;
|
||||
|
||||
// Floating point samplers
|
||||
layout (binding = 1) uniform sampler1D tex1D;
|
||||
layout (binding = 2) uniform sampler2D tex2D;
|
||||
layout (binding = 3) uniform sampler3D tex3D;
|
||||
layout (binding = 4) uniform samplerCube texCube;
|
||||
layout (binding = 5) uniform sampler1DArray tex1DArray;
|
||||
layout (binding = 6) uniform sampler2DArray tex2DArray;
|
||||
layout (binding = 7) uniform samplerCubeArray texCubeArray;
|
||||
layout (binding = 8) uniform sampler2DRect tex2DRect;
|
||||
layout (binding = 9) uniform samplerBuffer texBuffer;
|
||||
layout (binding = 10) uniform sampler2DMS tex2DMS;
|
||||
layout (binding = 11) uniform sampler2DMSArray tex2DMSArray;
|
||||
// End Textures
|
||||
)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -166,12 +166,7 @@ private slots:
|
||||
void performReplace();
|
||||
void performReplaceAll();
|
||||
|
||||
void snippet_textureDimensions();
|
||||
void snippet_selectedMip();
|
||||
void snippet_selectedSlice();
|
||||
void snippet_selectedSample();
|
||||
void snippet_selectedRange();
|
||||
void snippet_selectedType();
|
||||
void snippet_constants();
|
||||
void snippet_samplers();
|
||||
void snippet_resources();
|
||||
|
||||
|
||||
@@ -4246,7 +4246,8 @@ void TextureViewer::reloadCustomShaders(const QString &filter)
|
||||
|
||||
bytebuf shaderBytes(source.toUtf8());
|
||||
|
||||
rdcarray<ShaderEncoding> supported = m_Ctx.TargetShaderEncodings();
|
||||
rdcarray<ShaderEncoding> supported = m_Ctx.CustomShaderEncodings();
|
||||
rdcarray<ShaderSourcePrefix> prefixes = m_Ctx.CustomShaderSourcePrefixes();
|
||||
|
||||
rdcstr errors;
|
||||
|
||||
@@ -4258,6 +4259,16 @@ void TextureViewer::reloadCustomShaders(const QString &filter)
|
||||
// pick the first tool that can convert to an accepted format
|
||||
if(tool.input == encoding && supported.contains(tool.output))
|
||||
{
|
||||
// apply any prefix needed
|
||||
for(const ShaderSourcePrefix &prefix : prefixes)
|
||||
{
|
||||
if(prefix.encoding == encoding)
|
||||
{
|
||||
source = QString(prefix.prefix) + source;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderToolOutput out =
|
||||
tool.CompileShader(this, source, "main", ShaderStage::Pixel, "");
|
||||
|
||||
|
||||
@@ -637,6 +637,28 @@ of the compile process or using alternate/updated tools.
|
||||
)");
|
||||
virtual rdcarray<ShaderEncoding> GetCustomShaderEncodings() = 0;
|
||||
|
||||
DOCUMENT(R"(Retrieve a list of source prefixes that should be applied to custom shaders of each
|
||||
:class:`ShaderEncoding` before custom compilation prior to calling :meth:`BuildCustomShader`.
|
||||
|
||||
This list provides source code prefixes which should be applied to a given custom shader in a
|
||||
:class:`ShaderEncoding` *if and only if* that shader is being compiled in a custom step to a
|
||||
different encoding, prior to being passed to :meth:`BuildCustomShader`. This allows source
|
||||
compatibility even when doing custom compilation.
|
||||
|
||||
For example a shader written in :data:`ShaderEncoding.HLSL` may be custom compiled to
|
||||
:data:`ShaderEncoding.SPIRV` before being passed to :meth:`BuildCustomShader`. In this case any
|
||||
prefix for :data:`ShaderEncoding.HLSL` should be prepended to the source before custom compilation,
|
||||
to allow for defines and other helpers to be made available, since otherwise the shader may not
|
||||
compile.
|
||||
|
||||
If a shader encoding is not in the list, no prefix is required. This may be possible even for a
|
||||
high level language such as :data:`ShaderEncoding.GLSL`.
|
||||
|
||||
:return: A list of pairs, listing a prefix for each shader encoding referenced.
|
||||
:rtype: List[Tuple[ShaderEncoding,str]]
|
||||
)");
|
||||
virtual rdcarray<ShaderSourcePrefix> GetCustomShaderSourcePrefixes() = 0;
|
||||
|
||||
DOCUMENT(R"(Replace one resource with another for subsequent replay and analysis work.
|
||||
|
||||
This is commonly used for modifying the capture by selectively replacing resources with newly
|
||||
|
||||
@@ -1235,6 +1235,35 @@ struct ShaderCompileFlags
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(ShaderCompileFlags);
|
||||
|
||||
DOCUMENT("Contains the source prefix to add to a given type of shader source");
|
||||
struct ShaderSourcePrefix
|
||||
{
|
||||
DOCUMENT("");
|
||||
ShaderSourcePrefix() = default;
|
||||
ShaderSourcePrefix(const ShaderSourcePrefix &) = default;
|
||||
ShaderSourcePrefix &operator=(const ShaderSourcePrefix &) = default;
|
||||
|
||||
bool operator==(const ShaderSourcePrefix &o) const
|
||||
{
|
||||
return encoding == o.encoding && prefix == o.prefix;
|
||||
}
|
||||
bool operator<(const ShaderSourcePrefix &o) const
|
||||
{
|
||||
if(!(encoding == o.encoding))
|
||||
return encoding < o.encoding;
|
||||
if(!(prefix == o.prefix))
|
||||
return prefix < o.prefix;
|
||||
return false;
|
||||
}
|
||||
DOCUMENT("The encoding of the language this prefix applies to.");
|
||||
ShaderEncoding encoding;
|
||||
|
||||
DOCUMENT("The source prefix to add.");
|
||||
rdcstr prefix;
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(ShaderSourcePrefix);
|
||||
|
||||
DOCUMENT("Contains a source file available in a debug-compiled shader.");
|
||||
struct ShaderSourceFile
|
||||
{
|
||||
|
||||
@@ -184,6 +184,10 @@ public:
|
||||
{
|
||||
return m_Proxy->GetCustomShaderEncodings();
|
||||
}
|
||||
rdcarray<ShaderSourcePrefix> GetCustomShaderSourcePrefixes()
|
||||
{
|
||||
return m_Proxy->GetCustomShaderSourcePrefixes();
|
||||
}
|
||||
void SetCustomShaderIncludes(const rdcarray<rdcstr> &directories)
|
||||
{
|
||||
m_Proxy->SetCustomShaderIncludes(directories);
|
||||
|
||||
@@ -412,6 +412,14 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
rdcarray<ShaderSourcePrefix> GetCustomShaderSourcePrefixes()
|
||||
{
|
||||
if(m_Proxy)
|
||||
return m_Proxy->GetCustomShaderSourcePrefixes();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void FreeCustomShader(ResourceId id)
|
||||
{
|
||||
if(m_Proxy)
|
||||
|
||||
@@ -51,3 +51,463 @@
|
||||
#endif
|
||||
|
||||
#include "glsl_ubos.h"
|
||||
|
||||
struct RD_CustomShader_UBO_Type
|
||||
{
|
||||
uvec4 TexDim;
|
||||
uint SelectedMip;
|
||||
uint TextureType;
|
||||
uint SelectedSliceFace;
|
||||
int SelectedSample;
|
||||
uvec4 YUVDownsampleRate;
|
||||
uvec4 YUVAChannels;
|
||||
vec2 SelectedRange;
|
||||
};
|
||||
|
||||
#if defined(VULKAN)
|
||||
|
||||
#define HLSL_CUSTOM_PREFIX \
|
||||
R"EOPREFIX(
|
||||
|
||||
#define RD_FLOAT_1D_ARRAY_BINDING t6
|
||||
#define RD_FLOAT_1D_BINDING t6 // all textures treated as arrays, add macro aliases
|
||||
|
||||
#define RD_FLOAT_2D_ARRAY_BINDING t7
|
||||
#define RD_FLOAT_2D_BINDING t7
|
||||
|
||||
#define RD_FLOAT_3D_BINDING t8
|
||||
|
||||
#define RD_FLOAT_DEPTH_BINDING t7
|
||||
#define RD_FLOAT_DEPTH_ARRAY_BINDING t7
|
||||
|
||||
#define RD_FLOAT_STENCIL_BINDING t17
|
||||
#define RD_FLOAT_STENCIL_ARRAY_BINDING t17
|
||||
|
||||
#define RD_FLOAT_DEPTHMS_BINDING t9
|
||||
#define RD_FLOAT_DEPTHMS_ARRAY_BINDING t9
|
||||
|
||||
#define RD_FLOAT_STENCILMS_BINDING t19
|
||||
#define RD_FLOAT_STENCILMS_ARRAY_BINDING t19
|
||||
|
||||
#define RD_FLOAT_2DMS_ARRAY_BINDING t9
|
||||
#define RD_FLOAT_2DMS_BINDING t9
|
||||
|
||||
#define RD_FLOAT_YUV_ARRAY_BINDING t10
|
||||
#define RD_FLOAT_YUV_BINDING t10
|
||||
|
||||
#define RD_INT_1D_ARRAY_BINDING t11
|
||||
#define RD_INT_1D_BINDING t11
|
||||
|
||||
#define RD_INT_2D_ARRAY_BINDING t12
|
||||
#define RD_INT_2D_BINDING t12
|
||||
|
||||
#define RD_INT_3D_BINDING t13
|
||||
|
||||
#define RD_INT_2DMS_ARRAY_BINDING t14
|
||||
#define RD_INT_2DMS_BINDING t14
|
||||
|
||||
#define RD_UINT_1D_ARRAY_BINDING t16
|
||||
#define RD_UINT_1D_BINDING t16
|
||||
|
||||
#define RD_UINT_2D_ARRAY_BINDING t17
|
||||
#define RD_UINT_2D_BINDING t17
|
||||
|
||||
#define RD_UINT_3D_BINDING t18
|
||||
|
||||
#define RD_UINT_2DMS_ARRAY_BINDING t19
|
||||
#define RD_UINT_2DMS_BINDING t19
|
||||
|
||||
#define RD_POINT_SAMPLER_BINDING s50
|
||||
#define RD_LINEAR_SAMPLER_BINDING s51
|
||||
|
||||
#define RD_CONSTANT_BUFFER_BINDING b0
|
||||
|
||||
cbuffer RD_CBuffer_Type : register(RD_CONSTANT_BUFFER_BINDING)
|
||||
{
|
||||
struct RD_CBuffer_Struct
|
||||
{
|
||||
uint4 TexDim;
|
||||
uint SelectedMip;
|
||||
uint TextureType;
|
||||
uint SelectedSliceFace;
|
||||
int SelectedSample;
|
||||
uint4 YUVDownsampleRate;
|
||||
uint4 YUVAChannels;
|
||||
float2 SelectedRange;
|
||||
} RD_CBuffer_Data;
|
||||
};
|
||||
|
||||
#define RD_TextureType_1D 1
|
||||
#define RD_TextureType_2D 2
|
||||
#define RD_TextureType_3D 3
|
||||
#define RD_TextureType_Depth 999
|
||||
#define RD_TextureType_DepthStencil 999
|
||||
#define RD_TextureType_DepthMS 999
|
||||
#define RD_TextureType_DepthStencilMS 999
|
||||
#define RD_TextureType_2DMS 9
|
||||
|
||||
// for compatibility
|
||||
#define RD_TextureType_1D_Array 1
|
||||
#define RD_TextureType_2D_Array 2
|
||||
#define RD_TextureType_Cube 999
|
||||
#define RD_TextureType_Cube_Array 999
|
||||
|
||||
// possible values (these are only return values from this function, NOT texture binding points):
|
||||
// RD_TextureType_1D
|
||||
// RD_TextureType_2D
|
||||
// RD_TextureType_3D
|
||||
// RD_TextureType_Depth (D3D only)
|
||||
// RD_TextureType_DepthStencil (D3D only)
|
||||
// RD_TextureType_DepthMS (D3D only)
|
||||
// RD_TextureType_DepthStencilMS (D3D only)
|
||||
// RD_TextureType_2DMS
|
||||
uint RD_TextureType()
|
||||
{
|
||||
return RD_CBuffer_Data.TextureType;
|
||||
}
|
||||
|
||||
// selected sample, or -numSamples for resolve
|
||||
int RD_SelectedSample()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedSample;
|
||||
}
|
||||
|
||||
uint RD_SelectedSliceFace()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedSliceFace;
|
||||
}
|
||||
|
||||
uint RD_SelectedMip()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedMip;
|
||||
}
|
||||
|
||||
// xyz = width, height, depth (or array size). w = # mips
|
||||
uint4 RD_TexDim()
|
||||
{
|
||||
return RD_CBuffer_Data.TexDim;
|
||||
}
|
||||
|
||||
// x = horizontal downsample rate (1 full rate, 2 half rate)
|
||||
// y = vertical downsample rate
|
||||
// z = number of planes in input texture
|
||||
// w = number of bits per component (8, 10, 16)
|
||||
uint4 RD_YUVDownsampleRate()
|
||||
{
|
||||
return RD_CBuffer_Data.YUVDownsampleRate;
|
||||
}
|
||||
|
||||
// x = where Y channel comes from
|
||||
// y = where U channel comes from
|
||||
// z = where V channel comes from
|
||||
// w = where A channel comes from
|
||||
// each index will be [0,1,2,3] for xyzw in first plane,
|
||||
// [4,5,6,7] for xyzw in second plane texture, etc.
|
||||
// it will be 0xff = 255 if the channel does not exist.
|
||||
uint4 RD_YUVAChannels()
|
||||
{
|
||||
return RD_CBuffer_Data.YUVAChannels;
|
||||
}
|
||||
|
||||
// a pair with minimum and maximum selected range values
|
||||
float2 RD_SelectedRange()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedRange;
|
||||
}
|
||||
|
||||
)EOPREFIX"
|
||||
|
||||
#define GLSL_CUSTOM_PREFIX \
|
||||
R"EOPREFIX(
|
||||
#define RD_FLOAT_1D_ARRAY_BINDING 6
|
||||
#define RD_FLOAT_1D_BINDING 6 // all textures treated as arrays, add macro aliases
|
||||
|
||||
#define RD_FLOAT_2D_ARRAY_BINDING 7
|
||||
#define RD_FLOAT_2D_BINDING 7
|
||||
|
||||
// cubemaps can read from the 2D binding
|
||||
#define RD_FLOAT_CUBE_BINDING 7
|
||||
#define RD_FLOAT_CUBE_ARRAY_BINDING 7
|
||||
|
||||
// these have no equivalent. Define them to something valid so shaders still compile,
|
||||
// but they will break if used
|
||||
#define RD_FLOAT_BUFFER_BINDING 3
|
||||
#define RD_FLOAT_RECT_BINDING 4
|
||||
|
||||
#define RD_FLOAT_3D_BINDING 8
|
||||
|
||||
#define RD_FLOAT_2DMS_ARRAY_BINDING 9
|
||||
#define RD_FLOAT_2DMS_BINDING 9
|
||||
|
||||
#define RD_FLOAT_YUV_BINDING 10
|
||||
#define RD_FLOAT_YUV_ARRAY_SIZE 2
|
||||
|
||||
#define RD_INT_1D_ARRAY_BINDING 11
|
||||
#define RD_INT_1D_BINDING 11
|
||||
|
||||
#define RD_INT_2D_ARRAY_BINDING 12
|
||||
#define RD_INT_2D_BINDING 12
|
||||
|
||||
#define RD_INT_3D_BINDING 13
|
||||
|
||||
#define RD_INT_2DMS_ARRAY_BINDING 14
|
||||
#define RD_INT_2DMS_BINDING 14
|
||||
|
||||
#define RD_UINT_1D_ARRAY_BINDING 16
|
||||
#define RD_UINT_1D_BINDING 16
|
||||
|
||||
#define RD_UINT_2D_ARRAY_BINDING 17
|
||||
#define RD_UINT_2D_BINDING 17
|
||||
|
||||
#define RD_UINT_3D_BINDING 18
|
||||
|
||||
#define RD_UINT_2DMS_ARRAY_BINDING 19
|
||||
#define RD_UINT_2DMS_BINDING 19
|
||||
|
||||
#define RD_POINT_SAMPLER_BINDING 50
|
||||
#define RD_LINEAR_SAMPLER_BINDING 51
|
||||
|
||||
#define RD_CONSTANT_BUFFER_BINDING 0
|
||||
|
||||
layout(binding = RD_CONSTANT_BUFFER_BINDING) uniform RD_CBuffer_Type
|
||||
{
|
||||
uvec4 TexDim;
|
||||
uint SelectedMip;
|
||||
uint TextureType;
|
||||
uint SelectedSliceFace;
|
||||
int SelectedSample;
|
||||
uvec4 YUVDownsampleRate;
|
||||
uvec4 YUVAChannels;
|
||||
vec2 SelectedRange;
|
||||
} RD_CBuffer_Data;
|
||||
|
||||
#define RD_TextureType_1D 1
|
||||
#define RD_TextureType_2D 2
|
||||
#define RD_TextureType_3D 3
|
||||
#define RD_TextureType_2DMS 4
|
||||
|
||||
// for compatibility
|
||||
#define RD_TextureType_1D_Array 1
|
||||
#define RD_TextureType_2D_Array 2
|
||||
#define RD_TextureType_2DMS_Array 4
|
||||
#define RD_TextureType_Cube 999
|
||||
#define RD_TextureType_Cube_Array 999
|
||||
#define RD_TextureType_Rect 999
|
||||
#define RD_TextureType_Buffer 999
|
||||
#define RD_TextureType_Depth 999
|
||||
#define RD_TextureType_DepthStencil 999
|
||||
#define RD_TextureType_DepthMS 999
|
||||
#define RD_TextureType_DepthStencilMS 999
|
||||
|
||||
// possible values (these are only return values from this function, NOT texture binding points):
|
||||
// RD_TextureType_1D
|
||||
// RD_TextureType_2D
|
||||
// RD_TextureType_3D
|
||||
// RD_TextureType_Cube (OpenGL only)
|
||||
// RD_TextureType_1D_Array (OpenGL only)
|
||||
// RD_TextureType_2D_Array (OpenGL only)
|
||||
// RD_TextureType_Cube_Array (OpenGL only)
|
||||
// RD_TextureType_Rect (OpenGL only)
|
||||
// RD_TextureType_Buffer (OpenGL only)
|
||||
// RD_TextureType_2DMS
|
||||
// RD_TextureType_2DMS_Array (OpenGL only)
|
||||
uint RD_TextureType()
|
||||
{
|
||||
return RD_CBuffer_Data.TextureType;
|
||||
}
|
||||
|
||||
// selected sample, or -numSamples for resolve
|
||||
int RD_SelectedSample()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedSample;
|
||||
}
|
||||
|
||||
uint RD_SelectedSliceFace()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedSliceFace;
|
||||
}
|
||||
|
||||
uint RD_SelectedMip()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedMip;
|
||||
}
|
||||
|
||||
// xyz = width, height, depth (or array size). w = # mips
|
||||
uvec4 RD_TexDim()
|
||||
{
|
||||
return RD_CBuffer_Data.TexDim;
|
||||
}
|
||||
|
||||
// x = horizontal downsample rate (1 full rate, 2 half rate)
|
||||
// y = vertical downsample rate
|
||||
// z = number of planes in input texture
|
||||
// w = number of bits per component (8, 10, 16)
|
||||
uvec4 RD_YUVDownsampleRate()
|
||||
{
|
||||
return RD_CBuffer_Data.YUVDownsampleRate;
|
||||
}
|
||||
|
||||
// x = where Y channel comes from
|
||||
// y = where U channel comes from
|
||||
// z = where V channel comes from
|
||||
// w = where A channel comes from
|
||||
// each index will be [0,1,2,3] for xyzw in first plane,
|
||||
// [4,5,6,7] for xyzw in second plane texture, etc.
|
||||
// it will be 0xff = 255 if the channel does not exist.
|
||||
uvec4 RD_YUVAChannels()
|
||||
{
|
||||
return RD_CBuffer_Data.YUVAChannels;
|
||||
}
|
||||
|
||||
// a pair with minimum and maximum selected range values
|
||||
vec2 RD_SelectedRange()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedRange;
|
||||
}
|
||||
|
||||
)EOPREFIX"
|
||||
|
||||
#elif defined(OPENGL)
|
||||
|
||||
#define GLSL_CUSTOM_PREFIX \
|
||||
R"EOPREFIX(
|
||||
#define RD_FLOAT_1D_BINDING 1
|
||||
#define RD_FLOAT_2D_BINDING 2
|
||||
#define RD_FLOAT_3D_BINDING 3
|
||||
#define RD_FLOAT_CUBE_BINDING 4
|
||||
#define RD_FLOAT_1D_ARRAY_BINDING 5
|
||||
#define RD_FLOAT_2D_ARRAY_BINDING 6
|
||||
#define RD_FLOAT_CUBE_ARRAY_BINDING 7
|
||||
#define RD_FLOAT_RECT_BINDING 8
|
||||
#define RD_FLOAT_BUFFER_BINDING 9
|
||||
#define RD_FLOAT_2DMS_BINDING 10
|
||||
#define RD_FLOAT_2DMS_ARRAY_BINDING 11
|
||||
|
||||
#define RD_INT_1D_BINDING 1
|
||||
#define RD_INT_2D_BINDING 2
|
||||
#define RD_INT_3D_BINDING 3
|
||||
#define RD_INT_CUBE_BINDING 4
|
||||
#define RD_INT_1D_ARRAY_BINDING 5
|
||||
#define RD_INT_2D_ARRAY_BINDING 6
|
||||
#define RD_INT_CUBE_ARRAY_BINDING 7
|
||||
#define RD_INT_RECT_BINDING 8
|
||||
#define RD_INT_BUFFER_BINDING 9
|
||||
#define RD_INT_2DMS_BINDING 10
|
||||
#define RD_INT_2DMS_ARRAY_BINDING 11
|
||||
|
||||
#define RD_UINT_1D_BINDING 1
|
||||
#define RD_UINT_2D_BINDING 2
|
||||
#define RD_UINT_3D_BINDING 3
|
||||
#define RD_UINT_CUBE_BINDING 4
|
||||
#define RD_UINT_1D_ARRAY_BINDING 5
|
||||
#define RD_UINT_2D_ARRAY_BINDING 6
|
||||
#define RD_UINT_CUBE_ARRAY_BINDING 7
|
||||
#define RD_UINT_RECT_BINDING 8
|
||||
#define RD_UINT_BUFFER_BINDING 9
|
||||
#define RD_UINT_2DMS_BINDING 10
|
||||
#define RD_UINT_2DMS_ARRAY_BINDING 11
|
||||
|
||||
#define RD_CONSTANT_BUFFER_BINDING 0
|
||||
|
||||
layout(binding = RD_CONSTANT_BUFFER_BINDING) uniform RD_CBuffer_Type
|
||||
{
|
||||
uvec4 TexDim;
|
||||
uint SelectedMip;
|
||||
uint TextureType;
|
||||
uint SelectedSliceFace;
|
||||
int SelectedSample;
|
||||
uvec4 YUVDownsampleRate;
|
||||
uvec4 YUVAChannels;
|
||||
vec2 SelectedRange;
|
||||
} RD_CBuffer_Data;
|
||||
|
||||
#define RD_TextureType_1D 1
|
||||
#define RD_TextureType_2D 2
|
||||
#define RD_TextureType_3D 3
|
||||
#define RD_TextureType_Cube 4
|
||||
#define RD_TextureType_1D_Array 5
|
||||
#define RD_TextureType_2D_Array 6
|
||||
#define RD_TextureType_Cube_Array 7
|
||||
#define RD_TextureType_Rect 8
|
||||
#define RD_TextureType_Buffer 9
|
||||
#define RD_TextureType_2DMS 10
|
||||
#define RD_TextureType_2DMS_Array 11
|
||||
|
||||
// for compatibility
|
||||
#define RD_TextureType_Depth 999
|
||||
#define RD_TextureType_DepthStencil 999
|
||||
#define RD_TextureType_DepthMS 999
|
||||
#define RD_TextureType_DepthStencilMS 999
|
||||
|
||||
// possible values (these are only return values from this function, NOT texture binding points):
|
||||
// RD_TextureType_1D
|
||||
// RD_TextureType_2D
|
||||
// RD_TextureType_3D
|
||||
// RD_TextureType_Cube (OpenGL only)
|
||||
// RD_TextureType_1D_Array (OpenGL only)
|
||||
// RD_TextureType_2D_Array (OpenGL only)
|
||||
// RD_TextureType_Cube_Array (OpenGL only)
|
||||
// RD_TextureType_Rect (OpenGL only)
|
||||
// RD_TextureType_Buffer (OpenGL only)
|
||||
// RD_TextureType_2DMS
|
||||
// RD_TextureType_2DMS_Array (OpenGL only)
|
||||
uint RD_TextureType()
|
||||
{
|
||||
return RD_CBuffer_Data.TextureType;
|
||||
}
|
||||
|
||||
// selected sample, or -numSamples for resolve
|
||||
int RD_SelectedSample()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedSample;
|
||||
}
|
||||
|
||||
uint RD_SelectedSliceFace()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedSliceFace;
|
||||
}
|
||||
|
||||
uint RD_SelectedMip()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedMip;
|
||||
}
|
||||
|
||||
// xyz = width, height, depth (or array size). w = # mips
|
||||
uvec4 RD_TexDim()
|
||||
{
|
||||
return RD_CBuffer_Data.TexDim;
|
||||
}
|
||||
|
||||
// x = horizontal downsample rate (1 full rate, 2 half rate)
|
||||
// y = vertical downsample rate
|
||||
// z = number of planes in input texture
|
||||
// w = number of bits per component (8, 10, 16)
|
||||
uvec4 RD_YUVDownsampleRate()
|
||||
{
|
||||
return RD_CBuffer_Data.YUVDownsampleRate;
|
||||
}
|
||||
|
||||
// x = where Y channel comes from
|
||||
// y = where U channel comes from
|
||||
// z = where V channel comes from
|
||||
// w = where A channel comes from
|
||||
// each index will be [0,1,2,3] for xyzw in first plane,
|
||||
// [4,5,6,7] for xyzw in second plane texture, etc.
|
||||
// it will be 0xff = 255 if the channel does not exist.
|
||||
uvec4 RD_YUVAChannels()
|
||||
{
|
||||
return RD_CBuffer_Data.YUVAChannels;
|
||||
}
|
||||
|
||||
// a pair with minimum and maximum selected range values
|
||||
vec2 RD_SelectedRange()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedRange;
|
||||
}
|
||||
|
||||
)EOPREFIX"
|
||||
|
||||
#else
|
||||
|
||||
#error "OPENGL and VULKAN both not defined"
|
||||
#endif
|
||||
|
||||
@@ -171,6 +171,91 @@ rdcstr GenerateGLSLShader(const rdcstr &shader, ShaderType type, int version, co
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool isspacetab(char c)
|
||||
{
|
||||
return c == '\t' || c == ' ';
|
||||
}
|
||||
|
||||
static bool isnewline(char c)
|
||||
{
|
||||
return c == '\r' || c == '\n';
|
||||
}
|
||||
|
||||
rdcstr InsertSnippetAfterVersion(ShaderType type, const char *source, int len, const char *snippet)
|
||||
{
|
||||
// we require these enums to be compatible elsewhere
|
||||
glslang::TShader sh(EShLangFragment);
|
||||
|
||||
glslang::EShClient client =
|
||||
type == ShaderType::Vulkan ? glslang::EShClientVulkan : glslang::EShClientNone;
|
||||
glslang::EShTargetClientVersion targetversion =
|
||||
type == ShaderType::Vulkan ? glslang::EShTargetVulkan_1_0 : glslang::EShTargetOpenGL_450;
|
||||
int inputVersion = client != glslang::EShClientNone ? 100 : 0;
|
||||
|
||||
sh.setStringsWithLengths(&source, &len, 1);
|
||||
sh.setEnvInput(glslang::EShSourceGlsl, EShLangFragment, client, inputVersion);
|
||||
sh.setEnvClient(client, targetversion);
|
||||
sh.setEnvTarget(glslang::EShTargetNone, glslang::EShTargetSpv_1_0);
|
||||
|
||||
glslang::TShader::ForbidIncluder incl;
|
||||
|
||||
bool success;
|
||||
|
||||
EShMessages flags = EShMsgOnlyPreprocessor;
|
||||
if(type == ShaderType::Vulkan)
|
||||
flags = EShMessages(flags | EShMsgSpvRules | EShMsgVulkanRules);
|
||||
else if(type == ShaderType::GLSPIRV)
|
||||
flags = EShMessages(flags | EShMsgSpvRules);
|
||||
|
||||
rdcstr src;
|
||||
std::string outstr;
|
||||
{
|
||||
success =
|
||||
sh.preprocess(GetDefaultResources(), 100, ENoProfile, false, false, flags, &outstr, incl);
|
||||
src.assign(outstr.c_str(), outstr.size());
|
||||
}
|
||||
|
||||
// find if this source contains a #version, accounting for whitespace. It must be the first thing
|
||||
// (except for whitespace and comments, and comments have been removed)
|
||||
int32_t it = src.find("#");
|
||||
len = src.count();
|
||||
|
||||
if(it >= 0)
|
||||
{
|
||||
// advance past the #
|
||||
++it;
|
||||
|
||||
// skip whitespace
|
||||
while(it < len && isspacetab(src[it]))
|
||||
++it;
|
||||
|
||||
if(it + 7 < len && !strncmp(&src[it], "version", 7))
|
||||
{
|
||||
it = src.find_first_of("\r\n", it);
|
||||
while(it < len && isnewline(src[it]))
|
||||
it++;
|
||||
|
||||
// it points after the #version statement
|
||||
}
|
||||
else
|
||||
{
|
||||
it = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// no #version statement found - insert our own
|
||||
if(it < 0)
|
||||
{
|
||||
rdcstr version = "#version 430 core\n\n";
|
||||
src.insert(0, version);
|
||||
it = version.count();
|
||||
}
|
||||
|
||||
src.insert(it, snippet);
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
#if ENABLED(ENABLE_UNIT_TESTS)
|
||||
|
||||
#include "catch/catch.hpp"
|
||||
|
||||
@@ -36,6 +36,8 @@ enum class ShaderType
|
||||
rdcstr GenerateGLSLShader(const rdcstr &shader, ShaderType type, int version,
|
||||
const rdcstr &defines = "");
|
||||
|
||||
rdcstr InsertSnippetAfterVersion(ShaderType type, const char *source, int len, const char *snippet);
|
||||
|
||||
// for unit tests
|
||||
struct ShaderReflection;
|
||||
struct ShaderBindpointMapping;
|
||||
|
||||
@@ -247,3 +247,22 @@ cbuffer HistogramCBufferData REG(b0)
|
||||
#define SINT_TEX 0
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
struct RD_CustomShader_CBuffer_Type
|
||||
{
|
||||
uint4 TexDim;
|
||||
uint SelectedMip;
|
||||
uint TextureType;
|
||||
uint SelectedSliceFace;
|
||||
int SelectedSample;
|
||||
uint4 YUVDownsampleRate;
|
||||
uint4 YUVAChannels;
|
||||
float2 SelectedRange;
|
||||
};
|
||||
|
||||
// move to an #include since fxc barfs on it
|
||||
#include "hlsl_custom_prefix.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
|
||||
#define HLSL_CUSTOM_PREFIX \
|
||||
R"EOPREFIX(
|
||||
#define RD_FLOAT_1D_ARRAY_BINDING t1
|
||||
#define RD_FLOAT_1D_BINDING t1 // all textures treated as arrays, add macro aliases
|
||||
|
||||
#define RD_FLOAT_2D_ARRAY_BINDING t2
|
||||
#define RD_FLOAT_2D_BINDING t2
|
||||
|
||||
#define RD_FLOAT_3D_BINDING t3
|
||||
|
||||
#define RD_FLOAT_DEPTH_BINDING t4
|
||||
#define RD_FLOAT_DEPTH_ARRAY_BINDING t4
|
||||
|
||||
#define RD_FLOAT_STENCIL_BINDING t5
|
||||
#define RD_FLOAT_STENCIL_ARRAY_BINDING t5
|
||||
|
||||
#define RD_FLOAT_DEPTHMS_BINDING t6
|
||||
#define RD_FLOAT_DEPTHMS_ARRAY_BINDING t6
|
||||
|
||||
#define RD_FLOAT_STENCILMS_BINDING t7
|
||||
#define RD_FLOAT_STENCILMS_ARRAY_BINDING t7
|
||||
|
||||
#define RD_FLOAT_2DMS_ARRAY_BINDING t9
|
||||
#define RD_FLOAT_2DMS_BINDING t9
|
||||
|
||||
#define RD_FLOAT_YUV_ARRAY_BINDING t10
|
||||
#define RD_FLOAT_YUV_BINDING t10
|
||||
|
||||
#define RD_INT_1D_ARRAY_BINDING t11
|
||||
#define RD_INT_1D_BINDING t11
|
||||
|
||||
#define RD_INT_2D_ARRAY_BINDING t12
|
||||
#define RD_INT_2D_BINDING t12
|
||||
|
||||
#define RD_INT_3D_BINDING t13
|
||||
|
||||
#define RD_INT_2DMS_ARRAY_BINDING t19
|
||||
#define RD_INT_2DMS_BINDING t19
|
||||
|
||||
#define RD_UINT_1D_ARRAY_BINDING t21
|
||||
#define RD_UINT_1D_BINDING t21
|
||||
|
||||
#define RD_UINT_2D_ARRAY_BINDING t22
|
||||
#define RD_UINT_2D_BINDING t22
|
||||
|
||||
#define RD_UINT_3D_BINDING t23
|
||||
|
||||
#define RD_UINT_2DMS_ARRAY_BINDING t29
|
||||
#define RD_UINT_2DMS_BINDING t29
|
||||
|
||||
#define RD_POINT_SAMPLER_BINDING s0
|
||||
#define RD_LINEAR_SAMPLER_BINDING s1
|
||||
|
||||
#define RD_CONSTANT_BUFFER_BINDING b0
|
||||
|
||||
cbuffer RD_CBuffer_Type : register(RD_CONSTANT_BUFFER_BINDING)
|
||||
{
|
||||
struct RD_CBuffer_Struct
|
||||
{
|
||||
uint4 TexDim;
|
||||
uint SelectedMip;
|
||||
uint TextureType;
|
||||
uint SelectedSliceFace;
|
||||
int SelectedSample;
|
||||
uint4 YUVDownsampleRate;
|
||||
uint4 YUVAChannels;
|
||||
float2 SelectedRange;
|
||||
} RD_CBuffer_Data;
|
||||
};
|
||||
|
||||
#define RD_TextureType_1D 1
|
||||
#define RD_TextureType_2D 2
|
||||
#define RD_TextureType_3D 3
|
||||
#define RD_TextureType_Depth 4
|
||||
#define RD_TextureType_DepthStencil 5
|
||||
#define RD_TextureType_DepthMS 6
|
||||
#define RD_TextureType_DepthStencilMS 7
|
||||
#define RD_TextureType_2DMS 9
|
||||
|
||||
// for compatibility
|
||||
#define RD_TextureType_Cube 999
|
||||
#define RD_TextureType_Cube_Array 999
|
||||
#define RD_TextureType_1D_Array 999
|
||||
#define RD_TextureType_2D_Array 999
|
||||
#define RD_TextureType_Rect 999
|
||||
#define RD_TextureType_Buffer 999
|
||||
#define RD_TextureType_2DMS_Array 999
|
||||
|
||||
// possible values (these are only return values from this function, NOT texture binding points):
|
||||
// RD_TextureType_1D
|
||||
// RD_TextureType_2D
|
||||
// RD_TextureType_3D
|
||||
// RD_TextureType_Depth (D3D only)
|
||||
// RD_TextureType_DepthStencil (D3D only)
|
||||
// RD_TextureType_DepthMS (D3D only)
|
||||
// RD_TextureType_DepthStencilMS (D3D only)
|
||||
// RD_TextureType_2DMS
|
||||
uint RD_TextureType()
|
||||
{
|
||||
return RD_CBuffer_Data.TextureType;
|
||||
}
|
||||
|
||||
// selected sample, or -numSamples for resolve
|
||||
int RD_SelectedSample()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedSample;
|
||||
}
|
||||
|
||||
uint RD_SelectedSliceFace()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedSliceFace;
|
||||
}
|
||||
|
||||
uint RD_SelectedMip()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedMip;
|
||||
}
|
||||
|
||||
// xyz = width, height, depth (or array size). w = # mips
|
||||
uint4 RD_TexDim()
|
||||
{
|
||||
return RD_CBuffer_Data.TexDim;
|
||||
}
|
||||
|
||||
// x = horizontal downsample rate (1 full rate, 2 half rate)
|
||||
// y = vertical downsample rate
|
||||
// z = number of planes in input texture
|
||||
// w = number of bits per component (8, 10, 16)
|
||||
uint4 RD_YUVDownsampleRate()
|
||||
{
|
||||
return RD_CBuffer_Data.YUVDownsampleRate;
|
||||
}
|
||||
|
||||
// x = where Y channel comes from
|
||||
// y = where U channel comes from
|
||||
// z = where V channel comes from
|
||||
// w = where A channel comes from
|
||||
// each index will be [0,1,2,3] for xyzw in first plane,
|
||||
// [4,5,6,7] for xyzw in second plane texture, etc.
|
||||
// it will be 0xff = 255 if the channel does not exist.
|
||||
uint4 RD_YUVAChannels()
|
||||
{
|
||||
return RD_CBuffer_Data.YUVAChannels;
|
||||
}
|
||||
|
||||
// a pair with minimum and maximum selected range values
|
||||
float2 RD_SelectedRange()
|
||||
{
|
||||
return RD_CBuffer_Data.SelectedRange;
|
||||
}
|
||||
|
||||
)EOPREFIX"
|
||||
@@ -579,7 +579,7 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flag
|
||||
vertexData.VertexScale.y = (tex_y / m_OutputHeight) * cfg.scale * 2.0f;
|
||||
|
||||
ID3D11PixelShader *customPS = NULL;
|
||||
ID3D11Buffer *customBuff = NULL;
|
||||
ID3D11Buffer *customBuffs[2] = {};
|
||||
|
||||
if(cfg.customShaderId != ResourceId())
|
||||
{
|
||||
@@ -598,6 +598,24 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flag
|
||||
(WrappedID3D11Shader<ID3D11PixelShader> *)m_pDevice->GetResourceManager()->GetLiveResource(
|
||||
cfg.customShaderId);
|
||||
|
||||
RD_CustomShader_CBuffer_Type customCBuffer = {};
|
||||
|
||||
customCBuffer.TexDim.x = details.texWidth;
|
||||
customCBuffer.TexDim.y = details.texHeight;
|
||||
customCBuffer.TexDim.z =
|
||||
details.texType == eTexType_3D ? details.texDepth : details.texArraySize;
|
||||
customCBuffer.TexDim.w = details.texMips;
|
||||
customCBuffer.SelectedMip = cfg.subresource.mip;
|
||||
customCBuffer.SelectedSliceFace = cfg.subresource.slice;
|
||||
customCBuffer.SelectedSample = sampleIdx;
|
||||
customCBuffer.TextureType = (uint32_t)details.texType;
|
||||
customCBuffer.YUVDownsampleRate = details.YUVDownsampleRate;
|
||||
customCBuffer.YUVAChannels = details.YUVAChannels;
|
||||
customCBuffer.SelectedRange.x = cfg.rangeMin;
|
||||
customCBuffer.SelectedRange.y = cfg.rangeMax;
|
||||
|
||||
customBuffs[0] = GetDebugManager()->MakeCBuffer(&customCBuffer, sizeof(customCBuffer));
|
||||
|
||||
customPS = wrapped;
|
||||
|
||||
for(size_t i = 0; i < dxbc->GetReflection()->CBuffers.size(); i++)
|
||||
@@ -679,7 +697,7 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flag
|
||||
{
|
||||
int32_t *d = (int32_t *)(byteData + var.offset);
|
||||
|
||||
d[0] = cfg.subresource.sample;
|
||||
d[0] = sampleIdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -718,7 +736,27 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flag
|
||||
}
|
||||
}
|
||||
|
||||
customBuff = GetDebugManager()->MakeCBuffer(cbufData, cbuf.descriptor.byteSize);
|
||||
if(cbuf.reg == 0)
|
||||
{
|
||||
// with the prefix added, binding 0 should be 'reserved' for the modern cbuffer.
|
||||
// we can still make this work, but it's unexpected
|
||||
RDCWARN(
|
||||
"Unexpected globals cbuffer at binding 0, expected binding 1 after prefix "
|
||||
"cbuffer");
|
||||
customBuffs[0] = GetDebugManager()->MakeCBuffer(cbufData, cbuf.descriptor.byteSize);
|
||||
}
|
||||
else if(cbuf.reg == 1)
|
||||
{
|
||||
customBuffs[1] = GetDebugManager()->MakeCBuffer(cbufData, cbuf.descriptor.byteSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR(
|
||||
"Globals cbuffer at binding %d, unexpected and not handled - these constants "
|
||||
"will be "
|
||||
"undefined",
|
||||
cbuf.reg);
|
||||
}
|
||||
|
||||
SAFE_DELETE_ARRAY(cbufData);
|
||||
}
|
||||
@@ -820,7 +858,7 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flag
|
||||
if(customPS)
|
||||
{
|
||||
m_pImmediateContext->PSSetShader(customPS, NULL, 0);
|
||||
m_pImmediateContext->PSSetConstantBuffers(0, 1, &customBuff);
|
||||
m_pImmediateContext->PSSetConstantBuffers(0, 2, customBuffs);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2546,6 +2546,13 @@ void D3D11Replay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
SAFE_RELEASE(dummyTex);
|
||||
}
|
||||
|
||||
rdcarray<ShaderSourcePrefix> D3D11Replay::GetCustomShaderSourcePrefixes()
|
||||
{
|
||||
return {
|
||||
{ShaderEncoding::HLSL, HLSL_CUSTOM_PREFIX},
|
||||
};
|
||||
}
|
||||
|
||||
void D3D11Replay::ReplaceResource(ResourceId from, ResourceId to)
|
||||
{
|
||||
auto fromit = WrappedShader::m_ShaderList.find(from);
|
||||
|
||||
@@ -199,6 +199,7 @@ public:
|
||||
{
|
||||
return {ShaderEncoding::DXBC, ShaderEncoding::HLSL};
|
||||
}
|
||||
rdcarray<ShaderSourcePrefix> GetCustomShaderSourcePrefixes();
|
||||
rdcarray<ShaderEncoding> GetTargetShaderEncodings()
|
||||
{
|
||||
return {ShaderEncoding::DXBC, ShaderEncoding::HLSL};
|
||||
|
||||
@@ -512,6 +512,8 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture
|
||||
ID3D12PipelineState *customPSO = NULL;
|
||||
|
||||
D3D12_GPU_VIRTUAL_ADDRESS psCBuf = 0;
|
||||
D3D12_GPU_VIRTUAL_ADDRESS secondCBuf =
|
||||
GetDebugManager()->UploadConstants(&heatmapData, sizeof(heatmapData));
|
||||
|
||||
if(cfg.customShaderId != ResourceId())
|
||||
{
|
||||
@@ -521,6 +523,25 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture
|
||||
if(shader == NULL)
|
||||
return false;
|
||||
|
||||
RD_CustomShader_CBuffer_Type customCBuffer = {};
|
||||
|
||||
customCBuffer.TexDim.x = (uint32_t)resourceDesc.Width;
|
||||
customCBuffer.TexDim.y = resourceDesc.Height;
|
||||
customCBuffer.TexDim.z = resourceDesc.DepthOrArraySize;
|
||||
customCBuffer.TexDim.w = resourceDesc.MipLevels;
|
||||
customCBuffer.SelectedMip = cfg.subresource.mip;
|
||||
customCBuffer.SelectedSliceFace = cfg.subresource.slice;
|
||||
customCBuffer.SelectedSample = cfg.subresource.sample;
|
||||
if(cfg.subresource.sample == ~0U)
|
||||
customCBuffer.SelectedSample = -int(resourceDesc.SampleDesc.Count);
|
||||
customCBuffer.TextureType = (uint32_t)resType;
|
||||
customCBuffer.YUVDownsampleRate = YUVDownsampleRate;
|
||||
customCBuffer.YUVAChannels = YUVAChannels;
|
||||
customCBuffer.SelectedRange.x = cfg.rangeMin;
|
||||
customCBuffer.SelectedRange.y = cfg.rangeMax;
|
||||
|
||||
psCBuf = GetDebugManager()->UploadConstants(&customCBuffer, sizeof(customCBuffer));
|
||||
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeDesc = {};
|
||||
pipeDesc.pRootSignature = m_TexRender.RootSig;
|
||||
pipeDesc.VS.BytecodeLength = m_TexRender.VS->GetBufferSize();
|
||||
@@ -632,6 +653,8 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture
|
||||
int32_t *d = (int32_t *)(byteData + var.offset);
|
||||
|
||||
d[0] = cfg.subresource.sample;
|
||||
if(cfg.subresource.sample == ~0U)
|
||||
d[0] = -int(resourceDesc.SampleDesc.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -670,7 +693,25 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture
|
||||
}
|
||||
}
|
||||
|
||||
psCBuf = GetDebugManager()->UploadConstants(cbufData, cbuf.descriptor.byteSize);
|
||||
if(cbuf.reg == 0)
|
||||
{
|
||||
// with the prefix added, binding 0 should be 'reserved' for the modern cbuffer.
|
||||
// we can still make this work, but it's unexpected
|
||||
RDCWARN(
|
||||
"Unexpected globals cbuffer at binding 0, expected binding 1 after prefix cbuffer");
|
||||
psCBuf = GetDebugManager()->UploadConstants(cbufData, cbuf.descriptor.byteSize);
|
||||
}
|
||||
else if(cbuf.reg == 1)
|
||||
{
|
||||
secondCBuf = GetDebugManager()->UploadConstants(cbufData, cbuf.descriptor.byteSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR(
|
||||
"Globals cbuffer at binding %d, unexpected and not handled - these constants will be "
|
||||
"undefined",
|
||||
cbuf.reg);
|
||||
}
|
||||
|
||||
SAFE_DELETE_ARRAY(cbufData);
|
||||
}
|
||||
@@ -745,8 +786,7 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture
|
||||
list->SetGraphicsRootConstantBufferView(
|
||||
0, GetDebugManager()->UploadConstants(&vertexData, sizeof(vertexData)));
|
||||
list->SetGraphicsRootConstantBufferView(1, psCBuf);
|
||||
list->SetGraphicsRootConstantBufferView(
|
||||
2, GetDebugManager()->UploadConstants(&heatmapData, sizeof(heatmapData)));
|
||||
list->SetGraphicsRootConstantBufferView(2, secondCBuf);
|
||||
list->SetGraphicsRootDescriptorTable(3, GetDebugManager()->GetGPUHandle(FIRST_TEXDISPLAY_SRV));
|
||||
list->SetGraphicsRootDescriptorTable(4, GetDebugManager()->GetGPUHandle(FIRST_SAMP));
|
||||
|
||||
|
||||
@@ -3953,6 +3953,13 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub,
|
||||
SAFE_RELEASE(tmpTexture);
|
||||
}
|
||||
|
||||
rdcarray<ShaderSourcePrefix> D3D12Replay::GetCustomShaderSourcePrefixes()
|
||||
{
|
||||
return {
|
||||
{ShaderEncoding::HLSL, HLSL_CUSTOM_PREFIX},
|
||||
};
|
||||
}
|
||||
|
||||
void D3D12Replay::SetCustomShaderIncludes(const rdcarray<rdcstr> &directories)
|
||||
{
|
||||
m_CustomShaderIncludes = directories;
|
||||
|
||||
@@ -175,6 +175,7 @@ public:
|
||||
{
|
||||
return {ShaderEncoding::DXBC, ShaderEncoding::HLSL};
|
||||
}
|
||||
rdcarray<ShaderSourcePrefix> GetCustomShaderSourcePrefixes();
|
||||
rdcarray<ShaderEncoding> GetTargetShaderEncodings()
|
||||
{
|
||||
return {ShaderEncoding::DXBC, ShaderEncoding::HLSL};
|
||||
|
||||
@@ -491,6 +491,8 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flags)
|
||||
|
||||
drv.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]);
|
||||
|
||||
RDCCOMPILE_ASSERT(sizeof(RD_CustomShader_UBO_Type) <= sizeof(TexDisplayUBOData),
|
||||
"Custom shader UBO is bigger than tex display UBO, map is not valid");
|
||||
TexDisplayUBOData *ubo =
|
||||
(TexDisplayUBOData *)drv.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(TexDisplayUBOData),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
@@ -626,6 +628,29 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flags)
|
||||
ubo->YUVDownsampleRate = {};
|
||||
ubo->YUVAChannels = {};
|
||||
|
||||
if(customProgram)
|
||||
{
|
||||
// overwrite with data for custom UBO
|
||||
RD_CustomShader_UBO_Type customUBO = {};
|
||||
|
||||
customUBO.TexDim.x = texDetails.width;
|
||||
customUBO.TexDim.y = texDetails.height;
|
||||
customUBO.TexDim.z = texDetails.depth;
|
||||
customUBO.TexDim.w = (uint32_t)numMips;
|
||||
customUBO.SelectedMip = cfg.subresource.mip;
|
||||
customUBO.TextureType = resType;
|
||||
customUBO.SelectedSliceFace = cfg.subresource.slice;
|
||||
if(cfg.subresource.sample == ~0U)
|
||||
customUBO.SelectedSample = -texDetails.samples;
|
||||
else
|
||||
customUBO.SelectedSample = cfg.subresource.sample;
|
||||
customUBO.YUVDownsampleRate = Vec4u(1, 1, 1, 8);
|
||||
customUBO.YUVAChannels = Vec4u(0, 1, 2, 3);
|
||||
customUBO.SelectedRange = Vec2f(cfg.rangeMin, cfg.rangeMax);
|
||||
|
||||
memcpy(ubo, &customUBO, sizeof(RD_CustomShader_UBO_Type));
|
||||
}
|
||||
|
||||
drv.glUnmapBuffer(eGL_UNIFORM_BUFFER);
|
||||
|
||||
TextureSamplerState prevSampState = SetSamplerParams(target, texname, mode);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "gl_replay.h"
|
||||
#include "core/settings.h"
|
||||
#include "data/glsl_shaders.h"
|
||||
#include "driver/ihv/amd/amd_counters.h"
|
||||
#include "driver/ihv/arm/arm_counters.h"
|
||||
#include "driver/ihv/intel/intel_gl_counters.h"
|
||||
@@ -3021,6 +3022,17 @@ void GLReplay::BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &s
|
||||
const rdcstr &entry, const ShaderCompileFlags &compileFlags,
|
||||
ShaderStage type, ResourceId &id, rdcstr &errors)
|
||||
{
|
||||
if(sourceEncoding == ShaderEncoding::GLSL)
|
||||
{
|
||||
rdcstr sourceText = InsertSnippetAfterVersion(ShaderType::GLSL, (const char *)source.data(),
|
||||
source.count(), GLSL_CUSTOM_PREFIX);
|
||||
|
||||
bytebuf patchedSource;
|
||||
patchedSource.assign((byte *)sourceText.begin(), sourceText.size());
|
||||
|
||||
return BuildTargetShader(sourceEncoding, patchedSource, entry, compileFlags, type, id, errors);
|
||||
}
|
||||
|
||||
BuildTargetShader(sourceEncoding, source, entry, compileFlags, type, id, errors);
|
||||
}
|
||||
|
||||
|
||||
@@ -203,6 +203,14 @@ public:
|
||||
const MeshDisplay &cfg);
|
||||
|
||||
rdcarray<ShaderEncoding> GetCustomShaderEncodings() { return {ShaderEncoding::GLSL}; }
|
||||
rdcarray<ShaderSourcePrefix> GetCustomShaderSourcePrefixes()
|
||||
{
|
||||
// this is a complete hack, since we *do* want to define a prefix for GLSL. However GLSL sucks
|
||||
// and has the #version as the first thing, so we can't do a simple prepend of some defines.
|
||||
// Instead we will return no prefix and insert our own in BuildCustomShader if we see GLSL
|
||||
// coming in.
|
||||
return {};
|
||||
}
|
||||
rdcarray<ShaderEncoding> GetTargetShaderEncodings() { return {ShaderEncoding::GLSL}; }
|
||||
void BuildTargetShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry,
|
||||
const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id,
|
||||
|
||||
@@ -368,33 +368,21 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, const ImageState &i
|
||||
{
|
||||
// must match struct declared in user shader (see documentation / Shader Viewer window helper
|
||||
// menus)
|
||||
struct CustomTexDisplayUBOData
|
||||
{
|
||||
Vec4u texDim;
|
||||
uint32_t selectedMip;
|
||||
uint32_t texType;
|
||||
uint32_t selectedSliceFace;
|
||||
int32_t selectedSample;
|
||||
Vec4u YUVDownsampleRate;
|
||||
Vec4u YUVAChannels;
|
||||
float selectedRangeMin;
|
||||
float selectedRangeMax;
|
||||
};
|
||||
|
||||
CustomTexDisplayUBOData *customData = (CustomTexDisplayUBOData *)data;
|
||||
RD_CustomShader_UBO_Type *customData = (RD_CustomShader_UBO_Type *)data;
|
||||
|
||||
customData->texDim.x = iminfo.extent.width;
|
||||
customData->texDim.y = iminfo.extent.height;
|
||||
customData->texDim.z = iminfo.extent.depth;
|
||||
customData->texDim.w = iminfo.mipLevels;
|
||||
customData->selectedMip = cfg.subresource.mip;
|
||||
customData->selectedSliceFace = cfg.subresource.slice;
|
||||
customData->selectedSample = sampleIdx;
|
||||
customData->texType = (uint32_t)textype;
|
||||
customData->TexDim.x = iminfo.extent.width;
|
||||
customData->TexDim.y = iminfo.extent.height;
|
||||
customData->TexDim.z = iminfo.type == VK_IMAGE_TYPE_3D ? iminfo.extent.depth : iminfo.arrayLayers;
|
||||
customData->TexDim.w = iminfo.mipLevels;
|
||||
customData->SelectedMip = cfg.subresource.mip;
|
||||
customData->SelectedSliceFace = cfg.subresource.slice;
|
||||
customData->SelectedSample = sampleIdx;
|
||||
customData->TextureType = (uint32_t)textype;
|
||||
customData->YUVDownsampleRate = YUVDownsampleRate;
|
||||
customData->YUVAChannels = YUVAChannels;
|
||||
customData->selectedRangeMin = cfg.rangeMin;
|
||||
customData->selectedRangeMax = cfg.rangeMax;
|
||||
customData->SelectedRange.x = cfg.rangeMin;
|
||||
customData->SelectedRange.y = cfg.rangeMax;
|
||||
}
|
||||
|
||||
m_TexRender.UBO.Unmap();
|
||||
|
||||
@@ -28,8 +28,9 @@
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
#include "core/settings.h"
|
||||
#include "data/glsl_shaders.h"
|
||||
#include "driver/ihv/amd/amd_rgp.h"
|
||||
#include "driver/shaders/spirv/spirv_compile.h"
|
||||
#include "driver/shaders/spirv/glslang_compile.h"
|
||||
#include "maths/formatpacking.h"
|
||||
#include "maths/matrix.h"
|
||||
#include "replay/dummy_driver.h"
|
||||
@@ -4062,6 +4063,17 @@ void VulkanReplay::BuildCustomShader(ShaderEncoding sourceEncoding, const bytebu
|
||||
const rdcstr &entry, const ShaderCompileFlags &compileFlags,
|
||||
ShaderStage type, ResourceId &id, rdcstr &errors)
|
||||
{
|
||||
if(sourceEncoding == ShaderEncoding::GLSL)
|
||||
{
|
||||
rdcstr sourceText = InsertSnippetAfterVersion(ShaderType::Vulkan, (const char *)source.data(),
|
||||
source.count(), GLSL_CUSTOM_PREFIX);
|
||||
|
||||
bytebuf patchedSource;
|
||||
patchedSource.assign((byte *)sourceText.begin(), sourceText.size());
|
||||
|
||||
return BuildTargetShader(sourceEncoding, patchedSource, entry, compileFlags, type, id, errors);
|
||||
}
|
||||
|
||||
BuildTargetShader(sourceEncoding, source, entry, compileFlags, type, id, errors);
|
||||
}
|
||||
|
||||
@@ -4137,6 +4149,20 @@ ResourceId VulkanReplay::ApplyCustomShader(TextureDisplay &display)
|
||||
return GetResID(GetDebugManager()->GetCustomTexture());
|
||||
}
|
||||
|
||||
rdcarray<ShaderSourcePrefix> VulkanReplay::GetCustomShaderSourcePrefixes()
|
||||
{
|
||||
// this is a complete hack, since we *do* want to define a prefix for GLSL. However GLSL sucks
|
||||
// and has the #version as the first thing, so we can't do a simple prepend of some defines.
|
||||
// Instead we will return no prefix and insert our own in BuildCustomShader if we see GLSL
|
||||
// coming in.
|
||||
// For SPIR-V no prefix is needed (or possible)
|
||||
// For HLSL however we define our HLSL prefix so that custom-compiled HLSL to SPIR-V gets the
|
||||
// right binding and helper definitions
|
||||
return {
|
||||
{ShaderEncoding::HLSL, HLSL_CUSTOM_PREFIX},
|
||||
};
|
||||
}
|
||||
|
||||
void VulkanReplay::BuildTargetShader(ShaderEncoding sourceEncoding, const bytebuf &source,
|
||||
const rdcstr &entry, const ShaderCompileFlags &compileFlags,
|
||||
ShaderStage type, ResourceId &id, rdcstr &errors)
|
||||
|
||||
@@ -370,6 +370,7 @@ public:
|
||||
{
|
||||
return {ShaderEncoding::SPIRV, ShaderEncoding::GLSL};
|
||||
}
|
||||
rdcarray<ShaderSourcePrefix> GetCustomShaderSourcePrefixes();
|
||||
rdcarray<ShaderEncoding> GetTargetShaderEncodings()
|
||||
{
|
||||
return {ShaderEncoding::SPIRV, ShaderEncoding::GLSL};
|
||||
|
||||
@@ -225,6 +225,7 @@
|
||||
<ClInclude Include="data\glsl\vk_texsample.h" />
|
||||
<ClInclude Include="data\glsl_shaders.h" />
|
||||
<ClInclude Include="data\hlsl\hlsl_cbuffers.h" />
|
||||
<ClInclude Include="data\hlsl\hlsl_custom_prefix.h" />
|
||||
<ClInclude Include="data\resource.h" />
|
||||
<ClInclude Include="hooks\hooks.h" />
|
||||
<ClInclude Include="maths\camera.h" />
|
||||
|
||||
@@ -573,6 +573,9 @@
|
||||
<ClInclude Include="replay\dummy_driver.h">
|
||||
<Filter>Replay</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="data\hlsl\hlsl_custom_prefix.h">
|
||||
<Filter>Resources\hlsl</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="maths\camera.cpp">
|
||||
|
||||
@@ -42,6 +42,7 @@ DummyDriver::DummyDriver(IReplayDriver *original, const rdcarray<ShaderReflectio
|
||||
m_GPUs = original->GetAvailableGPUs();
|
||||
m_WindowSystems = original->GetSupportedWindowSystems();
|
||||
m_CustomEncodings = original->GetCustomShaderEncodings();
|
||||
m_CustomPrefixes = original->GetCustomShaderSourcePrefixes();
|
||||
}
|
||||
|
||||
DummyDriver::~DummyDriver()
|
||||
@@ -478,7 +479,12 @@ void DummyDriver::BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf
|
||||
|
||||
rdcarray<ShaderEncoding> DummyDriver::GetCustomShaderEncodings()
|
||||
{
|
||||
return {ShaderEncoding::HLSL, ShaderEncoding::GLSL};
|
||||
return m_CustomEncodings;
|
||||
}
|
||||
|
||||
rdcarray<ShaderSourcePrefix> DummyDriver::GetCustomShaderSourcePrefixes()
|
||||
{
|
||||
return m_CustomPrefixes;
|
||||
}
|
||||
|
||||
ResourceId DummyDriver::ApplyCustomShader(TextureDisplay &display)
|
||||
|
||||
@@ -167,6 +167,7 @@ public:
|
||||
const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id,
|
||||
rdcstr &errors);
|
||||
rdcarray<ShaderEncoding> GetCustomShaderEncodings();
|
||||
rdcarray<ShaderSourcePrefix> GetCustomShaderSourcePrefixes();
|
||||
ResourceId ApplyCustomShader(TextureDisplay &display);
|
||||
void FreeCustomShader(ResourceId id);
|
||||
|
||||
@@ -195,4 +196,5 @@ private:
|
||||
rdcarray<GPUDevice> m_GPUs;
|
||||
rdcarray<WindowingSystem> m_WindowSystems;
|
||||
rdcarray<ShaderEncoding> m_CustomEncodings;
|
||||
rdcarray<ShaderSourcePrefix> m_CustomPrefixes;
|
||||
};
|
||||
|
||||
@@ -1955,6 +1955,13 @@ rdcarray<ShaderEncoding> ReplayController::GetCustomShaderEncodings()
|
||||
return m_pDevice->GetCustomShaderEncodings();
|
||||
}
|
||||
|
||||
rdcarray<ShaderSourcePrefix> ReplayController::GetCustomShaderSourcePrefixes()
|
||||
{
|
||||
CHECK_REPLAY_THREAD();
|
||||
|
||||
return m_pDevice->GetCustomShaderSourcePrefixes();
|
||||
}
|
||||
|
||||
rdcarray<ShaderEncoding> ReplayController::GetTargetShaderEncodings()
|
||||
{
|
||||
CHECK_REPLAY_THREAD();
|
||||
|
||||
@@ -153,6 +153,7 @@ public:
|
||||
void FreeCustomShader(ResourceId id);
|
||||
|
||||
rdcarray<ShaderEncoding> GetCustomShaderEncodings();
|
||||
rdcarray<ShaderSourcePrefix> GetCustomShaderSourcePrefixes();
|
||||
rdcarray<ShaderEncoding> GetTargetShaderEncodings();
|
||||
rdcpair<ResourceId, rdcstr> BuildTargetShader(const rdcstr &entry, ShaderEncoding sourceEncoding,
|
||||
bytebuf source,
|
||||
|
||||
@@ -269,6 +269,7 @@ public:
|
||||
const rdcstr &entry, const ShaderCompileFlags &compileFlags,
|
||||
ShaderStage type, ResourceId &id, rdcstr &errors) = 0;
|
||||
virtual rdcarray<ShaderEncoding> GetCustomShaderEncodings() = 0;
|
||||
virtual rdcarray<ShaderSourcePrefix> GetCustomShaderSourcePrefixes() = 0;
|
||||
virtual ResourceId ApplyCustomShader(TextureDisplay &display) = 0;
|
||||
virtual void FreeCustomShader(ResourceId id) = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user