Simplify {vulkan,dx12,xaudio}_check macro (#1015)
This changes `vulkan_check` and other macros to directly take the call to be executed. It will execute it and check the result, if it's not successful, it will log an error with the function name. It also returns the result code, allowing further processing.
This commit is contained in:
+57
-66
@@ -31,7 +31,9 @@ static constexpr T AlignTo(T value, T alignment)
|
||||
#define fourccXWMA 'AMWX'
|
||||
#define fourccDPDS 'sdpd'
|
||||
|
||||
#define xaudio_check(hr) wilog_assert(SUCCEEDED(hr), "XAudio2 error: %s, line %d, hr = %s", relative_path(__FILE__), __LINE__, wi::helper::GetPlatformErrorString(hr).c_str())
|
||||
#define xaudio_assert(cond, fname) { wilog_assert(cond, "XAudio2 error: %s failed with %s (%s:%d)", fname, wi::helper::GetPlatformErrorString(hr), relative_path(__FILE__), __LINE__); }
|
||||
|
||||
#define xaudio_check(call) [&]() { HRESULT hr = call; char buf[256]; xaudio_assert(SUCCEEDED(hr), wi::backlog::internal::extract_function_name(buf, #call)); return hr; }()
|
||||
|
||||
namespace wi::audio
|
||||
{
|
||||
@@ -87,17 +89,15 @@ namespace wi::audio
|
||||
wi::Timer timer;
|
||||
|
||||
HRESULT hr;
|
||||
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
hr = xaudio_check(CoInitializeEx(NULL, COINIT_MULTITHREADED));
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
wilog_error("XAudio2: CoInitializeEx returned error: %s", wi::helper::GetPlatformErrorString(hr).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
hr = XAudio2Create(&audioEngine, 0, XAUDIO2_USE_DEFAULT_PROCESSOR);
|
||||
hr = xaudio_check(XAudio2Create(&audioEngine, 0, XAUDIO2_USE_DEFAULT_PROCESSOR));
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
wilog_error("XAudio2: XAudio2Create returned error: %s", wi::helper::GetPlatformErrorString(hr).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -108,10 +108,9 @@ namespace wi::audio
|
||||
audioEngine->SetDebugConfiguration(&debugConfig);
|
||||
#endif // _DEBUG
|
||||
|
||||
hr = audioEngine->CreateMasteringVoice(&masteringVoice);
|
||||
hr = xaudio_check(audioEngine->CreateMasteringVoice(&masteringVoice));
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
wilog_error("XAudio2: CreateMasteringVoice returned error: %s", wi::helper::GetPlatformErrorString(hr).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -123,7 +122,7 @@ namespace wi::audio
|
||||
|
||||
for (int i = 0; i < SUBMIX_TYPE_COUNT; ++i)
|
||||
{
|
||||
hr = audioEngine->CreateSubmixVoice(
|
||||
hr = xaudio_check(audioEngine->CreateSubmixVoice(
|
||||
&submixVoices[i],
|
||||
masteringVoiceDetails.InputChannels,
|
||||
masteringVoiceDetails.InputSampleRate,
|
||||
@@ -131,36 +130,33 @@ namespace wi::audio
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
));
|
||||
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
wilog_error("XAudio2: CreateSubmixVoice returned error: %s", wi::helper::GetPlatformErrorString(hr).c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD channelMask;
|
||||
masteringVoice->GetChannelMask(&channelMask);
|
||||
hr = X3DAudioInitialize(channelMask, X3DAUDIO_SPEED_OF_SOUND, audio3D);
|
||||
hr = xaudio_check(X3DAudioInitialize(channelMask, X3DAUDIO_SPEED_OF_SOUND, audio3D));
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
wilog_error("XAudio2: X3DAudioInitialize returned error: %s", wi::helper::GetPlatformErrorString(hr).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Reverb setup:
|
||||
{
|
||||
hr = XAudio2CreateReverb(&reverbEffect);
|
||||
hr = xaudio_check(XAudio2CreateReverb(&reverbEffect));
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
wilog_error("XAudio2: XAudio2CreateReverb returned error: %s", wi::helper::GetPlatformErrorString(hr).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
XAUDIO2_EFFECT_DESCRIPTOR effects[] = { { reverbEffect.Get(), TRUE, 1 } };
|
||||
XAUDIO2_EFFECT_CHAIN effectChain = { arraysize(effects), effects };
|
||||
hr = audioEngine->CreateSubmixVoice(
|
||||
hr = xaudio_check(audioEngine->CreateSubmixVoice(
|
||||
&reverbSubmix,
|
||||
1, // reverb is mono
|
||||
masteringVoiceDetails.InputSampleRate,
|
||||
@@ -168,19 +164,17 @@ namespace wi::audio
|
||||
0,
|
||||
nullptr,
|
||||
&effectChain
|
||||
);
|
||||
));
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
wilog_error("XAudio2: CreateSubmixVoice returned error: %s", wi::helper::GetPlatformErrorString(hr).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
XAUDIO2FX_REVERB_PARAMETERS native;
|
||||
ReverbConvertI3DL2ToNative(&reverbPresets[REVERB_PRESET_DEFAULT], &native);
|
||||
HRESULT hr = reverbSubmix->SetEffectParameters(0, &native, sizeof(native));
|
||||
HRESULT hr = xaudio_check(reverbSubmix->SetEffectParameters(0, &native, sizeof(native)));
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
wilog_error("XAudio2: SetEffectParameters returned error: %s", wi::helper::GetPlatformErrorString(hr).c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -443,18 +437,18 @@ namespace wi::audio
|
||||
instanceinternal->audio = audio_internal;
|
||||
instanceinternal->soundinternal = soundinternal;
|
||||
|
||||
XAUDIO2_SEND_DESCRIPTOR SFXSend[] = {
|
||||
XAUDIO2_SEND_DESCRIPTOR SFXSend[] = {
|
||||
{ XAUDIO2_SEND_USEFILTER, instanceinternal->audio->submixVoices[instance->type] },
|
||||
{ XAUDIO2_SEND_USEFILTER, instanceinternal->audio->reverbSubmix }, // this should be last to enable/disable reverb simply
|
||||
};
|
||||
XAUDIO2_VOICE_SENDS SFXSendList = {
|
||||
XAUDIO2_VOICE_SENDS SFXSendList = {
|
||||
(instance->IsEnableReverb() && instanceinternal->audio->reverbSubmix != nullptr) ? (uint32_t)arraysize(SFXSend) : 1,
|
||||
SFXSend
|
||||
SFXSend
|
||||
};
|
||||
|
||||
hr = instanceinternal->audio->audioEngine->CreateSourceVoice(&instanceinternal->sourceVoice, &soundinternal->wfx,
|
||||
0, XAUDIO2_DEFAULT_FREQ_RATIO, instanceinternal.get(), &SFXSendList, NULL);
|
||||
xaudio_check(hr);
|
||||
hr = xaudio_check(instanceinternal->audio->audioEngine->CreateSourceVoice(&instanceinternal->sourceVoice, &soundinternal->wfx,
|
||||
0, XAUDIO2_DEFAULT_FREQ_RATIO, instanceinternal.get(), &SFXSendList, NULL));
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return false;
|
||||
@@ -494,8 +488,8 @@ namespace wi::audio
|
||||
instanceinternal->buffer.Flags = XAUDIO2_END_OF_STREAM;
|
||||
instanceinternal->buffer.LoopCount = instance->IsLooped() ? XAUDIO2_LOOP_INFINITE : 0;
|
||||
|
||||
hr = instanceinternal->sourceVoice->SubmitSourceBuffer(&instanceinternal->buffer);
|
||||
xaudio_check(hr);
|
||||
hr = xaudio_check(instanceinternal->sourceVoice->SubmitSourceBuffer(&instanceinternal->buffer));
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return false;
|
||||
@@ -508,8 +502,8 @@ namespace wi::audio
|
||||
if (instance != nullptr && instance->IsValid())
|
||||
{
|
||||
auto instanceinternal = to_internal(instance);
|
||||
HRESULT hr = instanceinternal->sourceVoice->Start();
|
||||
xaudio_check(hr);
|
||||
xaudio_check(instanceinternal->sourceVoice->Start());
|
||||
|
||||
}
|
||||
}
|
||||
void Pause(SoundInstance* instance)
|
||||
@@ -517,8 +511,8 @@ namespace wi::audio
|
||||
if (instance != nullptr && instance->IsValid())
|
||||
{
|
||||
auto instanceinternal = to_internal(instance);
|
||||
HRESULT hr = instanceinternal->sourceVoice->Stop(); // preserves cursor position
|
||||
xaudio_check(hr);
|
||||
xaudio_check(instanceinternal->sourceVoice->Stop()); // preserves cursor position
|
||||
|
||||
}
|
||||
}
|
||||
void Stop(SoundInstance* instance)
|
||||
@@ -526,31 +520,31 @@ namespace wi::audio
|
||||
if (instance != nullptr && instance->IsValid())
|
||||
{
|
||||
auto instanceinternal = to_internal(instance);
|
||||
HRESULT hr = instanceinternal->sourceVoice->Stop(); // preserves cursor position
|
||||
xaudio_check(hr);
|
||||
hr = instanceinternal->sourceVoice->FlushSourceBuffers(); // reset submitted audio buffer
|
||||
xaudio_check(hr);
|
||||
xaudio_check(instanceinternal->sourceVoice->Stop()); // preserves cursor position
|
||||
|
||||
xaudio_check(instanceinternal->sourceVoice->FlushSourceBuffers()); // reset submitted audio buffer
|
||||
|
||||
if (!instanceinternal->ended) // if already ended, don't submit end again, it can cause high pitched jerky sound
|
||||
{
|
||||
hr = instanceinternal->sourceVoice->SubmitSourceBuffer(&audio_internal->termination_mark); // mark this as terminated, this resets XAUDIO2_VOICE_STATE::SamplesPlayed to zero
|
||||
xaudio_check(hr);
|
||||
xaudio_check(instanceinternal->sourceVoice->SubmitSourceBuffer(&audio_internal->termination_mark)); // mark this as terminated, this resets XAUDIO2_VOICE_STATE::SamplesPlayed to zero
|
||||
|
||||
}
|
||||
hr = instanceinternal->sourceVoice->SubmitSourceBuffer(&instanceinternal->buffer); // resubmit
|
||||
xaudio_check(hr);
|
||||
xaudio_check(instanceinternal->sourceVoice->SubmitSourceBuffer(&instanceinternal->buffer)); // resubmit
|
||||
|
||||
}
|
||||
}
|
||||
void SetVolume(float volume, SoundInstance* instance)
|
||||
{
|
||||
if (instance == nullptr || !instance->IsValid())
|
||||
{
|
||||
HRESULT hr = audio_internal->masteringVoice->SetVolume(volume);
|
||||
xaudio_check(hr);
|
||||
xaudio_check(audio_internal->masteringVoice->SetVolume(volume));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
auto instanceinternal = to_internal(instance);
|
||||
HRESULT hr = instanceinternal->sourceVoice->SetVolume(volume);
|
||||
xaudio_check(hr);
|
||||
xaudio_check(instanceinternal->sourceVoice->SetVolume(volume));
|
||||
|
||||
}
|
||||
}
|
||||
float GetVolume(const SoundInstance* instance)
|
||||
@@ -574,13 +568,13 @@ namespace wi::audio
|
||||
auto instanceinternal = to_internal(instance);
|
||||
if (instanceinternal->buffer.LoopCount == 0)
|
||||
return;
|
||||
HRESULT hr = instanceinternal->sourceVoice->ExitLoop();
|
||||
xaudio_check(hr);
|
||||
xaudio_check(instanceinternal->sourceVoice->ExitLoop());
|
||||
|
||||
if (instanceinternal->ended)
|
||||
{
|
||||
instanceinternal->buffer.LoopCount = 0;
|
||||
hr = instanceinternal->sourceVoice->SubmitSourceBuffer(&instanceinternal->buffer);
|
||||
xaudio_check(hr);
|
||||
xaudio_check(instanceinternal->sourceVoice->SubmitSourceBuffer(&instanceinternal->buffer));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -621,8 +615,8 @@ namespace wi::audio
|
||||
|
||||
void SetSubmixVolume(SUBMIX_TYPE type, float volume)
|
||||
{
|
||||
HRESULT hr = audio_internal->submixVoices[type]->SetVolume(volume);
|
||||
xaudio_check(hr);
|
||||
xaudio_check(audio_internal->submixVoices[type]->SetVolume(volume));
|
||||
|
||||
}
|
||||
float GetSubmixVolume(SUBMIX_TYPE type)
|
||||
{
|
||||
@@ -674,30 +668,27 @@ namespace wi::audio
|
||||
|
||||
X3DAudioCalculate(instanceinternal->audio->audio3D, &listener, &emitter, flags, &settings);
|
||||
|
||||
HRESULT hr;
|
||||
xaudio_check(instanceinternal->sourceVoice->SetFrequencyRatio(settings.DopplerFactor));
|
||||
|
||||
hr = instanceinternal->sourceVoice->SetFrequencyRatio(settings.DopplerFactor);
|
||||
xaudio_check(hr);
|
||||
|
||||
hr = instanceinternal->sourceVoice->SetOutputMatrix(
|
||||
xaudio_check(instanceinternal->sourceVoice->SetOutputMatrix(
|
||||
instanceinternal->audio->submixVoices[instance->type],
|
||||
settings.SrcChannelCount,
|
||||
settings.DstChannelCount,
|
||||
settings.SrcChannelCount,
|
||||
settings.DstChannelCount,
|
||||
settings.pMatrixCoefficients
|
||||
);
|
||||
xaudio_check(hr);
|
||||
));
|
||||
|
||||
|
||||
XAUDIO2_FILTER_PARAMETERS FilterParametersDirect = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI / 6.0f * settings.LPFDirectCoefficient), 1.0f };
|
||||
hr = instanceinternal->sourceVoice->SetOutputFilterParameters(instanceinternal->audio->submixVoices[instance->type], &FilterParametersDirect);
|
||||
xaudio_check(hr);
|
||||
xaudio_check(instanceinternal->sourceVoice->SetOutputFilterParameters(instanceinternal->audio->submixVoices[instance->type], &FilterParametersDirect));
|
||||
|
||||
|
||||
if (instance->IsEnableReverb() && instanceinternal->audio->reverbSubmix != nullptr)
|
||||
{
|
||||
hr = instanceinternal->sourceVoice->SetOutputMatrix(instanceinternal->audio->reverbSubmix, settings.SrcChannelCount, 1, &settings.ReverbLevel);
|
||||
xaudio_check(hr);
|
||||
xaudio_check(instanceinternal->sourceVoice->SetOutputMatrix(instanceinternal->audio->reverbSubmix, settings.SrcChannelCount, 1, &settings.ReverbLevel));
|
||||
|
||||
XAUDIO2_FILTER_PARAMETERS FilterParametersReverb = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI / 6.0f * settings.LPFReverbCoefficient), 1.0f };
|
||||
hr = instanceinternal->sourceVoice->SetOutputFilterParameters(instanceinternal->audio->reverbSubmix, &FilterParametersReverb);
|
||||
xaudio_check(hr);
|
||||
xaudio_check(instanceinternal->sourceVoice->SetOutputFilterParameters(instanceinternal->audio->reverbSubmix, &FilterParametersReverb));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -706,8 +697,8 @@ namespace wi::audio
|
||||
{
|
||||
XAUDIO2FX_REVERB_PARAMETERS native;
|
||||
ReverbConvertI3DL2ToNative(&reverbPresets[preset], &native);
|
||||
HRESULT hr = audio_internal->reverbSubmix->SetEffectParameters(0, &native, sizeof(native));
|
||||
xaudio_check(hr);
|
||||
xaudio_check(audio_internal->reverbSubmix->SetEffectParameters(0, &native, sizeof(native)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,16 @@ using namespace std::chrono_literals;
|
||||
|
||||
namespace wi::backlog
|
||||
{
|
||||
namespace internal {
|
||||
char* extract_function_name(char* dst, const char* src)
|
||||
{
|
||||
int i = 0;
|
||||
while (src[i] != '(') i++;
|
||||
memcpy(dst, src, i);
|
||||
dst[i] = 0;
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
bool enabled = false;
|
||||
bool was_ever_enabled = enabled;
|
||||
struct LogEntry
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
namespace wi::backlog
|
||||
{
|
||||
namespace internal {
|
||||
// Used by various *_check macros
|
||||
char* extract_function_name(char* dst, const char* src);
|
||||
}
|
||||
|
||||
// Do not modify the order, as this is exposed to LUA scripts as int!
|
||||
enum class LogLevel
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,9 @@
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
#define dx12_check(hr) wilog_assert(SUCCEEDED(hr), "DX12 error: %s, line %d, hr = %s", relative_path(__FILE__), __LINE__, wi::helper::GetPlatformErrorString(hr).c_str())
|
||||
#define dx12_assert(cond, fname) { wilog_assert(cond, "DX 12 error: %s failed with %s (%s:%d)", fname, wi::helper::GetPlatformErrorString(hr), relative_path(__FILE__), __LINE__); }
|
||||
|
||||
#define dx12_check(call) [&]() { HRESULT hr = call; char buf[256]; dx12_assert(SUCCEEDED(hr), wi::backlog::internal::extract_function_name(buf, #call)); return hr; }()
|
||||
|
||||
namespace wi::graphics
|
||||
{
|
||||
@@ -141,8 +143,7 @@ namespace wi::graphics
|
||||
if (semaphore_pool.empty())
|
||||
{
|
||||
Semaphore& dependency = semaphore_pool.emplace_back();
|
||||
HRESULT hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, PPV_ARGS(dependency.fence));
|
||||
dx12_check(hr);
|
||||
dx12_check(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, PPV_ARGS(dependency.fence)));
|
||||
}
|
||||
Semaphore semaphore = std::move(semaphore_pool.back());
|
||||
semaphore_pool.pop_back();
|
||||
@@ -456,8 +457,7 @@ namespace wi::graphics
|
||||
{
|
||||
// Descriptor heaps' progress is recorded by the GPU:
|
||||
fenceValue = allocationOffset.load();
|
||||
HRESULT hr = queue->Signal(fence.Get(), fenceValue);
|
||||
dx12_check(hr);
|
||||
dx12_check(queue->Signal(fence.Get(), fenceValue));
|
||||
cached_completedValue = fence->GetCompletedValue();
|
||||
}
|
||||
};
|
||||
@@ -492,8 +492,7 @@ namespace wi::graphics
|
||||
void block_allocate()
|
||||
{
|
||||
heaps.emplace_back();
|
||||
HRESULT hr = device->device->CreateDescriptorHeap(&desc, PPV_ARGS(heaps.back()));
|
||||
dx12_check(hr);
|
||||
dx12_check(device->device->CreateDescriptorHeap(&desc, PPV_ARGS(heaps.back())));
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE heap_start = heaps.back()->GetCPUDescriptorHandleForHeapStart();
|
||||
for (UINT i = 0; i < desc.NumDescriptors; ++i)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,13 @@
|
||||
#include <mutex>
|
||||
#include <algorithm>
|
||||
|
||||
#define vulkan_check(res) wilog_assert(res == VK_SUCCESS, "Vulkan error: %s, line %d, result = %s", relative_path(__FILE__), __LINE__, string_VkResult(res))
|
||||
#define vulkan_assert(cond, fname) { wilog_assert(cond, "Vulkan error: %s failed with %s (%s:%d)", fname, string_VkResult(res), relative_path(__FILE__), __LINE__); }
|
||||
|
||||
#define vulkan_check_cond(cond, call) [&]() { VkResult res = call; char buf[256]; vulkan_assert(cond, wi::backlog::internal::extract_function_name(buf, #call)); return res; }()
|
||||
|
||||
#define vulkan_check(call) vulkan_check_cond(res == VK_SUCCESS, call)
|
||||
|
||||
#define vulkan_check_lenient(call) vulkan_check_cond(res >= VK_SUCCESS, call)
|
||||
|
||||
namespace wi::graphics
|
||||
{
|
||||
@@ -210,8 +216,7 @@ namespace wi::graphics
|
||||
VkSemaphore& sema = semaphore_pool.emplace_back();
|
||||
VkSemaphoreCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
VkResult res = vkCreateSemaphore(device, &info, nullptr, &sema);
|
||||
vulkan_check(res);
|
||||
vulkan_check(vkCreateSemaphore(device, &info, nullptr, &sema));
|
||||
}
|
||||
VkSemaphore semaphore = semaphore_pool.back();
|
||||
semaphore_pool.pop_back();
|
||||
@@ -505,8 +510,7 @@ namespace wi::graphics
|
||||
poolInfo.maxSets = 1;
|
||||
poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT;
|
||||
|
||||
VkResult res = vkCreateDescriptorPool(device->device, &poolInfo, nullptr, &descriptorPool);
|
||||
vulkan_check(res);
|
||||
vulkan_check(vkCreateDescriptorPool(device->device, &poolInfo, nullptr, &descriptorPool));
|
||||
|
||||
#if 0
|
||||
VkDebugUtilsObjectNameInfoEXT info{ VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT };
|
||||
@@ -541,16 +545,14 @@ namespace wi::graphics
|
||||
bindingFlagsInfo.pBindingFlags = &bindingFlags;
|
||||
layoutInfo.pNext = &bindingFlagsInfo;
|
||||
|
||||
res = vkCreateDescriptorSetLayout(device->device, &layoutInfo, nullptr, &descriptorSetLayout);
|
||||
vulkan_check(res);
|
||||
vulkan_check(vkCreateDescriptorSetLayout(device->device, &layoutInfo, nullptr, &descriptorSetLayout));
|
||||
|
||||
VkDescriptorSetAllocateInfo allocInfo = {};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
allocInfo.descriptorPool = descriptorPool;
|
||||
allocInfo.descriptorSetCount = 1;
|
||||
allocInfo.pSetLayouts = &descriptorSetLayout;
|
||||
res = vkAllocateDescriptorSets(device->device, &allocInfo, &descriptorSet);
|
||||
vulkan_check(res);
|
||||
vulkan_check(vkAllocateDescriptorSets(device->device, &allocInfo, &descriptorSet));
|
||||
|
||||
for (int i = 0; i < (int)descriptorCount; ++i)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user