[General] Update to emscripten 4.0.13's emdawnwebgpu
[General] First triangle!
This commit is contained in:
parent
f1e3a25f3a
commit
cf374cd368
3 changed files with 28 additions and 17 deletions
|
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 4.0)
|
||||||
|
|
||||||
project(wgpu-wasm LANGUAGES C CXX)
|
project(wgpu-wasm LANGUAGES C CXX)
|
||||||
|
|
||||||
set(GLM_BUILD_LIBRARY FALSE)
|
set(GLM_BUILD_LIBRARY FALSE CACHE BOOL "")
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/contrib/glm)
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/contrib/glm)
|
||||||
|
|
||||||
add_custom_target(${CMAKE_PROJECT_NAME}_html COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/assets/index.html ${CMAKE_CURRENT_BINARY_DIR}/index.html
|
add_custom_target(${CMAKE_PROJECT_NAME}_html COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/assets/index.html ${CMAKE_CURRENT_BINARY_DIR}/index.html
|
||||||
|
|
@ -27,6 +27,7 @@ function(compile_and_package_shader SHADER_NAME TARGET)
|
||||||
#TODO: Add deptfile generation via slang for recompilation when embedded files change
|
#TODO: Add deptfile generation via slang for recompilation when embedded files change
|
||||||
add_dependencies(${TARGET} ${TARGET}_shader_${SHADER_NAME})
|
add_dependencies(${TARGET} ${TARGET}_shader_${SHADER_NAME})
|
||||||
target_link_options(${TARGET} PRIVATE --embed-file ${CMAKE_CURRENT_BINARY_DIR}/shaders/${SHADER_NAME}.wgsl@/shaders/${SHADER_NAME}.wgsl)
|
target_link_options(${TARGET} PRIVATE --embed-file ${CMAKE_CURRENT_BINARY_DIR}/shaders/${SHADER_NAME}.wgsl@/shaders/${SHADER_NAME}.wgsl)
|
||||||
|
set_target_properties(${TARGET} PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/shaders/${SHADER_NAME}.wgsl)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
compile_and_package_shader(shaders ${CMAKE_PROJECT_NAME})
|
compile_and_package_shader(shaders ${CMAKE_PROJECT_NAME})
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
struct STDVertex {
|
struct STDVertex {
|
||||||
float3 pos;
|
float3 pos;
|
||||||
float4 col;
|
float4 col;
|
||||||
|
|
@ -9,15 +8,17 @@ struct VertexOut {
|
||||||
float4 col;
|
float4 col;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct STDCamera {
|
struct STDCamera {
|
||||||
float4x4 mvp;
|
float4x4 mvp;
|
||||||
float3 position;
|
float3 position;
|
||||||
float3 direction;
|
float3 direction;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[vk::binding(0, 0)]
|
||||||
|
uniform ConstantBuffer<STDCamera> camera;
|
||||||
|
|
||||||
[shader("vertex")]
|
[shader("vertex")]
|
||||||
VertexOut vsMain(uint vertex_id: SV_VertexID, uint instance_id: SV_InstanceID, StructuredBuffer<STDVertex> vertices, uniform STDCamera camera) {
|
VertexOut vsMain(uint vertex_id: SV_VertexID, uint instance_id: SV_InstanceID, [vk::binding(1, 0)] StructuredBuffer<STDVertex> vertices) {
|
||||||
return VertexOut(mul(camera.mvp, float4(vertices[vertex_id].pos, 1.0)), vertices[vertex_id].col);
|
return VertexOut(mul(camera.mvp, float4(vertices[vertex_id].pos, 1.0)), vertices[vertex_id].col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
35
src/main.cpp
35
src/main.cpp
|
|
@ -1,16 +1,20 @@
|
||||||
#include "glm/ext/matrix_clip_space.hpp"
|
#include "glm/ext/matrix_transform.hpp"
|
||||||
#include "glm/trigonometric.hpp"
|
|
||||||
#include "webgpu/webgpu_cpp.h"
|
#include "webgpu/webgpu_cpp.h"
|
||||||
|
#include <webgpu/webgpu.h>
|
||||||
#ifdef EMSCRIPTEN
|
#ifdef EMSCRIPTEN
|
||||||
#include "emscripten/emscripten.h"
|
#include "emscripten/emscripten.h"
|
||||||
#endif
|
#endif
|
||||||
#define GLM_FORCE_ALIGNED_GENTYPES
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
#include <glm/ext/matrix_clip_space.hpp>
|
||||||
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include <glm/gtx/string_cast.hpp>
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
#ifdef EMSCRIPTEN
|
||||||
#define SHADERS_ROOT "/shaders/"
|
#define SHADERS_ROOT "/shaders/"
|
||||||
|
|
@ -85,9 +89,12 @@ wgpu::BindGroup basic_bind_group;
|
||||||
void request_adapter() {
|
void request_adapter() {
|
||||||
std::cout << "[WGPU] request_adapter()" << std::endl;
|
std::cout << "[WGPU] request_adapter()" << std::endl;
|
||||||
|
|
||||||
|
wgpu::InstanceFeatureName feature = wgpu::InstanceFeatureName::TimedWaitAny;
|
||||||
|
|
||||||
wgpu::InstanceDescriptor instance_desc{};
|
wgpu::InstanceDescriptor instance_desc{};
|
||||||
instance_desc.capabilities.timedWaitAnyEnable = true;
|
instance_desc.requiredFeatureCount = 1;
|
||||||
instance_desc.capabilities.timedWaitAnyMaxCount = 1;
|
instance_desc.requiredFeatures = &feature;
|
||||||
|
|
||||||
|
|
||||||
gpu_instance = wgpu::CreateInstance(&instance_desc);
|
gpu_instance = wgpu::CreateInstance(&instance_desc);
|
||||||
|
|
||||||
|
|
@ -200,7 +207,7 @@ std::string load_shader_source(const std::string_view& shader_name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream stream(path);
|
std::ifstream stream(path);
|
||||||
std::istream_iterator<char> start(stream), end{};
|
std::istreambuf_iterator<char> start(stream), end{};
|
||||||
|
|
||||||
return std::string(start, end);
|
return std::string(start, end);
|
||||||
}
|
}
|
||||||
|
|
@ -250,9 +257,11 @@ wgpu::PipelineLayout load_basic_pipeline_layout() {
|
||||||
layout_entries[0].binding = 1;
|
layout_entries[0].binding = 1;
|
||||||
layout_entries[0].buffer.minBindingSize = sizeof(float) * 8 * 3; //At least 3 STDVertex entries
|
layout_entries[0].buffer.minBindingSize = sizeof(float) * 8 * 3; //At least 3 STDVertex entries
|
||||||
layout_entries[0].buffer.type = wgpu::BufferBindingType::ReadOnlyStorage;
|
layout_entries[0].buffer.type = wgpu::BufferBindingType::ReadOnlyStorage;
|
||||||
|
layout_entries[0].visibility = wgpu::ShaderStage::Vertex;
|
||||||
layout_entries[1].binding = 0;
|
layout_entries[1].binding = 0;
|
||||||
layout_entries[1].buffer.minBindingSize = sizeof(float) * 24; //1 STDCamera entry
|
layout_entries[1].buffer.minBindingSize = sizeof(float) * 24; //1 STDCamera entry
|
||||||
layout_entries[1].buffer.type = wgpu::BufferBindingType::Uniform;
|
layout_entries[1].buffer.type = wgpu::BufferBindingType::Uniform;
|
||||||
|
layout_entries[1].visibility = wgpu::ShaderStage::Vertex;
|
||||||
|
|
||||||
wgpu::BindGroupLayoutDescriptor group_desc{};
|
wgpu::BindGroupLayoutDescriptor group_desc{};
|
||||||
group_desc.entryCount = 2;
|
group_desc.entryCount = 2;
|
||||||
|
|
@ -337,8 +346,7 @@ void fill_buffers() {
|
||||||
staging_buffer.WriteMappedRange(0, sample_triangle.data(), sample_triangle.size() * sizeof(STDVertex));
|
staging_buffer.WriteMappedRange(0, sample_triangle.data(), sample_triangle.size() * sizeof(STDVertex));
|
||||||
|
|
||||||
STDCamera cam{};
|
STDCamera cam{};
|
||||||
//cam.mvp = glm::perspectiveFov(glm::radians(90.0f), 1280.0f, 720.0f, 0.001f, 100.0f);
|
cam.mvp = glm::perspectiveRH(glm::radians(90.0f), 1280.0f / 720.0f, 0.001f, 100.0f) * glm::lookAtRH(glm::vec3(0, 0, 0), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0));
|
||||||
cam.mvp = glm::mat4(1.0f);
|
|
||||||
|
|
||||||
staging_buffer.WriteMappedRange(sizeof(STDVertex) * 3, &cam, sizeof(STDCamera));
|
staging_buffer.WriteMappedRange(sizeof(STDVertex) * 3, &cam, sizeof(STDCamera));
|
||||||
staging_buffer.Unmap();
|
staging_buffer.Unmap();
|
||||||
|
|
@ -357,9 +365,9 @@ void fill_buffers() {
|
||||||
|
|
||||||
gpu_device.GetQueue().Submit(1, &cmd);
|
gpu_device.GetQueue().Submit(1, &cmd);
|
||||||
|
|
||||||
auto f = gpu_device.GetQueue().OnSubmittedWorkDone(wgpu::CallbackMode::WaitAnyOnly, [](wgpu::QueueWorkDoneStatus status) -> void {
|
auto f = gpu_device.GetQueue().OnSubmittedWorkDone(wgpu::CallbackMode::WaitAnyOnly, [](wgpu::QueueWorkDoneStatus status, std::string_view error) -> void {
|
||||||
if (status != wgpu::QueueWorkDoneStatus::Success) {
|
if (status != wgpu::QueueWorkDoneStatus::Success) {
|
||||||
std::cout << "WAAAA x2" << std::endl;
|
std::cout << "[WGPU] Initial copy error: " << error << std::endl;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -424,14 +432,15 @@ EM_JS(void, resize_canvas, (const char* canvas_id, int width, int height), {
|
||||||
});
|
});
|
||||||
|
|
||||||
void update_camera(int width, int height) {
|
void update_camera(int width, int height) {
|
||||||
|
std::cout << "[WGPU] Updating camera " << width << "x" << height << std::endl;
|
||||||
auto map_future = staging_buffer.MapAsync(wgpu::MapMode::Write, 0, sizeof(STDCamera), wgpu::CallbackMode::WaitAnyOnly, [width, height](wgpu::MapAsyncStatus status, std::string_view error) -> void {
|
auto map_future = staging_buffer.MapAsync(wgpu::MapMode::Write, 0, sizeof(STDCamera), wgpu::CallbackMode::WaitAnyOnly, [width, height](wgpu::MapAsyncStatus status, std::string_view error) -> void {
|
||||||
if (status != wgpu::MapAsyncStatus::Success) {
|
if (status != wgpu::MapAsyncStatus::Success) {
|
||||||
std::cerr << "[WGPU] Map failure: " << error << std::endl;
|
std::cerr << "[WGPU] Map failure: " << error << std::endl;
|
||||||
throw std::runtime_error("Staging buffer map failure");
|
throw std::runtime_error("Staging buffer map failure");
|
||||||
}
|
}
|
||||||
|
|
||||||
STDCamera camera{};
|
STDCamera camera{};
|
||||||
camera.mvp = glm::perspectiveFov(glm::radians(90.0f), static_cast<float>(width), static_cast<float>(height), 0.001f, 100.0f);
|
camera.mvp = glm::perspectiveRH(glm::radians(90.0f), static_cast<float>(width) / height, 0.01f, 10.0f) * glm::lookAtRH(glm::vec3(0, 0, 0), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0));
|
||||||
camera.mvp = glm::mat4(1.0f);
|
|
||||||
|
|
||||||
staging_buffer.WriteMappedRange(0, &camera, sizeof(STDCamera));
|
staging_buffer.WriteMappedRange(0, &camera, sizeof(STDCamera));
|
||||||
staging_buffer.Unmap();
|
staging_buffer.Unmap();
|
||||||
|
|
@ -445,7 +454,7 @@ void update_camera(int width, int height) {
|
||||||
|
|
||||||
gpu_device.GetQueue().Submit(1, &cmd);
|
gpu_device.GetQueue().Submit(1, &cmd);
|
||||||
|
|
||||||
auto copy_future = gpu_device.GetQueue().OnSubmittedWorkDone(wgpu::CallbackMode::WaitAnyOnly, [](wgpu::QueueWorkDoneStatus) -> void {
|
auto copy_future = gpu_device.GetQueue().OnSubmittedWorkDone(wgpu::CallbackMode::WaitAnyOnly, [](wgpu::QueueWorkDoneStatus, std::string_view) -> void {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue