Add texture sampling code for all types/formats

This commit is contained in:
baldurk
2016-02-07 18:49:07 +01:00
parent 3bce54bb3d
commit 961616428d
15 changed files with 367 additions and 21 deletions
+1
View File
@@ -61,5 +61,6 @@ DECLARE_EMBED(spirv_minmaxresult_comp);
DECLARE_EMBED(spirv_histogram_comp);
DECLARE_EMBED(spirv_outline_frag);
DECLARE_EMBED(spirv_debuguniforms_h);
DECLARE_EMBED(spirv_texsample_h);
#undef DECLARE_EMBED
+1
View File
@@ -145,6 +145,7 @@ RESOURCE_spirv_minmaxresult_comp TYPE_EMBED "spv/minmaxresult.comp"
RESOURCE_spirv_histogram_comp TYPE_EMBED "spv/histogram.comp"
RESOURCE_spirv_outline_frag TYPE_EMBED "spv/outline.frag"
RESOURCE_spirv_debuguniforms_h TYPE_EMBED "spv/debuguniforms.h"
RESOURCE_spirv_texsample_h TYPE_EMBED "spv/texsample.h"
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
+1
View File
@@ -47,6 +47,7 @@
#define RESOURCE_spirv_histogram_comp 414
#define RESOURCE_spirv_outline_frag 415
#define RESOURCE_spirv_debuguniforms_h 416
#define RESOURCE_spirv_texsample_h 417
#if !defined(STRINGIZE)
#define STRINGIZE2(a) #a
+1 -1
View File
@@ -130,7 +130,7 @@ BINDING (0, 0) uniform TexDisplayUBOData
float RangeMinimum;
float InverseRangeSize;
float MipLevel;
int MipLevel;
int FlipY;
vec3 TextureResolutionPS;
-5
View File
@@ -30,11 +30,6 @@ in v2f
layout (location = 0) out vec4 color_out;
#define MESHDISPLAY_SOLID 0x1
#define MESHDISPLAY_FACELIT 0x2
#define MESHDISPLAY_SECONDARY 0x3
#define MESHDISPLAY_SECONDARY_ALPHA 0x4
void main(void)
{
uint type = Mesh.displayFormat;
+50 -9
View File
@@ -24,27 +24,68 @@
layout (location = 0) out vec4 color_out;
layout (binding = 1) uniform sampler2D tex;
//#include "texsample.h" // while includes aren't supported in glslang, this will be added in code
void main(void)
{
bool uintTex = (texdisplay.OutputDisplayFormat & TEXDISPLAY_UINT_TEX) != 0;
bool sintTex = (texdisplay.OutputDisplayFormat & TEXDISPLAY_SINT_TEX) != 0;
int texType = (texdisplay.OutputDisplayFormat & TEXDISPLAY_TYPEMASK);
vec4 col;
uvec4 ucol;
ivec4 scol;
// calc screen co-ords with origin top left, modified by Position
vec2 scr = gl_FragCoord.xy - texdisplay.Position.xy;
scr /= texdisplay.Scale;
if(scr.x < 0.0f || scr.y < 0.0f ||
scr.x > texdisplay.TextureResolutionPS.x || scr.y > texdisplay.TextureResolutionPS.y)
if(texType == RESTYPE_TEX1D || texType == RESTYPE_TEXBUFFER)
{
discard;
// by convention display 1D textures as 100 high
if(scr.x < 0.0f || scr.x > texdisplay.TextureResolutionPS.x || scr.y < 0.0f || scr.y > 100.0f)
discard;
}
else
{
if(scr.x < 0.0f || scr.y < 0.0f ||
scr.x > texdisplay.TextureResolutionPS.x || scr.y > texdisplay.TextureResolutionPS.y)
{
discard;
}
}
if (texdisplay.FlipY != 0)
scr.y = texdisplay.TextureResolutionPS.y - scr.y;
vec4 col = textureLod(tex, scr.xy / texdisplay.TextureResolutionPS.xy, float(texdisplay.MipLevel));
vec4 rawcol = col;
if(uintTex)
{
ucol = SampleTextureUInt4(texType, scr, texdisplay.Slice, texdisplay.MipLevel,
texdisplay.SampleIdx, texdisplay.TextureResolutionPS);
}
else if(sintTex)
{
scol = SampleTextureSInt4(texType, scr, texdisplay.Slice, texdisplay.MipLevel,
texdisplay.SampleIdx, texdisplay.TextureResolutionPS);
}
else
{
col = SampleTextureFloat4(texType, scr, texdisplay.Slice, texdisplay.MipLevel,
texdisplay.SampleIdx, texdisplay.TextureResolutionPS);
}
if(texdisplay.RawOutput != 0)
{
if (uintTex)
color_out = uintBitsToFloat(ucol);
else if (sintTex)
color_out = intBitsToFloat(scol);
else
color_out = col;
return;
}
// RGBM encoding
if(texdisplay.HDRMul > 0.0f)
@@ -118,5 +159,5 @@ void main(void)
col.rgb = pow(clamp(col.rgb, 0.0f.xxx, 1.0f.xxx), 2.2f.xxx);
}
color_out = (texdisplay.RawOutput != 0 ? rawcol : col);
color_out = col;
}
+155
View File
@@ -0,0 +1,155 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2015 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
// these bindings are defined based on the RESTYPE_ defines in debuguniforms.h
// binding = 5 + RESTYPE_x
layout (binding = 6) uniform sampler1DArray tex1DArray;
layout (binding = 7) uniform sampler2DArray tex2DArray;
layout (binding = 8) uniform sampler3D tex3D;
layout (binding = 9) uniform samplerBuffer texBuffer;
layout (binding = 10) uniform sampler2DMS tex2DMS;
vec4 SampleTextureFloat4(int type, vec2 pos, float slice, int mipLevel, int sampleIdx, vec3 texRes)
{
vec4 col;
if (type == RESTYPE_TEX1D)
{
col = textureLod(tex1DArray, vec2(pos.x / texRes.x, slice), float(mipLevel));
}
else if (type == RESTYPE_TEX2D)
{
col = textureLod(tex2DArray, vec3(pos / texRes.xy, slice), float(mipLevel));
}
else if (type == RESTYPE_TEX3D)
{
col = textureLod(tex3D, vec3(pos / texRes.xy, slice / texRes.z), float(mipLevel));
}
else if (type == RESTYPE_TEXBUFFER)
{
col = texelFetch(texBuffer, int(pos.x));
}
else if (type == RESTYPE_TEX2DMS)
{
if(sampleIdx < 0)
{
int sampleCount = -sampleIdx;
col = vec4(0, 0, 0, 0);
// worst resolve you've seen in your life
for(int i=0; i < sampleCount; i++)
col += texelFetch(tex2DMS, ivec2(pos), i);
col /= float(sampleCount);
}
else
{
col = texelFetch(tex2DMS, ivec2(pos), sampleIdx);
}
}
return col;
}
// these bindings are defined based on the RESTYPE_ defines in debuguniforms.h
// binding = 10 + RESTYPE_x
layout (binding = 11) uniform usampler1DArray texUInt1DArray;
layout (binding = 12) uniform usampler2DArray texUInt2DArray;
layout (binding = 13) uniform usampler3D texUInt3D;
layout (binding = 14) uniform usamplerBuffer texUIntBuffer;
layout (binding = 15) uniform usampler2DMS texUInt2DMS;
uvec4 SampleTextureUInt4(int type, vec2 pos, float slice, int mipLevel, int sampleIdx, vec3 texRes)
{
uvec4 col;
if (type == RESTYPE_TEX1D)
{
col = texelFetch(texUInt1DArray, ivec2(pos.x, slice), mipLevel);
}
else if (type == RESTYPE_TEX2D)
{
col = texelFetch(texUInt2DArray, ivec3(pos, slice), mipLevel);
}
else if (type == RESTYPE_TEX3D)
{
col = texelFetch(texUInt3D, ivec3(pos, slice), mipLevel);
}
else if (type == RESTYPE_TEXBUFFER)
{
col = texelFetch(texUIntBuffer, int(pos.x));
}
else if (type == RESTYPE_TEX2DMS)
{
if(sampleIdx < 0)
sampleIdx = 0;
col = texelFetch(texUInt2DMS, ivec2(pos), sampleIdx);
}
return col;
}
// these bindings are defined based on the RESTYPE_ defines in debuguniforms.h
// binding = 15 + RESTYPE_x
layout (binding = 16) uniform isampler1DArray texSInt1DArray;
layout (binding = 17) uniform isampler2DArray texSInt2DArray;
layout (binding = 18) uniform isampler3D texSInt3D;
layout (binding = 19) uniform isamplerBuffer texSIntBuffer;
layout (binding = 20) uniform isampler2DMS texSInt2DMS;
ivec4 SampleTextureSInt4(int type, vec2 pos, float slice, int mipLevel, int sampleIdx, vec3 texRes)
{
ivec4 col;
if (type == RESTYPE_TEX1D)
{
col = texelFetch(texSInt1DArray, ivec2(pos.x, slice), mipLevel);
}
else if (type == RESTYPE_TEX2D)
{
col = texelFetch(texSInt2DArray, ivec3(pos, slice), mipLevel);
}
else if (type == RESTYPE_TEX3D)
{
col = texelFetch(texSInt3D, ivec3(pos, slice), mipLevel);
}
else if (type == RESTYPE_TEXBUFFER)
{
col = texelFetch(texSIntBuffer, int(pos.x));
}
else if (type == RESTYPE_TEX2DMS)
{
if(sampleIdx < 0)
sampleIdx = 0;
col = texelFetch(texSInt2DMS, ivec2(pos), sampleIdx);
}
return col;
}
+26
View File
@@ -49,6 +49,32 @@ VkAccessFlags MakeAccessMask(VkImageLayout layout)
return VkAccessFlags(0);
}
int SampleCount(VkSampleCountFlagBits countFlag)
{
switch(countFlag)
{
case VK_SAMPLE_COUNT_1_BIT:
return 1;
case VK_SAMPLE_COUNT_2_BIT:
return 2;
case VK_SAMPLE_COUNT_4_BIT:
return 4;
case VK_SAMPLE_COUNT_8_BIT:
return 8;
case VK_SAMPLE_COUNT_16_BIT:
return 16;
case VK_SAMPLE_COUNT_32_BIT:
return 32;
case VK_SAMPLE_COUNT_64_BIT:
return 64;
default:
RDCERR("Unrecognised/not single flag %x", countFlag);
break;
}
return 1;
}
ResourceFormat MakeResourceFormat(VkFormat fmt)
{
ResourceFormat ret;
+2
View File
@@ -54,6 +54,8 @@ VkPrimitiveTopology MakeVkPrimitiveTopology(PrimitiveTopology Topo);
// set conservative access bits for this image layout
VkAccessFlags MakeAccessMask(VkImageLayout layout);
int SampleCount(VkSampleCountFlagBits countFlag);
// structure for casting to easily iterate and template specialising Serialise
struct VkGenericStruct
{
+20 -2
View File
@@ -384,7 +384,21 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
{
VkDescriptorSetLayoutBinding layoutBinding[] = {
{ 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }
{ 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 7, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 8, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 9, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 10, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 11, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 12, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 13, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 14, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 15, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 16, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 17, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 18, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 19, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
{ 20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, },
};
VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = {
@@ -636,12 +650,16 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
sources.resize(4);
sources[0] = "#version 430 core\n";
sources[1] = GetEmbeddedResource(spirv_debuguniforms_h);
sources[2] = ""; // #defines
sources[2] = ""; // #defines/#includes
for(size_t i=0; i < ARRAY_COUNT(module); i++)
{
sources[2] = "";
sources[3] = shaderSources[i];
if(sources[3].find("#include \"texsample.h\"") != string::npos)
sources[2] = GetEmbeddedResource(spirv_texsample_h);
string err = GetSPIRVBlob(shaderStages[i], sources, &shaderSPIRV[i]);
RDCASSERT(err.empty() && shaderSPIRV);
+37 -4
View File
@@ -956,7 +956,7 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
data->FlipY = cfg.FlipY ? 1 : 0;
data->MipLevel = (float)cfg.mip;
data->MipLevel = (int)cfg.mip;
data->Slice = 0;
if(iminfo.type != VK_IMAGE_TYPE_3D)
data->Slice = (float)cfg.sliceFace;
@@ -973,11 +973,45 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
data->NumSamples = iminfo.samples;
data->SampleIdx = cfg.sampleIdx;
if(cfg.sampleIdx == ~0U)
data->SampleIdx = -SampleCount(iminfo.samples);
data->OutputRes.x = (float)m_DebugWidth;
data->OutputRes.y = (float)m_DebugHeight;
int displayformat = 0;
int textype = 0;
if(iminfo.type == VK_IMAGE_TYPE_1D)
textype = RESTYPE_TEX1D;
if(iminfo.type == VK_IMAGE_TYPE_3D)
textype = RESTYPE_TEX3D;
if(iminfo.type == VK_IMAGE_TYPE_2D)
{
textype = RESTYPE_TEX2D;
if(iminfo.samples != VK_SAMPLE_COUNT_1_BIT)
textype = RESTYPE_TEX2DMS;
}
int displayformat = textype;
int descSetBinding = textype;
if(IsUIntFormat(iminfo.format))
{
descSetBinding += 10;
displayformat |= TEXDISPLAY_UINT_TEX;
}
else if(IsSIntFormat(iminfo.format))
{
descSetBinding += 15;
displayformat |= TEXDISPLAY_SINT_TEX;
}
else
{
descSetBinding += 5;
}
// VKTODOMED: RESTYPE_TEXBUFFER
if(!IsSRGBFormat(iminfo.format) && cfg.linearDisplayAsGamma)
displayformat |= TEXDISPLAY_GAMMA_CURVE;
@@ -988,7 +1022,6 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
if(cfg.overlay == eTexOverlay_Clipping)
displayformat |= TEXDISPLAY_CLIPPING;
// VKTODOMED handle different texture types/displays
data->OutputDisplayFormat = displayformat;
data->RawOutput = cfg.rawoutput ? 1 : 0;
@@ -1010,7 +1043,7 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
VkWriteDescriptorSet writeSet[] = {
{
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
Unwrap(descset), 1, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
Unwrap(descset), descSetBinding, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
&imdesc, NULL, NULL
},
{
+67
View File
@@ -242,6 +242,73 @@ bool IsSRGBFormat(VkFormat f)
return false;
}
bool IsUIntFormat(VkFormat f)
{
switch(f)
{
case VK_FORMAT_R8_UINT:
case VK_FORMAT_R8G8_UINT:
case VK_FORMAT_R8G8B8_UINT:
case VK_FORMAT_B8G8R8_UINT:
case VK_FORMAT_R8G8B8A8_UINT:
case VK_FORMAT_B8G8R8A8_UINT:
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
case VK_FORMAT_A2R10G10B10_UINT_PACK32:
case VK_FORMAT_A2B10G10R10_UINT_PACK32:
case VK_FORMAT_R16_UINT:
case VK_FORMAT_R16G16_UINT:
case VK_FORMAT_R16G16B16_UINT:
case VK_FORMAT_R16G16B16A16_UINT:
case VK_FORMAT_R32_UINT:
case VK_FORMAT_R32G32_UINT:
case VK_FORMAT_R32G32B32_UINT:
case VK_FORMAT_R32G32B32A32_UINT:
case VK_FORMAT_R64_UINT:
case VK_FORMAT_R64G64_UINT:
case VK_FORMAT_R64G64B64_UINT:
case VK_FORMAT_R64G64B64A64_UINT:
case VK_FORMAT_S8_UINT:
return true;
default:
break;
}
return false;
}
bool IsSIntFormat(VkFormat f)
{
switch(f)
{
case VK_FORMAT_R8_SINT:
case VK_FORMAT_R8G8_SINT:
case VK_FORMAT_R8G8B8_SINT:
case VK_FORMAT_B8G8R8_SINT:
case VK_FORMAT_R8G8B8A8_SINT:
case VK_FORMAT_B8G8R8A8_SINT:
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
case VK_FORMAT_A2R10G10B10_SINT_PACK32:
case VK_FORMAT_A2B10G10R10_SINT_PACK32:
case VK_FORMAT_R16_SINT:
case VK_FORMAT_R16G16_SINT:
case VK_FORMAT_R16G16B16_SINT:
case VK_FORMAT_R16G16B16A16_SINT:
case VK_FORMAT_R32_SINT:
case VK_FORMAT_R32G32_SINT:
case VK_FORMAT_R32G32B32_SINT:
case VK_FORMAT_R32G32B32A32_SINT:
case VK_FORMAT_R64_SINT:
case VK_FORMAT_R64G64_SINT:
case VK_FORMAT_R64G64B64_SINT:
case VK_FORMAT_R64G64B64A64_SINT:
return true;
default:
break;
}
return false;
}
uint32_t GetByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat Format, uint32_t mip)
{
uint32_t w = RDCMAX(Width>>mip, 1U);
+2
View File
@@ -791,5 +791,7 @@ bool IsBlockFormat(VkFormat f);
bool IsDepthStencilFormat(VkFormat f);
bool IsDepthOnlyFormat(VkFormat f);
bool IsSRGBFormat(VkFormat f);
bool IsUIntFormat(VkFormat f);
bool IsSIntFormat(VkFormat f);
uint32_t GetByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat Format, uint32_t mip);
+1
View File
@@ -256,6 +256,7 @@
<ClInclude Include="data\hlsl\debugcbuffers.h" />
<ClInclude Include="data\resource.h" />
<ClInclude Include="data\spv\debuguniforms.h" />
<ClInclude Include="data\spv\texsample.h" />
<ClInclude Include="data\version.h" />
<ClInclude Include="hooks\hooks.h" />
<ClInclude Include="maths\camera.h" />
+3
View File
@@ -234,6 +234,9 @@
<ClInclude Include="data\spv\debuguniforms.h">
<Filter>Resources\spv</Filter>
</ClInclude>
<ClInclude Include="data\spv\texsample.h">
<Filter>Resources\spv</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="maths\camera.cpp">