mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-13 18:21:01 +00:00
Remove use of legacy StringFormat::snprintf variants
This commit is contained in:
@@ -176,7 +176,7 @@ struct ShaderVariable
|
||||
}
|
||||
ShaderVariable(const ShaderVariable &) = default;
|
||||
ShaderVariable &operator=(const ShaderVariable &) = default;
|
||||
ShaderVariable(const char *n, float x, float y, float z, float w)
|
||||
ShaderVariable(const rdcstr &n, float x, float y, float z, float w)
|
||||
{
|
||||
name = n;
|
||||
rows = 1;
|
||||
@@ -190,7 +190,7 @@ struct ShaderVariable
|
||||
value.f.z = z;
|
||||
value.f.w = w;
|
||||
}
|
||||
ShaderVariable(const char *n, int x, int y, int z, int w)
|
||||
ShaderVariable(const rdcstr &n, int x, int y, int z, int w)
|
||||
{
|
||||
name = n;
|
||||
rows = 1;
|
||||
@@ -204,7 +204,7 @@ struct ShaderVariable
|
||||
value.i.z = z;
|
||||
value.i.w = w;
|
||||
}
|
||||
ShaderVariable(const char *n, uint32_t x, uint32_t y, uint32_t z, uint32_t w)
|
||||
ShaderVariable(const rdcstr &n, uint32_t x, uint32_t y, uint32_t z, uint32_t w)
|
||||
{
|
||||
name = n;
|
||||
rows = 1;
|
||||
|
||||
+13
-10
@@ -30,6 +30,9 @@
|
||||
#include "os/os_specific.h"
|
||||
#include "strings/string_utils.h"
|
||||
|
||||
int utf8printv(char *buf, size_t bufsize, const char *fmt, va_list args);
|
||||
int utf8printf(char *str, size_t bufSize, const char *fmt, ...);
|
||||
|
||||
void rdcassert(const char *msg, const char *file, unsigned int line, const char *func)
|
||||
{
|
||||
rdclog_direct(FILL_AUTO_VALUE, FILL_AUTO_VALUE, LogType::Error, RDCLOG_PROJECT, file, line,
|
||||
@@ -357,16 +360,16 @@ void rdclog_direct(time_t utcTime, uint32_t pid, LogType type, const char *proje
|
||||
va_list args2;
|
||||
va_copy(args2, args);
|
||||
|
||||
char timestamp[64] = {0};
|
||||
rdcstr timestamp;
|
||||
#if ENABLED(INCLUDE_TIMESTAMP_IN_LOG)
|
||||
StringFormat::sntimef(utcTime, timestamp, 63, "[%H:%M:%S] ");
|
||||
timestamp = StringFormat::sntimef(utcTime, "[%H:%M:%S] ");
|
||||
#endif
|
||||
|
||||
char location[64] = {0};
|
||||
#if ENABLED(INCLUDE_LOCATION_IN_LOG)
|
||||
rdcstr loc;
|
||||
loc = get_basename(file);
|
||||
StringFormat::snprintf(location, 63, "% 20s(%4d) - ", loc.c_str(), line);
|
||||
utf8printf(location, 63, "% 20s(%4d) - ", loc.c_str(), line);
|
||||
#endif
|
||||
|
||||
const char *typestr[(uint32_t)LogType::Count] = {
|
||||
@@ -384,8 +387,8 @@ void rdclog_direct(time_t utcTime, uint32_t pid, LogType type, const char *proje
|
||||
|
||||
char *base = output;
|
||||
|
||||
int numWritten = StringFormat::snprintf(output, available, "% 4s %06u: %s%s%s - ", project, pid,
|
||||
timestamp, location, typestr[(uint32_t)type]);
|
||||
int numWritten = utf8printf(output, available, "% 4s %06u: %s%s%s - ", project, pid,
|
||||
timestamp.c_str(), location, typestr[(uint32_t)type]);
|
||||
|
||||
if(numWritten < 0)
|
||||
{
|
||||
@@ -403,7 +406,7 @@ void rdclog_direct(time_t utcTime, uint32_t pid, LogType type, const char *proje
|
||||
|
||||
int totalWritten = numWritten;
|
||||
|
||||
numWritten = StringFormat::vsnprintf(output, available, fmt, args);
|
||||
numWritten = utf8printv(output, available, fmt, args);
|
||||
|
||||
totalWritten += numWritten;
|
||||
|
||||
@@ -426,9 +429,9 @@ void rdclog_direct(time_t utcTime, uint32_t pid, LogType type, const char *proje
|
||||
oversizedBuffer = output = new char[available + 3];
|
||||
base = output;
|
||||
|
||||
numWritten = StringFormat::snprintf(output, available, "% 4s %06u: %s%s%s - ", project,
|
||||
Process::GetCurrentPID(), timestamp, location,
|
||||
typestr[(uint32_t)type]);
|
||||
numWritten =
|
||||
utf8printf(output, available, "% 4s %06u: %s%s%s - ", project, Process::GetCurrentPID(),
|
||||
timestamp.c_str(), location, typestr[(uint32_t)type]);
|
||||
|
||||
output += numWritten;
|
||||
available -= numWritten;
|
||||
@@ -437,7 +440,7 @@ void rdclog_direct(time_t utcTime, uint32_t pid, LogType type, const char *proje
|
||||
|
||||
noPrefixOutput = (output - 3 - (sizeof(typestr[(uint32_t)type]) - 1));
|
||||
|
||||
numWritten = StringFormat::vsnprintf(output, available, fmt, args2);
|
||||
numWritten = utf8printv(output, available, fmt, args2);
|
||||
|
||||
output += numWritten;
|
||||
|
||||
|
||||
@@ -103,21 +103,12 @@ private:
|
||||
class ScopedTimer
|
||||
{
|
||||
public:
|
||||
ScopedTimer(const char *file, unsigned int line, const char *fmt, ...)
|
||||
ScopedTimer(const char *file, unsigned int line, const rdcstr &msg)
|
||||
{
|
||||
m_File = file;
|
||||
m_Line = line;
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
char buf[1024];
|
||||
buf[1023] = 0;
|
||||
StringFormat::vsnprintf(buf, 1023, fmt, args);
|
||||
|
||||
m_Message = buf;
|
||||
|
||||
va_end(args);
|
||||
m_Message = msg;
|
||||
}
|
||||
|
||||
~ScopedTimer()
|
||||
@@ -133,4 +124,5 @@ private:
|
||||
PerformanceTimer m_Timer;
|
||||
};
|
||||
|
||||
#define SCOPED_TIMER(...) ScopedTimer CONCAT(timer, __LINE__)(__FILE__, __LINE__, __VA_ARGS__);
|
||||
#define SCOPED_TIMER(...) \
|
||||
ScopedTimer CONCAT(timer, __LINE__)(__FILE__, __LINE__, StringFormat::Fmt(__VA_ARGS__));
|
||||
|
||||
@@ -1948,8 +1948,9 @@ bool WrappedID3D11Device::EndFrameCapture(void *dev, void *wnd)
|
||||
m_TextRenderer->SetOutputDimensions(swapper->GetWidth(), swapper->GetHeight());
|
||||
m_TextRenderer->SetOutputWindow(swapper->GetHWND());
|
||||
|
||||
m_TextRenderer->RenderText(0.0f, 0.0f, "Failed to capture frame %u: %s",
|
||||
m_CapturedFrames.back().frameNumber, reasonString);
|
||||
m_TextRenderer->RenderText(
|
||||
0.0f, 0.0f, StringFormat::Fmt("Failed to capture frame %u: %s",
|
||||
m_CapturedFrames.back().frameNumber, reasonString));
|
||||
}
|
||||
|
||||
old.ApplyState(m_pImmediateContext);
|
||||
@@ -2263,8 +2264,7 @@ HRESULT WrappedID3D11Device::Present(IDXGISwapper *swapper, UINT SyncInterval, U
|
||||
overlayText += StringFormat::Fmt(" %s\n", reasonString);
|
||||
}
|
||||
|
||||
if(!overlayText.empty())
|
||||
m_TextRenderer->RenderText(0.0f, 0.0f, overlayText.c_str());
|
||||
m_TextRenderer->RenderText(0.0f, 0.0f, overlayText);
|
||||
|
||||
old.ApplyState(m_pImmediateContext);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "d3d11_rendertext.h"
|
||||
#include "maths/matrix.h"
|
||||
#include "stb/stb_truetype.h"
|
||||
#include "strings/string_utils.h"
|
||||
#include "d3d11_context.h"
|
||||
#include "d3d11_device.h"
|
||||
#include "d3d11_resources.h"
|
||||
@@ -341,38 +342,25 @@ void D3D11TextRenderer::SetOutputWindow(HWND w)
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11TextRenderer::RenderText(float x, float y, const char *textfmt, ...)
|
||||
void D3D11TextRenderer::RenderText(float x, float y, const rdcstr &text)
|
||||
{
|
||||
static char tmpBuf[4096];
|
||||
rdcarray<rdcstr> lines;
|
||||
split(text, lines, '\n');
|
||||
|
||||
va_list args;
|
||||
va_start(args, textfmt);
|
||||
StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args);
|
||||
tmpBuf[4095] = '\0';
|
||||
va_end(args);
|
||||
|
||||
RenderTextInternal(x, y, tmpBuf);
|
||||
for(const rdcstr &line : lines)
|
||||
RenderTextInternal(x, y, line);
|
||||
}
|
||||
|
||||
void D3D11TextRenderer::RenderTextInternal(float x, float y, const char *text)
|
||||
void D3D11TextRenderer::RenderTextInternal(float x, float y, const rdcstr &text)
|
||||
{
|
||||
if(char *t = strchr((char *)text, '\n'))
|
||||
{
|
||||
*t = 0;
|
||||
RenderTextInternal(x, y, text);
|
||||
RenderTextInternal(x, y + 1.0f, t + 1);
|
||||
*t = '\n';
|
||||
if(text.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen(text) == 0)
|
||||
return;
|
||||
RDCASSERT(text.size() < FONT_MAX_CHARS);
|
||||
|
||||
if(!VS || !PS)
|
||||
return;
|
||||
|
||||
RDCASSERT(strlen(text) < FONT_MAX_CHARS);
|
||||
|
||||
FontCBuffer data = {};
|
||||
|
||||
data.TextPosition.x = x;
|
||||
@@ -421,14 +409,14 @@ void D3D11TextRenderer::RenderTextInternal(float x, float y, const char *text)
|
||||
{
|
||||
unsigned long *texs = (unsigned long *)mapped.pData;
|
||||
|
||||
for(size_t i = 0; i < strlen(text); i++)
|
||||
for(size_t i = 0; i < text.size(); i++)
|
||||
texs[i * 4] = (text[i] - ' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec4f *texs = (Vec4f *)mapped.pData;
|
||||
|
||||
for(size_t i = 0; i < strlen(text); i++)
|
||||
for(size_t i = 0; i < text.size(); i++)
|
||||
{
|
||||
texs[i * 6 + 0] = Vec4f(quadPos[0].x, quadPos[0].y, float(i), float(text[i] - ' '));
|
||||
texs[i * 6 + 1] = Vec4f(quadPos[1].x, quadPos[1].y, float(i), float(text[i] - ' '));
|
||||
@@ -487,8 +475,8 @@ void D3D11TextRenderer::RenderTextInternal(float x, float y, const char *text)
|
||||
m_pImmediateContext->OMSetBlendState(BlendState, factor, 0xffffffff);
|
||||
|
||||
if(modern)
|
||||
m_pImmediateContext->DrawInstanced(4, (uint32_t)strlen(text), 0, 0);
|
||||
m_pImmediateContext->DrawInstanced(4, (uint32_t)text.size(), 0, 0);
|
||||
else
|
||||
m_pImmediateContext->Draw(6 * (uint32_t)strlen(text), 0);
|
||||
m_pImmediateContext->Draw(6 * (uint32_t)text.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
int GetHeight() { return RDCMAX(1, m_height); }
|
||||
void SetOutputWindow(HWND w);
|
||||
|
||||
void RenderText(float x, float y, const char *textfmt, ...);
|
||||
void RenderText(float x, float y, const rdcstr &text);
|
||||
|
||||
private:
|
||||
int m_width = 1, m_height = 1;
|
||||
@@ -54,7 +54,7 @@ private:
|
||||
WrappedID3D11Device *m_pDevice = NULL;
|
||||
WrappedID3D11DeviceContext *m_pImmediateContext = NULL;
|
||||
|
||||
void RenderTextInternal(float x, float y, const char *text);
|
||||
void RenderTextInternal(float x, float y, const rdcstr &text);
|
||||
|
||||
static const int FONT_TEX_WIDTH = 256;
|
||||
static const int FONT_TEX_HEIGHT = 128;
|
||||
|
||||
@@ -766,12 +766,11 @@ bool D3D11DebugAPIWrapper::CalculateSampleGather(
|
||||
DXGI_FORMAT_UNKNOWN, // RETURN_TYPE_UNUSED
|
||||
};
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%s4", typeStr[resourceData.retType]);
|
||||
rdcstr type = StringFormat::Fmt("%s4", typeStr[resourceData.retType]);
|
||||
|
||||
if(retFmt == DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
funcRet = buf;
|
||||
funcRet = type;
|
||||
retFmt = fmts[resourceData.retType];
|
||||
}
|
||||
|
||||
@@ -779,13 +778,10 @@ bool D3D11DebugAPIWrapper::CalculateSampleGather(
|
||||
resourceData.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY)
|
||||
{
|
||||
if(resourceData.sampleCount > 0)
|
||||
StringFormat::snprintf(buf, 63, "%s4, %d", typeStr[resourceData.retType],
|
||||
resourceData.sampleCount);
|
||||
type += StringFormat::Fmt(", %d", resourceData.sampleCount);
|
||||
}
|
||||
|
||||
textureDecl += "<";
|
||||
textureDecl += buf;
|
||||
textureDecl += "> t";
|
||||
textureDecl += "<" + type + "> t";
|
||||
}
|
||||
|
||||
char *formats[4][2] = {
|
||||
@@ -870,66 +866,35 @@ bool D3D11DebugAPIWrapper::CalculateSampleGather(
|
||||
}
|
||||
}
|
||||
|
||||
char buf[256] = {0};
|
||||
char buf2[256] = {0};
|
||||
char buf3[256] = {0};
|
||||
rdcstr texcoords;
|
||||
|
||||
// because of unions in .value we can pass the float versions and printf will interpret it as
|
||||
// the right type according to formats
|
||||
if(texcoordType == 0)
|
||||
StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x,
|
||||
uv.value.f.y, uv.value.f.z, uv.value.f.w);
|
||||
texcoords = StringFormat::Fmt(formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x,
|
||||
uv.value.f.y, uv.value.f.z, uv.value.f.w);
|
||||
else
|
||||
StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], uv.value.i.x,
|
||||
uv.value.i.y, uv.value.i.z, uv.value.i.w);
|
||||
|
||||
if(ddxType == 0)
|
||||
StringFormat::snprintf(buf2, 255, formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.f.x,
|
||||
ddxCalc.value.f.y, ddxCalc.value.f.z, ddxCalc.value.f.w);
|
||||
else
|
||||
StringFormat::snprintf(buf2, 255, formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.i.x,
|
||||
ddxCalc.value.i.y, ddxCalc.value.i.z, ddxCalc.value.i.w);
|
||||
|
||||
if(ddyType == 0)
|
||||
StringFormat::snprintf(buf3, 255, formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.f.x,
|
||||
ddyCalc.value.f.y, ddyCalc.value.f.z, ddyCalc.value.f.w);
|
||||
else
|
||||
StringFormat::snprintf(buf3, 255, formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.i.x,
|
||||
ddyCalc.value.i.y, ddyCalc.value.i.z, ddyCalc.value.i.w);
|
||||
|
||||
rdcstr texcoords = buf;
|
||||
rdcstr ddx = buf2;
|
||||
rdcstr ddy = buf3;
|
||||
|
||||
if(opcode == OPCODE_LD_MS)
|
||||
{
|
||||
StringFormat::snprintf(buf, 255, formats[0][1], multisampleIndex);
|
||||
}
|
||||
|
||||
rdcstr sampleIdx = buf;
|
||||
texcoords = StringFormat::Fmt(formats[texdim + texdimOffs - 1][texcoordType], uv.value.i.x,
|
||||
uv.value.i.y, uv.value.i.z, uv.value.i.w);
|
||||
|
||||
rdcstr offsets = "";
|
||||
|
||||
if(useOffsets)
|
||||
{
|
||||
if(offsetDim == 1)
|
||||
StringFormat::snprintf(buf, 255, ", int(%d)", texelOffsets[0]);
|
||||
offsets = StringFormat::Fmt(", int(%d)", texelOffsets[0]);
|
||||
else if(offsetDim == 2)
|
||||
StringFormat::snprintf(buf, 255, ", int2(%d, %d)", texelOffsets[0], texelOffsets[1]);
|
||||
offsets = StringFormat::Fmt(", int2(%d, %d)", texelOffsets[0], texelOffsets[1]);
|
||||
else if(offsetDim == 3)
|
||||
StringFormat::snprintf(buf, 255, ", int3(%d, %d, %d)", texelOffsets[0], texelOffsets[1],
|
||||
texelOffsets[2]);
|
||||
offsets =
|
||||
StringFormat::Fmt(", int3(%d, %d, %d)", texelOffsets[0], texelOffsets[1], texelOffsets[2]);
|
||||
// texdim == 4 is cube arrays, no offset supported
|
||||
|
||||
offsets = buf;
|
||||
}
|
||||
|
||||
char elems[] = "xyzw";
|
||||
rdcstr strSwizzle = ".";
|
||||
for(int i = 0; i < 4; ++i)
|
||||
{
|
||||
strSwizzle += elems[swizzle[i]];
|
||||
}
|
||||
|
||||
rdcstr strGatherChannel;
|
||||
switch(gatherChannel)
|
||||
@@ -948,120 +913,134 @@ bool D3D11DebugAPIWrapper::CalculateSampleGather(
|
||||
|
||||
if(opcode == OPCODE_SAMPLE || opcode == OPCODE_SAMPLE_B || opcode == OPCODE_SAMPLE_D)
|
||||
{
|
||||
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
rdcstr ddx;
|
||||
|
||||
if(ddxType == 0)
|
||||
ddx = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.f.x,
|
||||
ddxCalc.value.f.y, ddxCalc.value.f.z, ddxCalc.value.f.w);
|
||||
else
|
||||
ddx = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.i.x,
|
||||
ddxCalc.value.i.y, ddxCalc.value.i.z, ddxCalc.value.i.w);
|
||||
|
||||
rdcstr ddy;
|
||||
|
||||
if(ddyType == 0)
|
||||
ddy = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.f.x,
|
||||
ddyCalc.value.f.y, ddyCalc.value.f.z, ddyCalc.value.f.w);
|
||||
else
|
||||
ddy = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.i.x,
|
||||
ddyCalc.value.i.y, ddyCalc.value.i.z, ddyCalc.value.i.w);
|
||||
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
|
||||
textureDecl.c_str(), samplerDecl.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram +=
|
||||
"t.SampleGrad(s, " + texcoords + ", " + ddx + ", " + ddy + offsets + ")" + strSwizzle + ";";
|
||||
sampleProgram += "\n}\n";
|
||||
StringFormat::Fmt("return t.SampleGrad(s, %s, %s, %s %s)%s;\n", texcoords.c_str(),
|
||||
ddx.c_str(), ddy.c_str(), offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_SAMPLE_L)
|
||||
{
|
||||
// lod selection
|
||||
StringFormat::snprintf(buf, 255, "%.10f", lodOrCompareValue);
|
||||
|
||||
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram += "t.SampleLevel(s, " + texcoords + ", " + buf + offsets + ")" + strSwizzle + ";";
|
||||
sampleProgram += "\n}\n";
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
|
||||
textureDecl.c_str(), samplerDecl.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram +=
|
||||
StringFormat::Fmt("return t.SampleLevel(s, %s, %.10f %s)%s;\n", texcoords.c_str(),
|
||||
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_SAMPLE_C || opcode == OPCODE_LOD)
|
||||
{
|
||||
// these operations need derivatives but have no hlsl function to call to provide them, so
|
||||
// we fake it in the vertex shader
|
||||
|
||||
rdcstr uvDim = "1";
|
||||
uvDim[0] += char(texdim + texdimOffs - 1);
|
||||
rdcstr uvdecl = StringFormat::Fmt("float%d uv : uvs", texdim + texdimOffs);
|
||||
|
||||
vsProgram = "void main(uint id : SV_VertexID, out float4 pos : SV_Position, out float" + uvDim +
|
||||
" uv : uvs) {\n";
|
||||
vsProgram =
|
||||
"void main(uint id : SV_VertexID, out float4 pos : SV_Position, out " + uvdecl + ") {\n";
|
||||
|
||||
StringFormat::snprintf(
|
||||
buf, 255, formats[texdim + texdimOffs - 1][texcoordType],
|
||||
uv.value.f.x + ddyCalc.value.f.x * 2.0f, uv.value.f.y + ddyCalc.value.f.y * 2.0f,
|
||||
uv.value.f.z + ddyCalc.value.f.z * 2.0f, uv.value.f.w + ddyCalc.value.f.w * 2.0f);
|
||||
rdcstr uvPlusDDX = StringFormat::Fmt(
|
||||
formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x + ddyCalc.value.f.x * 2.0f,
|
||||
uv.value.f.y + ddyCalc.value.f.y * 2.0f, uv.value.f.z + ddyCalc.value.f.z * 2.0f,
|
||||
uv.value.f.w + ddyCalc.value.f.w * 2.0f);
|
||||
|
||||
vsProgram += "if(id == 0) uv = " + rdcstr(buf) + ";\n";
|
||||
|
||||
StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x,
|
||||
uv.value.f.y, uv.value.f.z, uv.value.f.w);
|
||||
|
||||
vsProgram += "if(id == 1) uv = " + rdcstr(buf) + ";\n";
|
||||
|
||||
StringFormat::snprintf(
|
||||
buf, 255, formats[texdim + texdimOffs - 1][texcoordType],
|
||||
uv.value.f.x + ddxCalc.value.f.x * 2.0f, uv.value.f.y + ddxCalc.value.f.y * 2.0f,
|
||||
uv.value.f.z + ddxCalc.value.f.z * 2.0f, uv.value.f.w + ddxCalc.value.f.w * 2.0f);
|
||||
|
||||
vsProgram += "if(id == 2) uv = " + rdcstr(buf) + ";\n";
|
||||
rdcstr uvPlusDDY = StringFormat::Fmt(
|
||||
formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x + ddxCalc.value.f.x * 2.0f,
|
||||
uv.value.f.y + ddxCalc.value.f.y * 2.0f, uv.value.f.z + ddxCalc.value.f.z * 2.0f,
|
||||
uv.value.f.w + ddxCalc.value.f.w * 2.0f);
|
||||
|
||||
vsProgram += "if(id == 0) uv = " + uvPlusDDX + ";\n";
|
||||
vsProgram += "if(id == 1) uv = " + texcoords + ";\n";
|
||||
vsProgram += "if(id == 2) uv = " + uvPlusDDY + ";\n";
|
||||
vsProgram += "pos = float4((id == 2) ? 3.0f : -1.0f, (id == 0) ? -3.0f : 1.0f, 0.5, 1.0);\n";
|
||||
vsProgram += "}";
|
||||
|
||||
if(opcode == OPCODE_SAMPLE_C)
|
||||
{
|
||||
// comparison value
|
||||
StringFormat::snprintf(buf, 255, "%.10f", lodOrCompareValue);
|
||||
|
||||
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
|
||||
sampleProgram += funcRet + " main(float4 pos : SV_Position, float" + uvDim +
|
||||
" uv : uvs) : SV_Target0\n{\n";
|
||||
sampleProgram += "return t.SampleCmpLevelZero(s, uv, " + rdcstr(buf) + offsets + ").xxxx;";
|
||||
sampleProgram += "\n}\n";
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
|
||||
textureDecl.c_str(), samplerDecl.c_str());
|
||||
sampleProgram +=
|
||||
funcRet + " main(float4 pos : SV_Position, " + uvdecl + ") : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("return t.SampleCmpLevelZero(s, uv, %.10f %s).xxxx;\n",
|
||||
lodOrCompareValue, offsets.c_str());
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_LOD)
|
||||
{
|
||||
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
|
||||
sampleProgram += funcRet + " main(float4 pos : SV_Position, float" + uvDim +
|
||||
" uv : uvs) : SV_Target0\n{\n";
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
|
||||
textureDecl.c_str(), samplerDecl.c_str());
|
||||
sampleProgram +=
|
||||
"return float4(t.CalculateLevelOfDetail(s, uv), t.CalculateLevelOfDetailUnclamped(s, "
|
||||
"uv), 0.0f, 0.0f);";
|
||||
sampleProgram += "\n}\n";
|
||||
funcRet + " main(float4 pos : SV_Position, " + uvdecl + ") : SV_Target0\n{\n";
|
||||
sampleProgram +=
|
||||
"return float4(t.CalculateLevelOfDetail(s, uv),\n"
|
||||
" t.CalculateLevelOfDetailUnclamped(s, uv),\n"
|
||||
" 0.0f, 0.0f);\n";
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
}
|
||||
else if(opcode == OPCODE_SAMPLE_C_LZ)
|
||||
{
|
||||
// comparison value
|
||||
StringFormat::snprintf(buf, 255, "%.10f", lodOrCompareValue);
|
||||
|
||||
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
|
||||
textureDecl.c_str(), samplerDecl.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram +=
|
||||
"t.SampleCmpLevelZero(s, " + texcoords + ", " + buf + offsets + ")" + strSwizzle + ";";
|
||||
sampleProgram += "\n}\n";
|
||||
StringFormat::Fmt("return t.SampleCmpLevelZero(s, %s, %.10f %s)%s;\n", texcoords.c_str(),
|
||||
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_LD)
|
||||
{
|
||||
sampleProgram = textureDecl + " : register(t0);\n\n";
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram += "t.Load(" + texcoords + offsets + ")" + strSwizzle + ";";
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t0);\n\n", textureDecl.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram += "return t.Load(" + texcoords + offsets + ")" + strSwizzle + ";";
|
||||
sampleProgram += "\n}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_LD_MS)
|
||||
{
|
||||
sampleProgram = textureDecl + " : register(t0);\n\n";
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram += "t.Load(" + texcoords + ", " + sampleIdx + offsets + ")" + strSwizzle + ";";
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t0);\n\n", textureDecl.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("t.Load(%s, int(%d) %s)%s;\n", texcoords.c_str(),
|
||||
multisampleIndex, offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "\n}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_GATHER4 || opcode == OPCODE_GATHER4_PO)
|
||||
{
|
||||
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram +=
|
||||
"t.Gather" + strGatherChannel + "(s, " + texcoords + offsets + ")" + strSwizzle + ";";
|
||||
sampleProgram += "\n}\n";
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
|
||||
textureDecl.c_str(), samplerDecl.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("return t.Gather%s(s, %s %s)%s;\n", strGatherChannel.c_str(),
|
||||
texcoords.c_str(), offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_GATHER4_C || opcode == OPCODE_GATHER4_PO_C)
|
||||
{
|
||||
// comparison value
|
||||
StringFormat::snprintf(buf, 255, ", %.10f", lodOrCompareValue);
|
||||
|
||||
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram += "t.GatherCmp" + strGatherChannel + "(s, " + texcoords + buf + offsets + ")" +
|
||||
strSwizzle + ";";
|
||||
sampleProgram += "\n}\n";
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
|
||||
textureDecl.c_str(), samplerDecl.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("return t.GatherCmp%s(s, %s, %.10f %s)%s;\n",
|
||||
strGatherChannel.c_str(), texcoords.c_str(),
|
||||
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
|
||||
ID3D11VertexShader *vs =
|
||||
|
||||
@@ -737,10 +737,7 @@ rdcstr PIX3SprintfParams(const rdcstr &Format, const UINT64 *pData)
|
||||
// numerical values
|
||||
else
|
||||
{
|
||||
static const UINT MAX_CHARACTERS_FOR_VALUE = 32;
|
||||
char formattedValue[MAX_CHARACTERS_FOR_VALUE];
|
||||
StringFormat::snprintf(formattedValue, MAX_CHARACTERS_FOR_VALUE, formatPart.c_str(), *pData);
|
||||
finalString += formattedValue;
|
||||
finalString += StringFormat::Fmt(formatPart.c_str(), *pData);
|
||||
++pData;
|
||||
}
|
||||
|
||||
|
||||
@@ -1590,8 +1590,7 @@ HRESULT WrappedID3D12Device::Present(ID3D12GraphicsCommandList *pOverlayCommandL
|
||||
if(m_InvalidPSO)
|
||||
overlayText += "ERROR: Invalid PSO created, likely using DXIL which is not supported.\n";
|
||||
|
||||
if(!overlayText.empty())
|
||||
m_TextRenderer->RenderText(list, 0.0f, 0.0f, overlayText.c_str());
|
||||
m_TextRenderer->RenderText(list, 0.0f, 0.0f, overlayText);
|
||||
|
||||
// transition backbuffer back again
|
||||
std::swap(barrier.Transition.StateBefore, barrier.Transition.StateAfter);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "maths/matrix.h"
|
||||
#include "maths/vec.h"
|
||||
#include "stb/stb_truetype.h"
|
||||
#include "strings/string_utils.h"
|
||||
#include "d3d12_device.h"
|
||||
#include "d3d12_shader_cache.h"
|
||||
|
||||
@@ -444,35 +445,22 @@ D3D12TextRenderer::~D3D12TextRenderer()
|
||||
}
|
||||
|
||||
void D3D12TextRenderer::RenderText(ID3D12GraphicsCommandList *list, float x, float y,
|
||||
const char *textfmt, ...)
|
||||
const rdcstr &text)
|
||||
{
|
||||
static char tmpBuf[4096];
|
||||
rdcarray<rdcstr> lines;
|
||||
split(text, lines, '\n');
|
||||
|
||||
va_list args;
|
||||
va_start(args, textfmt);
|
||||
StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args);
|
||||
tmpBuf[4095] = '\0';
|
||||
va_end(args);
|
||||
|
||||
RenderTextInternal(list, x, y, tmpBuf);
|
||||
for(const rdcstr &line : lines)
|
||||
RenderTextInternal(list, x, y, line);
|
||||
}
|
||||
|
||||
void D3D12TextRenderer::RenderTextInternal(ID3D12GraphicsCommandList *list, float x, float y,
|
||||
const char *text)
|
||||
const rdcstr &text)
|
||||
{
|
||||
if(char *t = strchr((char *)text, '\n'))
|
||||
{
|
||||
*t = 0;
|
||||
RenderTextInternal(list, x, y, text);
|
||||
RenderTextInternal(list, x, y + 1.0f, t + 1);
|
||||
*t = '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen(text) == 0)
|
||||
if(text.empty())
|
||||
return;
|
||||
|
||||
RDCASSERT(strlen(text) < FONT_MAX_CHARS);
|
||||
RDCASSERT(text.size() < FONT_MAX_CHARS);
|
||||
|
||||
FontCBuffer data = {};
|
||||
|
||||
@@ -508,7 +496,7 @@ void D3D12TextRenderer::RenderTextInternal(ID3D12GraphicsCommandList *list, floa
|
||||
Constants->Unmap(0, &range);
|
||||
}
|
||||
|
||||
size_t chars = strlen(text);
|
||||
size_t chars = text.size();
|
||||
|
||||
size_t charOffset = CharOffset;
|
||||
|
||||
@@ -530,7 +518,7 @@ void D3D12TextRenderer::RenderTextInternal(ID3D12GraphicsCommandList *list, floa
|
||||
|
||||
texs += charOffset * 4;
|
||||
|
||||
for(size_t i = 0; i < strlen(text); i++)
|
||||
for(size_t i = 0; i < chars; i++)
|
||||
texs[i * 4] = (text[i] - ' ');
|
||||
|
||||
CharBuffer->Unmap(0, NULL);
|
||||
@@ -563,7 +551,7 @@ void D3D12TextRenderer::RenderTextInternal(ID3D12GraphicsCommandList *list, floa
|
||||
2, CharBuffer->GetGPUVirtualAddress() + charOffset * sizeof(Vec4f));
|
||||
list->SetGraphicsRootDescriptorTable(3, descHeap->GetGPUDescriptorHandleForHeapStart());
|
||||
|
||||
list->DrawInstanced(4, (uint32_t)strlen(text), 0, 0);
|
||||
list->DrawInstanced(4, (uint32_t)chars, 0, 0);
|
||||
}
|
||||
|
||||
ConstRingIdx++;
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
}
|
||||
int GetWidth() { return RDCMAX(1, m_width); }
|
||||
int GetHeight() { return RDCMAX(1, m_height); }
|
||||
void RenderText(ID3D12GraphicsCommandList *list, float x, float y, const char *textfmt, ...);
|
||||
void RenderText(ID3D12GraphicsCommandList *list, float x, float y, const rdcstr &text);
|
||||
|
||||
private:
|
||||
int m_width = 1, m_height = 1;
|
||||
@@ -59,7 +59,7 @@ private:
|
||||
FMTNUM_BACKBUFFER,
|
||||
} m_BBFmtIdx;
|
||||
|
||||
void RenderTextInternal(ID3D12GraphicsCommandList *list, float x, float y, const char *text);
|
||||
void RenderTextInternal(ID3D12GraphicsCommandList *list, float x, float y, const rdcstr &text);
|
||||
|
||||
static const int FONT_TEX_WIDTH = 256;
|
||||
static const int FONT_TEX_HEIGHT = 128;
|
||||
|
||||
@@ -254,12 +254,11 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
DXGI_FORMAT_UNKNOWN, // RETURN_TYPE_UNUSED
|
||||
};
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%s4", typeStr[resourceData.retType]);
|
||||
rdcstr type = StringFormat::Fmt("%s4", typeStr[resourceData.retType]);
|
||||
|
||||
if(retFmt == DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
funcRet = buf;
|
||||
funcRet = type;
|
||||
retFmt = fmts[resourceData.retType];
|
||||
}
|
||||
|
||||
@@ -267,13 +266,10 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
resourceData.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY)
|
||||
{
|
||||
if(resourceData.sampleCount > 0)
|
||||
StringFormat::snprintf(buf, 63, "%s4, %d", typeStr[resourceData.retType],
|
||||
resourceData.sampleCount);
|
||||
type += StringFormat::Fmt(", %d", resourceData.sampleCount);
|
||||
}
|
||||
|
||||
textureDecl += "<";
|
||||
textureDecl += buf;
|
||||
textureDecl += "> t";
|
||||
textureDecl += "<" + type + "> t";
|
||||
}
|
||||
|
||||
char *formats[4][2] = {
|
||||
@@ -358,65 +354,35 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
}
|
||||
}
|
||||
|
||||
char buf[256] = {0};
|
||||
char buf2[256] = {0};
|
||||
char buf3[256] = {0};
|
||||
rdcstr texcoords;
|
||||
|
||||
// because of unions in .value we can pass the float versions and printf will interpret it as
|
||||
// the right type according to formats
|
||||
if(texcoordType == 0)
|
||||
StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x,
|
||||
uv.value.f.y, uv.value.f.z, uv.value.f.w);
|
||||
texcoords = StringFormat::Fmt(formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x,
|
||||
uv.value.f.y, uv.value.f.z, uv.value.f.w);
|
||||
else
|
||||
StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], uv.value.i.x,
|
||||
uv.value.i.y, uv.value.i.z, uv.value.i.w);
|
||||
texcoords = StringFormat::Fmt(formats[texdim + texdimOffs - 1][texcoordType], uv.value.i.x,
|
||||
uv.value.i.y, uv.value.i.z, uv.value.i.w);
|
||||
|
||||
if(ddxType == 0)
|
||||
StringFormat::snprintf(buf2, 255, formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.f.x,
|
||||
ddxCalc.value.f.y, ddxCalc.value.f.z, ddxCalc.value.f.w);
|
||||
else
|
||||
StringFormat::snprintf(buf2, 255, formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.i.x,
|
||||
ddxCalc.value.i.y, ddxCalc.value.i.z, ddxCalc.value.i.w);
|
||||
|
||||
if(ddyType == 0)
|
||||
StringFormat::snprintf(buf3, 255, formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.f.x,
|
||||
ddyCalc.value.f.y, ddyCalc.value.f.z, ddyCalc.value.f.w);
|
||||
else
|
||||
StringFormat::snprintf(buf3, 255, formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.i.x,
|
||||
ddyCalc.value.i.y, ddyCalc.value.i.z, ddyCalc.value.i.w);
|
||||
|
||||
rdcstr texcoords = buf;
|
||||
rdcstr ddx = buf2;
|
||||
rdcstr ddy = buf3;
|
||||
|
||||
if(opcode == OPCODE_LD_MS)
|
||||
{
|
||||
StringFormat::snprintf(buf, 255, formats[0][1], multisampleIndex);
|
||||
}
|
||||
|
||||
rdcstr sampleIdx = buf;
|
||||
rdcstr offsets = "";
|
||||
|
||||
if(useOffsets)
|
||||
{
|
||||
if(offsetDim == 1)
|
||||
StringFormat::snprintf(buf, 255, ", int(%d)", texelOffsets[0]);
|
||||
offsets = StringFormat::Fmt(", int(%d)", texelOffsets[0]);
|
||||
else if(offsetDim == 2)
|
||||
StringFormat::snprintf(buf, 255, ", int2(%d, %d)", texelOffsets[0], texelOffsets[1]);
|
||||
offsets = StringFormat::Fmt(", int2(%d, %d)", texelOffsets[0], texelOffsets[1]);
|
||||
else if(offsetDim == 3)
|
||||
StringFormat::snprintf(buf, 255, ", int3(%d, %d, %d)", texelOffsets[0], texelOffsets[1],
|
||||
texelOffsets[2]);
|
||||
offsets =
|
||||
StringFormat::Fmt(", int3(%d, %d, %d)", texelOffsets[0], texelOffsets[1], texelOffsets[2]);
|
||||
// texdim == 4 is cube arrays, no offset supported
|
||||
|
||||
offsets = buf;
|
||||
}
|
||||
|
||||
char elems[] = "xyzw";
|
||||
rdcstr strSwizzle = ".";
|
||||
for(int i = 0; i < 4; ++i)
|
||||
{
|
||||
strSwizzle += elems[swizzle[i]];
|
||||
}
|
||||
|
||||
rdcstr strGatherChannel;
|
||||
switch(gatherChannel)
|
||||
@@ -438,12 +404,30 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
|
||||
if(opcode == OPCODE_SAMPLE || opcode == OPCODE_SAMPLE_B || opcode == OPCODE_SAMPLE_D)
|
||||
{
|
||||
rdcstr ddx;
|
||||
|
||||
if(ddxType == 0)
|
||||
ddx = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.f.x,
|
||||
ddxCalc.value.f.y, ddxCalc.value.f.z, ddxCalc.value.f.w);
|
||||
else
|
||||
ddx = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.i.x,
|
||||
ddxCalc.value.i.y, ddxCalc.value.i.z, ddxCalc.value.i.w);
|
||||
|
||||
rdcstr ddy;
|
||||
|
||||
if(ddyType == 0)
|
||||
ddy = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.f.x,
|
||||
ddyCalc.value.f.y, ddyCalc.value.f.z, ddyCalc.value.f.w);
|
||||
else
|
||||
ddy = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.i.x,
|
||||
ddyCalc.value.i.y, ddyCalc.value.i.z, ddyCalc.value.i.w);
|
||||
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram += StringFormat::Fmt("t.SampleGrad(s, %s, %s, %s%s)%s;", texcoords.c_str(),
|
||||
sampleProgram += StringFormat::Fmt("t.SampleGrad(s, %s, %s, %s %s)%s;\n", texcoords.c_str(),
|
||||
ddx.c_str(), ddy.c_str(), offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "\n}\n";
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_SAMPLE_L)
|
||||
{
|
||||
@@ -451,40 +435,33 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram += StringFormat::Fmt("t.SampleLevel(s, %s, %.10f%s)%s;", texcoords.c_str(),
|
||||
sampleProgram += StringFormat::Fmt("t.SampleLevel(s, %s, %.10f %s)%s;\n", texcoords.c_str(),
|
||||
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "\n}\n";
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_SAMPLE_C || opcode == OPCODE_LOD)
|
||||
{
|
||||
// these operations need derivatives but have no hlsl function to call to provide them, so
|
||||
// we fake it in the vertex shader
|
||||
|
||||
rdcstr uvDim = "1";
|
||||
uvDim[0] += char(texdim + texdimOffs - 1);
|
||||
rdcstr uvdecl = StringFormat::Fmt("float%d uv : uvs", texdim + texdimOffs);
|
||||
|
||||
vsProgram = "void main(uint id : SV_VertexID, out float4 pos : SV_Position, out float" + uvDim +
|
||||
" uv : uvs) {\n";
|
||||
vsProgram =
|
||||
"void main(uint id : SV_VertexID, out float4 pos : SV_Position, out " + uvdecl + ") {\n";
|
||||
|
||||
StringFormat::snprintf(
|
||||
buf, 255, formats[texdim + texdimOffs - 1][texcoordType],
|
||||
uv.value.f.x + ddyCalc.value.f.x * 2.0f, uv.value.f.y + ddyCalc.value.f.y * 2.0f,
|
||||
uv.value.f.z + ddyCalc.value.f.z * 2.0f, uv.value.f.w + ddyCalc.value.f.w * 2.0f);
|
||||
rdcstr uvPlusDDX = StringFormat::Fmt(
|
||||
formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x + ddyCalc.value.f.x * 2.0f,
|
||||
uv.value.f.y + ddyCalc.value.f.y * 2.0f, uv.value.f.z + ddyCalc.value.f.z * 2.0f,
|
||||
uv.value.f.w + ddyCalc.value.f.w * 2.0f);
|
||||
|
||||
vsProgram += "if(id == 0) uv = " + rdcstr(buf) + ";\n";
|
||||
|
||||
StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x,
|
||||
uv.value.f.y, uv.value.f.z, uv.value.f.w);
|
||||
|
||||
vsProgram += "if(id == 1) uv = " + rdcstr(buf) + ";\n";
|
||||
|
||||
StringFormat::snprintf(
|
||||
buf, 255, formats[texdim + texdimOffs - 1][texcoordType],
|
||||
uv.value.f.x + ddxCalc.value.f.x * 2.0f, uv.value.f.y + ddxCalc.value.f.y * 2.0f,
|
||||
uv.value.f.z + ddxCalc.value.f.z * 2.0f, uv.value.f.w + ddxCalc.value.f.w * 2.0f);
|
||||
|
||||
vsProgram += "if(id == 2) uv = " + rdcstr(buf) + ";\n";
|
||||
rdcstr uvPlusDDY = StringFormat::Fmt(
|
||||
formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x + ddxCalc.value.f.x * 2.0f,
|
||||
uv.value.f.y + ddxCalc.value.f.y * 2.0f, uv.value.f.z + ddxCalc.value.f.z * 2.0f,
|
||||
uv.value.f.w + ddxCalc.value.f.w * 2.0f);
|
||||
|
||||
vsProgram += "if(id == 0) uv = " + uvPlusDDX + ";\n";
|
||||
vsProgram += "if(id == 1) uv = " + texcoords + ";\n";
|
||||
vsProgram += "if(id == 2) uv = " + uvPlusDDY + ";\n";
|
||||
vsProgram += "pos = float4((id == 2) ? 3.0f : -1.0f, (id == 0) ? -3.0f : 1.0f, 0.5, 1.0);\n";
|
||||
vsProgram += "}";
|
||||
|
||||
@@ -493,22 +470,23 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
// comparison value
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram += funcRet + " main(float4 pos : SV_Position, float" + uvDim +
|
||||
" uv : uvs) : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("return t.SampleCmpLevelZero(s, uv, %.10f%s).xxxx;",
|
||||
sampleProgram +=
|
||||
funcRet + " main(float4 pos : SV_Position, " + uvdecl + ") : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("t.SampleCmpLevelZero(s, uv, %.10f %s).xxxx;\n",
|
||||
lodOrCompareValue, offsets.c_str());
|
||||
sampleProgram += "\n}\n";
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_LOD)
|
||||
{
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram += funcRet + " main(float4 pos : SV_Position, float" + uvDim +
|
||||
" uv : uvs) : SV_Target0\n{\n";
|
||||
sampleProgram +=
|
||||
"return float4(t.CalculateLevelOfDetail(s, uv), t.CalculateLevelOfDetailUnclamped(s, "
|
||||
"uv), 0.0f, 0.0f);";
|
||||
sampleProgram += "\n}\n";
|
||||
funcRet + " main(float4 pos : SV_Position, " + uvdecl + ") : SV_Target0\n{\n";
|
||||
sampleProgram +=
|
||||
"return float4(t.CalculateLevelOfDetail(s, uv),\n"
|
||||
" t.CalculateLevelOfDetailUnclamped(s, uv),\n"
|
||||
" 0.0f, 0.0f);\n";
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
}
|
||||
else if(opcode == OPCODE_SAMPLE_C_LZ)
|
||||
@@ -516,44 +494,46 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
// comparison value
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram += StringFormat::Fmt("t.SampleCmpLevelZero(s, %s, %.10f%s)%s;", texcoords.c_str(),
|
||||
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "\n}\n";
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram +=
|
||||
StringFormat::Fmt("return t.SampleCmpLevelZero(s, %s, %.10f %s)%s;\n", texcoords.c_str(),
|
||||
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_LD)
|
||||
{
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n\n", textureDecl.c_str(), texSlot);
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram += "t.Load(" + texcoords + offsets + ")" + strSwizzle + ";";
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram += "return t.Load(" + texcoords + offsets + ")" + strSwizzle + ";";
|
||||
sampleProgram += "\n}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_LD_MS)
|
||||
{
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n\n", textureDecl.c_str(), texSlot);
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram += "t.Load(" + texcoords + ", " + sampleIdx + offsets + ")" + strSwizzle + ";";
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("t.Load(%s, int(%d) %s)%s;\n", texcoords.c_str(),
|
||||
multisampleIndex, offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "\n}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_GATHER4 || opcode == OPCODE_GATHER4_PO)
|
||||
{
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram +=
|
||||
"t.Gather" + strGatherChannel + "(s, " + texcoords + offsets + ")" + strSwizzle + ";";
|
||||
sampleProgram += "\n}\n";
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("return t.Gather%s(s, %s %s)%s;\n", strGatherChannel.c_str(),
|
||||
texcoords.c_str(), offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_GATHER4_C || opcode == OPCODE_GATHER4_PO_C)
|
||||
{
|
||||
// comparison value
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram += StringFormat::Fmt("t.GatherCmp%s(s, %s, %.10f%s)%s;", strGatherChannel.c_str(),
|
||||
texcoords.c_str(), lodOrCompareValue, offsets.c_str(),
|
||||
strSwizzle.c_str());
|
||||
sampleProgram += "\n}\n";
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("return t.GatherCmp%s(s, %s, %.10f %s)%s;\n",
|
||||
strGatherChannel.c_str(), texcoords.c_str(),
|
||||
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
|
||||
// Create VS/PS to fetch the sample
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "d3d8_debug.h"
|
||||
#include "os/os_specific.h"
|
||||
#include "stb/stb_truetype.h"
|
||||
#include "strings/string_utils.h"
|
||||
|
||||
D3D8DebugManager::D3D8DebugManager(WrappedD3DDevice8 *wrapper)
|
||||
: m_WrappedDevice(wrapper), m_fvf(D3DFVF_XYZ | D3DFVF_TEX1)
|
||||
@@ -127,34 +128,21 @@ void D3D8DebugManager::SetOutputWindow(HWND w)
|
||||
// m_supersamplingY = float(m_height) / float(rect.bottom - rect.top);
|
||||
}
|
||||
|
||||
void D3D8DebugManager::RenderText(float x, float y, const char *textfmt, ...)
|
||||
void D3D8DebugManager::RenderText(float x, float y, const rdcstr &text)
|
||||
{
|
||||
static char tmpBuf[4096];
|
||||
rdcarray<rdcstr> lines;
|
||||
split(text, lines, '\n');
|
||||
|
||||
va_list args;
|
||||
va_start(args, textfmt);
|
||||
StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args);
|
||||
tmpBuf[4095] = '\0';
|
||||
va_end(args);
|
||||
|
||||
RenderTextInternal(x, y, tmpBuf);
|
||||
for(const rdcstr &line : lines)
|
||||
RenderTextInternal(x, y, line);
|
||||
}
|
||||
|
||||
void D3D8DebugManager::RenderTextInternal(float x, float y, const char *text)
|
||||
void D3D8DebugManager::RenderTextInternal(float x, float y, const rdcstr &text)
|
||||
{
|
||||
if(char *t = strchr((char *)text, '\n'))
|
||||
{
|
||||
*t = 0;
|
||||
RenderTextInternal(x, y, text);
|
||||
RenderTextInternal(x, y + 1.0f, t + 1);
|
||||
*t = '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen(text) == 0)
|
||||
if(text.empty())
|
||||
return;
|
||||
|
||||
RDCASSERT(strlen(text) < FONT_MAX_CHARS);
|
||||
RDCASSERT(text.size() < FONT_MAX_CHARS);
|
||||
|
||||
// transforms
|
||||
float width = (float)m_width;
|
||||
@@ -265,7 +253,7 @@ void D3D8DebugManager::RenderTextInternal(float x, float y, const char *text)
|
||||
Quad background;
|
||||
UINT triangleCount = 0;
|
||||
{
|
||||
UINT quadCount = (UINT)strlen(text); // calculate string length
|
||||
UINT quadCount = (UINT)text.size(); // calculate string length
|
||||
|
||||
triangleCount = quadCount * 2;
|
||||
// create text VB
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
D3D8DebugManager(WrappedD3DDevice8 *wrapper);
|
||||
~D3D8DebugManager();
|
||||
|
||||
void RenderText(float x, float y, const char *textfmt, ...);
|
||||
void RenderText(float x, float y, const rdcstr &text);
|
||||
|
||||
void SetOutputDimensions(int w, int h)
|
||||
{
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
bool InitFontRendering();
|
||||
void ShutdownFontRendering();
|
||||
|
||||
void RenderTextInternal(float x, float y, const char *text);
|
||||
void RenderTextInternal(float x, float y, const rdcstr &text);
|
||||
|
||||
static const int FONT_TEX_WIDTH = 256;
|
||||
static const int FONT_TEX_HEIGHT = 128;
|
||||
|
||||
@@ -283,8 +283,7 @@ HRESULT __stdcall WrappedD3DDevice8::Present(CONST RECT *pSourceRect, CONST RECT
|
||||
|
||||
overlayText += "Captures not supported with D3D8\n";
|
||||
|
||||
if(!overlayText.empty())
|
||||
GetDebugManager()->RenderText(0.0f, 0.0f, overlayText.c_str());
|
||||
GetDebugManager()->RenderText(0.0f, 0.0f, overlayText);
|
||||
|
||||
stateBlockRes = m_device->ApplyStateBlock(stateBlock);
|
||||
res |= m_device->EndScene();
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "d3d9_debug.h"
|
||||
#include "os/os_specific.h"
|
||||
#include "stb/stb_truetype.h"
|
||||
#include "strings/string_utils.h"
|
||||
|
||||
D3D9DebugManager::D3D9DebugManager(WrappedD3DDevice9 *wrapper)
|
||||
: m_WrappedDevice(wrapper), m_fvf(D3DFVF_XYZ | D3DFVF_TEX1)
|
||||
@@ -127,34 +128,21 @@ void D3D9DebugManager::SetOutputWindow(HWND w)
|
||||
// m_supersamplingY = float(m_height) / float(rect.bottom - rect.top);
|
||||
}
|
||||
|
||||
void D3D9DebugManager::RenderText(float x, float y, const char *textfmt, ...)
|
||||
void D3D9DebugManager::RenderText(float x, float y, const rdcstr &text)
|
||||
{
|
||||
static char tmpBuf[4096];
|
||||
rdcarray<rdcstr> lines;
|
||||
split(text, lines, '\n');
|
||||
|
||||
va_list args;
|
||||
va_start(args, textfmt);
|
||||
StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args);
|
||||
tmpBuf[4095] = '\0';
|
||||
va_end(args);
|
||||
|
||||
RenderTextInternal(x, y, tmpBuf);
|
||||
for(const rdcstr &line : lines)
|
||||
RenderTextInternal(x, y, line);
|
||||
}
|
||||
|
||||
void D3D9DebugManager::RenderTextInternal(float x, float y, const char *text)
|
||||
void D3D9DebugManager::RenderTextInternal(float x, float y, const rdcstr &text)
|
||||
{
|
||||
if(char *t = strchr((char *)text, '\n'))
|
||||
{
|
||||
*t = 0;
|
||||
RenderTextInternal(x, y, text);
|
||||
RenderTextInternal(x, y + 1.0f, t + 1);
|
||||
*t = '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen(text) == 0)
|
||||
if(text.empty())
|
||||
return;
|
||||
|
||||
RDCASSERT(strlen(text) < FONT_MAX_CHARS);
|
||||
RDCASSERT(text.size() < FONT_MAX_CHARS);
|
||||
|
||||
// transforms
|
||||
float width = (float)m_width;
|
||||
@@ -272,7 +260,7 @@ void D3D9DebugManager::RenderTextInternal(float x, float y, const char *text)
|
||||
Quad background;
|
||||
UINT triangleCount = 0;
|
||||
{
|
||||
UINT quadCount = (UINT)strlen(text); // calculate string length
|
||||
UINT quadCount = (UINT)text.size(); // calculate string length
|
||||
|
||||
triangleCount = quadCount * 2;
|
||||
// create text VB
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
D3D9DebugManager(WrappedD3DDevice9 *wrapper);
|
||||
~D3D9DebugManager();
|
||||
|
||||
void RenderText(float x, float y, const char *textfmt, ...);
|
||||
void RenderText(float x, float y, const rdcstr &text);
|
||||
|
||||
void SetOutputDimensions(int w, int h)
|
||||
{
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
bool InitFontRendering();
|
||||
void ShutdownFontRendering();
|
||||
|
||||
void RenderTextInternal(float x, float y, const char *text);
|
||||
void RenderTextInternal(float x, float y, const rdcstr &text);
|
||||
|
||||
static const int FONT_TEX_WIDTH = 256;
|
||||
static const int FONT_TEX_HEIGHT = 128;
|
||||
|
||||
@@ -251,8 +251,7 @@ HRESULT __stdcall WrappedD3DDevice9::Present(CONST RECT *pSourceRect, CONST RECT
|
||||
|
||||
overlayText += "Captures not supported with D3D9\n";
|
||||
|
||||
if(!overlayText.empty())
|
||||
GetDebugManager()->RenderText(0.0f, 0.0f, overlayText.c_str());
|
||||
GetDebugManager()->RenderText(0.0f, 0.0f, overlayText);
|
||||
|
||||
stateBlockRes = stateBlock->Apply();
|
||||
res |= m_device->EndScene();
|
||||
|
||||
@@ -2033,8 +2033,7 @@ void WrappedOpenGL::SwapBuffers(WindowingSystem winSystem, void *windowHandle)
|
||||
overlayText += StringFormat::Fmt(" %s\n", reasonString);
|
||||
}
|
||||
|
||||
if(!overlayText.empty())
|
||||
RenderOverlayText(0.0f, 0.0f, overlayText.c_str());
|
||||
RenderText(0.0f, 0.0f, overlayText);
|
||||
|
||||
// swallow all errors we might have inadvertantly caused. This is
|
||||
// better than letting an error propagate and maybe screw up the
|
||||
@@ -2380,8 +2379,8 @@ bool WrappedOpenGL::EndFrameCapture(void *dev, void *wnd)
|
||||
{
|
||||
ContextData &ctxdata = GetCtxData();
|
||||
|
||||
RenderOverlayText(0.0f, 0.0f, "Failed to capture frame %u: %s",
|
||||
m_CapturedFrames.back().frameNumber, reasonString);
|
||||
RenderText(0.0f, 0.0f, StringFormat::Fmt("Failed to capture frame %u: %s",
|
||||
m_CapturedFrames.back().frameNumber, reasonString));
|
||||
|
||||
// swallow all errors we might have inadvertantly caused. This is
|
||||
// better than letting an error propagate and maybe screw up the
|
||||
|
||||
@@ -531,8 +531,8 @@ private:
|
||||
static const int FONT_TEX_HEIGHT = 128;
|
||||
static const int FONT_MAX_CHARS = 256;
|
||||
|
||||
void RenderOverlayText(float x, float y, const char *fmt, ...);
|
||||
void RenderOverlayStr(float x, float y, const char *str);
|
||||
void RenderText(float x, float y, const rdcstr &text);
|
||||
void RenderTextInternal(float x, float y, const rdcstr &text);
|
||||
|
||||
void CreateReplayBackbuffer(const GLInitParams ¶ms, ResourceId fboOrigId, GLuint &fbo,
|
||||
rdcstr bbname);
|
||||
@@ -593,7 +593,7 @@ public:
|
||||
}
|
||||
SDFile &GetStructuredFile() { return *m_StructuredFile; }
|
||||
void SetFetchCounters(bool in) { m_FetchCounters = in; };
|
||||
void SetDebugMsgContext(const char *context) { m_DebugMsgContext = context; }
|
||||
void SetDebugMsgContext(const rdcstr &context) { m_DebugMsgContext = context; }
|
||||
void AddDebugMessage(DebugMessage msg)
|
||||
{
|
||||
if(IsReplayMode(m_State))
|
||||
@@ -2496,17 +2496,10 @@ public:
|
||||
class ScopedDebugContext
|
||||
{
|
||||
public:
|
||||
ScopedDebugContext(WrappedOpenGL *driver, const char *fmt, ...)
|
||||
ScopedDebugContext(WrappedOpenGL *driver, const rdcstr &msg)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char buf[1024];
|
||||
buf[1023] = 0;
|
||||
StringFormat::vsnprintf(buf, 1023, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
m_Driver = driver;
|
||||
m_Driver->SetDebugMsgContext(buf);
|
||||
m_Driver->SetDebugMsgContext(msg);
|
||||
}
|
||||
|
||||
~ScopedDebugContext() { m_Driver->SetDebugMsgContext(""); }
|
||||
|
||||
@@ -277,42 +277,29 @@ void WrappedOpenGL::ContextData::CreateDebugData()
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedOpenGL::RenderOverlayText(float x, float y, const char *fmt, ...)
|
||||
void WrappedOpenGL::RenderText(float x, float y, const rdcstr &text)
|
||||
{
|
||||
static char tmpBuf[4096];
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
StringFormat::vsnprintf(tmpBuf, 4095, fmt, args);
|
||||
tmpBuf[4095] = '\0';
|
||||
va_end(args);
|
||||
|
||||
ContextData &ctxdata = GetCtxData();
|
||||
|
||||
GLPushPopState textState;
|
||||
|
||||
textState.Push(ctxdata.Modern());
|
||||
|
||||
RenderOverlayStr(x, y, tmpBuf);
|
||||
rdcarray<rdcstr> lines;
|
||||
split(text, lines, '\n');
|
||||
|
||||
for(const rdcstr &line : lines)
|
||||
RenderTextInternal(x, y, line);
|
||||
|
||||
textState.Pop(ctxdata.Modern());
|
||||
}
|
||||
|
||||
void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text)
|
||||
void WrappedOpenGL::RenderTextInternal(float x, float y, const rdcstr &text)
|
||||
{
|
||||
if(char *t = strchr((char *)text, '\n'))
|
||||
{
|
||||
*t = 0;
|
||||
RenderOverlayStr(x, y, text);
|
||||
RenderOverlayStr(x, y + 1.0f, t + 1);
|
||||
*t = '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen(text) == 0)
|
||||
if(text.empty())
|
||||
return;
|
||||
|
||||
RDCASSERT(strlen(text) < (size_t)FONT_MAX_CHARS);
|
||||
RDCASSERT(text.size() < FONT_MAX_CHARS);
|
||||
|
||||
ContextData &ctxdata = GetCtxData();
|
||||
|
||||
@@ -324,7 +311,7 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text)
|
||||
{
|
||||
GL.glBindBuffer(eGL_ARRAY_BUFFER, ctxdata.ArrayBuffer);
|
||||
|
||||
size_t len = strlen(text);
|
||||
size_t len = text.size();
|
||||
|
||||
if((int)len > FONT_MAX_CHARS)
|
||||
{
|
||||
@@ -334,7 +321,7 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text)
|
||||
if(!printedWarning)
|
||||
{
|
||||
printedWarning = true;
|
||||
RDCWARN("log string '%s' is too long", text, (int)len);
|
||||
RDCWARN("log string '%s' is too long", text.c_str(), (int)len);
|
||||
}
|
||||
|
||||
len = FONT_MAX_CHARS;
|
||||
@@ -520,7 +507,7 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text)
|
||||
|
||||
stbtt_aligned_quad q;
|
||||
|
||||
const char *prepass = text;
|
||||
const char *prepass = text.c_str();
|
||||
while(*prepass)
|
||||
{
|
||||
char c = *prepass;
|
||||
@@ -554,9 +541,10 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text)
|
||||
|
||||
float mul = ctxdata.initParams.isYFlipped ? -1.0f : 1.0f;
|
||||
|
||||
while(*text)
|
||||
const char *str = text.c_str();
|
||||
while(*str)
|
||||
{
|
||||
char c = *text;
|
||||
char c = *str;
|
||||
if(c > FONT_FIRST_CHAR && c < FONT_LAST_CHAR)
|
||||
{
|
||||
stbtt_GetBakedQuad(chardata, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, c - FONT_FIRST_CHAR - 1, &x,
|
||||
@@ -574,7 +562,7 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text)
|
||||
{
|
||||
x += chardata[0].xadvance;
|
||||
}
|
||||
++text;
|
||||
++str;
|
||||
}
|
||||
}
|
||||
m_Platform.DrawQuads((float)ctxdata.initParams.width, (float)ctxdata.initParams.height, vertices);
|
||||
|
||||
@@ -144,10 +144,7 @@ rdcstr DoStringise(const UniformType &el)
|
||||
default: break;
|
||||
}
|
||||
|
||||
char tostrBuf[256] = {0};
|
||||
StringFormat::snprintf(tostrBuf, 255, "WrappedOpenGL::UniformType<%d>", el);
|
||||
|
||||
return tostrBuf;
|
||||
return StringFormat::Fmt("UniformType(%d)", el);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -4118,10 +4115,7 @@ rdcstr DoStringise(const RDCGLenum &el)
|
||||
default: break;
|
||||
}
|
||||
|
||||
char tostrBuf[256] = {0};
|
||||
StringFormat::snprintf(tostrBuf, 255, "GLenum<%x>", (uint32_t)el);
|
||||
|
||||
return tostrBuf;
|
||||
return StringFormat::Fmt("GLenum(%x)", el);
|
||||
|
||||
#define GLenum RDCGLenum
|
||||
}
|
||||
|
||||
@@ -46,8 +46,6 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
// useful reflection is present
|
||||
DXBC::Reflection *ret = new DXBC::Reflection;
|
||||
|
||||
char buf[64] = {0};
|
||||
|
||||
for(size_t i = 0; i < m_Declarations.size(); i++)
|
||||
{
|
||||
Declaration &dcl = m_Declarations[i];
|
||||
@@ -64,9 +62,7 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
|
||||
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
|
||||
|
||||
StringFormat::snprintf(buf, 63, "sampler%u", idx);
|
||||
|
||||
desc.name = buf;
|
||||
desc.name = StringFormat::Fmt("sampler%u", idx);
|
||||
desc.type = DXBC::ShaderInputBind::TYPE_SAMPLER;
|
||||
desc.space = dcl.space;
|
||||
desc.reg = idx;
|
||||
@@ -97,9 +93,7 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
|
||||
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
|
||||
|
||||
StringFormat::snprintf(buf, 63, "texture%u", idx);
|
||||
|
||||
desc.name = buf;
|
||||
desc.name = StringFormat::Fmt("texture%u", idx);
|
||||
desc.type = DXBC::ShaderInputBind::TYPE_TEXTURE;
|
||||
desc.space = dcl.space;
|
||||
desc.reg = idx;
|
||||
@@ -170,10 +164,8 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
|
||||
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
|
||||
|
||||
StringFormat::snprintf(buf, 63, "%sbytebuffer%u",
|
||||
dcl.operand.type != TYPE_RESOURCE ? "rw" : "", idx);
|
||||
|
||||
desc.name = buf;
|
||||
desc.name =
|
||||
StringFormat::Fmt("%sbytebuffer%u", dcl.operand.type != TYPE_RESOURCE ? "rw" : "", idx);
|
||||
desc.type = dcl.operand.type == TYPE_RESOURCE
|
||||
? DXBC::ShaderInputBind::TYPE_BYTEADDRESS
|
||||
: DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS;
|
||||
@@ -209,9 +201,7 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
|
||||
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
|
||||
|
||||
StringFormat::snprintf(buf, 63, "structuredbuffer%u", idx);
|
||||
|
||||
desc.name = buf;
|
||||
desc.name = StringFormat::Fmt("structuredbuffer%u", idx);
|
||||
desc.type = DXBC::ShaderInputBind::TYPE_STRUCTURED;
|
||||
desc.space = dcl.space;
|
||||
desc.reg = idx;
|
||||
@@ -242,9 +232,7 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
|
||||
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
|
||||
|
||||
StringFormat::snprintf(buf, 63, "uav%u", idx);
|
||||
|
||||
desc.name = buf;
|
||||
desc.name = StringFormat::Fmt("uav%u", idx);
|
||||
desc.type =
|
||||
DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED; // doesn't seem to be anything that
|
||||
// determines append vs consume vs
|
||||
@@ -280,9 +268,7 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
|
||||
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
|
||||
|
||||
StringFormat::snprintf(buf, 63, "uav%u", idx);
|
||||
|
||||
desc.name = buf;
|
||||
desc.name = StringFormat::Fmt("uav%u", idx);
|
||||
desc.type = DXBC::ShaderInputBind::TYPE_UAV_RWTYPED;
|
||||
desc.space = dcl.space;
|
||||
desc.reg = idx;
|
||||
@@ -346,9 +332,7 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
|
||||
uint32_t numVecs = (uint32_t)dcl.operand.indices[1].index;
|
||||
|
||||
StringFormat::snprintf(buf, 63, "cbuffer%u", idx);
|
||||
|
||||
desc.name = buf;
|
||||
desc.name = StringFormat::Fmt("cbuffer%u", idx);
|
||||
desc.type = DXBC::ShaderInputBind::TYPE_CBUFFER;
|
||||
desc.space = dcl.space;
|
||||
desc.reg = idx;
|
||||
@@ -386,11 +370,9 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
DXBC::CBufferVariable var;
|
||||
|
||||
if(desc.space > 0)
|
||||
StringFormat::snprintf(buf, 63, "cb%u_%u_v%u", desc.space, desc.reg, v);
|
||||
var.name = StringFormat::Fmt("cb%u_%u_v%u", desc.space, desc.reg, v);
|
||||
else
|
||||
StringFormat::snprintf(buf, 63, "cb%u_v%u", desc.reg, v);
|
||||
|
||||
var.name = buf;
|
||||
var.name = StringFormat::Fmt("cb%u_v%u", desc.reg, v);
|
||||
|
||||
var.descriptor.defaultValue.resize(4 * sizeof(float));
|
||||
|
||||
|
||||
@@ -342,27 +342,18 @@ rdcstr TypeName(CBufferVariableType::Descriptor desc)
|
||||
ret = "<unnamed>";
|
||||
else
|
||||
{
|
||||
char buf[64] = {0};
|
||||
|
||||
if(desc.rows > 1)
|
||||
{
|
||||
StringFormat::snprintf(buf, 63, "%s%dx%d", type, desc.rows, desc.cols);
|
||||
ret = StringFormat::Fmt("%s%dx%d", type, desc.rows, desc.cols);
|
||||
|
||||
if(desc.varClass == CLASS_MATRIX_ROWS)
|
||||
{
|
||||
ret = "row_major ";
|
||||
ret += buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = buf;
|
||||
ret = "row_major " + ret;
|
||||
}
|
||||
}
|
||||
else if(desc.cols > 1)
|
||||
{
|
||||
StringFormat::snprintf(buf, 63, "%s%d", type, desc.cols);
|
||||
|
||||
ret = buf;
|
||||
ret = StringFormat::Fmt("%s%d", type, desc.cols);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -400,9 +391,7 @@ CBufferVariableType DXBCContainer::ParseRDEFType(RDEFHeader *h, char *chunkConte
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "unnamed_iface_0x%08x", typeOffset);
|
||||
ret.descriptor.name += " " + rdcstr(buf);
|
||||
ret.descriptor.name += StringFormat::Fmt(" unnamed_iface_0x%08x", typeOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,9 +404,7 @@ CBufferVariableType DXBCContainer::ParseRDEFType(RDEFHeader *h, char *chunkConte
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "unnamed_struct_0x%08x", typeOffset);
|
||||
ret.descriptor.name = buf;
|
||||
ret.descriptor.name = StringFormat::Fmt("unnamed_struct_0x%08x", typeOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1093,11 +1093,7 @@ void State::Init()
|
||||
|
||||
for(uint32_t t = 0; t < decl.numTemps; t++)
|
||||
{
|
||||
char buf[64] = {0};
|
||||
|
||||
StringFormat::snprintf(buf, 63, "r%d", t);
|
||||
|
||||
registers.push_back(ShaderVariable(buf, 0l, 0l, 0l, 0l));
|
||||
registers.push_back(ShaderVariable(StringFormat::Fmt("r%u", t), 0l, 0l, 0l, 0l));
|
||||
}
|
||||
}
|
||||
if(decl.declaration == OPCODE_DCL_INDEXABLE_TEMP)
|
||||
@@ -1115,18 +1111,15 @@ void State::Init()
|
||||
{
|
||||
indexableTemps.resize(indexTempSizes.size());
|
||||
|
||||
for(int32_t i = 0; i < (int32_t)indexTempSizes.size(); i++)
|
||||
for(size_t i = 0; i < indexTempSizes.size(); i++)
|
||||
{
|
||||
if(indexTempSizes[i] > 0)
|
||||
{
|
||||
indexableTemps[i].members.resize(indexTempSizes[i]);
|
||||
for(uint32_t t = 0; t < indexTempSizes[i]; t++)
|
||||
{
|
||||
char buf[64] = {0};
|
||||
|
||||
StringFormat::snprintf(buf, 63, "x%u[%u]", i, t);
|
||||
|
||||
indexableTemps[i].members[t] = ShaderVariable(buf, 0l, 0l, 0l, 0l);
|
||||
indexableTemps[i].members[t] =
|
||||
ShaderVariable(StringFormat::Fmt("x%zu[%u]", i, t), 0l, 0l, 0l, 0l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,13 +608,15 @@ void Program::MakeDisassemblyString()
|
||||
prevLineInfo = lineInfo;
|
||||
}
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "% 4u", i);
|
||||
m_Disassembly += buf;
|
||||
m_Disassembly += ": ";
|
||||
for(int in = 0; in < indent - (m_Instructions[i].operation == OPCODE_ELSE ? 1 : 0); in++)
|
||||
m_Disassembly += " ";
|
||||
m_Disassembly += m_Instructions[i].str + "\n";
|
||||
int curIndent = indent;
|
||||
if(m_Instructions[i].operation == OPCODE_ELSE)
|
||||
curIndent--;
|
||||
|
||||
rdcstr whitespace;
|
||||
whitespace.fill(curIndent * 2, ' ');
|
||||
|
||||
m_Disassembly +=
|
||||
StringFormat::Fmt("% 4u: %s%s\n", i, whitespace.c_str(), m_Instructions[i].str.c_str());
|
||||
|
||||
if(m_Instructions[i].operation == OPCODE_IF || m_Instructions[i].operation == OPCODE_LOOP)
|
||||
{
|
||||
@@ -750,24 +752,18 @@ bool Program::ExtractOperand(uint32_t *&tokenStream, ToString flags, Operand &re
|
||||
RDCASSERT(ret);
|
||||
}
|
||||
|
||||
if(retOper.indices[idx].relative)
|
||||
retOper.indices[idx].str =
|
||||
"[" + retOper.indices[idx].operand.toString(m_Reflection, flags | ToString::ShowSwizzle) +
|
||||
" + ";
|
||||
|
||||
if(retOper.indices[idx].absolute)
|
||||
{
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%llu", retOper.indices[idx].index);
|
||||
retOper.indices[idx].str += buf;
|
||||
}
|
||||
else if(retOper.indices[idx].relative)
|
||||
retOper.indices[idx].str += "0";
|
||||
|
||||
if(retOper.indices[idx].relative)
|
||||
retOper.indices[idx].str += "]";
|
||||
|
||||
RDCASSERT(retOper.indices[idx].relative || retOper.indices[idx].absolute);
|
||||
|
||||
if(retOper.indices[idx].relative)
|
||||
{
|
||||
retOper.indices[idx].str = StringFormat::Fmt(
|
||||
"[%s + 0]",
|
||||
retOper.indices[idx].operand.toString(m_Reflection, flags | ToString::ShowSwizzle).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
retOper.indices[idx].str = ToStr(retOper.indices[idx].index);
|
||||
}
|
||||
}
|
||||
|
||||
if(retOper.type == TYPE_RESOURCE || retOper.type == TYPE_SAMPLER ||
|
||||
@@ -847,16 +843,9 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con
|
||||
}
|
||||
else if(type == TYPE_INTERFACE)
|
||||
{
|
||||
str = "fp";
|
||||
|
||||
RDCASSERT(indices.size() == 2);
|
||||
|
||||
str += indices[0].str;
|
||||
str += "[" + indices[1].str + "]";
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "[%u]", funcNum);
|
||||
str += buf;
|
||||
str = StringFormat::Fmt("fp%s[%s][%u]", indices[0].str.c_str(), indices[1].str.c_str(), funcNum);
|
||||
}
|
||||
else if(type == TYPE_RESOURCE || type == TYPE_SAMPLER || type == TYPE_UNORDERED_ACCESS_VIEW)
|
||||
{
|
||||
@@ -1195,9 +1184,7 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con
|
||||
else if(type == TYPE_IMMEDIATE64)
|
||||
{
|
||||
double *dv = (double *)values;
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "d(%lfl, %lfl)", dv[0], dv[1]);
|
||||
str += buf;
|
||||
str += StringFormat::Fmt("d(%lfl, %lfl)", dv[0], dv[1]);
|
||||
}
|
||||
else if(type == TYPE_RASTERIZER)
|
||||
str = "rasterizer";
|
||||
@@ -1503,20 +1490,14 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
}
|
||||
else if(op == OPCODE_DCL_TEMPS)
|
||||
{
|
||||
retDecl.str += " ";
|
||||
|
||||
retDecl.numTemps = tokenStream[0];
|
||||
|
||||
tokenStream++;
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%u", retDecl.numTemps);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(" %u", retDecl.numTemps);
|
||||
}
|
||||
else if(op == OPCODE_DCL_INDEXABLE_TEMP)
|
||||
{
|
||||
retDecl.str += " ";
|
||||
|
||||
retDecl.tempReg = tokenStream[0];
|
||||
tokenStream++;
|
||||
|
||||
@@ -1526,10 +1507,8 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
retDecl.tempComponentCount = tokenStream[0];
|
||||
tokenStream++;
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "x%u[%u], %u", retDecl.tempReg, retDecl.numTemps,
|
||||
retDecl.tempComponentCount);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(" x%u[%u], %u", retDecl.tempReg, retDecl.numTemps,
|
||||
retDecl.tempComponentCount);
|
||||
}
|
||||
else if(op == OPCODE_DCL_OUTPUT)
|
||||
{
|
||||
@@ -1548,9 +1527,7 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
|
||||
tokenStream++;
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%u", retDecl.maxOut);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(" %u", retDecl.maxOut);
|
||||
}
|
||||
else if(op == OPCODE_DCL_INPUT_SIV || op == OPCODE_DCL_INPUT_SGV ||
|
||||
op == OPCODE_DCL_INPUT_PS_SIV || op == OPCODE_DCL_INPUT_PS_SGV ||
|
||||
@@ -1686,15 +1663,10 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
retDecl.indexRange = tokenStream[0];
|
||||
tokenStream++;
|
||||
|
||||
retDecl.str += " ";
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%u", retDecl.indexRange);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(" %u", retDecl.indexRange);
|
||||
}
|
||||
else if(op == OPCODE_DCL_THREAD_GROUP)
|
||||
{
|
||||
retDecl.str += " ";
|
||||
|
||||
retDecl.groupSize[0] = tokenStream[0];
|
||||
tokenStream++;
|
||||
|
||||
@@ -1703,17 +1675,9 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
|
||||
retDecl.groupSize[2] = tokenStream[0];
|
||||
tokenStream++;
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[0]);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += ", ";
|
||||
|
||||
StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[1]);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += ", ";
|
||||
|
||||
StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[2]);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(" %u, %u, %u", retDecl.groupSize[0], retDecl.groupSize[1],
|
||||
retDecl.groupSize[2]);
|
||||
}
|
||||
else if(op == OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW)
|
||||
{
|
||||
@@ -1726,11 +1690,7 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
tokenStream++;
|
||||
|
||||
retDecl.str += retDecl.operand.toString(m_Reflection, flags);
|
||||
retDecl.str += ", ";
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%u", retDecl.count);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(", %u", retDecl.count);
|
||||
}
|
||||
else if(op == OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED)
|
||||
{
|
||||
@@ -1746,25 +1706,13 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
tokenStream++;
|
||||
|
||||
retDecl.str += retDecl.operand.toString(m_Reflection, flags);
|
||||
retDecl.str += ", ";
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%u", retDecl.stride);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += ", ";
|
||||
|
||||
StringFormat::snprintf(buf, 63, "%u", retDecl.count);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(", %u, %u", retDecl.stride, retDecl.count);
|
||||
}
|
||||
else if(op == OPCODE_DCL_INPUT_CONTROL_POINT_COUNT || op == OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT)
|
||||
{
|
||||
retDecl.str += " ";
|
||||
|
||||
retDecl.controlPointCount = Decl::ControlPointCount.Get(OpcodeToken0);
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%u", retDecl.controlPointCount);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(" %u", retDecl.controlPointCount);
|
||||
}
|
||||
else if(op == OPCODE_DCL_TESS_DOMAIN)
|
||||
{
|
||||
@@ -1814,11 +1762,8 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
else if(retDecl.inPrim >= PRIMITIVE_1_CONTROL_POINT_PATCH &&
|
||||
retDecl.inPrim <= PRIMITIVE_32_CONTROL_POINT_PATCH)
|
||||
{
|
||||
retDecl.str += "control_point_patch_";
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%u",
|
||||
1 + int(retDecl.inPrim - PRIMITIVE_1_CONTROL_POINT_PATCH));
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt("control_point_patch_%u",
|
||||
1 + int(retDecl.inPrim - PRIMITIVE_1_CONTROL_POINT_PATCH));
|
||||
}
|
||||
else
|
||||
RDCERR("Unexpected primitive type");
|
||||
@@ -1921,11 +1866,7 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
tokenStream++;
|
||||
|
||||
retDecl.str += retDecl.operand.toString(m_Reflection, flags);
|
||||
retDecl.str += ", ";
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%u", retDecl.stride);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(", %u", retDecl.stride);
|
||||
|
||||
if(retDecl.hasCounter)
|
||||
retDecl.str += ", hasOrderPreservingCounter";
|
||||
@@ -2016,11 +1957,7 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
retDecl.instanceCount = tokenStream[0];
|
||||
tokenStream++;
|
||||
|
||||
retDecl.str += " ";
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "%u", retDecl.instanceCount);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(" %u", retDecl.instanceCount);
|
||||
}
|
||||
else if(op == OPCODE_DCL_HS_MAX_TESSFACTOR)
|
||||
{
|
||||
@@ -2028,33 +1965,21 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
retDecl.maxTessFactor = *f;
|
||||
tokenStream++;
|
||||
|
||||
retDecl.str += " ";
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "l(%f)", retDecl.maxTessFactor);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(" l(%f)", retDecl.maxTessFactor);
|
||||
}
|
||||
else if(op == OPCODE_DCL_FUNCTION_BODY)
|
||||
{
|
||||
retDecl.functionBody = tokenStream[0];
|
||||
tokenStream++;
|
||||
|
||||
retDecl.str += " ";
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "fb%u", retDecl.functionBody);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(" fb%u", retDecl.functionBody);
|
||||
}
|
||||
else if(op == OPCODE_DCL_FUNCTION_TABLE)
|
||||
{
|
||||
retDecl.functionTable = tokenStream[0];
|
||||
tokenStream++;
|
||||
|
||||
retDecl.str += " ";
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "ft%u", retDecl.functionTable);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(" ft%u", retDecl.functionTable);
|
||||
|
||||
uint32_t TableLength = tokenStream[0];
|
||||
tokenStream++;
|
||||
@@ -2063,8 +1988,7 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
|
||||
for(uint32_t i = 0; i < TableLength; i++)
|
||||
{
|
||||
StringFormat::snprintf(buf, 63, "fb%u", tokenStream[0]);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt("fb%u", tokenStream[0]);
|
||||
|
||||
if(i + 1 < TableLength)
|
||||
retDecl.str += ", ";
|
||||
@@ -2089,19 +2013,14 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
retDecl.numInterfaces = Decl::NumInterfaces.Get(CountToken);
|
||||
uint32_t TableLength = Decl::TableLength.Get(CountToken);
|
||||
|
||||
retDecl.str += " ";
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "fp%u[%u][%u]", retDecl.interfaceID, retDecl.numInterfaces,
|
||||
retDecl.numTypes);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt(" fp%u[%u][%u]", retDecl.interfaceID, retDecl.numInterfaces,
|
||||
retDecl.numTypes);
|
||||
|
||||
retDecl.str += " = {";
|
||||
|
||||
for(uint32_t i = 0; i < TableLength; i++)
|
||||
{
|
||||
StringFormat::snprintf(buf, 63, "ft%u", tokenStream[0]);
|
||||
retDecl.str += buf;
|
||||
retDecl.str += StringFormat::Fmt("ft%u", tokenStream[0]);
|
||||
|
||||
if(i + 1 < TableLength)
|
||||
retDecl.str += ", ";
|
||||
@@ -2113,7 +2032,8 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
|
||||
retDecl.str += "}";
|
||||
}
|
||||
else if(op == OPCODE_HS_DECLS)
|
||||
;
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected opcode decl %d", op);
|
||||
@@ -2232,10 +2152,8 @@ bool Program::ExtractOperation(uint32_t *&tokenStream, Operation &retOp, bool fr
|
||||
if(retOp.texelOffset[2] > 7)
|
||||
retOp.texelOffset[2] -= 16;
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, "(%d,%d,%d)", retOp.texelOffset[0], retOp.texelOffset[1],
|
||||
retOp.texelOffset[2]);
|
||||
retOp.str += buf;
|
||||
retOp.str += StringFormat::Fmt("(%d,%d,%d)", retOp.texelOffset[0], retOp.texelOffset[1],
|
||||
retOp.texelOffset[2]);
|
||||
}
|
||||
else if(type == EXTENDED_OPCODE_RESOURCE_DIM)
|
||||
{
|
||||
@@ -2243,16 +2161,10 @@ bool Program::ExtractOperation(uint32_t *&tokenStream, Operation &retOp, bool fr
|
||||
|
||||
if(op == OPCODE_LD_STRUCTURED)
|
||||
{
|
||||
retOp.str += "_indexable(";
|
||||
retOp.str += toString(retOp.resDim);
|
||||
|
||||
retOp.stride = ExtendedOpcode::BufferStride.Get(OpcodeTokenN);
|
||||
|
||||
char buf[64] = {0};
|
||||
StringFormat::snprintf(buf, 63, ", stride=%u", retOp.stride);
|
||||
retOp.str += buf;
|
||||
|
||||
retOp.str += ")";
|
||||
retOp.str +=
|
||||
StringFormat::Fmt("_indexable(%s, stride=%u)", toString(retOp.resDim), retOp.stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2646,20 +2558,18 @@ rdcstr toString(const uint32_t values[], uint32_t numComps)
|
||||
float *vf = (float *)&values[i];
|
||||
int32_t *vi = (int32_t *)&values[i];
|
||||
|
||||
char buf[64] = {0};
|
||||
|
||||
if(!floatOutput)
|
||||
if(floatOutput)
|
||||
{
|
||||
str += ToStr(vf[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// print small ints straight up, otherwise as hex
|
||||
if(vi[0] <= 10000 && vi[0] >= -10000)
|
||||
StringFormat::snprintf(buf, 63, "%d", vi[0]);
|
||||
str += ToStr(vi[0]);
|
||||
else
|
||||
StringFormat::snprintf(buf, 63, "0x%08x", vi[0]);
|
||||
str += StringFormat::Fmt("0x%08x", vi[0]);
|
||||
}
|
||||
else
|
||||
StringFormat::snprintf(buf, 63, "%f", vf[0]);
|
||||
|
||||
str += buf;
|
||||
|
||||
if(i + 1 < numComps)
|
||||
str += ", ";
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "vk_rendertext.h"
|
||||
#include "3rdparty/stb/stb_truetype.h"
|
||||
#include "maths/matrix.h"
|
||||
#include "strings/string_utils.h"
|
||||
#include "vk_shader_cache.h"
|
||||
|
||||
#define VULKAN 1
|
||||
@@ -597,32 +598,19 @@ void VulkanTextRenderer::BeginText(const TextPrintState &textstate)
|
||||
}
|
||||
|
||||
void VulkanTextRenderer::RenderText(const TextPrintState &textstate, float x, float y,
|
||||
const char *textfmt, ...)
|
||||
const rdcstr &text)
|
||||
{
|
||||
static char tmpBuf[4096];
|
||||
rdcarray<rdcstr> lines;
|
||||
split(text, lines, '\n');
|
||||
|
||||
va_list args;
|
||||
va_start(args, textfmt);
|
||||
StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args);
|
||||
tmpBuf[4095] = '\0';
|
||||
va_end(args);
|
||||
|
||||
RenderTextInternal(textstate, x, y, tmpBuf);
|
||||
for(const rdcstr &line : lines)
|
||||
RenderTextInternal(textstate, x, y, line);
|
||||
}
|
||||
|
||||
void VulkanTextRenderer::RenderTextInternal(const TextPrintState &textstate, float x, float y,
|
||||
const char *text)
|
||||
const rdcstr &text)
|
||||
{
|
||||
if(char *t = strchr((char *)text, '\n'))
|
||||
{
|
||||
*t = 0;
|
||||
RenderTextInternal(textstate, x, y, text);
|
||||
RenderTextInternal(textstate, x, y + 1.0f, t + 1);
|
||||
*t = '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen(text) == 0)
|
||||
if(text.empty())
|
||||
return;
|
||||
|
||||
uint32_t offsets[2] = {0};
|
||||
@@ -643,14 +631,14 @@ void VulkanTextRenderer::RenderTextInternal(const TextPrintState &textstate, flo
|
||||
|
||||
m_TextGeneralUBO.Unmap();
|
||||
|
||||
size_t len = strlen(text);
|
||||
size_t len = text.size();
|
||||
|
||||
RDCASSERT(len <= MAX_SINGLE_LINE_LENGTH);
|
||||
|
||||
// only map enough for our string
|
||||
StringUBOData *stringData = (StringUBOData *)m_TextStringUBO.Map(&offsets[1], len * sizeof(Vec4u));
|
||||
|
||||
for(size_t i = 0; i < strlen(text); i++)
|
||||
for(size_t i = 0; i < len; i++)
|
||||
stringData->chars[i].x = uint32_t(text[i] - ' ');
|
||||
|
||||
m_TextStringUBO.Unmap();
|
||||
@@ -659,7 +647,7 @@ void VulkanTextRenderer::RenderTextInternal(const TextPrintState &textstate, flo
|
||||
->CmdBindDescriptorSets(Unwrap(textstate.cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_TextPipeLayout), 0, 1, UnwrapPtr(m_TextDescSet), 2, offsets);
|
||||
|
||||
ObjDisp(textstate.cmd)->CmdDraw(Unwrap(textstate.cmd), 6 * (uint32_t)strlen(text), 1, 0, 0);
|
||||
ObjDisp(textstate.cmd)->CmdDraw(Unwrap(textstate.cmd), 6 * (uint32_t)len, 1, 0, 0);
|
||||
}
|
||||
|
||||
void VulkanTextRenderer::EndText(const TextPrintState &textstate)
|
||||
|
||||
@@ -44,11 +44,11 @@ public:
|
||||
~VulkanTextRenderer();
|
||||
|
||||
void BeginText(const TextPrintState &textstate);
|
||||
void RenderText(const TextPrintState &textstate, float x, float y, const char *fmt, ...);
|
||||
void RenderText(const TextPrintState &textstate, float x, float y, const rdcstr &text);
|
||||
void EndText(const TextPrintState &textstate);
|
||||
|
||||
private:
|
||||
void RenderTextInternal(const TextPrintState &textstate, float x, float y, const char *text);
|
||||
void RenderTextInternal(const TextPrintState &textstate, float x, float y, const rdcstr &text);
|
||||
|
||||
static const uint32_t FONT_TEX_WIDTH = 256;
|
||||
static const uint32_t FONT_TEX_HEIGHT = 128;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "../vk_core.h"
|
||||
#include "api/replay/version.h"
|
||||
|
||||
static char fakeRenderDocUUID[VK_UUID_SIZE + 1] = {};
|
||||
static char fakeRenderDocUUID[VK_UUID_SIZE] = {};
|
||||
|
||||
void MakeFakeUUID()
|
||||
{
|
||||
@@ -37,7 +37,9 @@ void MakeFakeUUID()
|
||||
// rdocyymmddHHMMSS
|
||||
// we pass size+1 so that there's room for a null terminator (the UUID doesn't
|
||||
// need a null terminator as it's a fixed size non-string array)
|
||||
StringFormat::sntimef(fakeRenderDocUUID, VK_UUID_SIZE + 1, "rdoc%y%m%d%H%M%S");
|
||||
rdcstr uuid = StringFormat::sntimef(Timing::GetUTCTime(), "rdoc%y%m%d%H%M%S");
|
||||
RDCASSERT(uuid.size() == sizeof(fakeRenderDocUUID));
|
||||
memcpy(fakeRenderDocUUID, uuid.c_str(), RDCMIN(VK_UUID_SIZE, uuid.count()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -832,15 +832,17 @@ VkResult WrappedVulkan::vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR
|
||||
SubmitAndFlushExtQueue(swapQueueIndex);
|
||||
}
|
||||
|
||||
m_TextRenderer->BeginText(textstate);
|
||||
|
||||
int flags = activeWindow ? RenderDoc::eOverlay_ActiveWindow : 0;
|
||||
rdcstr overlayText = RenderDoc::Inst().GetOverlayText(RDCDriver::Vulkan, m_FrameCounter, flags);
|
||||
|
||||
if(!overlayText.empty())
|
||||
m_TextRenderer->RenderText(textstate, 0.0f, 0.0f, overlayText.c_str());
|
||||
{
|
||||
m_TextRenderer->BeginText(textstate);
|
||||
|
||||
m_TextRenderer->EndText(textstate);
|
||||
m_TextRenderer->RenderText(textstate, 0.0f, 0.0f, overlayText);
|
||||
|
||||
m_TextRenderer->EndText(textstate);
|
||||
}
|
||||
|
||||
std::swap(bbBarrier.srcQueueFamilyIndex, bbBarrier.dstQueueFamilyIndex);
|
||||
std::swap(bbBarrier.oldLayout, bbBarrier.newLayout);
|
||||
|
||||
@@ -27,32 +27,10 @@
|
||||
#include "api/replay/control_types.h"
|
||||
#include "strings/string_utils.h"
|
||||
|
||||
int utf8printf(char *buf, size_t bufsize, const char *fmt, va_list args);
|
||||
int utf8printv(char *buf, size_t bufsize, const char *fmt, va_list args);
|
||||
|
||||
namespace StringFormat
|
||||
{
|
||||
int snprintf(char *str, size_t bufSize, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
int ret = StringFormat::vsnprintf(str, bufSize, fmt, args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sntimef(char *str, size_t bufSize, const char *format)
|
||||
{
|
||||
StringFormat::sntimef(Timing::GetUTCTime(), str, bufSize, format);
|
||||
}
|
||||
|
||||
int vsnprintf(char *str, size_t bufSize, const char *format, va_list args)
|
||||
{
|
||||
return ::utf8printf(str, bufSize, format, args);
|
||||
}
|
||||
|
||||
rdcstr Fmt(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
@@ -61,11 +39,11 @@ rdcstr Fmt(const char *format, ...)
|
||||
va_list args2;
|
||||
va_copy(args2, args);
|
||||
|
||||
int size = StringFormat::vsnprintf(NULL, 0, format, args2);
|
||||
int size = ::utf8printv(NULL, 0, format, args2);
|
||||
|
||||
rdcstr ret;
|
||||
ret.resize(size);
|
||||
StringFormat::vsnprintf(ret.data(), size + 1, format, args);
|
||||
::utf8printv(ret.data(), size + 1, format, args);
|
||||
|
||||
va_end(args);
|
||||
va_end(args2);
|
||||
@@ -93,11 +71,9 @@ rdcstr Callstack::AddressDetails::formattedString(const char *commonPath)
|
||||
}
|
||||
|
||||
if(line > 0)
|
||||
StringFormat::snprintf(fmt, 511, "%s line %d", function.c_str(), line);
|
||||
return StringFormat::Fmt("%s line %d", function.c_str(), line);
|
||||
else
|
||||
StringFormat::snprintf(fmt, 511, "%s", function.c_str());
|
||||
|
||||
return fmt;
|
||||
return function;
|
||||
}
|
||||
|
||||
rdcstr OSUtility::MakeMachineIdentString(uint64_t ident)
|
||||
|
||||
@@ -434,7 +434,7 @@ struct rdcwstr : private rdcarray<wchar_t>
|
||||
// implemented per-platform
|
||||
namespace StringFormat
|
||||
{
|
||||
void sntimef(time_t utcTime, char *str, size_t bufSize, const char *format);
|
||||
rdcstr sntimef(time_t utcTime, const char *format);
|
||||
|
||||
rdcstr Wide2UTF8(const rdcwstr &str);
|
||||
rdcwstr UTF82Wide(const rdcstr &s);
|
||||
@@ -442,16 +442,6 @@ rdcwstr UTF82Wide(const rdcstr &s);
|
||||
void Shutdown();
|
||||
};
|
||||
|
||||
// utility functions, implemented in os_specific.cpp, not per-platform (assuming standard stdarg.h)
|
||||
// forwarded to custom printf implementation in utf8printf.cpp
|
||||
namespace StringFormat
|
||||
{
|
||||
int vsnprintf(char *str, size_t bufSize, const char *format, va_list v);
|
||||
int snprintf(char *str, size_t bufSize, const char *format, ...);
|
||||
|
||||
void sntimef(char *str, size_t bufSize, const char *format);
|
||||
};
|
||||
|
||||
namespace OSUtility
|
||||
{
|
||||
inline void ForceCrash();
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "common/common.h"
|
||||
#include "common/formatting.h"
|
||||
#include "os/os_specific.h"
|
||||
|
||||
#define LOGCAT_TAG "renderdoc"
|
||||
@@ -77,13 +78,11 @@ rdcstr GetAppFolderFilename(const rdcstr &filename)
|
||||
// For other APKs, we use it to get the writable temp directory.
|
||||
void GetExecutableFilename(rdcstr &selfName)
|
||||
{
|
||||
char buf[4096];
|
||||
snprintf(buf, sizeof(buf), "/proc/%u/cmdline", getpid());
|
||||
int fd = open(buf, O_RDONLY);
|
||||
int fd = open(StringFormat::Fmt("/proc/%u/cmdline", getpid()).c_str(), O_RDONLY);
|
||||
if(fd < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char buf[4096];
|
||||
ssize_t len = read(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
if(len < 0 || len == sizeof(buf))
|
||||
|
||||
@@ -388,9 +388,6 @@ Socket *CreateTCPServerSocket(const char *bindaddr, uint16_t port, int queuesize
|
||||
|
||||
Socket *CreateAbstractServerSocket(uint16_t port, int queuesize)
|
||||
{
|
||||
char socketName[17] = {0};
|
||||
StringFormat::snprintf(socketName, 16, "renderdoc_%d", port);
|
||||
int socketNameLength = strlen(socketName);
|
||||
int s = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if(s == -1)
|
||||
@@ -399,18 +396,20 @@ Socket *CreateAbstractServerSocket(uint16_t port, int queuesize)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rdcstr socketName = StringFormat::Fmt("renderdoc_%d", port);
|
||||
|
||||
sockaddr_un addr;
|
||||
RDCEraseEl(addr);
|
||||
|
||||
addr.sun_family = AF_UNIX;
|
||||
// first char is '\0'
|
||||
addr.sun_path[0] = '\0';
|
||||
strncpy(addr.sun_path + 1, socketName, socketNameLength + 1);
|
||||
strncpy(addr.sun_path + 1, socketName.c_str(), socketName.size() + 1);
|
||||
|
||||
int result = bind(s, (sockaddr *)&addr, offsetof(sockaddr_un, sun_path) + 1 + socketNameLength);
|
||||
int result = bind(s, (sockaddr *)&addr, socketName.size());
|
||||
if(result == -1)
|
||||
{
|
||||
RDCWARN("Failed to create abstract socket: %s", socketName);
|
||||
RDCWARN("Failed to create abstract socket: %s", socketName.c_str());
|
||||
close(s);
|
||||
return NULL;
|
||||
}
|
||||
@@ -419,7 +418,7 @@ Socket *CreateAbstractServerSocket(uint16_t port, int queuesize)
|
||||
result = listen(s, queuesize);
|
||||
if(result == -1)
|
||||
{
|
||||
RDCWARN("Failed to listen on %s", socketName);
|
||||
RDCWARN("Failed to listen on %s", socketName.c_str());
|
||||
close(s);
|
||||
return NULL;
|
||||
}
|
||||
@@ -432,9 +431,6 @@ Socket *CreateAbstractServerSocket(uint16_t port, int queuesize)
|
||||
|
||||
Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS)
|
||||
{
|
||||
char portstr[7] = {0};
|
||||
StringFormat::snprintf(portstr, 6, "%d", port);
|
||||
|
||||
addrinfo hints;
|
||||
RDCEraseEl(hints);
|
||||
hints.ai_family = AF_INET;
|
||||
@@ -442,7 +438,7 @@ Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS)
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
addrinfo *addrResult = NULL;
|
||||
int res = getaddrinfo(host, portstr, &hints, &addrResult);
|
||||
int res = getaddrinfo(host, ToStr(port).c_str(), &hints, &addrResult);
|
||||
if(res != 0)
|
||||
{
|
||||
RDCDEBUG("%s", gai_strerror(res));
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <unistd.h>
|
||||
#include "api/app/renderdoc_app.h"
|
||||
#include "api/replay/data_types.h"
|
||||
#include "common/formatting.h"
|
||||
#include "common/threading.h"
|
||||
#include "os/os_specific.h"
|
||||
#include "strings/string_utils.h"
|
||||
@@ -221,24 +222,18 @@ void GetDefaultFiles(const char *logBaseName, rdcstr &capture_filename, rdcstr &
|
||||
temp_folder[--len] = 0;
|
||||
}
|
||||
|
||||
char temp_filename[2048 + 128] = {0};
|
||||
|
||||
snprintf(temp_filename, sizeof(temp_filename) - 1, "%s/RenderDoc/%s_%04d.%02d.%02d_%02d.%02d.rdc",
|
||||
temp_folder, mod, 1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour,
|
||||
now.tm_min);
|
||||
|
||||
capture_filename = rdcstr(temp_filename);
|
||||
|
||||
snprintf(temp_filename, sizeof(temp_filename) - 1,
|
||||
"%s/RenderDoc/%s_%04d.%02d.%02d_%02d.%02d.%02d.log", temp_folder, logBaseName,
|
||||
1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
|
||||
capture_filename =
|
||||
StringFormat::Fmt("%s/RenderDoc/%s_%04d.%02d.%02d_%02d.%02d.rdc", temp_folder, mod,
|
||||
1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min);
|
||||
|
||||
// set by UI when launching programs so all logging goes to the same file
|
||||
char *logfile_override = getenv("RENDERDOC_DEBUG_LOG_FILE");
|
||||
if(logfile_override)
|
||||
logging_filename = rdcstr(logfile_override);
|
||||
else
|
||||
logging_filename = rdcstr(temp_filename);
|
||||
logging_filename = StringFormat::Fmt(
|
||||
"%s/RenderDoc/%s_%04d.%02d.%02d_%02d.%02d.%02d.log", temp_folder, logBaseName,
|
||||
1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
|
||||
}
|
||||
|
||||
uint64_t GetModifiedTimestamp(const rdcstr &filename)
|
||||
@@ -568,10 +563,39 @@ void logfile_close(LogFileHandle *logHandle, const char *deleteFilename)
|
||||
|
||||
namespace StringFormat
|
||||
{
|
||||
void sntimef(time_t utcTime, char *str, size_t bufSize, const char *format)
|
||||
rdcstr sntimef(time_t utcTime, const char *format)
|
||||
{
|
||||
tm *tmv = localtime(&utcTime);
|
||||
|
||||
strftime(str, bufSize, format, tmv);
|
||||
// conservatively assume that most formatters will replace like-for-like (e.g. %H with 12) and
|
||||
// a few will increase (%Y to 2019) but generally the string will stay the same size.
|
||||
size_t len = strlen(format) + 16;
|
||||
|
||||
size_t ret = 0;
|
||||
char *buf = NULL;
|
||||
|
||||
// loop until we have successfully formatted
|
||||
while(ret == 0)
|
||||
{
|
||||
// delete any previous buffer
|
||||
delete[] buf;
|
||||
|
||||
// alloate new one of the new size
|
||||
buf = new char[len + 1];
|
||||
buf[len] = 0;
|
||||
|
||||
// try formatting
|
||||
ret = strftime(buf, len, format, tmv);
|
||||
|
||||
// double the length for next time, if this failed
|
||||
len *= 2;
|
||||
}
|
||||
|
||||
rdcstr str = buf;
|
||||
|
||||
// delete successful buffer
|
||||
delete[] buf;
|
||||
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -397,9 +397,8 @@ Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS)
|
||||
wchar_t portwstr[7] = {0};
|
||||
|
||||
{
|
||||
char buf[7] = {0};
|
||||
int n = StringFormat::snprintf(buf, 6, "%d", port);
|
||||
for(int i = 0; i < n && i < 6; i++)
|
||||
rdcstr buf = ToStr(port);
|
||||
for(size_t i = 0; i < buf.size(); i++)
|
||||
portwstr[i] = (wchar_t)buf[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -745,26 +745,45 @@ void logfile_close(LogFileHandle *logHandle, const char *deleteFilename)
|
||||
|
||||
namespace StringFormat
|
||||
{
|
||||
void sntimef(time_t utcTime, char *str, size_t bufSize, const char *format)
|
||||
rdcstr sntimef(time_t utcTime, const char *format)
|
||||
{
|
||||
tm tmv;
|
||||
localtime_s(&tmv, &utcTime);
|
||||
|
||||
wchar_t *buf = new wchar_t[bufSize + 1];
|
||||
buf[bufSize] = 0;
|
||||
rdcstr result;
|
||||
|
||||
rdcwstr wfmt = StringFormat::UTF82Wide(format);
|
||||
|
||||
wcsftime(buf, bufSize, wfmt.c_str(), &tmv);
|
||||
// conservatively assume that most formatters will replace like-for-like (e.g. %H with 12) and
|
||||
// a few will increase (%Y to 2019) but generally the string will stay the same size.
|
||||
size_t len = strlen(format) + 16;
|
||||
|
||||
rdcstr result = StringFormat::Wide2UTF8(buf);
|
||||
size_t ret = 0;
|
||||
wchar_t *buf = NULL;
|
||||
|
||||
// loop until we have successfully formatted
|
||||
while(ret == 0)
|
||||
{
|
||||
// delete any previous buffer
|
||||
delete[] buf;
|
||||
|
||||
// alloate new one of the new size
|
||||
buf = new wchar_t[len + 1];
|
||||
buf[len] = 0;
|
||||
|
||||
// try formatting
|
||||
ret = wcsftime(buf, len, wfmt.c_str(), &tmv);
|
||||
|
||||
// double the length for next time, if this failed
|
||||
len *= 2;
|
||||
}
|
||||
|
||||
rdcstr str = StringFormat::Wide2UTF8(buf);
|
||||
|
||||
// delete successful buffer
|
||||
delete[] buf;
|
||||
|
||||
if(result.length() + 1 <= bufSize)
|
||||
{
|
||||
memcpy(str, result.c_str(), result.length());
|
||||
str[result.length()] = 0;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
|
||||
@@ -304,9 +304,8 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_CreateBugReport(const char
|
||||
|
||||
if(report.empty())
|
||||
{
|
||||
char filename[128] = {};
|
||||
StringFormat::sntimef(filename, 127, "/renderdoc_report_%H%M%S.zip");
|
||||
report = FileIO::GetTempFolderFilename() + filename;
|
||||
report = FileIO::GetTempFolderFilename() +
|
||||
StringFormat::sntimef(Timing::GetUTCTime(), "/renderdoc_report_%H%M%S.zip");
|
||||
}
|
||||
|
||||
FileIO::Delete(report.c_str());
|
||||
|
||||
@@ -1368,6 +1368,11 @@ rdcstr DoStringise(const TestBitfield &el)
|
||||
END_BITFIELD_STRINGISE();
|
||||
}
|
||||
|
||||
void test(const char *aasd)
|
||||
{
|
||||
RDCLOG("got a test of %s", aasd);
|
||||
}
|
||||
|
||||
TEST_CASE("Test stringification works as expected", "[tostr]")
|
||||
{
|
||||
SECTION("Enum classes")
|
||||
@@ -1391,6 +1396,17 @@ TEST_CASE("Test stringification works as expected", "[tostr]")
|
||||
CHECK(ToStr(foo) == "TestEnumClass(0)");
|
||||
};
|
||||
|
||||
SECTION("integers")
|
||||
{
|
||||
uint16_t a = 54;
|
||||
uint32_t b = 22;
|
||||
uint8_t c = 99;
|
||||
|
||||
test(ToStr(a).c_str());
|
||||
test(ToStr(b).c_str());
|
||||
test(ToStr(c).c_str());
|
||||
};
|
||||
|
||||
SECTION("plain enums")
|
||||
{
|
||||
TestEnum foo = TestA;
|
||||
|
||||
@@ -1180,7 +1180,7 @@ void formatargument(char type, void *rawarg, FormatterParams formatter, char *&o
|
||||
}
|
||||
}
|
||||
|
||||
int utf8printf(char *buf, size_t bufsize, const char *fmt, va_list args)
|
||||
int utf8printv(char *buf, size_t bufsize, const char *fmt, va_list args)
|
||||
{
|
||||
// format, buffer and string arguments are assumed to be UTF-8 (except wide strings).
|
||||
// note that since the format specifiers are entirely ascii, we can byte-copy safely and handle
|
||||
@@ -1452,23 +1452,23 @@ int utf8printf(char *buf, size_t bufsize, const char *fmt, va_list args)
|
||||
return int(actualsize);
|
||||
}
|
||||
|
||||
#if ENABLED(ENABLE_UNIT_TESTS)
|
||||
|
||||
#include "3rdparty/catch/catch.hpp"
|
||||
#include "common/formatting.h"
|
||||
|
||||
int utf8printf_wrapper(char *buf, size_t bufsize, const char *fmt, ...)
|
||||
int utf8printf(char *str, size_t bufSize, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
int ret = utf8printf(buf, bufsize, fmt, args);
|
||||
int ret = utf8printv(str, bufSize, fmt, args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if ENABLED(ENABLE_UNIT_TESTS)
|
||||
|
||||
#include "3rdparty/catch/catch.hpp"
|
||||
#include "common/formatting.h"
|
||||
|
||||
TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
|
||||
{
|
||||
int fourtytwo = 42;
|
||||
@@ -1477,7 +1477,7 @@ TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
|
||||
|
||||
SECTION("NULL input buffer")
|
||||
{
|
||||
int a = utf8printf_wrapper(NULL, 0, "%d %c", fourtytwo, x);
|
||||
int a = utf8printf(NULL, 0, "%d %c", fourtytwo, x);
|
||||
int b = snprintf(NULL, 0, "%d %c", fourtytwo, x);
|
||||
|
||||
CHECK(a == 4);
|
||||
@@ -1490,7 +1490,7 @@ TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
|
||||
char bufa[] = {0, 0, 0, 0, 0, 0};
|
||||
char bufb[] = {0, 0, 0, 0, 0, 0};
|
||||
|
||||
int a = utf8printf_wrapper(bufa, sizeof(bufa), "%d foo", largenum);
|
||||
int a = utf8printf(bufa, sizeof(bufa), "%d foo", largenum);
|
||||
int b = snprintf(bufb, sizeof(bufb), "%d foo", largenum);
|
||||
|
||||
RDCCOMPILE_ASSERT(sizeof(bufa) == 6, "bufa is mis-sized for test");
|
||||
@@ -1513,7 +1513,7 @@ TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
|
||||
SECTION("contains NULL terminator")
|
||||
{
|
||||
memset(bufa, 'a', sizeof(bufa));
|
||||
a = utf8printf_wrapper(bufa, sizeof(bufa), "%d foo", largenum);
|
||||
a = utf8printf(bufa, sizeof(bufa), "%d foo", largenum);
|
||||
INFO("bufa is '" << rdcstr(bufa) << "'");
|
||||
CHECK(memcmp(bufa, ref, sizeof(ref)) == 0);
|
||||
}
|
||||
@@ -1527,7 +1527,7 @@ TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
|
||||
memset(bufa, 'a', sizeof(bufa));
|
||||
memset(bufb, 'b', sizeof(bufb));
|
||||
|
||||
int a = utf8printf_wrapper(bufa, sizeof(bufa), "foobar %c %d", x, fourtytwo);
|
||||
int a = utf8printf(bufa, sizeof(bufa), "foobar %c %d", x, fourtytwo);
|
||||
int b = snprintf(bufb, sizeof(bufb), "foobar %c %d", x, fourtytwo);
|
||||
|
||||
CHECK(a == sizeof(bufa) - 1);
|
||||
@@ -1556,7 +1556,7 @@ TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
|
||||
memset(bufa, 'a', sizeof(bufa));
|
||||
memset(bufb, 'b', sizeof(bufb));
|
||||
|
||||
int a = utf8printf_wrapper(bufa, sizeof(bufa), "foobar %c %d", x, fourtytwo);
|
||||
int a = utf8printf(bufa, sizeof(bufa), "foobar %c %d", x, fourtytwo);
|
||||
int b = snprintf(bufb, sizeof(bufb), "foobar %c %d", x, fourtytwo);
|
||||
|
||||
CHECK(a == sizeof(bufa));
|
||||
@@ -1585,7 +1585,7 @@ TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
|
||||
memset(bufa, 'a', sizeof(bufa));
|
||||
memset(bufb, 'b', sizeof(bufb));
|
||||
|
||||
int a = utf8printf_wrapper(bufa, sizeof(bufa), "foobar %c %d", x, fourtytwo);
|
||||
int a = utf8printf(bufa, sizeof(bufa), "foobar %c %d", x, fourtytwo);
|
||||
int b = snprintf(bufb, sizeof(bufb), "foobar %c %d", x, fourtytwo);
|
||||
|
||||
CHECK(a == 11);
|
||||
|
||||
Reference in New Issue
Block a user