mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-08 08:40:55 +00:00
Implement histogram and min/max fetching via compute
This commit is contained in:
@@ -58,5 +58,8 @@ DECLARE_EMBED(fixedcolfs_spv);
|
||||
DECLARE_EMBED(meshvs_spv);
|
||||
DECLARE_EMBED(meshgs_spv);
|
||||
DECLARE_EMBED(meshfs_spv);
|
||||
DECLARE_EMBED(minmaxtilecs_spv);
|
||||
DECLARE_EMBED(minmaxresultcs_spv);
|
||||
DECLARE_EMBED(histogramcs_spv);
|
||||
|
||||
#undef DECLARE_EMBED
|
||||
|
||||
@@ -142,6 +142,9 @@ RESOURCE_fixedcolfs_spv TYPE_EMBED "spv/fixedcolfs.spv"
|
||||
RESOURCE_meshvs_spv TYPE_EMBED "spv/meshvs.spv"
|
||||
RESOURCE_meshgs_spv TYPE_EMBED "spv/meshgs.spv"
|
||||
RESOURCE_meshfs_spv TYPE_EMBED "spv/meshfs.spv"
|
||||
RESOURCE_minmaxtilecs_spv TYPE_EMBED "spv/minmaxtilecs.spv"
|
||||
RESOURCE_minmaxresultcs_spv TYPE_EMBED "spv/minmaxresultcs.spv"
|
||||
RESOURCE_histogramcs_spv TYPE_EMBED "spv/histogramcs.spv"
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+70
-67
@@ -1,67 +1,70 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by renderdoc.rc
|
||||
//
|
||||
#define TYPE_EMBED 256
|
||||
|
||||
#define RESOURCE_debugdisplay_hlsl 101
|
||||
#define RESOURCE_debugtext_hlsl 102
|
||||
#define RESOURCE_debugcbuffers_h 103
|
||||
#define RESOURCE_debugcommon_hlsl 104
|
||||
#define RESOURCE_histogram_hlsl 105
|
||||
#define RESOURCE_multisample_hlsl 106
|
||||
#define RESOURCE_mesh_hlsl 107
|
||||
|
||||
#define RESOURCE_blit_vert 201
|
||||
#define RESOURCE_blit_frag 202
|
||||
#define RESOURCE_texdisplay_frag 203
|
||||
#define RESOURCE_checkerboard_frag 204
|
||||
#define RESOURCE_generic_vert 205
|
||||
#define RESOURCE_generic_frag 206
|
||||
#define RESOURCE_mesh_vert 207
|
||||
#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_mesh_frag 213
|
||||
#define RESOURCE_mesh_geom 214
|
||||
#define RESOURCE_mesh_comp 215
|
||||
#define RESOURCE_arraymscopy_comp 216
|
||||
#define RESOURCE_quadoverdraw_frag 217
|
||||
#define RESOURCE_outline_frag 218
|
||||
|
||||
#define RESOURCE_sourcecodepro_ttf 301
|
||||
|
||||
#define RESOURCE_blitvs_spv 401
|
||||
#define RESOURCE_checkerboardfs_spv 402
|
||||
#define RESOURCE_texdisplayfs_spv 403
|
||||
#define RESOURCE_textvs_spv 404
|
||||
#define RESOURCE_textfs_spv 405
|
||||
#define RESOURCE_genericvs_spv 406
|
||||
#define RESOURCE_genericfs_spv 407
|
||||
#define RESOURCE_fixedcolfs_spv 408
|
||||
#define RESOURCE_meshvs_spv 409
|
||||
#define RESOURCE_meshgs_spv 410
|
||||
#define RESOURCE_meshfs_spv 411
|
||||
|
||||
#if !defined(STRINGIZE)
|
||||
#define STRINGIZE2(a) #a
|
||||
#define STRINGIZE(a) STRINGIZE2(a)
|
||||
#endif
|
||||
|
||||
#define GIT_COMMIT_HASH "NO_GIT_COMMIT_HASH_DEFINED"
|
||||
//#define RENDERDOC_OFFICIAL_BUILD // used to determine whether to submit auto crash reports
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 114
|
||||
#define _APS_NEXT_COMMAND_VALUE 40029
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "version.h"
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by renderdoc.rc
|
||||
//
|
||||
#define TYPE_EMBED 256
|
||||
|
||||
#define RESOURCE_debugdisplay_hlsl 101
|
||||
#define RESOURCE_debugtext_hlsl 102
|
||||
#define RESOURCE_debugcbuffers_h 103
|
||||
#define RESOURCE_debugcommon_hlsl 104
|
||||
#define RESOURCE_histogram_hlsl 105
|
||||
#define RESOURCE_multisample_hlsl 106
|
||||
#define RESOURCE_mesh_hlsl 107
|
||||
|
||||
#define RESOURCE_blit_vert 201
|
||||
#define RESOURCE_blit_frag 202
|
||||
#define RESOURCE_texdisplay_frag 203
|
||||
#define RESOURCE_checkerboard_frag 204
|
||||
#define RESOURCE_generic_vert 205
|
||||
#define RESOURCE_generic_frag 206
|
||||
#define RESOURCE_mesh_vert 207
|
||||
#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_mesh_frag 213
|
||||
#define RESOURCE_mesh_geom 214
|
||||
#define RESOURCE_mesh_comp 215
|
||||
#define RESOURCE_arraymscopy_comp 216
|
||||
#define RESOURCE_quadoverdraw_frag 217
|
||||
#define RESOURCE_outline_frag 218
|
||||
|
||||
#define RESOURCE_sourcecodepro_ttf 301
|
||||
|
||||
#define RESOURCE_blitvs_spv 401
|
||||
#define RESOURCE_checkerboardfs_spv 402
|
||||
#define RESOURCE_texdisplayfs_spv 403
|
||||
#define RESOURCE_textvs_spv 404
|
||||
#define RESOURCE_textfs_spv 405
|
||||
#define RESOURCE_genericvs_spv 406
|
||||
#define RESOURCE_genericfs_spv 407
|
||||
#define RESOURCE_fixedcolfs_spv 408
|
||||
#define RESOURCE_meshvs_spv 409
|
||||
#define RESOURCE_meshgs_spv 410
|
||||
#define RESOURCE_meshfs_spv 411
|
||||
#define RESOURCE_minmaxtilecs_spv 412
|
||||
#define RESOURCE_minmaxresultcs_spv 413
|
||||
#define RESOURCE_histogramcs_spv 414
|
||||
|
||||
#if !defined(STRINGIZE)
|
||||
#define STRINGIZE2(a) #a
|
||||
#define STRINGIZE(a) STRINGIZE2(a)
|
||||
#endif
|
||||
|
||||
#define GIT_COMMIT_HASH "NO_GIT_COMMIT_HASH_DEFINED"
|
||||
//#define RENDERDOC_OFFICIAL_BUILD // used to determine whether to submit auto crash reports
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 114
|
||||
#define _APS_NEXT_COMMAND_VALUE 40029
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "version.h"
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/******************************************************************************
|
||||
* 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.
|
||||
|
||||
#version 430 core
|
||||
|
||||
#define HGRAM_PIXELS_PER_TILE 64u
|
||||
#define HGRAM_TILES_PER_BLOCK 32u
|
||||
|
||||
#define HGRAM_NUM_BUCKETS 256u
|
||||
|
||||
layout(binding=0, std140) writeonly buffer minmaxresultdest
|
||||
{
|
||||
uint result[HGRAM_NUM_BUCKETS];
|
||||
} dest;
|
||||
|
||||
layout(binding=2, std140) uniform HistogramCBufferData
|
||||
{
|
||||
uint HistogramChannels;
|
||||
float HistogramMin;
|
||||
float HistogramMax;
|
||||
uint HistogramFlags;
|
||||
|
||||
float HistogramSlice;
|
||||
int HistogramMip;
|
||||
int HistogramSample;
|
||||
int HistogramNumSamples;
|
||||
|
||||
vec3 HistogramTextureResolution;
|
||||
float Padding3;
|
||||
} histogram;
|
||||
|
||||
layout (binding = 3) uniform sampler2D tex;
|
||||
|
||||
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;
|
||||
|
||||
uvec3 texDim = uvec3(histogram.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;
|
||||
|
||||
int i=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++)
|
||||
{
|
||||
uint bucketIdx = HGRAM_NUM_BUCKETS+1;
|
||||
|
||||
{
|
||||
vec4 data = textureLod(tex, vec2(x, y) / histogram.HistogramTextureResolution.xy, float(histogram.HistogramMip));
|
||||
|
||||
float divisor = 0.0f;
|
||||
float sum = 0.0f;
|
||||
if((histogram.HistogramChannels & 0x1u) > 0)
|
||||
{
|
||||
sum += data.x;
|
||||
divisor += 1.0f;
|
||||
}
|
||||
if((histogram.HistogramChannels & 0x2u) > 0)
|
||||
{
|
||||
sum += data.y;
|
||||
divisor += 1.0f;
|
||||
}
|
||||
if((histogram.HistogramChannels & 0x4u) > 0)
|
||||
{
|
||||
sum += data.z;
|
||||
divisor += 1.0f;
|
||||
}
|
||||
if((histogram.HistogramChannels & 0x8u) > 0)
|
||||
{
|
||||
sum += data.w;
|
||||
divisor += 1.0f;
|
||||
}
|
||||
|
||||
if(divisor > 0.0f)
|
||||
{
|
||||
float val = sum/divisor;
|
||||
|
||||
float normalisedVal = (val - histogram.HistogramMin)/(histogram.HistogramMax - histogram.HistogramMin);
|
||||
|
||||
if(normalisedVal < 0.0f)
|
||||
normalisedVal = 2.0f;
|
||||
|
||||
bucketIdx = uint(floor(normalisedVal*HGRAM_NUM_BUCKETS));
|
||||
}
|
||||
}
|
||||
|
||||
if(bucketIdx >= 0 && bucketIdx < HGRAM_NUM_BUCKETS)
|
||||
atomicAdd(dest.result[bucketIdx], 1U);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/******************************************************************************
|
||||
* 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.
|
||||
|
||||
#version 430 core
|
||||
|
||||
#define HGRAM_PIXELS_PER_TILE 64u
|
||||
#define HGRAM_TILES_PER_BLOCK 32u
|
||||
|
||||
#define HGRAM_NUM_BUCKETS 256u
|
||||
|
||||
layout(binding=0, std140) writeonly buffer minmaxresultdest
|
||||
{
|
||||
vec4 result[2];
|
||||
} dest;
|
||||
|
||||
layout(binding=1, std140) readonly buffer minmaxtilesrc
|
||||
{
|
||||
vec4 tiles[];
|
||||
} src;
|
||||
|
||||
layout(binding=2, std140) uniform HistogramCBufferData
|
||||
{
|
||||
uint HistogramChannels;
|
||||
float HistogramMin;
|
||||
float HistogramMax;
|
||||
uint HistogramFlags;
|
||||
|
||||
float HistogramSlice;
|
||||
int HistogramMip;
|
||||
int HistogramSample;
|
||||
int HistogramNumSamples;
|
||||
|
||||
vec3 HistogramTextureResolution;
|
||||
float Padding3;
|
||||
} minmax;
|
||||
|
||||
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
void main()
|
||||
{
|
||||
uvec3 texDim = uvec3(minmax.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)));
|
||||
|
||||
vec4 minvalF = src.tiles[0];
|
||||
vec4 maxvalF = src.tiles[1];
|
||||
|
||||
// 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)
|
||||
{
|
||||
minvalF = min(minvalF, src.tiles[i*2 + 0]);
|
||||
maxvalF = max(maxvalF, src.tiles[i*2 + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
dest.result[0] = minvalF;
|
||||
dest.result[1] = maxvalF;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/******************************************************************************
|
||||
* 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.
|
||||
|
||||
#version 430 core
|
||||
|
||||
#define HGRAM_PIXELS_PER_TILE 64u
|
||||
#define HGRAM_TILES_PER_BLOCK 32u
|
||||
|
||||
#define HGRAM_NUM_BUCKETS 256u
|
||||
|
||||
layout(binding=0, std140) writeonly buffer minmaxtiledest
|
||||
{
|
||||
vec4 tiles[];
|
||||
} dest;
|
||||
|
||||
layout(binding=2, std140) uniform HistogramCBufferData
|
||||
{
|
||||
uint HistogramChannels;
|
||||
float HistogramMin;
|
||||
float HistogramMax;
|
||||
uint HistogramFlags;
|
||||
|
||||
float HistogramSlice;
|
||||
int HistogramMip;
|
||||
int HistogramSample;
|
||||
int HistogramNumSamples;
|
||||
|
||||
vec3 HistogramTextureResolution;
|
||||
float Padding3;
|
||||
} minmax;
|
||||
|
||||
layout (binding = 3) uniform sampler2D tex;
|
||||
|
||||
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;
|
||||
|
||||
uvec3 texDim = uvec3(minmax.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;
|
||||
|
||||
{
|
||||
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 = textureLod(tex, vec2(x, y) / minmax.HistogramTextureResolution.xy, float(minmax.HistogramMip));
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +99,35 @@ struct meshuniforms
|
||||
Vec2f pointSpriteSize;
|
||||
};
|
||||
|
||||
// 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
|
||||
|
||||
struct histogramuniforms
|
||||
{
|
||||
uint32_t HistogramChannels;
|
||||
float HistogramMin;
|
||||
float HistogramMax;
|
||||
uint32_t HistogramFlags;
|
||||
|
||||
float HistogramSlice;
|
||||
uint32_t HistogramMip;
|
||||
int HistogramSample;
|
||||
int HistogramNumSamples;
|
||||
|
||||
Vec3f HistogramTextureResolution;
|
||||
float Padding3;
|
||||
};
|
||||
|
||||
void VulkanDebugManager::GPUBuffer::Create(WrappedVulkan *driver, VkDevice dev, VkDeviceSize size, uint32_t ringSize, uint32_t flags)
|
||||
{
|
||||
const VkLayerDispatchTable *vt = ObjDisp(dev);
|
||||
@@ -125,6 +154,9 @@ void VulkanDebugManager::GPUBuffer::Create(WrappedVulkan *driver, VkDevice dev,
|
||||
|
||||
if(flags & eGPUBufferVBuffer)
|
||||
bufInfo.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||
|
||||
if(flags & eGPUBufferSSBO)
|
||||
bufInfo.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
|
||||
VkResult vkr = vt->CreateBuffer(Unwrap(dev), &bufInfo, &buf);
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
@@ -365,6 +397,25 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), m_TextDescSetLayout);
|
||||
}
|
||||
|
||||
{
|
||||
VkDescriptorSetLayoutBinding layoutBinding[] = {
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, },
|
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, },
|
||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }
|
||||
};
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, NULL,
|
||||
ARRAY_COUNT(layoutBinding), &layoutBinding[0],
|
||||
};
|
||||
|
||||
vkr = vt->CreateDescriptorSetLayout(Unwrap(dev), &descsetLayoutInfo, &m_HistogramDescSetLayout);
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), m_HistogramDescSetLayout);
|
||||
}
|
||||
|
||||
VkPipelineLayoutCreateInfo pipeLayoutInfo = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, NULL,
|
||||
1, UnwrapPtr(m_TexDisplayDescSetLayout),
|
||||
@@ -404,15 +455,23 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), m_MeshPipeLayout);
|
||||
|
||||
pipeLayoutInfo.pSetLayouts = UnwrapPtr(m_HistogramDescSetLayout);
|
||||
|
||||
vkr = vt->CreatePipelineLayout(Unwrap(dev), &pipeLayoutInfo, &m_HistogramPipeLayout);
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), m_HistogramPipeLayout);
|
||||
|
||||
VkDescriptorTypeCount descPoolTypes[] = {
|
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1024, },
|
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1024, },
|
||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1024, },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1024, },
|
||||
};
|
||||
|
||||
VkDescriptorPoolCreateInfo descpoolInfo = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, NULL,
|
||||
VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 4+ARRAY_COUNT(m_TexDisplayDescSet),
|
||||
VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 6+ARRAY_COUNT(m_TexDisplayDescSet),
|
||||
ARRAY_COUNT(descPoolTypes), &descPoolTypes[0],
|
||||
};
|
||||
|
||||
@@ -453,6 +512,18 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), m_MeshDescSet);
|
||||
|
||||
vkr = vt->AllocDescriptorSets(Unwrap(dev), Unwrap(m_DescriptorPool), VK_DESCRIPTOR_SET_USAGE_STATIC, 1,
|
||||
UnwrapPtr(m_HistogramDescSetLayout), &m_HistogramDescSet[0]);
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), m_HistogramDescSet[0]);
|
||||
|
||||
vkr = vt->AllocDescriptorSets(Unwrap(dev), Unwrap(m_DescriptorPool), VK_DESCRIPTOR_SET_USAGE_STATIC, 1,
|
||||
UnwrapPtr(m_HistogramDescSetLayout), &m_HistogramDescSet[1]);
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), m_HistogramDescSet[1]);
|
||||
|
||||
m_GenericUBO.Create(driver, dev, 128, 10, 0);
|
||||
RDCCOMPILE_ASSERT(sizeof(genericuniforms) <= 128, "outline strip VBO size");
|
||||
@@ -504,6 +575,9 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
GetEmbeddedResource(meshvs_spv),
|
||||
GetEmbeddedResource(meshgs_spv),
|
||||
GetEmbeddedResource(meshfs_spv),
|
||||
GetEmbeddedResource(minmaxtilecs_spv),
|
||||
GetEmbeddedResource(minmaxresultcs_spv),
|
||||
GetEmbeddedResource(histogramcs_spv),
|
||||
};
|
||||
|
||||
VkShaderStage shaderStages[] = {
|
||||
@@ -517,6 +591,9 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
VK_SHADER_STAGE_VERTEX,
|
||||
VK_SHADER_STAGE_GEOMETRY,
|
||||
VK_SHADER_STAGE_FRAGMENT,
|
||||
VK_SHADER_STAGE_COMPUTE,
|
||||
VK_SHADER_STAGE_COMPUTE,
|
||||
VK_SHADER_STAGE_COMPUTE,
|
||||
};
|
||||
|
||||
enum shaderIdx
|
||||
@@ -531,6 +608,9 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
MESHVS,
|
||||
MESHGS,
|
||||
MESHFS,
|
||||
MINMAXTILECS,
|
||||
MINMAXRESULTCS,
|
||||
HISTOGRAMCS,
|
||||
NUM_SHADERS,
|
||||
};
|
||||
|
||||
@@ -756,6 +836,35 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), m_HighlightBoxPipeline);
|
||||
|
||||
VkComputePipelineCreateInfo compPipeInfo = {
|
||||
VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, NULL,
|
||||
{ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, VK_SHADER_STAGE_COMPUTE, VK_NULL_HANDLE, NULL },
|
||||
0, // flags
|
||||
Unwrap(m_HistogramPipeLayout),
|
||||
VK_NULL_HANDLE, 0, // base pipeline VkPipeline
|
||||
};
|
||||
|
||||
compPipeInfo.stage.shader = Unwrap(shader[MINMAXTILECS]);
|
||||
|
||||
vkr = vt->CreateComputePipelines(Unwrap(dev), VK_NULL_HANDLE, 1, &compPipeInfo, &m_MinMaxTilePipe);
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), m_MinMaxTilePipe);
|
||||
|
||||
compPipeInfo.stage.shader = Unwrap(shader[MINMAXRESULTCS]);
|
||||
|
||||
vkr = vt->CreateComputePipelines(Unwrap(dev), VK_NULL_HANDLE, 1, &compPipeInfo, &m_MinMaxResultPipe);
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), m_MinMaxResultPipe);
|
||||
|
||||
compPipeInfo.stage.shader = Unwrap(shader[HISTOGRAMCS]);
|
||||
|
||||
vkr = vt->CreateComputePipelines(Unwrap(dev), VK_NULL_HANDLE, 1, &compPipeInfo, &m_HistogramPipe);
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
|
||||
GetResourceManager()->WrapResource(Unwrap(dev), m_HistogramPipe);
|
||||
|
||||
vt->DestroyRenderPass(Unwrap(dev), RGBA32RP);
|
||||
vt->DestroyRenderPass(Unwrap(dev), RGBA8RP);
|
||||
|
||||
@@ -1099,6 +1208,21 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
memcpy(axisData, axisFrustum, sizeof(axisFrustum));
|
||||
|
||||
m_MeshAxisFrustumVB.Unmap(vt, dev);
|
||||
|
||||
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;
|
||||
|
||||
m_MinMaxTileResult.Create(driver, dev, byteSize, 1, GPUBuffer::eGPUBufferSSBO);
|
||||
m_MinMaxResult.Create(driver, dev, sizeof(Vec4f)*2, 1, GPUBuffer::eGPUBufferSSBO);
|
||||
m_MinMaxReadback.Create(driver, dev, sizeof(Vec4f)*2, 1, GPUBuffer::eGPUBufferReadback);
|
||||
m_HistogramBuf.Create(driver, dev, sizeof(uint32_t)*HGRAM_NUM_BUCKETS, 1, GPUBuffer::eGPUBufferSSBO);
|
||||
m_HistogramReadback.Create(driver, dev, sizeof(uint32_t)*HGRAM_NUM_BUCKETS, 1, GPUBuffer::eGPUBufferReadback);
|
||||
|
||||
// don't need to ring this, as we hard-sync for readback anyway
|
||||
m_HistogramUBO.Create(driver, dev, sizeof(histogramuniforms), 1, 0);
|
||||
|
||||
VkDescriptorInfo desc[7];
|
||||
RDCEraseEl(desc);
|
||||
@@ -1194,6 +1318,9 @@ VulkanDebugManager::~VulkanDebugManager()
|
||||
GetResourceManager()->ReleaseWrappedResource(m_TextDescSet);
|
||||
GetResourceManager()->ReleaseWrappedResource(m_MeshDescSet);
|
||||
|
||||
for(size_t i=0; i < ARRAY_COUNT(m_HistogramDescSet); i++)
|
||||
GetResourceManager()->ReleaseWrappedResource(m_HistogramDescSet[i]);
|
||||
|
||||
for(size_t i=0; i < ARRAY_COUNT(m_TexDisplayDescSet); i++)
|
||||
GetResourceManager()->ReleaseWrappedResource(m_TexDisplayDescSet[i]);
|
||||
|
||||
@@ -1375,6 +1502,43 @@ VulkanDebugManager::~VulkanDebugManager()
|
||||
m_OutlineStripVBO.Destroy(vt, dev);
|
||||
m_GenericUBO.Destroy(vt, dev);
|
||||
|
||||
if(m_HistogramDescSetLayout != VK_NULL_HANDLE)
|
||||
{
|
||||
vt->DestroyDescriptorSetLayout(Unwrap(dev), Unwrap(m_HistogramDescSetLayout));
|
||||
GetResourceManager()->ReleaseWrappedResource(m_HistogramDescSetLayout);
|
||||
}
|
||||
|
||||
if(m_HistogramPipeLayout != VK_NULL_HANDLE)
|
||||
{
|
||||
vt->DestroyPipelineLayout(Unwrap(dev), Unwrap(m_HistogramPipeLayout));
|
||||
GetResourceManager()->ReleaseWrappedResource(m_HistogramPipeLayout);
|
||||
}
|
||||
|
||||
if(m_MinMaxResultPipe != VK_NULL_HANDLE)
|
||||
{
|
||||
vt->DestroyPipeline(Unwrap(dev), Unwrap(m_MinMaxResultPipe));
|
||||
GetResourceManager()->ReleaseWrappedResource(m_MinMaxResultPipe);
|
||||
}
|
||||
|
||||
if(m_MinMaxTilePipe != VK_NULL_HANDLE)
|
||||
{
|
||||
vt->DestroyPipeline(Unwrap(dev), Unwrap(m_MinMaxTilePipe));
|
||||
GetResourceManager()->ReleaseWrappedResource(m_MinMaxTilePipe);
|
||||
}
|
||||
|
||||
if(m_HistogramPipe != VK_NULL_HANDLE)
|
||||
{
|
||||
vt->DestroyPipeline(Unwrap(dev), Unwrap(m_HistogramPipe));
|
||||
GetResourceManager()->ReleaseWrappedResource(m_HistogramPipe);
|
||||
}
|
||||
|
||||
m_MinMaxTileResult.Destroy(vt, dev);
|
||||
m_MinMaxResult.Destroy(vt, dev);
|
||||
m_MinMaxReadback.Destroy(vt, dev);
|
||||
m_HistogramBuf.Destroy(vt, dev);
|
||||
m_HistogramReadback.Destroy(vt, dev);
|
||||
m_HistogramUBO.Destroy(vt, dev);
|
||||
|
||||
// overlay resources are allocated through driver
|
||||
if(m_OverlayNoDepthFB != VK_NULL_HANDLE)
|
||||
m_pDriver->vkDestroyFramebuffer(dev, m_OverlayNoDepthFB);
|
||||
|
||||
@@ -74,6 +74,7 @@ class VulkanDebugManager
|
||||
{
|
||||
eGPUBufferReadback = 0x1,
|
||||
eGPUBufferVBuffer = 0x2,
|
||||
eGPUBufferSSBO = 0x4,
|
||||
};
|
||||
GPUBuffer() : buf(VK_NULL_HANDLE), mem(VK_NULL_HANDLE) {}
|
||||
void Create(WrappedVulkan *driver, VkDevice dev, VkDeviceSize size, uint32_t ringSize, uint32_t flags);
|
||||
@@ -162,6 +163,17 @@ class VulkanDebugManager
|
||||
GPUBuffer m_MeshUBO, m_MeshBBoxVB, m_MeshAxisFrustumVB;
|
||||
VkShader m_MeshShaders[3];
|
||||
VkShaderModule m_MeshModules[3];
|
||||
|
||||
GPUBuffer m_MinMaxTileResult; // tile result buffer
|
||||
GPUBuffer m_MinMaxResult, m_MinMaxReadback; // Vec4f[2] final result buffer
|
||||
GPUBuffer m_HistogramBuf, m_HistogramReadback; // uint32_t * num buckets buffer
|
||||
VkDescriptorSetLayout m_HistogramDescSetLayout;
|
||||
VkPipelineLayout m_HistogramPipeLayout;
|
||||
VkDescriptorSet m_HistogramDescSet[2];
|
||||
GPUBuffer m_HistogramUBO;
|
||||
VkPipeline m_MinMaxResultPipe;
|
||||
VkPipeline m_MinMaxTilePipe;
|
||||
VkPipeline m_HistogramPipe;
|
||||
|
||||
MeshDisplayPipelines CacheMeshDisplayPipelines(const MeshFormat &primary, const MeshFormat &secondary);
|
||||
|
||||
|
||||
@@ -80,6 +80,27 @@ struct meshuniforms
|
||||
#define MESHDISPLAY_SECONDARY 0x3
|
||||
#define MESHDISPLAY_SECONDARY_ALPHA 0x4
|
||||
|
||||
#define HGRAM_PIXELS_PER_TILE 64
|
||||
#define HGRAM_TILES_PER_BLOCK 32
|
||||
|
||||
#define HGRAM_NUM_BUCKETS 256
|
||||
|
||||
struct histogramuniforms
|
||||
{
|
||||
uint32_t HistogramChannels;
|
||||
float HistogramMin;
|
||||
float HistogramMax;
|
||||
uint32_t HistogramFlags;
|
||||
|
||||
float HistogramSlice;
|
||||
uint32_t HistogramMip;
|
||||
int HistogramSample;
|
||||
int HistogramNumSamples;
|
||||
|
||||
Vec3f HistogramTextureResolution;
|
||||
float Padding3;
|
||||
};
|
||||
|
||||
VulkanReplay::OutputWindow::OutputWindow() : wnd(NULL_WND_HANDLE), width(0), height(0),
|
||||
dsimg(VK_NULL_HANDLE), dsmem(VK_NULL_HANDLE)
|
||||
{
|
||||
@@ -3133,14 +3154,411 @@ void VulkanReplay::FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, ve
|
||||
|
||||
bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval)
|
||||
{
|
||||
RDCUNIMPLEMENTED("GetMinMax");
|
||||
return false;
|
||||
VkDevice dev = m_pDriver->GetDev();
|
||||
VkCmdBuffer cmd = m_pDriver->GetNextCmd();
|
||||
const VkLayerDispatchTable *vt = ObjDisp(dev);
|
||||
|
||||
ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid];
|
||||
VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid];
|
||||
VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle<VkImage>(texid);
|
||||
|
||||
// VKTODOMED handle multiple subresources with different layouts etc
|
||||
VkImageLayout origLayout = layouts.subresourceStates[0].newLayout;
|
||||
VkImageView liveImView = iminfo.view;
|
||||
|
||||
if(liveImView == VK_NULL_HANDLE)
|
||||
{
|
||||
VkImageViewCreateInfo viewInfo = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL,
|
||||
Unwrap(liveIm), VK_IMAGE_VIEW_TYPE_2D,
|
||||
iminfo.format,
|
||||
{ VK_CHANNEL_SWIZZLE_R, VK_CHANNEL_SWIZZLE_G, VK_CHANNEL_SWIZZLE_B, VK_CHANNEL_SWIZZLE_A },
|
||||
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, RDCMAX(1U, (uint32_t)iminfo.mipLevels), 0, 1, },
|
||||
0
|
||||
};
|
||||
|
||||
// Only needed on AMD - does the wrong thing on nvidia - so commented for now while AMD
|
||||
// drivers aren't on 0.9.2
|
||||
//if(iminfo.format == VK_FORMAT_B8G8R8A8_UNORM || iminfo.format == VK_FORMAT_B8G8R8A8_SRGB)
|
||||
//std::swap(viewInfo.channels.r, viewInfo.channels.b);
|
||||
|
||||
VkResult vkr = ObjDisp(dev)->CreateImageView(Unwrap(dev), &viewInfo, &iminfo.view);
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
|
||||
ResourceId viewid = m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), iminfo.view);
|
||||
// register as a live-only resource, so it is cleaned up properly
|
||||
m_pDriver->GetResourceManager()->AddLiveResource(viewid, iminfo.view);
|
||||
|
||||
liveImView = iminfo.view;
|
||||
}
|
||||
|
||||
VkDescriptorInfo desc = {0};
|
||||
desc.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
desc.imageView = Unwrap(liveImView);
|
||||
desc.sampler = Unwrap(GetDebugManager()->m_PointSampler);
|
||||
|
||||
VkDescriptorInfo bufdescs[3];
|
||||
RDCEraseEl(bufdescs);
|
||||
GetDebugManager()->m_MinMaxTileResult.FillDescriptor(bufdescs[0]);
|
||||
GetDebugManager()->m_MinMaxResult.FillDescriptor(bufdescs[1]);
|
||||
GetDebugManager()->m_HistogramUBO.FillDescriptor(bufdescs[2]);
|
||||
|
||||
VkWriteDescriptorSet writeSet[] = {
|
||||
|
||||
// first pass on tiles
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
|
||||
Unwrap(GetDebugManager()->m_HistogramDescSet[0]),
|
||||
0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufdescs[0] // destination = tile result
|
||||
},
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
|
||||
Unwrap(GetDebugManager()->m_HistogramDescSet[0]),
|
||||
1, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufdescs[0] // source = unused, bind tile result
|
||||
},
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
|
||||
Unwrap(GetDebugManager()->m_HistogramDescSet[0]),
|
||||
2, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufdescs[2]
|
||||
},
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
|
||||
Unwrap(GetDebugManager()->m_HistogramDescSet[0]),
|
||||
3, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &desc
|
||||
},
|
||||
|
||||
// second pass from tiles to result
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
|
||||
Unwrap(GetDebugManager()->m_HistogramDescSet[1]),
|
||||
0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufdescs[1] // destination = result
|
||||
},
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
|
||||
Unwrap(GetDebugManager()->m_HistogramDescSet[1]),
|
||||
1, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufdescs[0] // source = tile result
|
||||
},
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
|
||||
Unwrap(GetDebugManager()->m_HistogramDescSet[1]),
|
||||
2, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufdescs[2]
|
||||
},
|
||||
};
|
||||
|
||||
vt->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL);
|
||||
|
||||
histogramuniforms *data = (histogramuniforms *)GetDebugManager()->m_HistogramUBO.Map(vt, dev, NULL);
|
||||
|
||||
data->HistogramTextureResolution.x = (float)RDCMAX(uint32_t(iminfo.extent.width)>>mip, 1U);
|
||||
data->HistogramTextureResolution.y = (float)RDCMAX(uint32_t(iminfo.extent.height)>>mip, 1U);
|
||||
data->HistogramTextureResolution.z = (float)RDCMAX(uint32_t(iminfo.arraySize)>>mip, 1U);
|
||||
data->HistogramSlice = (float)sliceFace;
|
||||
data->HistogramMip = (int)mip;
|
||||
data->HistogramNumSamples = iminfo.samples;
|
||||
data->HistogramSample = (int)RDCCLAMP(sample, 0U, uint32_t(iminfo.samples)-1);
|
||||
if(sample == ~0U) data->HistogramSample = -iminfo.samples;
|
||||
data->HistogramMin = 0.0f;
|
||||
data->HistogramMax = 1.0f;
|
||||
data->HistogramChannels = 0xf;
|
||||
|
||||
if(iminfo.type == VK_IMAGE_TYPE_3D)
|
||||
data->HistogramSlice = float(sliceFace)/float(iminfo.extent.depth);
|
||||
|
||||
GetDebugManager()->m_HistogramUBO.Unmap(vt, dev);
|
||||
|
||||
VkImageMemoryBarrier srcimTrans = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL,
|
||||
0, 0, origLayout, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(liveIm),
|
||||
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
|
||||
};
|
||||
|
||||
// ensure all previous writes have completed
|
||||
srcimTrans.outputMask =
|
||||
VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT|
|
||||
VK_MEMORY_OUTPUT_SHADER_WRITE_BIT|
|
||||
VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT|
|
||||
VK_MEMORY_OUTPUT_TRANSFER_BIT;
|
||||
// before we go reading
|
||||
srcimTrans.inputMask = VK_MEMORY_INPUT_SHADER_READ_BIT;
|
||||
|
||||
VkCmdBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, NULL, VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT };
|
||||
|
||||
vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
|
||||
void *barrier = (void *)&srcimTrans;
|
||||
|
||||
vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
|
||||
srcimTrans.oldLayout = srcimTrans.newLayout;
|
||||
|
||||
srcimTrans.outputMask = 0;
|
||||
srcimTrans.inputMask = 0;
|
||||
|
||||
int blocksX = (int)ceil(iminfo.extent.width/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK));
|
||||
int blocksY = (int)ceil(iminfo.extent.height/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK));
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_MinMaxTilePipe));
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipeLayout),
|
||||
0, 1, UnwrapPtr(GetDebugManager()->m_HistogramDescSet[0]), 0, NULL);
|
||||
|
||||
vt->CmdDispatch(Unwrap(cmd), blocksX, blocksY, 1);
|
||||
|
||||
VkBufferMemoryBarrier tilebarrier = {
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, NULL,
|
||||
VK_MEMORY_OUTPUT_SHADER_WRITE_BIT, VK_MEMORY_INPUT_SHADER_READ_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(GetDebugManager()->m_MinMaxTileResult.buf),
|
||||
0, GetDebugManager()->m_MinMaxTileResult.totalsize,
|
||||
};
|
||||
|
||||
// image layout back to normal
|
||||
srcimTrans.newLayout = origLayout;
|
||||
vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
|
||||
|
||||
// ensure shader writes complete before coalescing the tiles
|
||||
barrier = (void *)&tilebarrier;
|
||||
vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_MinMaxResultPipe));
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipeLayout),
|
||||
0, 1, UnwrapPtr(GetDebugManager()->m_HistogramDescSet[1]), 0, NULL);
|
||||
|
||||
vt->CmdDispatch(Unwrap(cmd), 1, 1, 1);
|
||||
|
||||
// ensure shader writes complete before copying back to readback buffer
|
||||
tilebarrier.inputMask = VK_MEMORY_INPUT_TRANSFER_BIT;
|
||||
tilebarrier.buffer = Unwrap(GetDebugManager()->m_MinMaxResult.buf);
|
||||
tilebarrier.size = GetDebugManager()->m_MinMaxResult.totalsize;
|
||||
|
||||
vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
|
||||
|
||||
VkBufferCopy bufcopy = {
|
||||
0, 0, GetDebugManager()->m_MinMaxResult.totalsize,
|
||||
};
|
||||
|
||||
vt->CmdCopyBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_MinMaxResult.buf), Unwrap(GetDebugManager()->m_MinMaxReadback.buf), 1, &bufcopy);
|
||||
|
||||
// wait for copy to complete before mapping
|
||||
tilebarrier.outputMask = VK_MEMORY_OUTPUT_TRANSFER_BIT;
|
||||
tilebarrier.inputMask = VK_MEMORY_INPUT_HOST_READ_BIT;
|
||||
tilebarrier.buffer = Unwrap(GetDebugManager()->m_MinMaxReadback.buf);
|
||||
tilebarrier.size = GetDebugManager()->m_MinMaxResult.totalsize;
|
||||
|
||||
vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
|
||||
|
||||
vt->EndCommandBuffer(Unwrap(cmd));
|
||||
|
||||
// submit cmds and wait for idle so we can readback
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
|
||||
Vec4f *minmax = (Vec4f *)GetDebugManager()->m_MinMaxReadback.Map(vt, dev, NULL);
|
||||
|
||||
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;
|
||||
|
||||
GetDebugManager()->m_MinMaxReadback.Unmap(vt, dev);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VulkanReplay::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;
|
||||
if(minval >= maxval) return false;
|
||||
|
||||
VkDevice dev = m_pDriver->GetDev();
|
||||
VkCmdBuffer cmd = m_pDriver->GetNextCmd();
|
||||
const VkLayerDispatchTable *vt = ObjDisp(dev);
|
||||
|
||||
ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid];
|
||||
VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid];
|
||||
VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle<VkImage>(texid);
|
||||
|
||||
// VKTODOMED handle multiple subresources with different layouts etc
|
||||
VkImageLayout origLayout = layouts.subresourceStates[0].newLayout;
|
||||
VkImageView liveImView = iminfo.view;
|
||||
|
||||
if(liveImView == VK_NULL_HANDLE)
|
||||
{
|
||||
VkImageViewCreateInfo viewInfo = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL,
|
||||
Unwrap(liveIm), VK_IMAGE_VIEW_TYPE_2D,
|
||||
iminfo.format,
|
||||
{ VK_CHANNEL_SWIZZLE_R, VK_CHANNEL_SWIZZLE_G, VK_CHANNEL_SWIZZLE_B, VK_CHANNEL_SWIZZLE_A },
|
||||
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, RDCMAX(1U, (uint32_t)iminfo.mipLevels), 0, 1, },
|
||||
0
|
||||
};
|
||||
|
||||
// Only needed on AMD - does the wrong thing on nvidia - so commented for now while AMD
|
||||
// drivers aren't on 0.9.2
|
||||
//if(iminfo.format == VK_FORMAT_B8G8R8A8_UNORM || iminfo.format == VK_FORMAT_B8G8R8A8_SRGB)
|
||||
//std::swap(viewInfo.channels.r, viewInfo.channels.b);
|
||||
|
||||
VkResult vkr = ObjDisp(dev)->CreateImageView(Unwrap(dev), &viewInfo, &iminfo.view);
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
|
||||
ResourceId viewid = m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), iminfo.view);
|
||||
// register as a live-only resource, so it is cleaned up properly
|
||||
m_pDriver->GetResourceManager()->AddLiveResource(viewid, iminfo.view);
|
||||
|
||||
liveImView = iminfo.view;
|
||||
}
|
||||
|
||||
VkDescriptorInfo desc = {0};
|
||||
desc.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
desc.imageView = Unwrap(liveImView);
|
||||
desc.sampler = Unwrap(GetDebugManager()->m_PointSampler);
|
||||
|
||||
VkDescriptorInfo bufdescs[2];
|
||||
RDCEraseEl(bufdescs);
|
||||
GetDebugManager()->m_HistogramBuf.FillDescriptor(bufdescs[0]);
|
||||
GetDebugManager()->m_HistogramUBO.FillDescriptor(bufdescs[1]);
|
||||
|
||||
VkWriteDescriptorSet writeSet[] = {
|
||||
|
||||
// histogram pass
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
|
||||
Unwrap(GetDebugManager()->m_HistogramDescSet[0]),
|
||||
0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufdescs[0] // destination = histogram result
|
||||
},
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
|
||||
Unwrap(GetDebugManager()->m_HistogramDescSet[0]),
|
||||
1, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufdescs[0] // source = unused, bind histogram result
|
||||
},
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
|
||||
Unwrap(GetDebugManager()->m_HistogramDescSet[0]),
|
||||
2, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufdescs[1]
|
||||
},
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL,
|
||||
Unwrap(GetDebugManager()->m_HistogramDescSet[0]),
|
||||
3, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &desc
|
||||
},
|
||||
};
|
||||
|
||||
vt->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL);
|
||||
|
||||
histogramuniforms *data = (histogramuniforms *)GetDebugManager()->m_HistogramUBO.Map(vt, dev, NULL);
|
||||
|
||||
data->HistogramTextureResolution.x = (float)RDCMAX(uint32_t(iminfo.extent.width)>>mip, 1U);
|
||||
data->HistogramTextureResolution.y = (float)RDCMAX(uint32_t(iminfo.extent.height)>>mip, 1U);
|
||||
data->HistogramTextureResolution.z = (float)RDCMAX(uint32_t(iminfo.arraySize)>>mip, 1U);
|
||||
data->HistogramSlice = (float)sliceFace;
|
||||
data->HistogramMip = (int)mip;
|
||||
data->HistogramNumSamples = iminfo.samples;
|
||||
data->HistogramSample = (int)RDCCLAMP(sample, 0U, uint32_t(iminfo.samples)-1);
|
||||
if(sample == ~0U) data->HistogramSample = -iminfo.samples;
|
||||
data->HistogramMin = minval;
|
||||
data->HistogramMax = maxval;
|
||||
|
||||
uint32_t chans = 0;
|
||||
if(channels[0]) chans |= 0x1;
|
||||
if(channels[1]) chans |= 0x2;
|
||||
if(channels[2]) chans |= 0x4;
|
||||
if(channels[3]) chans |= 0x8;
|
||||
|
||||
data->HistogramChannels = chans;
|
||||
data->HistogramFlags = 0;
|
||||
|
||||
if(iminfo.type == VK_IMAGE_TYPE_3D)
|
||||
data->HistogramSlice = float(sliceFace)/float(iminfo.extent.depth);
|
||||
|
||||
GetDebugManager()->m_HistogramUBO.Unmap(vt, dev);
|
||||
|
||||
VkImageMemoryBarrier srcimTrans = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL,
|
||||
0, 0, origLayout, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(liveIm),
|
||||
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
|
||||
};
|
||||
|
||||
// ensure all previous writes have completed
|
||||
srcimTrans.outputMask =
|
||||
VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT|
|
||||
VK_MEMORY_OUTPUT_SHADER_WRITE_BIT|
|
||||
VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT|
|
||||
VK_MEMORY_OUTPUT_TRANSFER_BIT;
|
||||
// before we go reading
|
||||
srcimTrans.inputMask = VK_MEMORY_INPUT_SHADER_READ_BIT;
|
||||
|
||||
VkCmdBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, NULL, VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT };
|
||||
|
||||
vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
|
||||
void *barrier = (void *)&srcimTrans;
|
||||
|
||||
vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
|
||||
srcimTrans.oldLayout = srcimTrans.newLayout;
|
||||
|
||||
srcimTrans.outputMask = 0;
|
||||
srcimTrans.inputMask = 0;
|
||||
|
||||
int blocksX = (int)ceil(iminfo.extent.width/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK));
|
||||
int blocksY = (int)ceil(iminfo.extent.height/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK));
|
||||
|
||||
vt->CmdFillBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_HistogramBuf.buf), 0, GetDebugManager()->m_HistogramBuf.totalsize, 0);
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipe));
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipeLayout),
|
||||
0, 1, UnwrapPtr(GetDebugManager()->m_HistogramDescSet[0]), 0, NULL);
|
||||
|
||||
vt->CmdDispatch(Unwrap(cmd), blocksX, blocksY, 1);
|
||||
|
||||
VkBufferMemoryBarrier tilebarrier = {
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, NULL,
|
||||
VK_MEMORY_OUTPUT_SHADER_WRITE_BIT, VK_MEMORY_INPUT_TRANSFER_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(GetDebugManager()->m_HistogramBuf.buf),
|
||||
0, GetDebugManager()->m_HistogramBuf.totalsize,
|
||||
};
|
||||
|
||||
// image layout back to normal
|
||||
srcimTrans.newLayout = origLayout;
|
||||
vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
|
||||
|
||||
// ensure shader writes complete before copying to readback buf
|
||||
barrier = (void *)&tilebarrier;
|
||||
vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
|
||||
|
||||
VkBufferCopy bufcopy = {
|
||||
0, 0, GetDebugManager()->m_HistogramBuf.totalsize,
|
||||
};
|
||||
|
||||
vt->CmdCopyBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_HistogramBuf.buf), Unwrap(GetDebugManager()->m_HistogramReadback.buf), 1, &bufcopy);
|
||||
|
||||
// wait for copy to complete before mapping
|
||||
tilebarrier.outputMask = VK_MEMORY_OUTPUT_TRANSFER_BIT;
|
||||
tilebarrier.inputMask = VK_MEMORY_INPUT_HOST_READ_BIT;
|
||||
tilebarrier.buffer = Unwrap(GetDebugManager()->m_HistogramReadback.buf);
|
||||
tilebarrier.size = GetDebugManager()->m_HistogramReadback.totalsize;
|
||||
|
||||
vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
|
||||
|
||||
vt->EndCommandBuffer(Unwrap(cmd));
|
||||
|
||||
// submit cmds and wait for idle so we can readback
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
|
||||
uint32_t *buckets = (uint32_t *)GetDebugManager()->m_HistogramReadback.Map(vt, dev, NULL);
|
||||
|
||||
histogram.assign(buckets, buckets+HGRAM_NUM_BUCKETS);
|
||||
|
||||
GetDebugManager()->m_HistogramReadback.Unmap(vt, dev);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VulkanReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
|
||||
|
||||
@@ -367,12 +367,18 @@
|
||||
<None Include="data\spv\generic.vert" />
|
||||
<None Include="data\spv\genericfs.spv" />
|
||||
<None Include="data\spv\genericvs.spv" />
|
||||
<None Include="data\spv\histogram.comp" />
|
||||
<None Include="data\spv\histogramcs.spv" />
|
||||
<None Include="data\spv\mesh.frag" />
|
||||
<None Include="data\spv\mesh.geom" />
|
||||
<None Include="data\spv\mesh.vert" />
|
||||
<None Include="data\spv\meshfs.spv" />
|
||||
<None Include="data\spv\meshgs.spv" />
|
||||
<None Include="data\spv\meshvs.spv" />
|
||||
<None Include="data\spv\minmaxresult.comp" />
|
||||
<None Include="data\spv\minmaxresultcs.spv" />
|
||||
<None Include="data\spv\minmaxtile.comp" />
|
||||
<None Include="data\spv\minmaxtilecs.spv" />
|
||||
<None Include="data\spv\texdisplay.frag" />
|
||||
<None Include="data\spv\texdisplayfs.spv" />
|
||||
<None Include="data\spv\text.frag" />
|
||||
|
||||
@@ -496,6 +496,24 @@
|
||||
<None Include="data\spv\meshfs.spv">
|
||||
<Filter>Resources\spv</Filter>
|
||||
</None>
|
||||
<None Include="data\spv\histogram.comp">
|
||||
<Filter>Resources\spv</Filter>
|
||||
</None>
|
||||
<None Include="data\spv\histogramcs.spv">
|
||||
<Filter>Resources\spv</Filter>
|
||||
</None>
|
||||
<None Include="data\spv\minmaxresult.comp">
|
||||
<Filter>Resources\spv</Filter>
|
||||
</None>
|
||||
<None Include="data\spv\minmaxresultcs.spv">
|
||||
<Filter>Resources\spv</Filter>
|
||||
</None>
|
||||
<None Include="data\spv\minmaxtile.comp">
|
||||
<Filter>Resources\spv</Filter>
|
||||
</None>
|
||||
<None Include="data\spv\minmaxtilecs.spv">
|
||||
<Filter>Resources\spv</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="data\renderdoc.rc">
|
||||
|
||||
Reference in New Issue
Block a user