mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-24 07:40:22 +01:00
Merged 13 commits.
This commit is contained in:
parent
4ce6bd8cff
commit
83bdfef8e0
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2021-05-16: Update to latest WebGPU specs (compatible with Emscripten 2.0.20 and Chrome Canary 92).
|
||||||
// 2021-02-18: Change blending equation to preserve alpha in output buffer.
|
// 2021-02-18: Change blending equation to preserve alpha in output buffer.
|
||||||
// 2021-01-28: Initial version.
|
// 2021-01-28: Initial version.
|
||||||
|
|
||||||
@ -22,11 +23,16 @@
|
|||||||
|
|
||||||
#define HAS_EMSCRIPTEN_VERSION(major, minor, tiny) (__EMSCRIPTEN_major__ > (major) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ > (minor)) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ == (minor) && __EMSCRIPTEN_tiny__ >= (tiny)))
|
#define HAS_EMSCRIPTEN_VERSION(major, minor, tiny) (__EMSCRIPTEN_major__ > (major) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ > (minor)) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ == (minor) && __EMSCRIPTEN_tiny__ >= (tiny)))
|
||||||
|
|
||||||
|
#if defined(__EMSCRIPTEN__) && !HAS_EMSCRIPTEN_VERSION(2, 0, 20)
|
||||||
|
#error "Requires at least emscripten 2.0.20"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Dear ImGui prototypes from imgui_internal.h
|
// Dear ImGui prototypes from imgui_internal.h
|
||||||
extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed = 0);
|
extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed = 0);
|
||||||
|
|
||||||
// WebGPU data
|
// WebGPU data
|
||||||
static WGPUDevice g_wgpuDevice = NULL;
|
static WGPUDevice g_wgpuDevice = NULL;
|
||||||
|
static WGPUQueue g_defaultQueue = NULL;
|
||||||
static WGPUTextureFormat g_renderTargetFormat = WGPUTextureFormat_Undefined;
|
static WGPUTextureFormat g_renderTargetFormat = WGPUTextureFormat_Undefined;
|
||||||
static WGPURenderPipeline g_pipelineState = NULL;
|
static WGPURenderPipeline g_pipelineState = NULL;
|
||||||
|
|
||||||
@ -37,9 +43,9 @@ struct RenderResources
|
|||||||
WGPUSampler Sampler; // Sampler for the font texture
|
WGPUSampler Sampler; // Sampler for the font texture
|
||||||
WGPUBuffer Uniforms; // Shader uniforms
|
WGPUBuffer Uniforms; // Shader uniforms
|
||||||
WGPUBindGroup CommonBindGroup; // Resources bind-group to bind the common resources to pipeline
|
WGPUBindGroup CommonBindGroup; // Resources bind-group to bind the common resources to pipeline
|
||||||
WGPUBindGroupLayout ImageBindGroupLayout; // Bind group layout for image textures
|
|
||||||
ImGuiStorage ImageBindGroups; // Resources bind-group to bind the font/image resources to pipeline (this is a key->value map)
|
ImGuiStorage ImageBindGroups; // Resources bind-group to bind the font/image resources to pipeline (this is a key->value map)
|
||||||
WGPUBindGroup ImageBindGroup; // Default font-resource of Dear ImGui
|
WGPUBindGroup ImageBindGroup; // Default font-resource of Dear ImGui
|
||||||
|
WGPUBindGroupLayout ImageBindGroupLayout; // Cache layout used for the image bind group. Avoids allocating unnecessary JS objects when working with WebASM
|
||||||
};
|
};
|
||||||
static RenderResources g_resources;
|
static RenderResources g_resources;
|
||||||
|
|
||||||
@ -241,8 +247,8 @@ static void SafeRelease(RenderResources& res)
|
|||||||
SafeRelease(res.Sampler);
|
SafeRelease(res.Sampler);
|
||||||
SafeRelease(res.Uniforms);
|
SafeRelease(res.Uniforms);
|
||||||
SafeRelease(res.CommonBindGroup);
|
SafeRelease(res.CommonBindGroup);
|
||||||
SafeRelease(res.ImageBindGroupLayout);
|
|
||||||
SafeRelease(res.ImageBindGroup);
|
SafeRelease(res.ImageBindGroup);
|
||||||
|
SafeRelease(res.ImageBindGroupLayout);
|
||||||
};
|
};
|
||||||
|
|
||||||
static void SafeRelease(FrameResources& res)
|
static void SafeRelease(FrameResources& res)
|
||||||
@ -296,23 +302,21 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas
|
|||||||
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||||
};
|
};
|
||||||
wgpuQueueWriteBuffer(wgpuDeviceGetDefaultQueue(g_wgpuDevice), g_resources.Uniforms, 0, mvp, sizeof(mvp));
|
wgpuQueueWriteBuffer(g_defaultQueue, g_resources.Uniforms, 0, mvp, sizeof(mvp));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup viewport
|
// Setup viewport
|
||||||
wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->DisplaySize.x, draw_data->DisplaySize.y, 0, 1);
|
wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->DisplaySize.x, draw_data->DisplaySize.y, 0, 1);
|
||||||
|
|
||||||
// Bind shader and vertex buffers
|
// Bind shader and vertex buffers
|
||||||
unsigned int stride = sizeof(ImDrawVert);
|
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, 0);
|
||||||
unsigned int offset = 0;
|
wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, 0);
|
||||||
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, offset, fr->VertexBufferSize * stride);
|
|
||||||
wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, fr->IndexBufferSize * sizeof(ImDrawIdx));
|
|
||||||
wgpuRenderPassEncoderSetPipeline(ctx, g_pipelineState);
|
wgpuRenderPassEncoderSetPipeline(ctx, g_pipelineState);
|
||||||
wgpuRenderPassEncoderSetBindGroup(ctx, 0, g_resources.CommonBindGroup, 0, NULL);
|
wgpuRenderPassEncoderSetBindGroup(ctx, 0, g_resources.CommonBindGroup, 0, NULL);
|
||||||
|
|
||||||
// Setup blend factor
|
// Setup blend factor
|
||||||
WGPUColor blend_color = { 0.f, 0.f, 0.f, 0.f };
|
WGPUColor blend_color = { 0.f, 0.f, 0.f, 0.f };
|
||||||
wgpuRenderPassEncoderSetBlendColor(ctx, &blend_color);
|
wgpuRenderPassEncoderSetBlendConstant(ctx, &blend_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render function
|
// Render function
|
||||||
@ -331,7 +335,11 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||||||
// Create and grow vertex/index buffers if needed
|
// Create and grow vertex/index buffers if needed
|
||||||
if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount)
|
if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount)
|
||||||
{
|
{
|
||||||
SafeRelease(fr->VertexBuffer);
|
if (fr->VertexBuffer)
|
||||||
|
{
|
||||||
|
wgpuBufferDestroy(fr->VertexBuffer);
|
||||||
|
wgpuBufferRelease(fr->VertexBuffer);
|
||||||
|
}
|
||||||
SafeRelease(fr->VertexBufferHost);
|
SafeRelease(fr->VertexBufferHost);
|
||||||
fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||||
|
|
||||||
@ -351,7 +359,11 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||||||
}
|
}
|
||||||
if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount)
|
if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount)
|
||||||
{
|
{
|
||||||
SafeRelease(fr->IndexBuffer);
|
if (fr->IndexBuffer)
|
||||||
|
{
|
||||||
|
wgpuBufferDestroy(fr->IndexBuffer);
|
||||||
|
wgpuBufferRelease(fr->IndexBuffer);
|
||||||
|
}
|
||||||
SafeRelease(fr->IndexBufferHost);
|
SafeRelease(fr->IndexBufferHost);
|
||||||
fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||||
|
|
||||||
@ -383,8 +395,8 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||||||
}
|
}
|
||||||
int64_t vb_write_size = ((char*)vtx_dst - (char*)fr->VertexBufferHost + 3) & ~3;
|
int64_t vb_write_size = ((char*)vtx_dst - (char*)fr->VertexBufferHost + 3) & ~3;
|
||||||
int64_t ib_write_size = ((char*)idx_dst - (char*)fr->IndexBufferHost + 3) & ~3;
|
int64_t ib_write_size = ((char*)idx_dst - (char*)fr->IndexBufferHost + 3) & ~3;
|
||||||
wgpuQueueWriteBuffer(wgpuDeviceGetDefaultQueue(g_wgpuDevice), fr->VertexBuffer, 0, fr->VertexBufferHost, vb_write_size);
|
wgpuQueueWriteBuffer(g_defaultQueue, fr->VertexBuffer, 0, fr->VertexBufferHost, vb_write_size);
|
||||||
wgpuQueueWriteBuffer(wgpuDeviceGetDefaultQueue(g_wgpuDevice), fr->IndexBuffer, 0, fr->IndexBufferHost, ib_write_size);
|
wgpuQueueWriteBuffer(g_defaultQueue, fr->IndexBuffer, 0, fr->IndexBufferHost, ib_write_size);
|
||||||
|
|
||||||
// Setup desired render state
|
// Setup desired render state
|
||||||
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
|
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
|
||||||
@ -439,18 +451,6 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static WGPUBuffer ImGui_ImplWGPU_CreateBufferFromData(const WGPUDevice& device, const void* data, uint64_t size, WGPUBufferUsage usage)
|
|
||||||
{
|
|
||||||
WGPUBufferDescriptor descriptor = {};
|
|
||||||
descriptor.size = size;
|
|
||||||
descriptor.usage = usage | WGPUBufferUsage_CopyDst;
|
|
||||||
WGPUBuffer buffer = wgpuDeviceCreateBuffer(device, &descriptor);
|
|
||||||
|
|
||||||
WGPUQueue queue = wgpuDeviceGetDefaultQueue(g_wgpuDevice);
|
|
||||||
wgpuQueueWriteBuffer(queue, buffer, 0, data, size);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWGPU_CreateFontsTexture()
|
static void ImGui_ImplWGPU_CreateFontsTexture()
|
||||||
{
|
{
|
||||||
// Build texture atlas
|
// Build texture atlas
|
||||||
@ -466,7 +466,7 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
|
|||||||
tex_desc.dimension = WGPUTextureDimension_2D;
|
tex_desc.dimension = WGPUTextureDimension_2D;
|
||||||
tex_desc.size.width = width;
|
tex_desc.size.width = width;
|
||||||
tex_desc.size.height = height;
|
tex_desc.size.height = height;
|
||||||
tex_desc.size.depth = 1;
|
tex_desc.size.depthOrArrayLayers = 1;
|
||||||
tex_desc.sampleCount = 1;
|
tex_desc.sampleCount = 1;
|
||||||
tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
|
tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
|
||||||
tex_desc.mipLevelCount = 1;
|
tex_desc.mipLevelCount = 1;
|
||||||
@ -486,34 +486,17 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
|
|||||||
|
|
||||||
// Upload texture data
|
// Upload texture data
|
||||||
{
|
{
|
||||||
WGPUBuffer staging_buffer = ImGui_ImplWGPU_CreateBufferFromData(g_wgpuDevice, pixels, (uint32_t)(width * size_pp * height), WGPUBufferUsage_CopySrc);
|
WGPUImageCopyTexture dst_view = {};
|
||||||
|
dst_view.texture = g_resources.FontTexture;
|
||||||
WGPUBufferCopyView bufferCopyView = {};
|
dst_view.mipLevel = 0;
|
||||||
bufferCopyView.buffer = staging_buffer;
|
dst_view.origin = { 0, 0, 0 };
|
||||||
bufferCopyView.layout.offset = 0;
|
dst_view.aspect = WGPUTextureAspect_All;
|
||||||
bufferCopyView.layout.bytesPerRow = width * size_pp;
|
WGPUTextureDataLayout layout = {};
|
||||||
bufferCopyView.layout.rowsPerImage = height;
|
layout.offset = 0;
|
||||||
|
layout.bytesPerRow = width * size_pp;
|
||||||
WGPUTextureCopyView textureCopyView = {};
|
layout.rowsPerImage = height;
|
||||||
textureCopyView.texture = g_resources.FontTexture;
|
WGPUExtent3D size = { static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1 };
|
||||||
textureCopyView.mipLevel = 0;
|
wgpuQueueWriteTexture(g_defaultQueue, &dst_view, pixels, (uint32_t)(width * size_pp * height), &layout, &size);
|
||||||
textureCopyView.origin = { 0, 0, 0 };
|
|
||||||
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
|
|
||||||
textureCopyView.aspect = WGPUTextureAspect_All;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WGPUExtent3D copySize = { (uint32_t)width, (uint32_t)height, 1 };
|
|
||||||
|
|
||||||
WGPUCommandEncoderDescriptor enc_desc = {};
|
|
||||||
WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(g_wgpuDevice, &enc_desc);
|
|
||||||
wgpuCommandEncoderCopyBufferToTexture(encoder, &bufferCopyView, &textureCopyView, ©Size);
|
|
||||||
WGPUCommandBufferDescriptor cmd_buf_desc = {};
|
|
||||||
WGPUCommandBuffer copy = wgpuCommandEncoderFinish(encoder, &cmd_buf_desc);
|
|
||||||
WGPUQueue queue = wgpuDeviceGetDefaultQueue(g_wgpuDevice);
|
|
||||||
wgpuQueueSubmit(queue, 1, ©);
|
|
||||||
|
|
||||||
wgpuCommandEncoderRelease(encoder);
|
|
||||||
wgpuBufferRelease(staging_buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the associated sampler
|
// Create the associated sampler
|
||||||
@ -525,9 +508,7 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
|
|||||||
sampler_desc.addressModeU = WGPUAddressMode_Repeat;
|
sampler_desc.addressModeU = WGPUAddressMode_Repeat;
|
||||||
sampler_desc.addressModeV = WGPUAddressMode_Repeat;
|
sampler_desc.addressModeV = WGPUAddressMode_Repeat;
|
||||||
sampler_desc.addressModeW = WGPUAddressMode_Repeat;
|
sampler_desc.addressModeW = WGPUAddressMode_Repeat;
|
||||||
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
|
|
||||||
sampler_desc.maxAnisotropy = 1;
|
sampler_desc.maxAnisotropy = 1;
|
||||||
#endif
|
|
||||||
g_resources.Sampler = wgpuDeviceCreateSampler(g_wgpuDevice, &sampler_desc);
|
g_resources.Sampler = wgpuDeviceCreateSampler(g_wgpuDevice, &sampler_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,139 +538,82 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
|||||||
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
||||||
|
|
||||||
// Create render pipeline
|
// Create render pipeline
|
||||||
WGPURenderPipelineDescriptor graphics_pipeline_desc = {};
|
WGPURenderPipelineDescriptor2 graphics_pipeline_desc = {};
|
||||||
graphics_pipeline_desc.primitiveTopology = WGPUPrimitiveTopology_TriangleList;
|
graphics_pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList;
|
||||||
graphics_pipeline_desc.sampleCount = 1;
|
graphics_pipeline_desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined;
|
||||||
graphics_pipeline_desc.sampleMask = UINT_MAX;
|
graphics_pipeline_desc.primitive.frontFace = WGPUFrontFace_CW;
|
||||||
|
graphics_pipeline_desc.primitive.cullMode = WGPUCullMode_None;
|
||||||
WGPUBindGroupLayoutEntry common_bg_layout_entries[2] = {};
|
graphics_pipeline_desc.multisample.count = 1;
|
||||||
common_bg_layout_entries[0].binding = 0;
|
graphics_pipeline_desc.multisample.mask = UINT_MAX;
|
||||||
common_bg_layout_entries[0].visibility = WGPUShaderStage_Vertex;
|
graphics_pipeline_desc.multisample.alphaToCoverageEnabled = false;
|
||||||
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
|
graphics_pipeline_desc.layout = nullptr; // Use automatic layout generation
|
||||||
common_bg_layout_entries[0].buffer.type = WGPUBufferBindingType_Uniform;
|
|
||||||
#else
|
|
||||||
common_bg_layout_entries[0].type = WGPUBindingType_UniformBuffer;
|
|
||||||
#endif
|
|
||||||
common_bg_layout_entries[1].binding = 1;
|
|
||||||
common_bg_layout_entries[1].visibility = WGPUShaderStage_Fragment;
|
|
||||||
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
|
|
||||||
common_bg_layout_entries[1].sampler.type = WGPUSamplerBindingType_Filtering;
|
|
||||||
#else
|
|
||||||
common_bg_layout_entries[1].type = WGPUBindingType_Sampler;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WGPUBindGroupLayoutEntry image_bg_layout_entries[1] = {};
|
|
||||||
image_bg_layout_entries[0].binding = 0;
|
|
||||||
image_bg_layout_entries[0].visibility = WGPUShaderStage_Fragment;
|
|
||||||
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
|
|
||||||
image_bg_layout_entries[0].texture.sampleType = WGPUTextureSampleType_Float;
|
|
||||||
image_bg_layout_entries[0].texture.viewDimension = WGPUTextureViewDimension_2D;
|
|
||||||
#else
|
|
||||||
image_bg_layout_entries[0].type = WGPUBindingType_SampledTexture;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WGPUBindGroupLayoutDescriptor common_bg_layout_desc = {};
|
|
||||||
common_bg_layout_desc.entryCount = 2;
|
|
||||||
common_bg_layout_desc.entries = common_bg_layout_entries;
|
|
||||||
|
|
||||||
WGPUBindGroupLayoutDescriptor image_bg_layout_desc = {};
|
|
||||||
image_bg_layout_desc.entryCount = 1;
|
|
||||||
image_bg_layout_desc.entries = image_bg_layout_entries;
|
|
||||||
|
|
||||||
WGPUBindGroupLayout bg_layouts[2];
|
|
||||||
bg_layouts[0] = wgpuDeviceCreateBindGroupLayout(g_wgpuDevice, &common_bg_layout_desc);
|
|
||||||
bg_layouts[1] = wgpuDeviceCreateBindGroupLayout(g_wgpuDevice, &image_bg_layout_desc);
|
|
||||||
|
|
||||||
WGPUPipelineLayoutDescriptor layout_desc = {};
|
|
||||||
layout_desc.bindGroupLayoutCount = 2;
|
|
||||||
layout_desc.bindGroupLayouts = bg_layouts;
|
|
||||||
graphics_pipeline_desc.layout = wgpuDeviceCreatePipelineLayout(g_wgpuDevice, &layout_desc);
|
|
||||||
|
|
||||||
// Create the vertex shader
|
// Create the vertex shader
|
||||||
WGPUProgrammableStageDescriptor vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_vert_spv, sizeof(__glsl_shader_vert_spv) / sizeof(uint32_t));
|
WGPUProgrammableStageDescriptor vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_vert_spv, sizeof(__glsl_shader_vert_spv) / sizeof(uint32_t));
|
||||||
graphics_pipeline_desc.vertexStage = vertex_shader_desc;
|
graphics_pipeline_desc.vertex.module = vertex_shader_desc.module;
|
||||||
|
graphics_pipeline_desc.vertex.entryPoint = vertex_shader_desc.entryPoint;
|
||||||
|
|
||||||
// Vertex input configuration
|
// Vertex input configuration
|
||||||
WGPUVertexAttributeDescriptor attribute_binding_desc[] =
|
WGPUVertexAttribute attribute_desc[] =
|
||||||
{
|
{
|
||||||
{ WGPUVertexFormat_Float2, (uint64_t)IM_OFFSETOF(ImDrawVert, pos), 0 },
|
{ WGPUVertexFormat_Float32x2, (uint64_t)IM_OFFSETOF(ImDrawVert, pos), 0 },
|
||||||
{ WGPUVertexFormat_Float2, (uint64_t)IM_OFFSETOF(ImDrawVert, uv), 1 },
|
{ WGPUVertexFormat_Float32x2, (uint64_t)IM_OFFSETOF(ImDrawVert, uv), 1 },
|
||||||
{ WGPUVertexFormat_UChar4Norm, (uint64_t)IM_OFFSETOF(ImDrawVert, col), 2 },
|
{ WGPUVertexFormat_Unorm8x4, (uint64_t)IM_OFFSETOF(ImDrawVert, col), 2 },
|
||||||
};
|
};
|
||||||
|
|
||||||
WGPUVertexBufferLayoutDescriptor buffer_binding_desc;
|
WGPUVertexBufferLayout buffer_layouts[1];
|
||||||
buffer_binding_desc.arrayStride = sizeof(ImDrawVert);
|
buffer_layouts[0].arrayStride = sizeof(ImDrawVert);
|
||||||
buffer_binding_desc.stepMode = WGPUInputStepMode_Vertex;
|
buffer_layouts[0].stepMode = WGPUInputStepMode_Vertex;
|
||||||
buffer_binding_desc.attributeCount = 3;
|
buffer_layouts[0].attributeCount = 3;
|
||||||
buffer_binding_desc.attributes = attribute_binding_desc;
|
buffer_layouts[0].attributes = attribute_desc;
|
||||||
|
|
||||||
WGPUVertexStateDescriptor vertex_state_desc = {};
|
graphics_pipeline_desc.vertex.bufferCount = 1;
|
||||||
vertex_state_desc.indexFormat = WGPUIndexFormat_Undefined;
|
graphics_pipeline_desc.vertex.buffers = buffer_layouts;
|
||||||
vertex_state_desc.vertexBufferCount = 1;
|
|
||||||
vertex_state_desc.vertexBuffers = &buffer_binding_desc;
|
|
||||||
|
|
||||||
graphics_pipeline_desc.vertexState = &vertex_state_desc;
|
|
||||||
|
|
||||||
// Create the pixel shader
|
// Create the pixel shader
|
||||||
WGPUProgrammableStageDescriptor pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_frag_spv, sizeof(__glsl_shader_frag_spv) / sizeof(uint32_t));
|
WGPUProgrammableStageDescriptor pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_frag_spv, sizeof(__glsl_shader_frag_spv) / sizeof(uint32_t));
|
||||||
graphics_pipeline_desc.fragmentStage = &pixel_shader_desc;
|
|
||||||
|
|
||||||
// Create the blending setup
|
// Create the blending setup
|
||||||
WGPUColorStateDescriptor color_state = {};
|
WGPUBlendState blend_state = {};
|
||||||
{
|
blend_state.alpha.operation = WGPUBlendOperation_Add;
|
||||||
|
blend_state.alpha.srcFactor = WGPUBlendFactor_One;
|
||||||
|
blend_state.alpha.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
|
||||||
|
blend_state.color.operation = WGPUBlendOperation_Add;
|
||||||
|
blend_state.color.srcFactor = WGPUBlendFactor_SrcAlpha;
|
||||||
|
blend_state.color.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
|
||||||
|
|
||||||
|
WGPUColorTargetState color_state = {};
|
||||||
color_state.format = g_renderTargetFormat;
|
color_state.format = g_renderTargetFormat;
|
||||||
color_state.alphaBlend.operation = WGPUBlendOperation_Add;
|
color_state.blend = &blend_state;
|
||||||
color_state.alphaBlend.srcFactor = WGPUBlendFactor_One;
|
|
||||||
color_state.alphaBlend.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
|
|
||||||
color_state.colorBlend.operation = WGPUBlendOperation_Add;
|
|
||||||
color_state.colorBlend.srcFactor = WGPUBlendFactor_SrcAlpha;
|
|
||||||
color_state.colorBlend.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
|
|
||||||
color_state.writeMask = WGPUColorWriteMask_All;
|
color_state.writeMask = WGPUColorWriteMask_All;
|
||||||
|
|
||||||
graphics_pipeline_desc.colorStateCount = 1;
|
WGPUFragmentState fragment_state = {};
|
||||||
graphics_pipeline_desc.colorStates = &color_state;
|
fragment_state.module = pixel_shader_desc.module;
|
||||||
graphics_pipeline_desc.alphaToCoverageEnabled = false;
|
fragment_state.entryPoint = pixel_shader_desc.entryPoint;
|
||||||
}
|
fragment_state.targetCount = 1;
|
||||||
|
fragment_state.targets = &color_state;
|
||||||
|
|
||||||
// Create the rasterizer state
|
graphics_pipeline_desc.fragment = &fragment_state;
|
||||||
WGPURasterizationStateDescriptor raster_desc = {};
|
|
||||||
{
|
|
||||||
raster_desc.cullMode = WGPUCullMode_None;
|
|
||||||
raster_desc.frontFace = WGPUFrontFace_CW;
|
|
||||||
raster_desc.depthBias = 0;
|
|
||||||
raster_desc.depthBiasClamp = 0;
|
|
||||||
raster_desc.depthBiasSlopeScale = 0;
|
|
||||||
graphics_pipeline_desc.rasterizationState = &raster_desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create depth-stencil State
|
// Create depth-stencil State
|
||||||
WGPUDepthStencilStateDescriptor depth_desc = {};
|
WGPUDepthStencilState depth_stencil_state = {};
|
||||||
{
|
depth_stencil_state.depthBias = 0;
|
||||||
// Configure disabled state
|
depth_stencil_state.depthBiasClamp = 0;
|
||||||
depth_desc.format = WGPUTextureFormat_Undefined;
|
depth_stencil_state.depthBiasSlopeScale = 0;
|
||||||
depth_desc.depthWriteEnabled = true;
|
|
||||||
depth_desc.depthCompare = WGPUCompareFunction_Always;
|
|
||||||
depth_desc.stencilReadMask = 0;
|
|
||||||
depth_desc.stencilWriteMask = 0;
|
|
||||||
depth_desc.stencilBack.compare = WGPUCompareFunction_Always;
|
|
||||||
depth_desc.stencilBack.failOp = WGPUStencilOperation_Keep;
|
|
||||||
depth_desc.stencilBack.depthFailOp = WGPUStencilOperation_Keep;
|
|
||||||
depth_desc.stencilBack.passOp = WGPUStencilOperation_Keep;
|
|
||||||
depth_desc.stencilFront.compare = WGPUCompareFunction_Always;
|
|
||||||
depth_desc.stencilFront.failOp = WGPUStencilOperation_Keep;
|
|
||||||
depth_desc.stencilFront.depthFailOp = WGPUStencilOperation_Keep;
|
|
||||||
depth_desc.stencilFront.passOp = WGPUStencilOperation_Keep;
|
|
||||||
|
|
||||||
// No depth buffer corresponds to no configuration
|
// Configure disabled depth-stencil state
|
||||||
graphics_pipeline_desc.depthStencilState = NULL;
|
graphics_pipeline_desc.depthStencil = nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
g_pipelineState = wgpuDeviceCreateRenderPipeline(g_wgpuDevice, &graphics_pipeline_desc);
|
g_pipelineState = wgpuDeviceCreateRenderPipeline2(g_wgpuDevice, &graphics_pipeline_desc);
|
||||||
|
|
||||||
ImGui_ImplWGPU_CreateFontsTexture();
|
ImGui_ImplWGPU_CreateFontsTexture();
|
||||||
ImGui_ImplWGPU_CreateUniformBuffer();
|
ImGui_ImplWGPU_CreateUniformBuffer();
|
||||||
|
|
||||||
// Create resource bind group
|
// Create resource bind group
|
||||||
|
WGPUBindGroupLayout bg_layouts[2];
|
||||||
|
bg_layouts[0] = wgpuRenderPipelineGetBindGroupLayout(g_pipelineState, 0);
|
||||||
|
bg_layouts[1] = wgpuRenderPipelineGetBindGroupLayout(g_pipelineState, 1);
|
||||||
|
|
||||||
WGPUBindGroupEntry common_bg_entries[] =
|
WGPUBindGroupEntry common_bg_entries[] =
|
||||||
{
|
{
|
||||||
{ 0, g_resources.Uniforms, 0, sizeof(Uniforms), 0, 0 },
|
{ 0, g_resources.Uniforms, 0, sizeof(Uniforms), 0, 0 },
|
||||||
@ -701,10 +625,10 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
|||||||
common_bg_descriptor.entryCount = sizeof(common_bg_entries) / sizeof(WGPUBindGroupEntry);
|
common_bg_descriptor.entryCount = sizeof(common_bg_entries) / sizeof(WGPUBindGroupEntry);
|
||||||
common_bg_descriptor.entries = common_bg_entries;
|
common_bg_descriptor.entries = common_bg_entries;
|
||||||
g_resources.CommonBindGroup = wgpuDeviceCreateBindGroup(g_wgpuDevice, &common_bg_descriptor);
|
g_resources.CommonBindGroup = wgpuDeviceCreateBindGroup(g_wgpuDevice, &common_bg_descriptor);
|
||||||
g_resources.ImageBindGroupLayout = bg_layouts[1];
|
|
||||||
|
|
||||||
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bg_layouts[1], g_resources.FontTextureView);
|
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bg_layouts[1], g_resources.FontTextureView);
|
||||||
g_resources.ImageBindGroup = image_bind_group;
|
g_resources.ImageBindGroup = image_bind_group;
|
||||||
|
g_resources.ImageBindGroupLayout = bg_layouts[1];
|
||||||
g_resources.ImageBindGroups.SetVoidPtr(ImHashData(&g_resources.FontTextureView, sizeof(ImTextureID)), image_bind_group);
|
g_resources.ImageBindGroups.SetVoidPtr(ImHashData(&g_resources.FontTextureView, sizeof(ImTextureID)), image_bind_group);
|
||||||
|
|
||||||
SafeRelease(vertex_shader_desc.module);
|
SafeRelease(vertex_shader_desc.module);
|
||||||
@ -737,6 +661,7 @@ bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextur
|
|||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
|
|
||||||
g_wgpuDevice = device;
|
g_wgpuDevice = device;
|
||||||
|
g_defaultQueue = wgpuDeviceGetQueue(g_wgpuDevice);
|
||||||
g_renderTargetFormat = rt_format;
|
g_renderTargetFormat = rt_format;
|
||||||
g_pFrameResources = new FrameResources[num_frames_in_flight];
|
g_pFrameResources = new FrameResources[num_frames_in_flight];
|
||||||
g_numFramesInFlight = num_frames_in_flight;
|
g_numFramesInFlight = num_frames_in_flight;
|
||||||
@ -747,9 +672,9 @@ bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextur
|
|||||||
g_resources.Sampler = NULL;
|
g_resources.Sampler = NULL;
|
||||||
g_resources.Uniforms = NULL;
|
g_resources.Uniforms = NULL;
|
||||||
g_resources.CommonBindGroup = NULL;
|
g_resources.CommonBindGroup = NULL;
|
||||||
g_resources.ImageBindGroupLayout = NULL;
|
|
||||||
g_resources.ImageBindGroups.Data.reserve(100);
|
g_resources.ImageBindGroups.Data.reserve(100);
|
||||||
g_resources.ImageBindGroup = NULL;
|
g_resources.ImageBindGroup = NULL;
|
||||||
|
g_resources.ImageBindGroupLayout = NULL;
|
||||||
|
|
||||||
// Create buffers with a default size (they will later be grown as needed)
|
// Create buffers with a default size (they will later be grown as needed)
|
||||||
for (int i = 0; i < num_frames_in_flight; i++)
|
for (int i = 0; i < num_frames_in_flight; i++)
|
||||||
@ -771,6 +696,7 @@ void ImGui_ImplWGPU_Shutdown()
|
|||||||
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
||||||
delete[] g_pFrameResources;
|
delete[] g_pFrameResources;
|
||||||
g_pFrameResources = NULL;
|
g_pFrameResources = NULL;
|
||||||
|
wgpuQueueRelease(g_defaultQueue);
|
||||||
g_wgpuDevice = NULL;
|
g_wgpuDevice = NULL;
|
||||||
g_numFramesInFlight = 0;
|
g_numFramesInFlight = 0;
|
||||||
g_frameIndex = UINT_MAX;
|
g_frameIndex = UINT_MAX;
|
||||||
|
@ -83,6 +83,7 @@ Other Changes:
|
|||||||
entering the rendering function. (#4045) [@Nemirtingas]
|
entering the rendering function. (#4045) [@Nemirtingas]
|
||||||
- Backends: Vulkan: Fix mapped memory Vulkan validation error when buffer sizes are not multiple of
|
- Backends: Vulkan: Fix mapped memory Vulkan validation error when buffer sizes are not multiple of
|
||||||
VkPhysicalDeviceLimits::nonCoherentAtomSize. (#3957) [@AgentX1994]
|
VkPhysicalDeviceLimits::nonCoherentAtomSize. (#3957) [@AgentX1994]
|
||||||
|
- Backends: WebGPU: Update to latest specs (Chrome Canary 92 and Emscripten 2.0.20). (#4116, #3632) [@bfierz, @Kangz]
|
||||||
- Backends: OpenGL3: Don't try to read GL_CLIP_ORIGIN unless we're OpenGL 4.5. (#3998, #2366, #2186) [@s7jones]
|
- Backends: OpenGL3: Don't try to read GL_CLIP_ORIGIN unless we're OpenGL 4.5. (#3998, #2366, #2186) [@s7jones]
|
||||||
- Examples: OpenGL: Add OpenGL ES 2.0 support to modern GL examples. (#2837, #3951) [@lethal-guitar, @hinxx]
|
- Examples: OpenGL: Add OpenGL ES 2.0 support to modern GL examples. (#2837, #3951) [@lethal-guitar, @hinxx]
|
||||||
- Examples: Vulkan: Rebuild swapchain on VK_SUBOPTIMAL_KHR. (#3881)
|
- Examples: Vulkan: Rebuild swapchain on VK_SUBOPTIMAL_KHR. (#3881)
|
||||||
|
@ -147,7 +147,7 @@ static void main_loop(void* window)
|
|||||||
wgpu_swap_chain_height = height;
|
wgpu_swap_chain_height = height;
|
||||||
|
|
||||||
WGPUSwapChainDescriptor swap_chain_desc = {};
|
WGPUSwapChainDescriptor swap_chain_desc = {};
|
||||||
swap_chain_desc.usage = WGPUTextureUsage_OutputAttachment;
|
swap_chain_desc.usage = WGPUTextureUsage_RenderAttachment;
|
||||||
swap_chain_desc.format = WGPUTextureFormat_RGBA8Unorm;
|
swap_chain_desc.format = WGPUTextureFormat_RGBA8Unorm;
|
||||||
swap_chain_desc.width = width;
|
swap_chain_desc.width = width;
|
||||||
swap_chain_desc.height = height;
|
swap_chain_desc.height = height;
|
||||||
@ -202,11 +202,11 @@ static void main_loop(void* window)
|
|||||||
// Rendering
|
// Rendering
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
|
||||||
WGPURenderPassColorAttachmentDescriptor color_attachments = {};
|
WGPURenderPassColorAttachment color_attachments = {};
|
||||||
color_attachments.loadOp = WGPULoadOp_Clear;
|
color_attachments.loadOp = WGPULoadOp_Clear;
|
||||||
color_attachments.storeOp = WGPUStoreOp_Store;
|
color_attachments.storeOp = WGPUStoreOp_Store;
|
||||||
color_attachments.clearColor = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
|
color_attachments.clearColor = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
|
||||||
color_attachments.attachment = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain);
|
color_attachments.view = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain);
|
||||||
WGPURenderPassDescriptor render_pass_desc = {};
|
WGPURenderPassDescriptor render_pass_desc = {};
|
||||||
render_pass_desc.colorAttachmentCount = 1;
|
render_pass_desc.colorAttachmentCount = 1;
|
||||||
render_pass_desc.colorAttachments = &color_attachments;
|
render_pass_desc.colorAttachments = &color_attachments;
|
||||||
@ -221,7 +221,7 @@ static void main_loop(void* window)
|
|||||||
|
|
||||||
WGPUCommandBufferDescriptor cmd_buffer_desc = {};
|
WGPUCommandBufferDescriptor cmd_buffer_desc = {};
|
||||||
WGPUCommandBuffer cmd_buffer = wgpuCommandEncoderFinish(encoder, &cmd_buffer_desc);
|
WGPUCommandBuffer cmd_buffer = wgpuCommandEncoderFinish(encoder, &cmd_buffer_desc);
|
||||||
WGPUQueue queue = wgpuDeviceGetDefaultQueue(wgpu_device);
|
WGPUQueue queue = wgpuDeviceGetQueue(wgpu_device);
|
||||||
wgpuQueueSubmit(queue, 1, &cmd_buffer);
|
wgpuQueueSubmit(queue, 1, &cmd_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user