Fix glTFViewer by using push constants (#224)

* Works on Metal
* Not working on OpenGL (black screen; not sure why)
* Not working on Vulkan or D3D12 (push constants not implemented)
This commit is contained in:
Kai Ninomiya 2018-07-17 11:12:47 -07:00 committed by GitHub
parent b7ecfaa347
commit cfa524b86b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 9 additions and 25 deletions

View File

@ -64,7 +64,6 @@ namespace gl {
} }
struct MaterialInfo { struct MaterialInfo {
nxt::Buffer uniformBuffer;
nxt::RenderPipeline pipeline; nxt::RenderPipeline pipeline;
nxt::BindGroup bindGroup0; nxt::BindGroup bindGroup0;
std::map<uint32_t, std::string> slotSemantics; std::map<uint32_t, std::string> slotSemantics;
@ -179,7 +178,7 @@ namespace {
auto oVSModule = utils::CreateShaderModule(device, nxt::ShaderStage::Vertex, R"( auto oVSModule = utils::CreateShaderModule(device, nxt::ShaderStage::Vertex, R"(
#version 450 #version 450
layout(set = 0, binding = 0) uniform u_transform_block { layout(push_constant) uniform u_transform_block {
mat4 modelViewProj; mat4 modelViewProj;
mat4 modelInvTr; mat4 modelInvTr;
} u_transform; } u_transform;
@ -273,10 +272,9 @@ namespace {
constexpr nxt::ShaderStageBit kNoStages{}; constexpr nxt::ShaderStageBit kNoStages{};
nxt::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout( nxt::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
device, { device, {
{0, nxt::ShaderStageBit::Vertex, nxt::BindingType::UniformBuffer}, {0, hasTexture ? nxt::ShaderStageBit::Fragment : kNoStages,
{1, hasTexture ? nxt::ShaderStageBit::Fragment : kNoStages,
nxt::BindingType::Sampler}, nxt::BindingType::Sampler},
{2, hasTexture ? nxt::ShaderStageBit::Fragment : kNoStages, {1, hasTexture ? nxt::ShaderStageBit::Fragment : kNoStages,
nxt::BindingType::SampledTexture}, nxt::BindingType::SampledTexture},
}); });
@ -297,28 +295,17 @@ namespace {
.SetDepthStencilState(depthStencilState) .SetDepthStencilState(depthStencilState)
.GetResult(); .GetResult();
auto uniformBuffer = device.CreateBufferBuilder()
.SetAllowedUsage(nxt::BufferUsageBit::TransferDst | nxt::BufferUsageBit::Uniform)
.SetSize(sizeof(u_transform_block))
.GetResult();
auto uniformView = uniformBuffer.CreateBufferViewBuilder()
.SetExtent(0, sizeof(u_transform_block))
.GetResult();
auto bindGroupBuilder = device.CreateBindGroupBuilder(); auto bindGroupBuilder = device.CreateBindGroupBuilder();
bindGroupBuilder.SetLayout(bindGroupLayout) bindGroupBuilder.SetLayout(bindGroupLayout)
.SetUsage(nxt::BindGroupUsage::Frozen) .SetUsage(nxt::BindGroupUsage::Frozen);
.SetBufferViews(0, 1, &uniformView);
if (hasTexture) { if (hasTexture) {
const auto& textureView = textures[iTextureID]; const auto& textureView = textures[iTextureID];
const auto& iSamplerID = scene.textures[iTextureID].sampler; const auto& iSamplerID = scene.textures[iTextureID].sampler;
bindGroupBuilder.SetSamplers(1, 1, &samplers[iSamplerID]); bindGroupBuilder.SetSamplers(0, 1, &samplers[iSamplerID]);
bindGroupBuilder.SetTextureViews(2, 1, &textureView); bindGroupBuilder.SetTextureViews(1, 1, &textureView);
} }
MaterialInfo material = { MaterialInfo material = {
uniformBuffer.Get(),
pipeline.Get(), pipeline.Get(),
bindGroupBuilder.GetResult(), bindGroupBuilder.GetResult(),
std::map<uint32_t, std::string>(), std::map<uint32_t, std::string>(),
@ -491,14 +478,11 @@ namespace {
} }
} }
const MaterialInfo& material = getMaterial(iPrim.material, strides[0], strides[1], strides[2]); const MaterialInfo& material = getMaterial(iPrim.material, strides[0], strides[1], strides[2]);
// TODO(cwallez@google.com): This is updating the uniform buffer with a device-level command
// but the draw is queue level command that is pipelined. This causes bad rendering for models
// that use the same part multiple time.
material.uniformBuffer.SetSubData(0,
sizeof(u_transform_block),
reinterpret_cast<const uint8_t*>(&transforms));
cmd.SetRenderPipeline(material.pipeline); cmd.SetRenderPipeline(material.pipeline);
cmd.SetBindGroup(0, material.bindGroup0); cmd.SetBindGroup(0, material.bindGroup0);
cmd.SetPushConstants(nxt::ShaderStageBit::Vertex,
0, sizeof(u_transform_block) / sizeof(uint32_t),
reinterpret_cast<const uint32_t*>(&transforms));
uint32_t vertexCount = 0; uint32_t vertexCount = 0;
for (const auto& s : slotSemantics) { for (const auto& s : slotSemantics) {