Implement min/max calculation for OpenGL

* Same implementation as D3D11 essentially
* Split out the texture sampling from texdisplay.frag into its own file so
  it can be reused. Also removed the discard;s from the texture sample
  functions and moved them up into the texture display function.
This commit is contained in:
baldurk
2014-11-02 20:26:09 +00:00
parent 823821d775
commit 02aa3e7912
12 changed files with 839 additions and 301 deletions
+20 -15
View File
@@ -57,6 +57,7 @@ os/linux/linux_stringio.o \
os/linux/linux_threading.o \
hooks/linux_libentry.o
DATA=data/glsl/debuguniforms.ho \
data/glsl/texsample.ho \
data/glsl/blit.frago \
data/glsl/blit.verto \
data/glsl/texdisplay.frago \
@@ -66,6 +67,7 @@ data/glsl/generic.verto \
data/glsl/mesh.verto \
data/glsl/text.verto \
data/glsl/text.frago \
data/glsl/histogram.compo \
data/sourcecodepro.ttfo
.PHONY: all
@@ -83,25 +85,28 @@ $(OBJDIR)/%.o: %.c
# objcopy needs to be run in with paths in current directory
# to produce the right symbol names
OBJGEN = \
mkdir -p $$(dirname $@); \
cd $$(dirname $<); \
objcopy --input binary --output elf64-x86-64 --binary-architecture i386 $$(basename $<) $$(basename $@); \
cd - > /dev/null 2>&1; \
mv $$(dirname $<)/$$(basename $@) $@;
$(OBJDIR)/%.verto: %.vert
@mkdir -p $$(dirname $@)
cd $$(dirname $<) && objcopy --input binary --output elf64-x86-64 --binary-architecture i386 $$(basename $<) $$(basename $@)
@mv $$(dirname $<)/$$(basename $@) $@
@echo Object building $@
@$(OBJGEN)
$(OBJDIR)/%.frago: %.frag
@mkdir -p $$(dirname $@)
cd $$(dirname $<) && objcopy --input binary --output elf64-x86-64 --binary-architecture i386 $$(basename $<) $$(basename $@)
@mv $$(dirname $<)/$$(basename $@) $@
@echo Object building $@
@$(OBJGEN)
$(OBJDIR)/%.compo: %.comp
@echo Object building $@
@$(OBJGEN)
$(OBJDIR)/%.ttfo: %.ttf
@mkdir -p $$(dirname $@)
cd $$(dirname $<) && objcopy --input binary --output elf64-x86-64 --binary-architecture i386 $$(basename $<) $$(basename $@)
@mv $$(dirname $<)/$$(basename $@) $@
@echo Object building $@
@$(OBJGEN)
$(OBJDIR)/%.ho: %.h
@mkdir -p $$(dirname $@)
cd $$(dirname $<) && objcopy --input binary --output elf64-x86-64 --binary-architecture i386 $$(basename $<) $$(basename $@)
@mv $$(dirname $<)/$$(basename $@) $@
@echo Object building $@
@$(OBJGEN)
OBJDIR_OBJECTS=$(addprefix $(OBJDIR)/, $(OBJECTS))
OBJDIR_DATA=$(addprefix $(OBJDIR)/, $(DATA))
+31
View File
@@ -30,6 +30,7 @@
#define vec2 Vec2f
#define vec3 Vec3f
#define vec4 Vec4f
#define uint uint32_t
#define BINDING(b)
@@ -72,6 +73,22 @@ BINDING(0) uniform FontUniforms
vec2 FontScreenAspect;
};
BINDING(0) uniform HistogramCBufferData
{
uint HistogramChannels;
float HistogramMin;
float HistogramMax;
uint HistogramFlags;
float HistogramSlice;
int HistogramMip;
int HistogramSample;
uint Padding2;
vec3 HistogramTextureResolution;
float Padding3;
};
// some constants available to both C++ and GLSL for configuring display
#define CUBEMAP_FACE_POS_X 0
#define CUBEMAP_FACE_NEG_X 1
@@ -93,3 +110,17 @@ BINDING(0) uniform FontUniforms
#define TEXDISPLAY_SINT_TEX 0x10
#define TEXDISPLAY_DEPTH_TEX 0x20
// histogram/minmax is calculated in blocks of NxN each with MxM tiles.
// e.g. a tile is 32x32 pixels, then this is arranged in blocks of 32x32 tiles.
// 1 compute thread = 1 tile, 1 compute group = 1 block
//
// NOTE because of this a block can cover more than the texture (think of a 1280x720
// texture covered by 2x1 blocks)
//
// these values are in each dimension
#define HGRAM_PIXELS_PER_TILE 64
#define HGRAM_TILES_PER_BLOCK 32
#define HGRAM_NUM_BUCKETS 256
+243
View File
@@ -0,0 +1,243 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2014 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.
******************************************************************************/
// compute shaders that figure out the min/max values or histogram in a texture heirarchically
// note that we have to conditionally compile this shader for float/uint/sint as doing that
// dynamically produces a shader with too many temp registers unfortunately.
#extension GL_ARB_compute_shader : require
#extension GL_ARB_shader_storage_buffer_object : require
#if RENDERDOC_TileMinMaxCS
layout(binding=0) writeonly buffer minmaxtiledest
{
#if UINT_TEX
uvec4 tiles[];
#elif SINT_TEX
ivec4 tiles[];
#else
vec4 tiles[];
#endif
} dest;
layout (local_size_x = HGRAM_TILES_PER_BLOCK, local_size_y = HGRAM_TILES_PER_BLOCK) in;
void main()
{
uvec3 tid = gl_LocalInvocationID;
uvec3 gid = gl_WorkGroupID;
int texType = SHADER_RESTYPE;
uvec3 texDim = uvec3(HistogramTextureResolution);
uint blocksX = uint(ceil(float(texDim.x)/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)));
uvec2 topleft = (gid.xy*HGRAM_TILES_PER_BLOCK + tid.xy)*HGRAM_PIXELS_PER_TILE;
uint outIdx = (tid.y*HGRAM_TILES_PER_BLOCK + tid.x) + (gid.y*blocksX + gid.x)*(HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK);
int i=0;
#if UINT_TEX
{
uvec4 minval = uvec4(0,0,0,0);
uvec4 maxval = uvec4(0,0,0,0);
for(uint y=topleft.y; y < min(texDim.y, topleft.y + HGRAM_PIXELS_PER_TILE); y++)
{
for(uint x=topleft.x; x < min(texDim.x, topleft.x + HGRAM_PIXELS_PER_TILE); x++)
{
uvec4 data = SampleTextureUInt4(vec2(x, y), texType, false,
HistogramMip, HistogramSlice);
// HistogramSample, texDim
if(i == 0)
{
minval = maxval = data;
}
else
{
minval = min(minval, data);
maxval = max(maxval, data);
}
i++;
}
}
dest.tiles[outIdx*2+0] = minval;
dest.tiles[outIdx*2+1] = maxval;
}
#elif SINT_TEX
{
ivec4 minval = ivec4(0,0,0,0);
ivec4 maxval = ivec4(0,0,0,0);
for(uint y=topleft.y; y < min(texDim.y, topleft.y + HGRAM_PIXELS_PER_TILE); y++)
{
for(uint x=topleft.x; x < min(texDim.x, topleft.x + HGRAM_PIXELS_PER_TILE); x++)
{
ivec4 data = SampleTextureSInt4(vec2(x, y), texType, false,
HistogramMip, HistogramSlice);
// HistogramSample, texDim
if(i == 0)
{
minval = maxval = data;
}
else
{
minval = min(minval, data);
maxval = max(maxval, data);
}
i++;
}
}
dest.tiles[outIdx*2+0] = minval;
dest.tiles[outIdx*2+1] = maxval;
}
#else
{
vec4 minval = vec4(0,0,0,0);
vec4 maxval = vec4(0,0,0,0);
for(uint y=topleft.y; y < min(texDim.y, topleft.y + HGRAM_PIXELS_PER_TILE); y++)
{
for(uint x=topleft.x; x < min(texDim.x, topleft.x + HGRAM_PIXELS_PER_TILE); x++)
{
vec4 data = SampleTextureFloat4(vec2(x, y), RESTYPE_TEX2D, false, true,
HistogramMip, HistogramSlice);
// HistogramSample, texDim
if(i == 0)
{
minval = maxval = data;
}
else
{
minval = min(minval, data);
maxval = max(maxval, data);
}
i++;
}
}
dest.tiles[outIdx*2+0] = minval;
dest.tiles[outIdx*2+1] = maxval;
}
#endif
}
#endif // #if RENDERDOC_TileMinMaxCS
#if RENDERDOC_ResultMinMaxCS
layout(binding=0) writeonly buffer minmaxresultdest
{
#if UINT_TEX
uvec4 result[2];
#elif SINT_TEX
ivec4 result[2];
#else
vec4 result[2];
#endif
} dest;
layout(binding=1) readonly buffer minmaxtilesrc
{
#if UINT_TEX
uvec4 tiles[];
#elif SINT_TEX
ivec4 tiles[];
#else
vec4 tiles[];
#endif
} src;
layout (local_size_x = 1) in;
void main()
{
uvec3 texDim = uvec3(HistogramTextureResolution);
uint blocksX = uint(ceil(float(texDim.x)/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)));
uint blocksY = uint(ceil(float(texDim.y)/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)));
#if UINT_TEX
uvec4 minvalU = src.tiles[0];
uvec4 maxvalU = src.tiles[1];
#elif SINT_TEX
ivec4 minvalI = src.tiles[0];
ivec4 maxvalI = src.tiles[1];
#else
vec4 minvalF = src.tiles[0];
vec4 maxvalF = src.tiles[1];
#endif
// i is the tile we're looking at
for(uint i=1; i < blocksX*blocksY*HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK; i++)
{
uint blockIdx = i/(HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK);
uint tileIdx = i%(HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK);
// which block and tile is this in
uvec2 blockXY = uvec2(blockIdx % blocksX, blockIdx / blocksX);
uvec2 tileXY = uvec2(tileIdx % HGRAM_TILES_PER_BLOCK, tileIdx / HGRAM_TILES_PER_BLOCK);
// if this is at least partially within the texture, include it.
if(blockXY.x*(HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK) + tileXY.x*HGRAM_PIXELS_PER_TILE < texDim.x &&
blockXY.y*(HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK) + tileXY.y*HGRAM_PIXELS_PER_TILE < texDim.y)
{
#if UINT_TEX
minvalU = min(minvalU, src.tiles[i*2 + 0]);
maxvalU = max(maxvalU, src.tiles[i*2 + 1]);
#elif SINT_TEX
minvalI = min(minvalI, src.tiles[i*2 + 0]);
maxvalI = max(maxvalI, src.tiles[i*2 + 1]);
#else
minvalF = min(minvalF, src.tiles[i*2 + 0]);
maxvalF = max(maxvalF, src.tiles[i*2 + 1]);
#endif
}
}
#if UINT_TEX
dest.result[0] = minvalU;
dest.result[1] = maxvalU;
#elif SINT_TEX
dest.result[0] = minvalI;
dest.result[1] = maxvalI;
#else
dest.result[0] = minvalF;
dest.result[1] = maxvalF;
#endif
}
#endif // #if RENDERDOC_ResultMinMaxCS
+19 -242
View File
@@ -22,248 +22,8 @@
* THE SOFTWARE.
******************************************************************************/
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 = 9) uniform usampler1D texUInt1D;
layout (binding = 10) uniform usampler2D texUInt2D;
layout (binding = 11) uniform usampler3D texUInt3D;
layout (binding = 13) uniform usampler1DArray texUInt1DArray;
layout (binding = 14) uniform usampler2DArray texUInt2DArray;
layout (binding = 16) uniform isampler1D texSInt1D;
layout (binding = 17) uniform isampler2D texSInt2D;
layout (binding = 18) uniform isampler3D texSInt3D;
layout (binding = 20) uniform isampler1DArray texSInt1DArray;
layout (binding = 21) uniform isampler2DArray texSInt2DArray;
layout (location = 0) out vec4 color_out;
vec3 CalcCubeCoord(vec2 uv, int face)
{
// Map UVs to [-0.5, 0.5] and rotate
uv -= vec2(0.5);
vec3 coord;
if (face == CUBEMAP_FACE_POS_X)
coord = vec3(0.5, uv.y, -uv.x);
else if (face == CUBEMAP_FACE_NEG_X)
coord = vec3(-0.5, -uv.y, uv.x);
else if (face == CUBEMAP_FACE_POS_Y)
coord = vec3(uv.x, 0.5, uv.y);
else if (face == CUBEMAP_FACE_NEG_Y)
coord = vec3(uv.x, -0.5, -uv.y);
else if (face == CUBEMAP_FACE_POS_Z)
coord = vec3(uv.x, -uv.y, 0.5);
else // face == CUBEMAP_FACE_NEG_Z
coord = vec3(-uv.x, -uv.y, -0.5);
return coord;
}
uvec4 SampleTextureUInt4(vec2 pos, int type, bool flipY, int mipLevel, float slice)
{
uvec4 col;
if (type == RESTYPE_TEX1D)
{
int size = textureSize(texUInt1D, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size) discard;
col = texelFetch(texUInt1D, int(pos.x), mipLevel);
}
else if (type == RESTYPE_TEX1DARRAY)
{
ivec2 size = textureSize(texUInt1DArray, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x) discard;
col = texelFetch(texUInt1DArray, ivec2(pos.x, slice), mipLevel);
}
else if (type == RESTYPE_TEX2D)
{
ivec2 size = textureSize(texUInt2D, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
if (flipY)
pos.y = size.y - pos.y;
col = texelFetch(texUInt2D, ivec2(pos), mipLevel);
}
else if (type == RESTYPE_TEX2DARRAY)
{
ivec3 size = textureSize(texUInt2DArray, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
if (flipY)
pos.y = size.y - pos.y;
col = texelFetch(texUInt2DArray, ivec3(pos, slice), mipLevel);
}
else // if (type == RESTYPE_TEX3D)
{
ivec3 size = textureSize(texUInt3D, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
if (flipY)
pos.y = size.y - pos.y;
col = texelFetch(texUInt3D, ivec3(pos, slice), mipLevel);
}
return col;
}
ivec4 SampleTextureSInt4(vec2 pos, int type, bool flipY, int mipLevel, float slice)
{
ivec4 col;
if (type == RESTYPE_TEX1D)
{
int size = textureSize(texSInt1D, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size) discard;
col = texelFetch(texSInt1D, int(pos.x), mipLevel);
}
else if (type == RESTYPE_TEX1DARRAY)
{
ivec2 size = textureSize(texSInt1DArray, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x) discard;
col = texelFetch(texSInt1DArray, ivec2(pos.x, slice), mipLevel);
}
else if (type == RESTYPE_TEX2D)
{
ivec2 size = textureSize(texSInt2D, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
if (flipY)
pos.y = size.y - pos.y;
col = texelFetch(texSInt2D, ivec2(pos), mipLevel);
}
else if (type == RESTYPE_TEX2DARRAY)
{
ivec3 size = textureSize(texSInt2DArray, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
if (flipY)
pos.y = size.y - pos.y;
col = texelFetch(texSInt2DArray, ivec3(pos, slice), mipLevel);
}
else // if (type == RESTYPE_TEX3D)
{
ivec3 size = textureSize(texSInt3D, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
if (flipY)
pos.y = size.y - pos.y;
col = texelFetch(texSInt3D, ivec3(pos, slice), mipLevel);
}
return col;
}
vec4 SampleTextureFloat4(vec2 pos, int type, bool flipY, bool linearSample, int mipLevel, float slice)
{
vec4 col;
if (type == RESTYPE_TEX1D)
{
int size = textureSize(tex1D, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size) discard;
if (linearSample)
col = texture(tex1D, pos.x / size);
else
col = texelFetch(tex1D, int(pos.x), mipLevel);
}
else if (type == RESTYPE_TEX1DARRAY)
{
ivec2 size = textureSize(tex1DArray, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x) discard;
if (linearSample)
col = texture(tex1DArray, vec2(pos.x / size.x, slice));
else
col = texelFetch(tex1DArray, ivec2(pos.x, slice), mipLevel);
}
else if (type == RESTYPE_TEX2D)
{
ivec2 size = textureSize(tex2D, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
if (flipY)
pos.y = size.y - pos.y;
if (linearSample)
col = texture(tex2D, pos / size);
else
col = texelFetch(tex2D, ivec2(pos), mipLevel);
}
else if (type == RESTYPE_TEX2DARRAY)
{
ivec3 size = textureSize(tex2DArray, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
if (flipY)
pos.y = size.y - pos.y;
if (linearSample)
col = texture(tex2DArray, vec3(pos / size.xy, slice));
else
col = texelFetch(tex2DArray, ivec3(pos, slice), mipLevel);
}
else if (type == RESTYPE_TEX3D)
{
ivec3 size = textureSize(tex3D, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
if (flipY)
pos.y = size.y - pos.y;
if (linearSample)
col = texture(tex3D, vec3(pos / size.xy, slice));
else
col = texelFetch(tex3D, ivec3(pos, slice), mipLevel);
}
else if (type == RESTYPE_TEXCUBE)
{
ivec2 size = textureSize(texCube, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
if (flipY)
pos.y = size.y - pos.y;
vec3 cubeCoord = CalcCubeCoord(pos / size, int(slice));
if (linearSample)
col = texture(texCube, cubeCoord);
else
col = textureLod(texCube, cubeCoord, mipLevel);
}
else // type == RESTYPE_TEXCUBEARRAY
{
ivec3 size = textureSize(texCubeArray, mipLevel);
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
if (flipY)
pos.y = size.y - pos.y;
vec3 cubeCoord = CalcCubeCoord(pos / size.xy, int(slice) % 6);
vec4 arrayCoord = vec4(cubeCoord, int(Slice) / 6);
if (linearSample)
col = texture(texCubeArray, arrayCoord);
else
col = textureLod(texCubeArray, arrayCoord, mipLevel);
}
return col;
}
void main(void)
{
bool uintTex = (OutputDisplayFormat & TEXDISPLAY_UINT_TEX) != 0;
@@ -277,18 +37,35 @@ void main(void)
// calc screen co-ords with origin top left, modified by Position
vec2 scr = vec2(gl_FragCoord.x, OutputRes.y - gl_FragCoord.y) - Position.xy;
scr /= Scale;
int texType = (OutputDisplayFormat & TEXDISPLAY_TYPEMASK);
if(texType == RESTYPE_TEX1D || texType == RESTYPE_TEX1DARRAY)
{
if(scr.x < 0.0f || scr.x > TextureResolutionPS.x)
discard;
}
else
{
if(scr.x < 0.0f || scr.y < 0.0f ||
scr.x > TextureResolutionPS.x || scr.y > TextureResolutionPS.y)
discard;
}
// sample the texture.
if (uintTex)
{
ucol = SampleTextureUInt4(scr / Scale, OutputDisplayFormat & TEXDISPLAY_TYPEMASK, FlipY == 0, int(MipLevel), Slice);
ucol = SampleTextureUInt4(scr, texType, FlipY == 0, int(MipLevel), Slice);
}
else if (sintTex)
{
scol = SampleTextureSInt4(scr / Scale, OutputDisplayFormat & TEXDISPLAY_TYPEMASK, FlipY == 0, int(MipLevel), Slice);
scol = SampleTextureSInt4(scr, texType, FlipY == 0, int(MipLevel), Slice);
}
else
{
col = SampleTextureFloat4(scr / Scale, OutputDisplayFormat & TEXDISPLAY_TYPEMASK, FlipY == 0, (Scale < 1.0 && MipLevel == 0.0 && !depthTex), int(MipLevel), Slice);
col = SampleTextureFloat4(scr, texType, FlipY == 0, (Scale < 1.0 && MipLevel == 0.0 && !depthTex), int(MipLevel), Slice);
}
if(RawOutput != 0)
+246
View File
@@ -0,0 +1,246 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2014 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.
******************************************************************************/
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 = 9) uniform usampler1D texUInt1D;
layout (binding = 10) uniform usampler2D texUInt2D;
layout (binding = 11) uniform usampler3D texUInt3D;
layout (binding = 13) uniform usampler1DArray texUInt1DArray;
layout (binding = 14) uniform usampler2DArray texUInt2DArray;
layout (binding = 16) uniform isampler1D texSInt1D;
layout (binding = 17) uniform isampler2D texSInt2D;
layout (binding = 18) uniform isampler3D texSInt3D;
layout (binding = 20) uniform isampler1DArray texSInt1DArray;
layout (binding = 21) uniform isampler2DArray texSInt2DArray;
vec3 CalcCubeCoord(vec2 uv, int face)
{
// Map UVs to [-0.5, 0.5] and rotate
uv -= vec2(0.5);
vec3 coord;
if (face == CUBEMAP_FACE_POS_X)
coord = vec3(0.5, uv.y, -uv.x);
else if (face == CUBEMAP_FACE_NEG_X)
coord = vec3(-0.5, -uv.y, uv.x);
else if (face == CUBEMAP_FACE_POS_Y)
coord = vec3(uv.x, 0.5, uv.y);
else if (face == CUBEMAP_FACE_NEG_Y)
coord = vec3(uv.x, -0.5, -uv.y);
else if (face == CUBEMAP_FACE_POS_Z)
coord = vec3(uv.x, -uv.y, 0.5);
else // face == CUBEMAP_FACE_NEG_Z
coord = vec3(-uv.x, -uv.y, -0.5);
return coord;
}
uvec4 SampleTextureUInt4(vec2 pos, int type, bool flipY, int mipLevel, float slice)
{
uvec4 col;
if (type == RESTYPE_TEX1D)
{
int size = textureSize(texUInt1D, mipLevel);
col = texelFetch(texUInt1D, int(pos.x), mipLevel);
}
else if (type == RESTYPE_TEX1DARRAY)
{
ivec2 size = textureSize(texUInt1DArray, mipLevel);
col = texelFetch(texUInt1DArray, ivec2(pos.x, slice), mipLevel);
}
else if (type == RESTYPE_TEX2D)
{
ivec2 size = textureSize(texUInt2D, mipLevel);
if (flipY)
pos.y = size.y - pos.y;
col = texelFetch(texUInt2D, ivec2(pos), mipLevel);
}
else if (type == RESTYPE_TEX2DARRAY)
{
ivec3 size = textureSize(texUInt2DArray, mipLevel);
if (flipY)
pos.y = size.y - pos.y;
col = texelFetch(texUInt2DArray, ivec3(pos, slice), mipLevel);
}
else // if (type == RESTYPE_TEX3D)
{
ivec3 size = textureSize(texUInt3D, mipLevel);
if (flipY)
pos.y = size.y - pos.y;
col = texelFetch(texUInt3D, ivec3(pos, slice), mipLevel);
}
return col;
}
ivec4 SampleTextureSInt4(vec2 pos, int type, bool flipY, int mipLevel, float slice)
{
ivec4 col;
if (type == RESTYPE_TEX1D)
{
int size = textureSize(texSInt1D, mipLevel);
col = texelFetch(texSInt1D, int(pos.x), mipLevel);
}
else if (type == RESTYPE_TEX1DARRAY)
{
ivec2 size = textureSize(texSInt1DArray, mipLevel);
col = texelFetch(texSInt1DArray, ivec2(pos.x, slice), mipLevel);
}
else if (type == RESTYPE_TEX2D)
{
ivec2 size = textureSize(texSInt2D, mipLevel);
if (flipY)
pos.y = size.y - pos.y;
col = texelFetch(texSInt2D, ivec2(pos), mipLevel);
}
else if (type == RESTYPE_TEX2DARRAY)
{
ivec3 size = textureSize(texSInt2DArray, mipLevel);
if (flipY)
pos.y = size.y - pos.y;
col = texelFetch(texSInt2DArray, ivec3(pos, slice), mipLevel);
}
else // if (type == RESTYPE_TEX3D)
{
ivec3 size = textureSize(texSInt3D, mipLevel);
if (flipY)
pos.y = size.y - pos.y;
col = texelFetch(texSInt3D, ivec3(pos, slice), mipLevel);
}
return col;
}
vec4 SampleTextureFloat4(vec2 pos, int type, bool flipY, bool linearSample, int mipLevel, float slice)
{
vec4 col;
if (type == RESTYPE_TEX1D)
{
int size = textureSize(tex1D, mipLevel);
if (linearSample)
col = texture(tex1D, pos.x / size);
else
col = texelFetch(tex1D, int(pos.x), mipLevel);
}
else if (type == RESTYPE_TEX1DARRAY)
{
ivec2 size = textureSize(tex1DArray, mipLevel);
if (linearSample)
col = texture(tex1DArray, vec2(pos.x / size.x, slice));
else
col = texelFetch(tex1DArray, ivec2(pos.x, slice), mipLevel);
}
else if (type == RESTYPE_TEX2D)
{
ivec2 size = textureSize(tex2D, mipLevel);
if (flipY)
pos.y = size.y - pos.y;
if (linearSample)
col = texture(tex2D, pos / size);
else
col = texelFetch(tex2D, ivec2(pos), mipLevel);
}
else if (type == RESTYPE_TEX2DARRAY)
{
ivec3 size = textureSize(tex2DArray, mipLevel);
if (flipY)
pos.y = size.y - pos.y;
if (linearSample)
col = texture(tex2DArray, vec3(pos / size.xy, slice));
else
col = texelFetch(tex2DArray, ivec3(pos, slice), mipLevel);
}
else if (type == RESTYPE_TEX3D)
{
ivec3 size = textureSize(tex3D, mipLevel);
if (flipY)
pos.y = size.y - pos.y;
if (linearSample)
col = texture(tex3D, vec3(pos / size.xy, slice));
else
col = texelFetch(tex3D, ivec3(pos, slice), mipLevel);
}
else if (type == RESTYPE_TEXCUBE)
{
ivec2 size = textureSize(texCube, mipLevel);
if (flipY)
pos.y = size.y - pos.y;
vec3 cubeCoord = CalcCubeCoord(pos / size, int(slice));
if (linearSample)
col = texture(texCube, cubeCoord);
else
col = textureLod(texCube, cubeCoord, mipLevel);
}
else // type == RESTYPE_TEXCUBEARRAY
{
ivec3 size = textureSize(texCubeArray, mipLevel);
if (flipY)
pos.y = size.y - pos.y;
vec3 cubeCoord = CalcCubeCoord(pos / size.xy, int(slice) % 6);
vec4 arrayCoord = vec4(cubeCoord, int(slice) / 6);
if (linearSample)
col = texture(texCubeArray, arrayCoord);
else
col = textureLod(texCubeArray, arrayCoord, mipLevel);
}
return col;
}
+2
View File
@@ -119,6 +119,8 @@ RESOURCE_mesh_vert TYPE_EMBED "glsl/mesh.vert"
RESOURCE_debuguniforms_h TYPE_EMBED "glsl/debuguniforms.h"
RESOURCE_text_vert TYPE_EMBED "glsl/text.vert"
RESOURCE_text_frag TYPE_EMBED "glsl/text.frag"
RESOURCE_texsample_h TYPE_EMBED "glsl/texsample.h"
RESOURCE_histogram_comp TYPE_EMBED "glsl/histogram.comp"
RESOURCE_sourcecodepro_ttf TYPE_EMBED "sourcecodepro.ttf"
+2
View File
@@ -21,6 +21,8 @@
#define RESOURCE_debuguniforms_h 208
#define RESOURCE_text_vert 209
#define RESOURCE_text_frag 210
#define RESOURCE_texsample_h 211
#define RESOURCE_histogram_comp 212
#define RESOURCE_sourcecodepro_ttf 301
+249 -27
View File
@@ -30,6 +30,48 @@
#include "common/string_utils.h"
GLuint GLReplay::CreateCShaderProgram(const char *csSrc)
{
if(m_pDriver == NULL) return 0;
MakeCurrentReplayContext(m_DebugCtx);
WrappedOpenGL &gl = *m_pDriver;
GLuint cs = gl.glCreateShader(eGL_COMPUTE_SHADER);
gl.glShaderSource(cs, 1, &csSrc, NULL);
gl.glCompileShader(cs);
char buffer[1024];
GLint status = 0;
gl.glGetShaderiv(cs, eGL_COMPILE_STATUS, &status);
if(status == 0)
{
gl.glGetShaderInfoLog(cs, 1024, NULL, buffer);
RDCERR("Shader error: %hs", buffer);
}
GLuint ret = gl.glCreateProgram();
gl.glAttachShader(ret, cs);
gl.glLinkProgram(ret);
gl.glGetProgramiv(ret, eGL_LINK_STATUS, &status);
if(status == 0)
{
gl.glGetProgramInfoLog(ret, 1024, NULL, buffer);
RDCERR("Link error: %hs", buffer);
}
gl.glDeleteShader(cs);
return ret;
}
GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *psSrc)
{
if(m_pDriver == NULL) return 0;
@@ -49,20 +91,20 @@ GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *psSrc)
gl.glCompileShader(vs);
gl.glCompileShader(fs);
char buffer[4096];
char buffer[1024];
GLint status = 0;
gl.glGetShaderiv(vs, eGL_COMPILE_STATUS, &status);
if(status == 0)
{
gl.glGetShaderInfoLog(vs, 4096, NULL, buffer);
gl.glGetShaderInfoLog(vs, 1024, NULL, buffer);
RDCERR("Shader error: %hs", buffer);
}
gl.glGetShaderiv(fs, eGL_COMPILE_STATUS, &status);
if(status == 0)
{
gl.glGetShaderInfoLog(fs, 4096, NULL, buffer);
gl.glGetShaderInfoLog(fs, 1024, NULL, buffer);
RDCERR("Shader error: %hs", buffer);
}
@@ -89,6 +131,8 @@ void GLReplay::InitDebugData()
uint64_t id = MakeOutputWindow(NULL, true);
m_DebugCtx = &m_OutputWindows[id];
MakeCurrentReplayContext(m_DebugCtx);
}
DebugData.outWidth = 0.0f; DebugData.outHeight = 0.0f;
@@ -99,6 +143,7 @@ void GLReplay::InitDebugData()
DebugData.blitProg = CreateShaderProgram(DebugData.blitvsSource.c_str(), DebugData.blitfsSource.c_str());
string texfs = GetEmbeddedResource(debuguniforms_h);
texfs += GetEmbeddedResource(texsample_h);
texfs += GetEmbeddedResource(texdisplay_frag);
DebugData.texDisplayProg = CreateShaderProgram(DebugData.blitvsSource.c_str(), texfs.c_str());
@@ -153,7 +198,10 @@ void GLReplay::InitDebugData()
for(size_t i=0; i < ARRAY_COUNT(DebugData.UBOs); i++)
{
gl.glBindBuffer(eGL_UNIFORM_BUFFER, DebugData.UBOs[i]);
gl.glBufferData(eGL_UNIFORM_BUFFER, sizeof(texdisplay), NULL, eGL_DYNAMIC_DRAW);
gl.glBufferData(eGL_UNIFORM_BUFFER, 512, NULL, eGL_DYNAMIC_DRAW);
RDCCOMPILE_ASSERT(sizeof(texdisplay) < 512, "texdisplay UBO too large");
RDCCOMPILE_ASSERT(sizeof(FontUniforms) < 512, "texdisplay UBO too large");
RDCCOMPILE_ASSERT(sizeof(HistogramCBufferData) < 512, "texdisplay UBO too large");
}
DebugData.overlayTexWidth = DebugData.overlayTexHeight = 0;
@@ -174,6 +222,64 @@ void GLReplay::InitDebugData()
gl.glGenVertexArrays(1, &DebugData.emptyVAO);
gl.glBindVertexArray(DebugData.emptyVAO);
// histogram/minmax data
{
string glslheader = GetEmbeddedResource(debuguniforms_h);
string histogramglsl = GetEmbeddedResource(texsample_h);
histogramglsl += GetEmbeddedResource(histogram_comp);
RDCEraseEl(DebugData.minmaxTileProgram);
RDCEraseEl(DebugData.histogramProgram);
RDCEraseEl(DebugData.minmaxResultProgram);
for(int t=1; t <= TEXDISPLAY_TYPEMASK; t++)
{
// float, uint, sint
for(int i=0; i < 3; i++)
{
int idx = t;
if(i == 1) idx |= TEXDISPLAY_UINT_TEX;
if(i == 2) idx |= TEXDISPLAY_SINT_TEX;
{
string glsl = glslheader;
glsl += string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n";
glsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n";
glsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n";
glsl += string("#define RENDERDOC_TileMinMaxCS 1\n");
glsl += histogramglsl;
DebugData.minmaxTileProgram[idx] = CreateCShaderProgram(glsl.c_str());
}
if(t == 1)
{
string glsl = glslheader;
glsl += string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n";
glsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n";
glsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n";
glsl += string("#define RENDERDOC_ResultMinMaxCS 1\n");
glsl += histogramglsl;
DebugData.minmaxResultProgram[i] = CreateCShaderProgram(glsl.c_str());
}
}
}
gl.glGenBuffers(1, &DebugData.minmaxTileResult);
gl.glGenBuffers(1, &DebugData.minmaxResult);
const uint32_t maxTexDim = 16384;
const uint32_t blockPixSize = HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK;
const uint32_t maxBlocksNeeded = (maxTexDim*maxTexDim)/(blockPixSize*blockPixSize);
const size_t byteSize = 2*sizeof(Vec4f)*HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK*maxBlocksNeeded;
gl.glNamedBufferStorageEXT(DebugData.minmaxTileResult, byteSize, NULL, 0);
gl.glNamedBufferStorageEXT(DebugData.minmaxResult, sizeof(Vec4f)*2, NULL, GL_MAP_READ_BIT);
}
MakeCurrentReplayContext(&m_ReplayCtx);
@@ -181,6 +287,122 @@ void GLReplay::InitDebugData()
gl.glBindVertexArray(DebugData.meshVAO);
}
bool GLReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval)
{
if(m_pDriver->m_Textures.find(texid) == m_pDriver->m_Textures.end())
return false;
auto &texDetails = m_pDriver->m_Textures[texid];
FetchTexture details = GetTexture(texid);
const GLHookSet &gl = m_pDriver->GetHookset();
gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]);
HistogramCBufferData *cdata = (HistogramCBufferData *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(HistogramCBufferData),
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
cdata->HistogramTextureResolution.x = (float)RDCMAX(details.width>>mip, 1U);
cdata->HistogramTextureResolution.y = (float)RDCMAX(details.height>>mip, 1U);
cdata->HistogramTextureResolution.z = (float)RDCMAX(details.depth>>mip, 1U);
cdata->HistogramSlice = (float)sliceFace;
cdata->HistogramMip = (int)mip;
cdata->HistogramSample = (int)RDCCLAMP(sample, 0U, details.msSamp-1);
if(sample == ~0U) cdata->HistogramSample = -int(details.msSamp);
cdata->HistogramMin = 0.0f;
cdata->HistogramMax = 1.0f;
cdata->HistogramChannels = 0xf;
int texSlot = 0;
int intIdx = 0;
switch (texDetails.curType)
{
case eGL_TEXTURE_1D:
texSlot = RESTYPE_TEX1D;
break;
default:
RDCWARN("Unexpected texture type");
case eGL_TEXTURE_2D:
texSlot = RESTYPE_TEX2D;
break;
case eGL_TEXTURE_3D:
texSlot = RESTYPE_TEX3D;
break;
case eGL_TEXTURE_CUBE_MAP:
texSlot = RESTYPE_TEXCUBE;
break;
case eGL_TEXTURE_1D_ARRAY:
texSlot = RESTYPE_TEX1DARRAY;
break;
case eGL_TEXTURE_2D_ARRAY:
texSlot = RESTYPE_TEX2DARRAY;
break;
case eGL_TEXTURE_CUBE_MAP_ARRAY:
texSlot = RESTYPE_TEXCUBEARRAY;
break;
}
if(details.format.compType == eCompType_UInt)
{
texSlot |= TEXDISPLAY_UINT_TEX;
intIdx = 1;
}
if(details.format.compType == eCompType_SInt)
{
texSlot |= TEXDISPLAY_SINT_TEX;
intIdx = 2;
}
if(details.dimension == 3)
cdata->HistogramSlice = float(sliceFace)/float(details.depth);
int blocksX = (int)ceil(cdata->HistogramTextureResolution.x/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK));
int blocksY = (int)ceil(cdata->HistogramTextureResolution.y/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK));
gl.glUnmapBuffer(eGL_UNIFORM_BUFFER);
gl.glActiveTexture((RDCGLenum)(eGL_TEXTURE0 + texSlot));
gl.glBindTexture(texDetails.curType, texDetails.resource.name);
gl.glBindSampler(texSlot, DebugData.pointSampler);
gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 0, DebugData.minmaxTileResult);
gl.glUseProgram(DebugData.minmaxTileProgram[texSlot]);
gl.glDispatchCompute(blocksX, blocksY, 1);
gl.glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 0, DebugData.minmaxResult);
gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 1, DebugData.minmaxTileResult);
gl.glUseProgram(DebugData.minmaxResultProgram[intIdx]);
gl.glDispatchCompute(1, 1, 1);
gl.glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Vec4f minmax[2];
gl.glBindBuffer(eGL_COPY_READ_BUFFER, DebugData.minmaxResult);
gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, 0, sizeof(minmax), minmax);
minval[0] = minmax[0].x;
minval[1] = minmax[0].y;
minval[2] = minmax[0].z;
minval[3] = minmax[0].w;
maxval[0] = minmax[1].x;
maxval[1] = minmax[1].y;
maxval[2] = minmax[1].z;
maxval[3] = minmax[1].w;
return true;
}
bool GLReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector<uint32_t> &histogram)
{
return true;
}
void GLReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4])
{
WrappedOpenGL &gl = *m_pDriver;
@@ -236,29 +458,29 @@ bool GLReplay::RenderTexture(TextureDisplay cfg)
int resType;
switch (texDetails.curType)
{
case eGL_TEXTURE_1D:
resType = RESTYPE_TEX1D;
break;
default:
RDCWARN("Unexpected texture type");
case eGL_TEXTURE_2D:
resType = RESTYPE_TEX2D;
break;
case eGL_TEXTURE_3D:
resType = RESTYPE_TEX3D;
break;
case eGL_TEXTURE_CUBE_MAP:
resType = RESTYPE_TEXCUBE;
break;
case eGL_TEXTURE_1D_ARRAY:
resType = RESTYPE_TEX1DARRAY;
break;
case eGL_TEXTURE_2D_ARRAY:
resType = RESTYPE_TEX2DARRAY;
break;
case eGL_TEXTURE_CUBE_MAP_ARRAY:
resType = RESTYPE_TEXCUBEARRAY;
break;
case eGL_TEXTURE_1D:
resType = RESTYPE_TEX1D;
break;
default:
RDCWARN("Unexpected texture type");
case eGL_TEXTURE_2D:
resType = RESTYPE_TEX2D;
break;
case eGL_TEXTURE_3D:
resType = RESTYPE_TEX3D;
break;
case eGL_TEXTURE_CUBE_MAP:
resType = RESTYPE_TEXCUBE;
break;
case eGL_TEXTURE_1D_ARRAY:
resType = RESTYPE_TEX1DARRAY;
break;
case eGL_TEXTURE_2D_ARRAY:
resType = RESTYPE_TEX2DARRAY;
break;
case eGL_TEXTURE_CUBE_MAP_ARRAY:
resType = RESTYPE_TEXCUBEARRAY;
break;
}
RDCGLenum dsTexMode = eGL_NONE;
+6 -15
View File
@@ -95,7 +95,10 @@ vector<ResourceId> GLReplay::GetTextures()
vector<ResourceId> ret;
for(auto it=m_pDriver->m_Textures.begin(); it != m_pDriver->m_Textures.end(); ++it)
{
ret.push_back(it->first);
CacheTexture(it->first);
}
return ret;
}
@@ -309,7 +312,7 @@ bool GLReplay::IsRenderOutput(ResourceId id)
return false;
}
FetchTexture GLReplay::GetTexture(ResourceId id)
void GLReplay::CacheTexture(ResourceId id)
{
FetchTexture tex;
@@ -321,7 +324,7 @@ FetchTexture GLReplay::GetTexture(ResourceId id)
{
RDCERR("Details for invalid texture id %llu requested", id);
RDCEraseEl(tex);
return tex;
return;
}
WrappedOpenGL &gl = *m_pDriver;
@@ -478,7 +481,7 @@ FetchTexture GLReplay::GetTexture(ResourceId id)
}
}
return tex;
m_CachedTextures[id] = tex;
}
FetchBuffer GLReplay::GetBuffer(ResourceId id)
@@ -1425,18 +1428,6 @@ void GLReplay::FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector
#pragma endregion
bool GLReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval)
{
RDCUNIMPLEMENTED("GetMinMax");
return false;
}
bool GLReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector<uint32_t> &histogram)
{
RDCUNIMPLEMENTED("GetHistogram");
return false;
}
void GLReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
{
GLNOTIMP("GLReplay::InitPostVSBuffers");
+12 -1
View File
@@ -50,7 +50,7 @@ class GLReplay : public IReplayDriver
FetchBuffer GetBuffer(ResourceId id);
vector<ResourceId> GetTextures();
FetchTexture GetTexture(ResourceId id);
FetchTexture GetTexture(ResourceId id) { return m_CachedTextures[id]; }
ShaderReflection *GetShader(ResourceId id);
@@ -175,6 +175,12 @@ class GLReplay : public IReplayDriver
string genericvsSource;
string genericfsSource;
// min/max data
GLuint minmaxTileResult; // tile result buffer
GLuint minmaxResult; // Vec4f[2] final result buffer
GLuint minmaxResultProgram[3]; // float/uint/sint tile result -> final result program
GLuint minmaxTileProgram[32]; // RESTYPE indexed (see debuguniforms.h, 1d/2d/3d etc | uint/sint) src tex -> tile result buf program
// program that does a blit of texture from input to output,
// no transformation or scaling
GLuint blitProg;
@@ -209,6 +215,7 @@ class GLReplay : public IReplayDriver
void InitDebugData();
GLuint CreateShaderProgram(const char *vs, const char *ps);
GLuint CreateCShaderProgram(const char *cs);
void InitOutputWindow(OutputWindow &outwin);
void CreateOutputWindowBackbuffer(OutputWindow &outwin);
@@ -224,6 +231,10 @@ class GLReplay : public IReplayDriver
map<uint64_t, OutputWindow> m_OutputWindows;
bool m_Proxy;
void CacheTexture(ResourceId id);
map<ResourceId, FetchTexture> m_CachedTextures;
WrappedOpenGL *m_pDriver;
+3 -1
View File
@@ -249,6 +249,7 @@
<ClInclude Include="core\resource_manager.h" />
<ClInclude Include="core\socket_helpers.h" />
<ClInclude Include="data\glsl\debuguniforms.h" />
<ClInclude Include="data\glsl\texsample.h" />
<ClInclude Include="data\hlsl\debugcbuffers.h" />
<ClInclude Include="data\resource.h" />
<ClInclude Include="data\version.h" />
@@ -376,6 +377,7 @@
<None Include="data\glsl\checkerboard.frag" />
<None Include="data\glsl\generic.frag" />
<None Include="data\glsl\generic.vert" />
<None Include="data\glsl\histogram.comp" />
<None Include="data\glsl\mesh.vert" />
<None Include="data\glsl\texdisplay.frag" />
<None Include="data\glsl\text.frag" />
@@ -390,4 +392,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
+6
View File
@@ -303,6 +303,9 @@
<ClInclude Include="3rdparty\stb\stb_truetype.h">
<Filter>3rdparty\stb</Filter>
</ClInclude>
<ClInclude Include="data\glsl\texsample.h">
<Filter>Resources\glsl</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="maths\camera.cpp">
@@ -565,6 +568,9 @@
<None Include="data\glsl\text.vert">
<Filter>Resources\glsl</Filter>
</None>
<None Include="data\glsl\histogram.comp">
<Filter>Resources\glsl</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="data\renderdoc.rc">