D3D12RenderState::D3D12RenderState() { views.clear(); scissors.clear(); rts.clear(); rtSingle = false; dsv = PortableHandle(); m_ResourceManager = NULL; heaps.clear(); pipe = graphics.rootsig = compute.rootsig = ResourceId(); graphics.sigelems.clear(); compute.sigelems.clear(); topo = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; stencilRef = 0; RDCEraseEl(blendFactor); RDCEraseEl(ibuffer); vbuffers.clear(); }
void D3D12Descriptor::Init(const D3D12_SAMPLER_DESC *pDesc) { if(pDesc) samp.desc = *pDesc; else RDCEraseEl(samp.desc); }
ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive) { ShaderDebugTrace ret; RDCEraseEl(ret); return ret; }
ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) { ShaderDebugTrace ret; RDCEraseEl(ret); return ret; }
Socket *CreateServerSocket(const char *bindaddr, uint16_t port, int queuesize) { SOCKET s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT); if(s == INVALID_SOCKET) return NULL; sockaddr_in addr; RDCEraseEl(addr); addr.sin_family = AF_INET; inet_pton(AF_INET, bindaddr, &addr.sin_addr); addr.sin_port = htons(port); int result = bind(s, (SOCKADDR *)&addr, sizeof(addr)); if(result == SOCKET_ERROR) { RDCWARN("Failed to bind to %s:%d - %d", bindaddr, port, WSAGetLastError()); closesocket(s); return NULL; } result = listen(s, queuesize); if(result == SOCKET_ERROR) { RDCWARN("Failed to listen on %s:%d - %d", bindaddr, port, WSAGetLastError()); closesocket(s); return NULL; } u_long nonblock = 1; ioctlsocket(s, FIONBIO, &nonblock); return new Socket((ptrdiff_t)s); }
ReplayOutput::ReplayOutput(ReplayRenderer *parent, void *w) { m_pRenderer = parent; m_MainOutput.dirty = true; m_OverlayDirty = true; m_pDevice = parent->GetDevice(); m_OverlayResourceId = ResourceId(); RDCEraseEl(m_RenderData); m_PixelContext.wndHandle = 0; m_PixelContext.outputID = 0; m_PixelContext.texture = ResourceId(); m_PixelContext.depthMode = false; m_ContextX = -1.0f; m_ContextY = -1.0f; m_Config.m_Type = eOutputType_None; if(w) m_MainOutput.outputID = m_pDevice->MakeOutputWindow(w, true); else m_MainOutput.outputID = 0; m_MainOutput.texture = ResourceId(); m_pDevice->GetOutputWindowDimensions(m_MainOutput.outputID, m_Width, m_Height); m_FirstDeferredEvent = 0; m_LastDeferredEvent = 0; m_CustomShaderResourceId = ResourceId(); }
ImageViewer(IReplayDriver *proxy, const char *filename) : m_Proxy(proxy), m_Filename(filename), m_TextureID() { if(m_Proxy == NULL) RDCERR("Unexpectedly NULL proxy at creation of ImageViewer"); m_Props.pipelineType = ePipelineState_D3D11; m_Props.degraded = false; m_FrameRecord.frameInfo.fileOffset = 0; m_FrameRecord.frameInfo.firstEvent = 1; m_FrameRecord.frameInfo.frameNumber = 1; m_FrameRecord.frameInfo.immContextId = ResourceId(); RDCEraseEl(m_FrameRecord.frameInfo.stats); create_array_uninit(m_FrameRecord.drawcallList, 1); FetchDrawcall &d = m_FrameRecord.drawcallList[0]; d.context = ResourceId(); d.drawcallID = 1; d.eventID = 1; d.name = filename; RefreshFile(); create_array_uninit(m_PipelineState.m_OM.RenderTargets, 1); m_PipelineState.m_OM.RenderTargets[0].Resource = m_TextureID; }
void Win32CallstackResolver::OpenPdblocateHandle() { STARTUPINFOW si; RDCEraseEl(si); PROCESS_INFORMATION pi; RDCEraseEl(pi); wchar_t locateCmd[128] = {0}; wcscpy_s(locateCmd, L"\".\\pdblocate\\pdblocate.exe\""); BOOL success = CreateProcessW(NULL, locateCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if(!success) return; Sleep(100); CloseHandle(pi.hThread); pdblocateProcess = pi.hProcess; pdblocatePipe = CreateFileW(L"\\\\.\\pipe\\RenderDoc.pdblocate", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if(pdblocatePipe == INVALID_HANDLE_VALUE) { RDCERR("Couldn't open pdblocate pipe"); CloseHandle(pdblocatePipe); pdblocatePipe = NULL; return; } DWORD mode = PIPE_READMODE_MESSAGE; success = SetNamedPipeHandleState(pdblocatePipe, &mode, NULL, NULL); if(!success) { RDCERR("Couldn't set pdblocate pipe to message mode"); CloseHandle(pdblocatePipe); pdblocatePipe = NULL; return; } }
void D3D12Descriptor::Init(ID3D12Resource *pResource, const D3D12_RENDER_TARGET_VIEW_DESC *pDesc) { nonsamp.type = TypeRTV; nonsamp.resource = pResource; if(pDesc) nonsamp.rtv = *pDesc; else RDCEraseEl(nonsamp.rtv); }
void D3D12Descriptor::Init(ID3D12Resource *pResource, const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc) { nonsamp.type = TypeSRV; nonsamp.resource = pResource; if(pDesc) nonsamp.srv = *pDesc; else RDCEraseEl(nonsamp.srv); }
void D3D12Descriptor::Init(const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc) { nonsamp.type = TypeCBV; nonsamp.resource = NULL; if(pDesc) nonsamp.cbv = *pDesc; else RDCEraseEl(nonsamp.cbv); }
PostVSMeshData GLReplay::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage) { PostVSMeshData ret; RDCEraseEl(ret); GLNOTIMP("GLReplay::GetPostVSBuffers"); return ret; }
void D3D12Descriptor::Init(ID3D12Resource *pResource, const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc) { nonsamp.type = TypeDSV; nonsamp.resource = pResource; if(pDesc) nonsamp.dsv = *pDesc; else RDCEraseEl(nonsamp.dsv); }
GLReplay::GLReplay() { m_pDriver = NULL; m_Proxy = false; RDCEraseEl(m_ReplayCtx); m_DebugCtx = NULL; m_OutputWindowID = 1; }
void D3D12Descriptor::Init(ID3D12Resource *pResource, ID3D12Resource *pCounterResource, const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc) { nonsamp.type = TypeUAV; nonsamp.resource = pResource; nonsamp.uav.counterResource = pCounterResource; if(pDesc) nonsamp.uav.desc.Init(*pDesc); else RDCEraseEl(nonsamp.uav.desc); }
OpenGLHook() { LibraryHooks::GetInstance().RegisterHook("libGL.so", this); RDCEraseEl(GL); m_GLDriver = NULL; m_EnabledHooks = true; m_PopulatedHooks = false; }
string GetReplayAppFilename() { HMODULE hModule = NULL; GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)&dllLocator, &hModule); wchar_t curFile[512] = {0}; GetModuleFileNameW(hModule, curFile, 511); string path = StringFormat::Wide2UTF8(wstring(curFile)); path = dirname(path); string exe = path + "/renderdocui.exe"; FILE *f = FileIO::fopen(exe.c_str(), "rb"); if(f) { FileIO::fclose(f); return exe; } // if renderdocui.exe doesn't live in the same dir, we must be in x86/ // so look one up the tree. exe = path + "/../renderdocui.exe"; f = FileIO::fopen(exe.c_str(), "rb"); if(f) { FileIO::fclose(f); return exe; } // if we didn't find the exe at all, we must not be in a standard // distributed renderdoc package. On windows we can check in the registry // to try and find the installed path. DWORD type = 0; DWORD dataSize = sizeof(curFile); RDCEraseEl(curFile); RegGetValueW(HKEY_CLASSES_ROOT, L"RenderDoc.RDCCapture.1\\DefaultIcon", NULL, RRF_RT_ANY, &type, (void *)curFile, &dataSize); if(type == REG_EXPAND_SZ || type == REG_SZ) { return StringFormat::Wide2UTF8(wstring(curFile)); } return ""; }
bool ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *ret) { if(ret == NULL || tex == ResourceId()) return false; RDCEraseEl(ret->value_f); bool decodeRamp = false; FormatComponentType typeHint = m_RenderData.texDisplay.typeHint; if(customShader && m_RenderData.texDisplay.CustomShader != ResourceId() && m_CustomShaderResourceId != ResourceId()) { tex = m_CustomShaderResourceId; typeHint = eCompType_None; } if((m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawDraw || m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawPass) && m_OverlayResourceId != ResourceId()) { decodeRamp = true; tex = m_OverlayResourceId; typeHint = eCompType_None; } m_pDevice->PickPixel(m_pDevice->GetLiveID(tex), x, y, sliceFace, mip, sample, typeHint, ret->value_f); if(decodeRamp) { for(size_t c = 0; c < ARRAY_COUNT(overdrawRamp); c++) { if(fabs(ret->value_f[0] - overdrawRamp[c].x) < 0.00005f && fabs(ret->value_f[1] - overdrawRamp[c].y) < 0.00005f && fabs(ret->value_f[2] - overdrawRamp[c].z) < 0.00005f) { ret->value_i[0] = (int32_t)c; ret->value_i[1] = 0; ret->value_i[2] = 0; ret->value_i[3] = 0; break; } } } return true; }
bool CreateHooks(const char *libName) { RDCEraseEl(GL); if(!m_EnabledHooks) return false; bool success = SetupHooks(); if(!success) return false; m_HasHooks = true; return true; }
ReplayOutput::ReplayOutput(ReplayRenderer *parent, WindowingSystem system, void *data, OutputType type) { m_pRenderer = parent; m_MainOutput.dirty = true; m_OverlayDirty = true; m_ForceOverlayRefresh = false; m_pDevice = parent->GetDevice(); m_EventID = parent->m_EventID; m_OverlayResourceId = ResourceId(); RDCEraseEl(m_RenderData); m_PixelContext.outputID = 0; m_PixelContext.texture = ResourceId(); m_PixelContext.depthMode = false; m_ContextX = -1.0f; m_ContextY = -1.0f; m_Config.m_Type = type; if(system != eWindowingSystem_Unknown) m_MainOutput.outputID = m_pDevice->MakeOutputWindow(system, data, type == eOutputType_MeshDisplay); else m_MainOutput.outputID = 0; m_MainOutput.texture = ResourceId(); m_pDevice->GetOutputWindowDimensions(m_MainOutput.outputID, m_Width, m_Height); m_FirstDeferredEvent = 0; m_LastDeferredEvent = 0; m_CustomShaderResourceId = ResourceId(); }
Socket *CreateServerSocket(const char *bindaddr, uint16_t port, int queuesize) { int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(s == -1) return NULL; sockaddr_in addr; RDCEraseEl(addr); hostent *hp = gethostbyname(bindaddr); addr.sin_family = AF_INET; memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); addr.sin_port = htons(port); int result = bind(s, (sockaddr *)&addr, sizeof(addr)); if(result == -1) { RDCWARN("Failed to bind to %s:%d - %d", bindaddr, port, errno); close(s); return NULL; } result = listen(s, queuesize); if(result == -1) { RDCWARN("Failed to listen on %s:%d - %d", bindaddr, port, errno); close(s); return NULL; } int flags = fcntl(s, F_GETFL, 0); fcntl(s, F_SETFL, flags | O_NONBLOCK); return new Socket((ptrdiff_t)s); }
void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkGraphicsPipelineCreateInfo* pCreateInfo) { flags = pCreateInfo->flags; layout = resourceMan->GetNonDispWrapper(pCreateInfo->layout)->id; renderpass = resourceMan->GetNonDispWrapper(pCreateInfo->renderPass)->id; subpass = pCreateInfo->subpass; // need to figure out which states are valid to be NULL // VkPipelineShaderStageCreateInfo for(uint32_t i=0; i < pCreateInfo->stageCount; i++) { ResourceId id = resourceMan->GetNonDispWrapper(pCreateInfo->pStages[i].module)->id; // convert shader bit to shader index int stageIndex = StageIndex(pCreateInfo->pStages[i].stage); Shader &shad = shaders[stageIndex]; shad.module = id; shad.entryPoint = pCreateInfo->pStages[i].pName; ShaderModule::Reflection &reflData = info.m_ShaderModule[id].m_Reflections[shad.entryPoint]; if(reflData.entryPoint.empty()) { reflData.entryPoint = shad.entryPoint; info.m_ShaderModule[id].spirv.MakeReflection(reflData.entryPoint, &reflData.refl, &reflData.mapping); } if(pCreateInfo->pStages[i].pSpecializationInfo) { shad.specdata.resize(pCreateInfo->pStages[i].pSpecializationInfo->dataSize); memcpy(&shad.specdata[0], pCreateInfo->pStages[i].pSpecializationInfo->pData, shad.specdata.size()); const VkSpecializationMapEntry *maps = pCreateInfo->pStages[i].pSpecializationInfo->pMapEntries; for(uint32_t s=0; s < pCreateInfo->pStages[i].pSpecializationInfo->mapEntryCount; s++) { Shader::SpecInfo spec; spec.specID = maps[s].constantID; spec.data = &shad.specdata[maps[s].offset]; spec.size = maps[s].size; // ignore maps[s].size, assume it's enough for the type shad.specialization.push_back(spec); } } shad.refl = &reflData.refl; shad.mapping = &reflData.mapping; } if(pCreateInfo->pVertexInputState) { vertexBindings.resize(pCreateInfo->pVertexInputState->vertexBindingDescriptionCount); for(uint32_t i=0; i < pCreateInfo->pVertexInputState->vertexBindingDescriptionCount; i++) { vertexBindings[i].vbufferBinding = pCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].binding; vertexBindings[i].bytestride = pCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].stride; vertexBindings[i].perInstance = pCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].inputRate == VK_VERTEX_INPUT_RATE_INSTANCE; } vertexAttrs.resize(pCreateInfo->pVertexInputState->vertexAttributeDescriptionCount); for(uint32_t i=0; i < pCreateInfo->pVertexInputState->vertexAttributeDescriptionCount; i++) { vertexAttrs[i].binding = pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].binding; vertexAttrs[i].location = pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].location; vertexAttrs[i].format = pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].format; vertexAttrs[i].byteoffset = pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].offset; } } topology = pCreateInfo->pInputAssemblyState->topology; primitiveRestartEnable = pCreateInfo->pInputAssemblyState->primitiveRestartEnable ? true : false; if(pCreateInfo->pTessellationState) patchControlPoints = pCreateInfo->pTessellationState->patchControlPoints; else patchControlPoints = 0; if(pCreateInfo->pViewportState) viewportCount = pCreateInfo->pViewportState->viewportCount; else viewportCount = 0; viewports.resize(viewportCount); scissors.resize(viewportCount); for(size_t i=0; i < viewports.size(); i++) { if(pCreateInfo->pViewportState->pViewports) viewports[i] = pCreateInfo->pViewportState->pViewports[i]; if(pCreateInfo->pViewportState->pScissors) scissors[i] = pCreateInfo->pViewportState->pScissors[i]; } // VkPipelineRasterStateCreateInfo depthClampEnable = pCreateInfo->pRasterizationState->depthClampEnable ? true : false; rasterizerDiscardEnable = pCreateInfo->pRasterizationState->rasterizerDiscardEnable ? true : false; polygonMode = pCreateInfo->pRasterizationState->polygonMode; cullMode = pCreateInfo->pRasterizationState->cullMode; frontFace = pCreateInfo->pRasterizationState->frontFace; depthBiasEnable = pCreateInfo->pRasterizationState->depthBiasEnable ? true : false; depthBiasConstantFactor = pCreateInfo->pRasterizationState->depthBiasConstantFactor; depthBiasClamp = pCreateInfo->pRasterizationState->depthBiasClamp; depthBiasSlopeFactor = pCreateInfo->pRasterizationState->depthBiasSlopeFactor; lineWidth = pCreateInfo->pRasterizationState->lineWidth; // VkPipelineMultisampleStateCreateInfo if(pCreateInfo->pMultisampleState) { rasterizationSamples = pCreateInfo->pMultisampleState->rasterizationSamples; sampleShadingEnable = pCreateInfo->pMultisampleState->sampleShadingEnable ? true : false; minSampleShading = pCreateInfo->pMultisampleState->minSampleShading; sampleMask = pCreateInfo->pMultisampleState->pSampleMask ? *pCreateInfo->pMultisampleState->pSampleMask : ~0U; alphaToCoverageEnable = pCreateInfo->pMultisampleState->alphaToCoverageEnable ? true : false; alphaToOneEnable = pCreateInfo->pMultisampleState->alphaToOneEnable ? true : false; } else { rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; sampleShadingEnable = false; minSampleShading = 1.0f; sampleMask = ~0U; alphaToCoverageEnable = false; alphaToOneEnable = false; } // VkPipelineDepthStencilStateCreateInfo if(pCreateInfo->pDepthStencilState) { depthTestEnable = pCreateInfo->pDepthStencilState->depthTestEnable ? true : false; depthWriteEnable = pCreateInfo->pDepthStencilState->depthWriteEnable ? true : false; depthCompareOp = pCreateInfo->pDepthStencilState->depthCompareOp; depthBoundsEnable = pCreateInfo->pDepthStencilState->depthBoundsTestEnable ? true : false; stencilTestEnable = pCreateInfo->pDepthStencilState->stencilTestEnable ? true : false; front = pCreateInfo->pDepthStencilState->front; back = pCreateInfo->pDepthStencilState->back; minDepthBounds = pCreateInfo->pDepthStencilState->minDepthBounds; maxDepthBounds = pCreateInfo->pDepthStencilState->maxDepthBounds; } else { depthTestEnable = false; depthWriteEnable = false; depthCompareOp = VK_COMPARE_OP_ALWAYS; depthBoundsEnable = false; stencilTestEnable = false; front.failOp = VK_STENCIL_OP_KEEP; front.passOp = VK_STENCIL_OP_KEEP; front.depthFailOp = VK_STENCIL_OP_KEEP; front.compareOp = VK_COMPARE_OP_ALWAYS; front.compareMask = 0xff; front.writeMask = 0xff; front.reference = 0; back = front; minDepthBounds = 0.0f; maxDepthBounds = 1.0f; } // VkPipelineColorBlendStateCreateInfo if(pCreateInfo->pColorBlendState) { logicOpEnable = pCreateInfo->pColorBlendState->logicOpEnable ? true : false; logicOp = pCreateInfo->pColorBlendState->logicOp; memcpy(blendConst, pCreateInfo->pColorBlendState->blendConstants, sizeof(blendConst)); attachments.resize(pCreateInfo->pColorBlendState->attachmentCount); for(uint32_t i=0; i < pCreateInfo->pColorBlendState->attachmentCount; i++) { attachments[i].blendEnable = pCreateInfo->pColorBlendState->pAttachments[i].blendEnable ? true : false; attachments[i].blend.Source = pCreateInfo->pColorBlendState->pAttachments[i].srcColorBlendFactor; attachments[i].blend.Destination = pCreateInfo->pColorBlendState->pAttachments[i].dstColorBlendFactor; attachments[i].blend.Operation = pCreateInfo->pColorBlendState->pAttachments[i].colorBlendOp; attachments[i].alphaBlend.Source = pCreateInfo->pColorBlendState->pAttachments[i].srcAlphaBlendFactor; attachments[i].alphaBlend.Destination = pCreateInfo->pColorBlendState->pAttachments[i].dstAlphaBlendFactor; attachments[i].alphaBlend.Operation = pCreateInfo->pColorBlendState->pAttachments[i].alphaBlendOp; attachments[i].channelWriteMask = (uint8_t)pCreateInfo->pColorBlendState->pAttachments[i].colorWriteMask; } } else { logicOpEnable = false; logicOp = VK_LOGIC_OP_NO_OP; RDCEraseEl(blendConst); attachments.clear(); } RDCEraseEl(dynamicStates); if(pCreateInfo->pDynamicState) { for(uint32_t i=0; i < pCreateInfo->pDynamicState->dynamicStateCount; i++) dynamicStates[ pCreateInfo->pDynamicState->pDynamicStates[i] ] = true; } }
void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkComputePipelineCreateInfo* pCreateInfo) { flags = pCreateInfo->flags; layout = resourceMan->GetNonDispWrapper(pCreateInfo->layout)->id; // need to figure out which states are valid to be NULL // VkPipelineShaderStageCreateInfo { ResourceId id = resourceMan->GetNonDispWrapper(pCreateInfo->stage.module)->id; Shader &shad = shaders[5]; // 5 is the compute shader's index (VS, TCS, TES, GS, FS, CS) shad.module = id; shad.entryPoint = pCreateInfo->stage.pName; ShaderModule::Reflection &reflData = info.m_ShaderModule[id].m_Reflections[shad.entryPoint]; if(reflData.entryPoint.empty()) { reflData.entryPoint = shad.entryPoint; info.m_ShaderModule[id].spirv.MakeReflection(reflData.entryPoint, &reflData.refl, &reflData.mapping); } if(pCreateInfo->stage.pSpecializationInfo) { shad.specdata.resize(pCreateInfo->stage.pSpecializationInfo->dataSize); memcpy(&shad.specdata[0], pCreateInfo->stage.pSpecializationInfo->pData, shad.specdata.size()); const VkSpecializationMapEntry *maps = pCreateInfo->stage.pSpecializationInfo->pMapEntries; for(uint32_t s=0; s < pCreateInfo->stage.pSpecializationInfo->mapEntryCount; s++) { Shader::SpecInfo spec; spec.specID = maps[s].constantID; spec.data = &shad.specdata[maps[s].offset]; spec.size = maps[s].size; shad.specialization.push_back(spec); } } shad.refl = &reflData.refl; shad.mapping = &reflData.mapping; } topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; primitiveRestartEnable = false; patchControlPoints = 0; viewportCount = 0; // VkPipelineRasterStateCreateInfo depthClampEnable = false; rasterizerDiscardEnable = false; polygonMode = VK_POLYGON_MODE_FILL; cullMode = VK_CULL_MODE_NONE; frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; // VkPipelineMultisampleStateCreateInfo rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; sampleShadingEnable = false; minSampleShading = 1.0f; sampleMask = ~0U; // VkPipelineDepthStencilStateCreateInfo depthTestEnable = false; depthWriteEnable = false; depthCompareOp = VK_COMPARE_OP_ALWAYS; depthBoundsEnable = false; stencilTestEnable = false; RDCEraseEl(front); RDCEraseEl(back); // VkPipelineColorBlendStateCreateInfo alphaToCoverageEnable = false; logicOpEnable = false; logicOp = VK_LOGIC_OP_NO_OP; }
ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) { ShaderDebugTrace ret; RDCEraseEl(ret); return ret; }
MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) { MeshFormat ret; RDCEraseEl(ret); return ret; }
void DescribeCounter(uint32_t counterID, CounterDescription &desc) { RDCEraseEl(desc); desc.counterID = counterID; }
FetchBuffer GetBuffer(ResourceId id) { FetchBuffer ret; RDCEraseEl(ret); return ret; }
ProgramUniformValue() { Type = eGL_NONE; Location = 0; RDCEraseEl(data); }
static BOOL WINAPI Hook_CreateProcessW( PFN_CREATE_PROCESS_W realFunc, __in_opt LPCWSTR lpApplicationName, __inout_opt LPWSTR lpCommandLine, __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in BOOL bInheritHandles, __in DWORD dwCreationFlags, __in_opt LPVOID lpEnvironment, __in_opt LPCWSTR lpCurrentDirectory, __in LPSTARTUPINFOW lpStartupInfo, __out LPPROCESS_INFORMATION lpProcessInformation) { PROCESS_INFORMATION dummy; RDCEraseEl(dummy); // not sure if this is valid, but I need the PID so I'll fill in my own struct to ensure that. if(lpProcessInformation == NULL) { lpProcessInformation = &dummy; } else { *lpProcessInformation = dummy; } dwCreationFlags |= CREATE_SUSPENDED; BOOL ret = realFunc(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); if(ret && RenderDoc::Inst().GetCaptureOptions().HookIntoChildren) { RDCDEBUG("Intercepting CreateProcessW"); bool inject = true; // sanity check to make sure we're not going to go into an infinity loop injecting into // ourselves. if(lpApplicationName) { wstring app = lpApplicationName; app = strlower(app); if(app.find(L"renderdoccmd.exe") != wstring::npos || app.find(L"renderdocui.vshost.exe") != wstring::npos || app.find(L"qrenderdoc.exe") != string::npos || app.find(L"renderdocui.exe") != wstring::npos) { inject = false; } } if(lpCommandLine) { wstring cmd = lpCommandLine; cmd = strlower(cmd); if(cmd.find(L"renderdoccmd.exe") != wstring::npos || cmd.find(L"renderdocui.vshost.exe") != wstring::npos || cmd.find(L"qrenderdoc.exe") != wstring::npos || cmd.find(L"renderdocui.exe") != wstring::npos) { inject = false; } } if(inject) { // inherit logfile and capture options uint32_t ident = RENDERDOC_InjectIntoProcess(lpProcessInformation->dwProcessId, NULL, RenderDoc::Inst().GetLogFile(), &RenderDoc::Inst().GetCaptureOptions(), false); RenderDoc::Inst().AddChildProcess((uint32_t)lpProcessInformation->dwProcessId, ident); } } ResumeThread(lpProcessInformation->hThread); // ensure we clean up after ourselves if(dummy.dwProcessId != 0) { CloseHandle(dummy.hProcess); CloseHandle(dummy.hThread); } return ret; }
bool write_dds_to_file(FILE *f, const dds_data &data) { if(!f) return false; uint32_t magic = dds_fourcc; DDS_HEADER header; DDS_HEADER_DXT10 headerDXT10; RDCEraseEl(header); RDCEraseEl(headerDXT10); header.dwSize = sizeof(DDS_HEADER); header.ddspf.dwSize = sizeof(DDS_PIXELFORMAT); header.dwWidth = data.width; header.dwHeight = data.height; header.dwDepth = data.depth; header.dwMipMapCount = data.mips; header.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; if(data.mips > 1) header.dwFlags |= DDSD_MIPMAPCOUNT; if(data.depth > 1) header.dwFlags |= DDSD_DEPTH; bool blockFormat = false; if(data.format.Special()) { switch(data.format.type) { case ResourceFormatType::BC1: case ResourceFormatType::BC2: case ResourceFormatType::BC3: case ResourceFormatType::BC4: case ResourceFormatType::BC5: case ResourceFormatType::BC6: case ResourceFormatType::BC7: blockFormat = true; break; case ResourceFormatType::ETC2: case ResourceFormatType::EAC: case ResourceFormatType::ASTC: case ResourceFormatType::YUV: RDCERR("Unsupported file format, %u", data.format.type); return false; default: break; } } if(blockFormat) header.dwFlags |= DDSD_LINEARSIZE; else header.dwFlags |= DDSD_PITCH; header.dwCaps = DDSCAPS_TEXTURE; if(data.mips > 1) header.dwCaps |= DDSCAPS_MIPMAP; if(data.mips > 1 || data.slices > 1 || data.depth > 1) header.dwCaps |= DDSCAPS_COMPLEX; header.dwCaps2 = data.depth > 1 ? DDSCAPS2_VOLUME : 0; bool dx10Header = false; headerDXT10.dxgiFormat = ResourceFormat2DXGIFormat(data.format); headerDXT10.resourceDimension = data.depth > 1 ? D3D10_RESOURCE_DIMENSION_TEXTURE3D : D3D10_RESOURCE_DIMENSION_TEXTURE2D; headerDXT10.miscFlag = 0; headerDXT10.arraySize = data.slices; if(headerDXT10.dxgiFormat == DXGI_FORMAT_UNKNOWN) { RDCERR("Couldn't convert resource format to DXGI format"); return false; } if(data.cubemap) { header.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES; headerDXT10.miscFlag |= DDS_RESOURCE_MISC_TEXTURECUBE; headerDXT10.arraySize /= 6; } if(headerDXT10.arraySize > 1) dx10Header = true; // need to specify dx10 header to give array size uint32_t bytesPerPixel = 1; if(blockFormat) { int blockSize = (data.format.type == ResourceFormatType::BC1 || data.format.type == ResourceFormatType::BC4) ? 8 : 16; header.dwPitchOrLinearSize = RDCMAX(1U, ((header.dwWidth + 3) / 4)) * blockSize; } else { switch(data.format.type) { case ResourceFormatType::S8: bytesPerPixel = 1; break; case ResourceFormatType::R10G10B10A2: case ResourceFormatType::R9G9B9E5: case ResourceFormatType::R11G11B10: case ResourceFormatType::D24S8: bytesPerPixel = 4; break; case ResourceFormatType::R5G6B5: case ResourceFormatType::R5G5B5A1: case ResourceFormatType::R4G4B4A4: bytesPerPixel = 2; break; case ResourceFormatType::D32S8: bytesPerPixel = 8; break; case ResourceFormatType::D16S8: case ResourceFormatType::YUV: case ResourceFormatType::R4G4: RDCERR("Unsupported file format %u", data.format.type); return false; default: bytesPerPixel = data.format.compCount * data.format.compByteWidth; } header.dwPitchOrLinearSize = header.dwWidth * bytesPerPixel; } // special case a couple of formats to write out non-DX10 style, for // backwards compatibility if(data.format.compByteWidth == 1 && data.format.compCount == 4 && data.format.compType == CompType::UNorm) { header.ddspf.dwFlags = DDPF_RGBA; header.ddspf.dwRGBBitCount = 32; header.ddspf.dwRBitMask = 0x000000ff; header.ddspf.dwGBitMask = 0x0000ff00; header.ddspf.dwBBitMask = 0x00ff0000; header.ddspf.dwABitMask = 0xff000000; if(data.format.bgraOrder) std::swap(header.ddspf.dwRBitMask, header.ddspf.dwBBitMask); } else if(data.format.type == ResourceFormatType::BC1) { header.ddspf.dwFlags = DDPF_FOURCC; header.ddspf.dwFourCC = MAKE_FOURCC('D', 'X', 'T', '1'); } else if(data.format.type == ResourceFormatType::BC2) { header.ddspf.dwFlags = DDPF_FOURCC; header.ddspf.dwFourCC = MAKE_FOURCC('D', 'X', 'T', '3'); } else if(data.format.type == ResourceFormatType::BC3) { header.ddspf.dwFlags = DDPF_FOURCC; header.ddspf.dwFourCC = MAKE_FOURCC('D', 'X', 'T', '5'); } else if(data.format.type == ResourceFormatType::BC4 && data.format.compType == CompType::UNorm) { header.ddspf.dwFlags = DDPF_FOURCC; header.ddspf.dwFourCC = MAKE_FOURCC('B', 'C', '4', 'U'); } else if(data.format.type == ResourceFormatType::BC4 && data.format.compType == CompType::SNorm) { header.ddspf.dwFlags = DDPF_FOURCC; header.ddspf.dwFourCC = MAKE_FOURCC('B', 'C', '4', 'S'); } else if(data.format.type == ResourceFormatType::BC5 && data.format.compType == CompType::UNorm) { header.ddspf.dwFlags = DDPF_FOURCC; header.ddspf.dwFourCC = MAKE_FOURCC('A', 'T', 'I', '2'); } else if(data.format.type == ResourceFormatType::BC5 && data.format.compType == CompType::SNorm) { header.ddspf.dwFlags = DDPF_FOURCC; header.ddspf.dwFourCC = MAKE_FOURCC('B', 'C', '5', 'S'); } else { // just write out DX10 header dx10Header = true; } if(dx10Header) { header.ddspf.dwFlags = DDPF_FOURCC; header.ddspf.dwFourCC = MAKE_FOURCC('D', 'X', '1', '0'); } { FileIO::fwrite(&magic, sizeof(magic), 1, f); FileIO::fwrite(&header, sizeof(header), 1, f); if(dx10Header) FileIO::fwrite(&headerDXT10, sizeof(headerDXT10), 1, f); int i = 0; for(int slice = 0; slice < RDCMAX(1, data.slices); slice++) { for(int mip = 0; mip < RDCMAX(1, data.mips); mip++) { int numdepths = RDCMAX(1, data.depth >> mip); for(int d = 0; d < numdepths; d++) { byte *bytedata = data.subdata[i]; int rowlen = RDCMAX(1, data.width >> mip); int numRows = RDCMAX(1, data.height >> mip); int pitch = RDCMAX(1U, rowlen * bytesPerPixel); // pitch/rows are in blocks, not pixels, for block formats. if(blockFormat) { numRows = RDCMAX(1, numRows / 4); int blockSize = (data.format.type == ResourceFormatType::BC1 || data.format.type == ResourceFormatType::BC4) ? 8 : 16; pitch = RDCMAX(blockSize, (((rowlen + 3) / 4)) * blockSize); } for(int row = 0; row < numRows; row++) { FileIO::fwrite(bytedata, 1, pitch, f); bytedata += pitch; } i++; } } } } return true; }