Archived
1
Fork 0

Okay, reformat the rest of the engine code!

This commit is contained in:
Joshua Goins 2022-08-15 11:07:28 -04:00
parent 100e1d7434
commit b00a39c474
75 changed files with 3059 additions and 2975 deletions

View file

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <d3d12.h> #include <d3d12.h>
#include <dxgi1_6.h>
#include <d3dcompiler.h> #include <d3dcompiler.h>
#include <dxgi1_6.h>
#include <wrl.h> #include <wrl.h>
#include "gfx.hpp" #include "gfx.hpp"
@ -11,9 +11,18 @@ using namespace Microsoft::WRL;
class gfx_dx12 : public GFX { class gfx_dx12 : public GFX {
public: public:
bool is_supported() override { return true; } bool is_supported() override {
ShaderLanguage accepted_shader_language() override { return ShaderLanguage::HLSL; } return true;
GFXContext required_context() override { return GFXContext::DirectX; } }
ShaderLanguage accepted_shader_language() override {
return ShaderLanguage::HLSL;
}
GFXContext required_context() override {
return GFXContext::DirectX;
}
bool initialize(const GFXCreateInfo& info) override; bool initialize(const GFXCreateInfo& info) override;
const char* get_name() override; const char* get_name() override;

View file

@ -1,11 +1,11 @@
#include "gfx_dx12.hpp" #include "gfx_dx12.hpp"
#include <d3d12.h> #include <d3d12.h>
#include <dxgi1_6.h>
#include <d3dcompiler.h> #include <d3dcompiler.h>
#include <dxgi1_6.h>
#include <wrl.h>
#include <codecvt> #include <codecvt>
#include <wrl.h>
// from https://stackoverflow.com/a/18374698 // from https://stackoverflow.com/a/18374698
std::string ws2s(const std::wstring& wstr) { std::string ws2s(const std::wstring& wstr) {

View file

@ -8,15 +8,23 @@
class GFXMetal : public GFX { class GFXMetal : public GFX {
public: public:
bool is_supported() override; bool is_supported() override;
GFXContext required_context() override { return GFXContext::Metal; }
ShaderLanguage accepted_shader_language() override { return ShaderLanguage::MSL; } GFXContext required_context() override {
return GFXContext::Metal;
}
ShaderLanguage accepted_shader_language() override {
return ShaderLanguage::MSL;
}
const char* get_name() override; const char* get_name() override;
bool supports_feature(GFXFeature feature) override; bool supports_feature(GFXFeature feature) override;
bool initialize(const GFXCreateInfo& createInfo) override; bool initialize(const GFXCreateInfo& createInfo) override;
void initialize_view(void* native_handle, platform::window_ptr identifier, uint32_t width, uint32_t height) override; void
initialize_view(void* native_handle, platform::window_ptr identifier, uint32_t width, uint32_t height) override;
void remove_view(platform::window_ptr identifier) override; void remove_view(platform::window_ptr identifier) override;
// buffer operations // buffer operations

View file

@ -1,16 +1,16 @@
#include "gfx_metal.hpp" #include "gfx_metal.hpp"
#include "gfx_metal_buffer.hpp"
#include "gfx_metal_pipeline.hpp"
#include "gfx_commandbuffer.hpp"
#include "gfx_metal_texture.hpp"
#include "gfx_metal_renderpass.hpp"
#include "gfx_metal_framebuffer.hpp"
#include "gfx_metal_sampler.hpp"
#include "file.hpp" #include "file.hpp"
#include "gfx_commandbuffer.hpp"
#include "gfx_metal_buffer.hpp"
#include "gfx_metal_framebuffer.hpp"
#include "gfx_metal_pipeline.hpp"
#include "gfx_metal_renderpass.hpp"
#include "gfx_metal_sampler.hpp"
#include "gfx_metal_texture.hpp"
#include "log.hpp" #include "log.hpp"
#include "utility.hpp"
#include "string_utils.hpp" #include "string_utils.hpp"
#include "utility.hpp"
static inline bool debug_enabled = false; static inline bool debug_enabled = false;
@ -69,8 +69,7 @@ MTL::SamplerAddressMode toSamplingMode(SamplingMode mode) {
return MTL::SamplerAddressModeRepeat; return MTL::SamplerAddressModeRepeat;
case SamplingMode::ClampToEdge: case SamplingMode::ClampToEdge:
return MTL::SamplerAddressModeClampToEdge; return MTL::SamplerAddressModeClampToEdge;
case SamplingMode::ClampToBorder: case SamplingMode::ClampToBorder: {
{
#if defined(PLATFORM_IOS) || defined(PLATFORM_TVOS) #if defined(PLATFORM_IOS) || defined(PLATFORM_TVOS)
return MTL::SamplerAddressModeRepeat; return MTL::SamplerAddressModeRepeat;
#else #else
@ -168,7 +167,11 @@ bool GFXMetal::supports_feature(const GFXFeature feature) {
return false; return false;
} }
void GFXMetal::initialize_view(void* native_handle, const platform::window_ptr identifier, const uint32_t, const uint32_t) { void GFXMetal::initialize_view(
void* native_handle,
const platform::window_ptr identifier,
const uint32_t,
const uint32_t) {
auto native = new NativeMTLView(); auto native = new NativeMTLView();
native->identifier = identifier; native->identifier = identifier;
@ -230,18 +233,14 @@ GFXTexture* GFXMetal::create_texture(const GFXTextureCreateInfo& info) {
case GFXTextureType::Array2D: case GFXTextureType::Array2D:
textureDescriptor->setTextureType(MTL::TextureType2DArray); textureDescriptor->setTextureType(MTL::TextureType2DArray);
break; break;
case GFXTextureType::Cubemap: case GFXTextureType::Cubemap: {
{
textureDescriptor->setTextureType(MTL::TextureTypeCube); textureDescriptor->setTextureType(MTL::TextureTypeCube);
texture->is_cubemap = true; texture->is_cubemap = true;
} } break;
break; case GFXTextureType::CubemapArray: {
case GFXTextureType::CubemapArray:
{
textureDescriptor->setTextureType(MTL::TextureTypeCubeArray); textureDescriptor->setTextureType(MTL::TextureTypeCubeArray);
texture->is_cubemap = true; texture->is_cubemap = true;
} } break;
break;
} }
if ((info.usage & GFXTextureUsage::Attachment) == GFXTextureUsage::Attachment) { if ((info.usage & GFXTextureUsage::Attachment) == GFXTextureUsage::Attachment) {
@ -353,7 +352,8 @@ void GFXMetal::copy_texture(GFXTexture* from, GFXBuffer* to) {
MTL::CommandBuffer* commandBuffer = command_queue->commandBuffer(); MTL::CommandBuffer* commandBuffer = command_queue->commandBuffer();
MTL::BlitCommandEncoder* commandEncoder = commandBuffer->blitCommandEncoder(); MTL::BlitCommandEncoder* commandEncoder = commandBuffer->blitCommandEncoder();
commandEncoder->copyFromTexture(metalFromTexture->handle, 0, 0, origin, size, metalToBuffer->handle, 0, metalFromTexture->width * byteSize, 0); commandEncoder->copyFromTexture(
metalFromTexture->handle, 0, 0, origin, size, metalToBuffer->handle, 0, metalFromTexture->width * byteSize, 0);
commandEncoder->endEncoding(); commandEncoder->endEncoding();
commandBuffer->commit(); commandBuffer->commit();
commandBuffer->waitUntilCompleted(); commandBuffer->waitUntilCompleted();
@ -443,16 +443,20 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
} }
} }
vertexLibrary = device->newLibrary(NS::String::string(vertex_src.c_str(), NS::ASCIIStringEncoding), nullptr,&error); vertexLibrary =
device->newLibrary(NS::String::string(vertex_src.c_str(), NS::ASCIIStringEncoding), nullptr, &error);
if (vertexLibrary == nullptr) if (vertexLibrary == nullptr)
prism::log("Metal shader compiler error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); prism::log(
"Metal shader compiler error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding));
auto vertex_constants = get_constant_values(info.shaders.vertex_constants); auto vertex_constants = get_constant_values(info.shaders.vertex_constants);
vertexFunc = vertexLibrary->newFunction(NS::String::string("main0", NS::ASCIIStringEncoding), vertex_constants, (NS::Error**)nullptr); vertexFunc = vertexLibrary->newFunction(
NS::String::string("main0", NS::ASCIIStringEncoding), vertex_constants, (NS::Error**)nullptr);
if (debug_enabled && info.shaders.vertex_src.is_path()) if (debug_enabled && info.shaders.vertex_src.is_path())
vertexFunc->setLabel(NS::String::string(info.shaders.vertex_src.as_path().string().data(), NS::ASCIIStringEncoding)); vertexFunc->setLabel(
NS::String::string(info.shaders.vertex_src.as_path().string().data(), NS::ASCIIStringEncoding));
pipelineDescriptor->setVertexFunction(vertexFunc); pipelineDescriptor->setVertexFunction(vertexFunc);
} }
@ -476,17 +480,21 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
} }
} }
fragmentLibrary = device->newLibrary(NS::String::string(fragment_src.c_str(), NS::ASCIIStringEncoding), nullptr,&error); fragmentLibrary =
device->newLibrary(NS::String::string(fragment_src.c_str(), NS::ASCIIStringEncoding), nullptr, &error);
if (fragmentLibrary == nullptr) if (fragmentLibrary == nullptr)
prism::log("Metal shader compiler error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); prism::log(
"Metal shader compiler error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding));
} }
auto fragment_constants = get_constant_values(info.shaders.fragment_constants); auto fragment_constants = get_constant_values(info.shaders.fragment_constants);
fragmentFunc = fragmentLibrary->newFunction(NS::String::string("main0", NS::ASCIIStringEncoding), fragment_constants, (NS::Error**)nullptr); fragmentFunc = fragmentLibrary->newFunction(
NS::String::string("main0", NS::ASCIIStringEncoding), fragment_constants, (NS::Error**)nullptr);
if (debug_enabled && info.shaders.fragment_src.is_path()) if (debug_enabled && info.shaders.fragment_src.is_path())
fragmentFunc->setLabel(NS::String::string(info.shaders.fragment_src.as_path().string().data(), NS::ASCIIStringEncoding)); fragmentFunc->setLabel(
NS::String::string(info.shaders.fragment_src.as_path().string().data(), NS::ASCIIStringEncoding));
pipelineDescriptor->setFragmentFunction(fragmentFunc); pipelineDescriptor->setFragmentFunction(fragmentFunc);
} }
@ -543,7 +551,8 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
unsigned int i = 0; unsigned int i = 0;
for (const auto& attachment : metalRenderPass->attachments) { for (const auto& attachment : metalRenderPass->attachments) {
if (attachment != MTL::PixelFormatDepth32Float) { if (attachment != MTL::PixelFormatDepth32Float) {
MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = pipelineDescriptor->colorAttachments()->object(i++); MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor =
pipelineDescriptor->colorAttachments()->object(i++);
colorAttachmentDescriptor->setPixelFormat(attachment); colorAttachmentDescriptor->setPixelFormat(attachment);
colorAttachmentDescriptor->setBlendingEnabled(info.blending.enable_blending); colorAttachmentDescriptor->setBlendingEnabled(info.blending.enable_blending);
@ -558,7 +567,8 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
} }
} }
} else { } else {
MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = pipelineDescriptor->colorAttachments()->object(0); MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor =
pipelineDescriptor->colorAttachments()->object(0);
colorAttachmentDescriptor->setPixelFormat(nativeViews[0]->format); colorAttachmentDescriptor->setPixelFormat(nativeViews[0]->format);
colorAttachmentDescriptor->setBlendingEnabled(info.blending.enable_blending); colorAttachmentDescriptor->setBlendingEnabled(info.blending.enable_blending);
@ -577,7 +587,8 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
pipeline->handle = device->newRenderPipelineState(pipelineDescriptor, &error); pipeline->handle = device->newRenderPipelineState(pipelineDescriptor, &error);
if (!pipeline->handle) if (!pipeline->handle)
prism::log("Metal render pipeline creation error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); prism::log(
"Metal render pipeline creation error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding));
switch (info.rasterization.primitive_type) { switch (info.rasterization.primitive_type) {
case GFXPrimitiveType::Triangle: case GFXPrimitiveType::Triangle:
@ -649,9 +660,11 @@ GFXPipeline* GFXMetal::create_compute_pipeline(const GFXComputePipelineCreateInf
} }
} }
computeLibrary = device->newLibrary(NS::String::string(compute_src.c_str(), NS::ASCIIStringEncoding), nullptr, &error); computeLibrary =
device->newLibrary(NS::String::string(compute_src.c_str(), NS::ASCIIStringEncoding), nullptr, &error);
if (!computeLibrary) if (!computeLibrary)
prism::log("Compute library compilation error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); prism::log(
"Compute library compilation error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding));
} }
MTL::Function* computeFunc = computeLibrary->newFunction(NS::String::string("main0", NS::ASCIIStringEncoding)); MTL::Function* computeFunc = computeLibrary->newFunction(NS::String::string("main0", NS::ASCIIStringEncoding));
@ -666,7 +679,8 @@ GFXPipeline* GFXMetal::create_compute_pipeline(const GFXComputePipelineCreateInf
pipeline->label = info.label; pipeline->label = info.label;
} }
pipeline->compute_handle = device->newComputePipelineState(pipelineDescriptor, MTL::PipelineOptionNone, nullptr, &error); pipeline->compute_handle =
device->newComputePipelineState(pipelineDescriptor, MTL::PipelineOptionNone, nullptr, &error);
if (!pipeline->compute_handle) if (!pipeline->compute_handle)
prism::log("Compute pipeline error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding)); prism::log("Compute pipeline error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding));
@ -755,8 +769,7 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
switch (encoder) { switch (encoder) {
case CurrentEncoder::None: case CurrentEncoder::None:
break; break;
case CurrentEncoder::Render: case CurrentEncoder::Render: {
{
MTL::RenderPassDescriptor* descriptor = MTL::RenderPassDescriptor::alloc()->init(); MTL::RenderPassDescriptor* descriptor = MTL::RenderPassDescriptor::alloc()->init();
if (currentRenderPass != nullptr && currentFramebuffer != nullptr) { if (currentRenderPass != nullptr && currentFramebuffer != nullptr) {
@ -768,7 +781,8 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
depthAttachment->setLoadAction(MTL::LoadActionClear); depthAttachment->setLoadAction(MTL::LoadActionClear);
depthAttachment->setStoreAction(MTL::StoreActionStore); depthAttachment->setStoreAction(MTL::StoreActionStore);
} else { } else {
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = descriptor->colorAttachments()->object(i); MTL::RenderPassColorAttachmentDescriptor* colorAttachment =
descriptor->colorAttachments()->object(i);
colorAttachment->setTexture(attachment->handle); colorAttachment->setTexture(attachment->handle);
colorAttachment->setLoadAction(MTL::LoadActionClear); colorAttachment->setLoadAction(MTL::LoadActionClear);
@ -777,7 +791,8 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
} }
} }
} else { } else {
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = descriptor->colorAttachments()->object(0); MTL::RenderPassColorAttachmentDescriptor* colorAttachment =
descriptor->colorAttachments()->object(0);
colorAttachment->setTexture(drawable->texture()); colorAttachment->setTexture(drawable->texture());
colorAttachment->setLoadAction(MTL::LoadActionClear); colorAttachment->setLoadAction(MTL::LoadActionClear);
@ -791,18 +806,13 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
renderEncoder->setViewport(currentViewport); renderEncoder->setViewport(currentViewport);
descriptor->release(); descriptor->release();
} } break;
break; case CurrentEncoder::Compute: {
case CurrentEncoder::Compute:
{
computeEncoder = commandBuffer->computeCommandEncoder(); computeEncoder = commandBuffer->computeCommandEncoder();
} } break;
break; case CurrentEncoder::Blit: {
case CurrentEncoder::Blit:
{
blitEncoder = commandBuffer->blitCommandEncoder(); blitEncoder = commandBuffer->blitCommandEncoder();
} } break;
break;
} }
current_encoder = encoder; current_encoder = encoder;
@ -812,9 +822,9 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
switch (command.type) { switch (command.type) {
case GFXCommandType::Invalid: case GFXCommandType::Invalid:
break; break;
case GFXCommandType::SetRenderPass: case GFXCommandType::SetRenderPass: {
{ currentClearColor = MTL::ClearColor(
currentClearColor = MTL::ClearColor(command.data.set_render_pass.clear_color.r, command.data.set_render_pass.clear_color.r,
command.data.set_render_pass.clear_color.g, command.data.set_render_pass.clear_color.g,
command.data.set_render_pass.clear_color.b, command.data.set_render_pass.clear_color.b,
command.data.set_render_pass.clear_color.a); command.data.set_render_pass.clear_color.a);
@ -824,78 +834,96 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
currentViewport = MTL::Viewport(); currentViewport = MTL::Viewport();
needEncoder(CurrentEncoder::Render, true); needEncoder(CurrentEncoder::Render, true);
} } break;
break; case GFXCommandType::SetGraphicsPipeline: {
case GFXCommandType::SetGraphicsPipeline:
{
needEncoder(CurrentEncoder::Render); needEncoder(CurrentEncoder::Render);
currentPipeline = (GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline; currentPipeline = (GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline;
renderEncoder->setRenderPipelineState(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->handle); renderEncoder->setRenderPipelineState(
((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->handle);
renderEncoder->setDepthStencilState(currentPipeline->depthStencil); renderEncoder->setDepthStencilState(currentPipeline->depthStencil);
renderEncoder->setCullMode(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->cullMode); renderEncoder->setCullMode(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->cullMode);
renderEncoder->setFrontFacingWinding(toWinding(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->winding_mode)); renderEncoder->setFrontFacingWinding(
toWinding(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->winding_mode));
if (currentPipeline->renderWire) if (currentPipeline->renderWire)
renderEncoder->setTriangleFillMode(MTL::TriangleFillModeLines); renderEncoder->setTriangleFillMode(MTL::TriangleFillModeLines);
else else
renderEncoder->setTriangleFillMode(MTL::TriangleFillModeFill); renderEncoder->setTriangleFillMode(MTL::TriangleFillModeFill);
} } break;
break; case GFXCommandType::SetComputePipeline: {
case GFXCommandType::SetComputePipeline:
{
needEncoder(CurrentEncoder::Compute); needEncoder(CurrentEncoder::Compute);
currentPipeline = (GFXMetalPipeline*)command.data.set_compute_pipeline.pipeline; currentPipeline = (GFXMetalPipeline*)command.data.set_compute_pipeline.pipeline;
computeEncoder->setComputePipelineState(((GFXMetalPipeline*)command.data.set_compute_pipeline.pipeline)->compute_handle); computeEncoder->setComputePipelineState(
} ((GFXMetalPipeline*)command.data.set_compute_pipeline.pipeline)->compute_handle);
break; } break;
case GFXCommandType::SetVertexBuffer: case GFXCommandType::SetVertexBuffer: {
{
needEncoder(CurrentEncoder::Render); needEncoder(CurrentEncoder::Render);
renderEncoder->setVertexBuffer(((GFXMetalBuffer*)command.data.set_vertex_buffer.buffer)->handle, command.data.set_vertex_buffer.offset, 30 -command.data.set_vertex_buffer.index); renderEncoder->setVertexBuffer(
} ((GFXMetalBuffer*)command.data.set_vertex_buffer.buffer)->handle,
break; command.data.set_vertex_buffer.offset,
case GFXCommandType::SetIndexBuffer: 30 - command.data.set_vertex_buffer.index);
{ } break;
case GFXCommandType::SetIndexBuffer: {
needEncoder(CurrentEncoder::Render); needEncoder(CurrentEncoder::Render);
currentIndexBuffer = (GFXMetalBuffer*)command.data.set_index_buffer.buffer; currentIndexBuffer = (GFXMetalBuffer*)command.data.set_index_buffer.buffer;
currentIndextype = command.data.set_index_buffer.index_type; currentIndextype = command.data.set_index_buffer.index_type;
} } break;
break; case GFXCommandType::SetPushConstant: {
case GFXCommandType::SetPushConstant:
{
if (current_encoder == CurrentEncoder::Render) { if (current_encoder == CurrentEncoder::Render) {
renderEncoder->setVertexBytes(command.data.set_push_constant.bytes.data(), command.data.set_push_constant.size, currentPipeline->pushConstantIndex); renderEncoder->setVertexBytes(
renderEncoder->setFragmentBytes(command.data.set_push_constant.bytes.data(), command.data.set_push_constant.size, currentPipeline->pushConstantIndex); command.data.set_push_constant.bytes.data(),
command.data.set_push_constant.size,
currentPipeline->pushConstantIndex);
renderEncoder->setFragmentBytes(
command.data.set_push_constant.bytes.data(),
command.data.set_push_constant.size,
currentPipeline->pushConstantIndex);
} else if (current_encoder == CurrentEncoder::Compute) { } else if (current_encoder == CurrentEncoder::Compute) {
computeEncoder->setBytes(command.data.set_push_constant.bytes.data(), command.data.set_push_constant.size, currentPipeline->pushConstantIndex); computeEncoder->setBytes(
command.data.set_push_constant.bytes.data(),
command.data.set_push_constant.size,
currentPipeline->pushConstantIndex);
} }
} } break;
break; case GFXCommandType::BindShaderBuffer: {
case GFXCommandType::BindShaderBuffer:
{
if (current_encoder == CurrentEncoder::Render) { if (current_encoder == CurrentEncoder::Render) {
renderEncoder->setVertexBuffer(((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle, command.data.bind_shader_buffer.offset, command.data.bind_shader_buffer.index); renderEncoder->setVertexBuffer(
renderEncoder->setFragmentBuffer(((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle, command.data.bind_shader_buffer.offset, command.data.bind_shader_buffer.index); ((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle,
command.data.bind_shader_buffer.offset,
command.data.bind_shader_buffer.index);
renderEncoder->setFragmentBuffer(
((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle,
command.data.bind_shader_buffer.offset,
command.data.bind_shader_buffer.index);
} else if (current_encoder == CurrentEncoder::Compute) { } else if (current_encoder == CurrentEncoder::Compute) {
computeEncoder->setBuffer(((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle, command.data.bind_shader_buffer.offset, command.data.bind_shader_buffer.index); computeEncoder->setBuffer(
((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle,
command.data.bind_shader_buffer.offset,
command.data.bind_shader_buffer.index);
} }
} } break;
break; case GFXCommandType::BindTexture: {
case GFXCommandType::BindTexture:
{
if (current_encoder == CurrentEncoder::Render) { if (current_encoder == CurrentEncoder::Render) {
if (command.data.bind_texture.texture != nullptr) { if (command.data.bind_texture.texture != nullptr) {
renderEncoder->setVertexTexture(((GFXMetalTexture*)command.data.bind_texture.texture)->handle, command.data.bind_texture.index); renderEncoder->setVertexTexture(
renderEncoder->setVertexSamplerState(((GFXMetalTexture*)command.data.bind_texture.texture)->sampler, command.data.bind_texture.index); ((GFXMetalTexture*)command.data.bind_texture.texture)->handle,
command.data.bind_texture.index);
renderEncoder->setVertexSamplerState(
((GFXMetalTexture*)command.data.bind_texture.texture)->sampler,
command.data.bind_texture.index);
renderEncoder->setFragmentTexture(((GFXMetalTexture*)command.data.bind_texture.texture)->handle, command.data.bind_texture.index); renderEncoder->setFragmentTexture(
renderEncoder->setFragmentSamplerState(((GFXMetalTexture*)command.data.bind_texture.texture)->sampler, command.data.bind_texture.index); ((GFXMetalTexture*)command.data.bind_texture.texture)->handle,
command.data.bind_texture.index);
renderEncoder->setFragmentSamplerState(
((GFXMetalTexture*)command.data.bind_texture.texture)->sampler,
command.data.bind_texture.index);
} else { } else {
renderEncoder->setVertexTexture(nullptr, command.data.bind_texture.index); renderEncoder->setVertexTexture(nullptr, command.data.bind_texture.index);
renderEncoder->setVertexSamplerState(nullptr, command.data.bind_texture.index); renderEncoder->setVertexSamplerState(nullptr, command.data.bind_texture.index);
@ -904,37 +932,34 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
renderEncoder->setFragmentSamplerState(nullptr, command.data.bind_texture.index); renderEncoder->setFragmentSamplerState(nullptr, command.data.bind_texture.index);
} }
} else if (current_encoder == CurrentEncoder::Compute) { } else if (current_encoder == CurrentEncoder::Compute) {
computeEncoder->setTexture(((GFXMetalTexture*)command.data.bind_texture.texture)->handle, command.data.bind_texture.index); computeEncoder->setTexture(
((GFXMetalTexture*)command.data.bind_texture.texture)->handle, command.data.bind_texture.index);
} }
} } break;
break; case GFXCommandType::BindSampler: {
case GFXCommandType::BindSampler:
{
needEncoder(CurrentEncoder::Render); needEncoder(CurrentEncoder::Render);
if (command.data.bind_sampler.sampler != nullptr) { if (command.data.bind_sampler.sampler != nullptr) {
renderEncoder->setFragmentSamplerState(((GFXMetalSampler*)command.data.bind_sampler.sampler)->handle, command.data.bind_sampler.index); renderEncoder->setFragmentSamplerState(
((GFXMetalSampler*)command.data.bind_sampler.sampler)->handle, command.data.bind_sampler.index);
} else { } else {
renderEncoder->setFragmentSamplerState(nullptr, command.data.bind_sampler.index); renderEncoder->setFragmentSamplerState(nullptr, command.data.bind_sampler.index);
} }
} } break;
break; case GFXCommandType::Draw: {
case GFXCommandType::Draw:
{
needEncoder(CurrentEncoder::Render); needEncoder(CurrentEncoder::Render);
if (currentPipeline == nullptr) if (currentPipeline == nullptr)
continue; continue;
renderEncoder->drawPrimitives(currentPipeline->primitiveType, renderEncoder->drawPrimitives(
currentPipeline->primitiveType,
command.data.draw.vertex_offset, command.data.draw.vertex_offset,
command.data.draw.vertex_count, command.data.draw.vertex_count,
command.data.draw.instance_count, command.data.draw.instance_count,
command.data.draw.base_instance); command.data.draw.base_instance);
} } break;
break; case GFXCommandType::DrawIndexed: {
case GFXCommandType::DrawIndexed:
{
needEncoder(CurrentEncoder::Render); needEncoder(CurrentEncoder::Render);
if (currentIndexBuffer == nullptr) if (currentIndexBuffer == nullptr)
@ -946,49 +971,46 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
MTL::IndexType indexType; MTL::IndexType indexType;
int indexSize; int indexSize;
switch (currentIndextype) { switch (currentIndextype) {
case IndexType::UINT16: case IndexType::UINT16: {
{
indexType = MTL::IndexTypeUInt16; indexType = MTL::IndexTypeUInt16;
indexSize = sizeof(uint16_t); indexSize = sizeof(uint16_t);
} } break;
break; case IndexType::UINT32: {
case IndexType::UINT32:
{
indexType = MTL::IndexTypeUInt32; indexType = MTL::IndexTypeUInt32;
indexSize = sizeof(uint32_t); indexSize = sizeof(uint32_t);
} } break;
break;
} }
for (auto& stride : currentPipeline->vertexStrides) for (auto& stride : currentPipeline->vertexStrides)
renderEncoder->setVertexBufferOffset(command.data.draw_indexed.vertex_offset * stride.stride, 30 - stride.location); renderEncoder->setVertexBufferOffset(
command.data.draw_indexed.vertex_offset * stride.stride, 30 - stride.location);
renderEncoder->drawIndexedPrimitives(currentPipeline->primitiveType, renderEncoder->drawIndexedPrimitives(
currentPipeline->primitiveType,
command.data.draw_indexed.index_count, command.data.draw_indexed.index_count,
indexType, indexType,
currentIndexBuffer->handle, currentIndexBuffer->handle,
command.data.draw_indexed.first_index * indexSize); command.data.draw_indexed.first_index * indexSize);
} } break;
break; case GFXCommandType::MemoryBarrier: {
case GFXCommandType::MemoryBarrier:
{
needEncoder(CurrentEncoder::Render); needEncoder(CurrentEncoder::Render);
#ifdef PLATFORM_MACOS #ifdef PLATFORM_MACOS
renderEncoder->memoryBarrier(MTL::BarrierScopeTextures, MTL::RenderStageFragment, MTL::RenderStageFragment); renderEncoder->memoryBarrier(
MTL::BarrierScopeTextures, MTL::RenderStageFragment, MTL::RenderStageFragment);
#endif #endif
} } break;
break; case GFXCommandType::CopyTexture: {
case GFXCommandType::CopyTexture:
{
needEncoder(CurrentEncoder::Blit); needEncoder(CurrentEncoder::Blit);
auto metalFromTexture = (GFXMetalTexture*)command.data.copy_texture.src; auto metalFromTexture = (GFXMetalTexture*)command.data.copy_texture.src;
auto metalToTexture = (GFXMetalTexture*)command.data.copy_texture.dst; auto metalToTexture = (GFXMetalTexture*)command.data.copy_texture.dst;
if (metalFromTexture != nullptr && metalToTexture != nullptr) { if (metalFromTexture != nullptr && metalToTexture != nullptr) {
const int slice_offset = command.data.copy_texture.to_slice + command.data.copy_texture.to_layer * 6; const int slice_offset =
command.data.copy_texture.to_slice + command.data.copy_texture.to_layer * 6;
blitEncoder->copyFromTexture(metalFromTexture->handle, blitEncoder->copyFromTexture(
metalFromTexture->handle,
0, 0,
0, 0,
MTL::Origin(0, 0, 0), MTL::Origin(0, 0, 0),
@ -998,10 +1020,8 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
command.data.copy_texture.to_level, command.data.copy_texture.to_level,
MTL::Origin(0, 0, 0)); MTL::Origin(0, 0, 0));
} }
} } break;
break; case GFXCommandType::SetViewport: {
case GFXCommandType::SetViewport:
{
needEncoder(CurrentEncoder::Render); needEncoder(CurrentEncoder::Render);
MTL::Viewport viewport = {}; MTL::Viewport viewport = {};
@ -1014,10 +1034,8 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
renderEncoder->setViewport(viewport); renderEncoder->setViewport(viewport);
currentViewport = viewport; currentViewport = viewport;
} } break;
break; case GFXCommandType::SetScissor: {
case GFXCommandType::SetScissor:
{
needEncoder(CurrentEncoder::Render); needEncoder(CurrentEncoder::Render);
MTL::ScissorRect rect = {}; MTL::ScissorRect rect = {};
@ -1027,60 +1045,64 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
rect.height = command.data.set_scissor.rect.extent.height; rect.height = command.data.set_scissor.rect.extent.height;
renderEncoder->setScissorRect(rect); renderEncoder->setScissorRect(rect);
} } break;
break;
case GFXCommandType::GenerateMipmaps: { case GFXCommandType::GenerateMipmaps: {
needEncoder(CurrentEncoder::Blit); needEncoder(CurrentEncoder::Blit);
auto metalTexture = (GFXMetalTexture*)command.data.generate_mipmaps.texture; auto metalTexture = (GFXMetalTexture*)command.data.generate_mipmaps.texture;
blitEncoder->generateMipmaps(metalTexture->handle); blitEncoder->generateMipmaps(metalTexture->handle);
} } break;
break;
case GFXCommandType::SetDepthBias: { case GFXCommandType::SetDepthBias: {
needEncoder(CurrentEncoder::Render); needEncoder(CurrentEncoder::Render);
renderEncoder->setDepthBias(command.data.set_depth_bias.constant, command.data.set_depth_bias.slope_factor, command.data.set_depth_bias.clamp); renderEncoder->setDepthBias(
} command.data.set_depth_bias.constant,
break; command.data.set_depth_bias.slope_factor,
command.data.set_depth_bias.clamp);
} break;
case GFXCommandType::PushGroup: { case GFXCommandType::PushGroup: {
commandBuffer->pushDebugGroup(NS::String::string(command.data.push_group.name.data(), NS::ASCIIStringEncoding)); commandBuffer->pushDebugGroup(
} NS::String::string(command.data.push_group.name.data(), NS::ASCIIStringEncoding));
break; } break;
case GFXCommandType::PopGroup: { case GFXCommandType::PopGroup: {
commandBuffer->popDebugGroup(); commandBuffer->popDebugGroup();
} } break;
break;
case GFXCommandType::InsertLabel: { case GFXCommandType::InsertLabel: {
switch (current_encoder) { switch (current_encoder) {
case CurrentEncoder::Render: case CurrentEncoder::Render:
renderEncoder->insertDebugSignpost(NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding)); renderEncoder->insertDebugSignpost(
NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding));
break; break;
case CurrentEncoder::Blit: case CurrentEncoder::Blit:
blitEncoder->insertDebugSignpost(NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding)); blitEncoder->insertDebugSignpost(
NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding));
break; break;
case CurrentEncoder::Compute: case CurrentEncoder::Compute:
computeEncoder->insertDebugSignpost(NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding)); computeEncoder->insertDebugSignpost(
NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding));
break; break;
default: default:
break; break;
} }
} } break;
break;
case GFXCommandType::Dispatch: { case GFXCommandType::Dispatch: {
needEncoder(CurrentEncoder::Compute); needEncoder(CurrentEncoder::Compute);
computeEncoder->dispatchThreadgroups(MTL::Size(command.data.dispatch.group_count_x, command.data.dispatch.group_count_y, command.data.dispatch.group_count_z), currentPipeline->threadGroupSize); computeEncoder->dispatchThreadgroups(
} MTL::Size(
break; command.data.dispatch.group_count_x,
command.data.dispatch.group_count_y,
command.data.dispatch.group_count_z),
currentPipeline->threadGroupSize);
} break;
case GFXCommandType::EndRenderPass: { case GFXCommandType::EndRenderPass: {
currentFramebuffer = nullptr; currentFramebuffer = nullptr;
currentRenderPass = nullptr; currentRenderPass = nullptr;
currentPipeline = nullptr; currentPipeline = nullptr;
renderEncoder->endEncoding(); renderEncoder->endEncoding();
renderEncoder = nullptr; renderEncoder = nullptr;
} } break;
break;
} }
} }

View file

@ -1,12 +1,12 @@
#pragma once #pragma once
#include <string> #include <string>
#include <vector>
#include <variant> #include <variant>
#include <vector>
#include "shadercompiler.hpp"
#include "platform.hpp"
#include "gfx_context.hpp" #include "gfx_context.hpp"
#include "platform.hpp"
#include "shadercompiler.hpp"
class GFXBuffer; class GFXBuffer;
class GFXPipeline; class GFXPipeline;
@ -293,69 +293,112 @@ enum class GFXFeature {
class GFX { class GFX {
public: public:
// check for runtime support // check for runtime support
virtual bool is_supported() { return false; } virtual bool is_supported() {
virtual GFXContext required_context() { return GFXContext::None; } return false;
virtual ShaderLanguage accepted_shader_language() { return ShaderLanguage::GLSL; } }
virtual const char* get_name() { return nullptr; }
virtual bool supports_feature([[maybe_unused]] const GFXFeature feature) { return false; } virtual GFXContext required_context() {
return GFXContext::None;
}
virtual ShaderLanguage accepted_shader_language() {
return ShaderLanguage::GLSL;
}
virtual const char* get_name() {
return nullptr;
}
virtual bool supports_feature([[maybe_unused]] const GFXFeature feature) {
return false;
}
// try to initialize // try to initialize
virtual bool initialize([[maybe_unused]] const GFXCreateInfo& createInfo) { return false; } virtual bool initialize([[maybe_unused]] const GFXCreateInfo& createInfo) {
return false;
}
virtual void initialize_view([[maybe_unused]] void* native_handle, virtual void initialize_view(
[[maybe_unused]] void* native_handle,
[[maybe_unused]] const platform::window_ptr identifier, [[maybe_unused]] const platform::window_ptr identifier,
[[maybe_unused]] const uint32_t width, [[maybe_unused]] const uint32_t width,
[[maybe_unused]] const uint32_t height) {} [[maybe_unused]] const uint32_t height) {}
virtual void recreate_view([[maybe_unused]] const platform::window_ptr identifier, virtual void recreate_view(
[[maybe_unused]] const platform::window_ptr identifier,
[[maybe_unused]] const uint32_t width, [[maybe_unused]] const uint32_t width,
[[maybe_unused]] const uint32_t height) {} [[maybe_unused]] const uint32_t height) {}
virtual void remove_view([[maybe_unused]] const platform::window_ptr identifier) {} virtual void remove_view([[maybe_unused]] const platform::window_ptr identifier) {}
// buffer operations // buffer operations
virtual GFXBuffer* create_buffer([[maybe_unused]] void* data, virtual GFXBuffer* create_buffer(
[[maybe_unused]] void* data,
[[maybe_unused]] const GFXSize size, [[maybe_unused]] const GFXSize size,
[[maybe_unused]] const bool is_dynamic, [[maybe_unused]] const bool is_dynamic,
[[maybe_unused]] const GFXBufferUsage usage) { return nullptr; } [[maybe_unused]] const GFXBufferUsage usage) {
virtual void copy_buffer([[maybe_unused]] GFXBuffer* buffer, return nullptr;
}
virtual void copy_buffer(
[[maybe_unused]] GFXBuffer* buffer,
[[maybe_unused]] void* data, [[maybe_unused]] void* data,
[[maybe_unused]] const GFXSize offset, [[maybe_unused]] const GFXSize offset,
[[maybe_unused]] const GFXSize size) {} [[maybe_unused]] const GFXSize size) {}
virtual void* get_buffer_contents([[maybe_unused]] GFXBuffer* buffer) { return nullptr; } virtual void* get_buffer_contents([[maybe_unused]] GFXBuffer* buffer) {
virtual void release_buffer_contents([[maybe_unused]] GFXBuffer* buffer, return nullptr;
[[maybe_unused]] void* handle) {} }
virtual void release_buffer_contents([[maybe_unused]] GFXBuffer* buffer, [[maybe_unused]] void* handle) {}
// texture operations // texture operations
virtual GFXTexture* create_texture([[maybe_unused]] const GFXTextureCreateInfo& info) { return nullptr; } virtual GFXTexture* create_texture([[maybe_unused]] const GFXTextureCreateInfo& info) {
virtual void copy_texture([[maybe_unused]] GFXTexture* texture, return nullptr;
}
virtual void copy_texture(
[[maybe_unused]] GFXTexture* texture,
[[maybe_unused]] void* data, [[maybe_unused]] void* data,
[[maybe_unused]] const GFXSize size) {} [[maybe_unused]] const GFXSize size) {}
virtual void copy_texture([[maybe_unused]] GFXTexture* from,
[[maybe_unused]] GFXTexture* to) {} virtual void copy_texture([[maybe_unused]] GFXTexture* from, [[maybe_unused]] GFXTexture* to) {}
virtual void copy_texture([[maybe_unused]] GFXTexture* from,
[[maybe_unused]] GFXBuffer* to) {} virtual void copy_texture([[maybe_unused]] GFXTexture* from, [[maybe_unused]] GFXBuffer* to) {}
// sampler opeations // sampler opeations
virtual GFXSampler* create_sampler([[maybe_unused]] const GFXSamplerCreateInfo& info) { return nullptr; } virtual GFXSampler* create_sampler([[maybe_unused]] const GFXSamplerCreateInfo& info) {
return nullptr;
}
// framebuffer operations // framebuffer operations
virtual GFXFramebuffer* create_framebuffer([[maybe_unused]] const GFXFramebufferCreateInfo& info) { return nullptr; } virtual GFXFramebuffer* create_framebuffer([[maybe_unused]] const GFXFramebufferCreateInfo& info) {
return nullptr;
}
// render pass operations // render pass operations
virtual GFXRenderPass* create_render_pass([[maybe_unused]] const GFXRenderPassCreateInfo& info) { return nullptr; } virtual GFXRenderPass* create_render_pass([[maybe_unused]] const GFXRenderPassCreateInfo& info) {
return nullptr;
}
// pipeline operations // pipeline operations
virtual GFXPipeline* create_graphics_pipeline([[maybe_unused]] const GFXGraphicsPipelineCreateInfo& info) { return nullptr; } virtual GFXPipeline* create_graphics_pipeline([[maybe_unused]] const GFXGraphicsPipelineCreateInfo& info) {
virtual GFXPipeline* create_compute_pipeline([[maybe_unused]] const GFXComputePipelineCreateInfo& info) { return nullptr; } return nullptr;
}
virtual GFXPipeline* create_compute_pipeline([[maybe_unused]] const GFXComputePipelineCreateInfo& info) {
return nullptr;
}
// misc operations // misc operations
virtual GFXSize get_alignment(const GFXSize size) { return size; } virtual GFXSize get_alignment(const GFXSize size) {
return size;
}
virtual GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use) { return nullptr; } virtual GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use) {
return nullptr;
}
virtual void submit([[maybe_unused]] GFXCommandBuffer* command_buffer, virtual void
[[maybe_unused]] const platform::window_ptr window) {} submit([[maybe_unused]] GFXCommandBuffer* command_buffer, [[maybe_unused]] const platform::window_ptr window) {}
}; };

View file

@ -4,5 +4,4 @@
class GFXBuffer : public GFXObject { class GFXBuffer : public GFXObject {
public: public:
}; };

View file

@ -1,9 +1,9 @@
#pragma once #pragma once
#include <vector>
#include <cstring>
#include <array> #include <array>
#include <cstring>
#include <string_view> #include <string_view>
#include <vector>
#include "common.hpp" #include "common.hpp"
@ -230,7 +230,6 @@ public:
command.data.bind_shader_buffer.index = index; command.data.bind_shader_buffer.index = index;
command.data.bind_shader_buffer.size = size; command.data.bind_shader_buffer.size = size;
commands.push_back(command); commands.push_back(command);
} }
@ -252,7 +251,8 @@ public:
commands.push_back(command); commands.push_back(command);
} }
void draw(const uint32_t offset, const uint32_t count, const uint32_t instance_base, const uint32_t instance_count) { void
draw(const uint32_t offset, const uint32_t count, const uint32_t instance_base, const uint32_t instance_count) {
GFXDrawCommand command; GFXDrawCommand command;
command.type = GFXCommandType::Draw; command.type = GFXCommandType::Draw;
command.data.draw.vertex_offset = offset; command.data.draw.vertex_offset = offset;
@ -263,7 +263,11 @@ public:
commands.push_back(command); commands.push_back(command);
} }
void draw_indexed(const uint32_t indexCount, const uint32_t firstIndex, const int32_t vertexOffset, const uint32_t base_instance) { void draw_indexed(
const uint32_t indexCount,
const uint32_t firstIndex,
const int32_t vertexOffset,
const uint32_t base_instance) {
GFXDrawCommand command; GFXDrawCommand command;
command.type = GFXCommandType::DrawIndexed; command.type = GFXCommandType::DrawIndexed;
command.data.draw_indexed.vertex_offset = vertexOffset; command.data.draw_indexed.vertex_offset = vertexOffset;
@ -281,7 +285,8 @@ public:
commands.push_back(command); commands.push_back(command);
} }
void copy_texture(GFXTexture* src, int width, int height, GFXTexture* dst, int to_slice, int to_layer, int to_level) { void
copy_texture(GFXTexture* src, int width, int height, GFXTexture* dst, int to_slice, int to_layer, int to_level) {
GFXDrawCommand command; GFXDrawCommand command;
command.type = GFXCommandType::CopyTexture; command.type = GFXCommandType::CopyTexture;
command.data.copy_texture.src = src; command.data.copy_texture.src = src;

View file

@ -4,5 +4,4 @@
class GFXFramebuffer : public GFXObject { class GFXFramebuffer : public GFXObject {
public: public:
}; };

View file

@ -4,5 +4,4 @@
class GFXRenderPass : public GFXObject { class GFXRenderPass : public GFXObject {
public: public:
}; };

View file

@ -4,5 +4,4 @@
class GFXSampler : public GFXObject { class GFXSampler : public GFXObject {
public: public:
}; };

View file

@ -2,8 +2,8 @@
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <map>
#include <array> #include <array>
#include <map>
#include "gfx.hpp" #include "gfx.hpp"
#include "gfx_vulkan_constants.hpp" #include "gfx_vulkan_constants.hpp"
@ -37,16 +37,26 @@ class GFXVulkanPipeline;
class GFXVulkan : public GFX { class GFXVulkan : public GFX {
public: public:
bool is_supported() override { return true; } bool is_supported() override {
ShaderLanguage accepted_shader_language() override { return ShaderLanguage::SPIRV; } return true;
GFXContext required_context() override { return GFXContext::Vulkan; } }
ShaderLanguage accepted_shader_language() override {
return ShaderLanguage::SPIRV;
}
GFXContext required_context() override {
return GFXContext::Vulkan;
}
const char* get_name() override; const char* get_name() override;
bool supports_feature(GFXFeature feature) override; bool supports_feature(GFXFeature feature) override;
bool initialize(const GFXCreateInfo& info) override; bool initialize(const GFXCreateInfo& info) override;
void initialize_view(void* native_handle, platform::window_ptr identifier, uint32_t width, uint32_t height) override; void
initialize_view(void* native_handle, platform::window_ptr identifier, uint32_t width, uint32_t height) override;
void recreate_view(platform::window_ptr identifier, uint32_t width, uint32_t height) override; void recreate_view(platform::window_ptr identifier, uint32_t width, uint32_t height) override;
// buffer operations // buffer operations
@ -95,8 +105,15 @@ private:
uint64_t getDescriptorHash(GFXVulkanPipeline* pipeline); uint64_t getDescriptorHash(GFXVulkanPipeline* pipeline);
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties); uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
void transitionImageLayout(VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageSubresourceRange range, VkImageLayout oldLayout, VkImageLayout newLayout); void transitionImageLayout(
void inlineTransitionImageLayout(VkCommandBuffer command_buffer, VkImage image,
VkFormat format,
VkImageAspectFlags aspect,
VkImageSubresourceRange range,
VkImageLayout oldLayout,
VkImageLayout newLayout);
void inlineTransitionImageLayout(
VkCommandBuffer command_buffer,
VkImage image, VkImage image,
VkFormat format, VkFormat format,
VkImageAspectFlags aspect, VkImageAspectFlags aspect,

File diff suppressed because it is too large Load diff

View file

@ -11,8 +11,7 @@ namespace prism {
log_output += str + "\n"; log_output += str + "\n";
} }
template <typename S, typename... Args> template<typename S, typename... Args> inline void log(const S& format, Args&&... args) {
inline void log(const S& format, Args&&... args) {
vlog(format, fmt::make_args_checked<Args...>(format, args...)); vlog(format, fmt::make_args_checked<Args...>(format, args...));
} }
} } // namespace prism

View file

@ -22,4 +22,4 @@ namespace prism {
float3(aabb.min.x, aabb.max.y, aabb.max.z), float3(aabb.min.x, aabb.max.y, aabb.max.z),
float3(aabb.max.x, aabb.max.y, aabb.max.z)}; float3(aabb.max.x, aabb.max.y, aabb.max.z)};
} }
} } // namespace prism

View file

@ -1,26 +1,23 @@
#pragma once #pragma once
#include "matrix.hpp" #include "matrix.hpp"
#include "ray.hpp"
#include "transform.hpp" #include "transform.hpp"
#include "vector.hpp" #include "vector.hpp"
#include "ray.hpp"
constexpr double PI = 3.141592653589793; constexpr double PI = 3.141592653589793;
template<typename T> template<typename T> constexpr inline T radians(const T degrees) {
constexpr inline T radians(const T degrees) {
return degrees / static_cast<T>(180) * static_cast<T>(PI); return degrees / static_cast<T>(180) * static_cast<T>(PI);
} }
template<typename T> template<typename T> constexpr inline T degrees(const T radians) {
constexpr inline T degrees(const T radians) {
return radians / static_cast<T>(PI) * static_cast<T>(180); return radians / static_cast<T>(PI) * static_cast<T>(180);
} }
template<typename T> template<typename T> constexpr inline bool nearly_equal(const T a, const T b) {
constexpr inline bool nearly_equal(const T a, const T b) { return std::nextafter(a, std::numeric_limits<T>::lowest()) <= b &&
return std::nextafter(a, std::numeric_limits<T>::lowest()) <= b std::nextafter(a, std::numeric_limits<T>::max()) >= b;
&& std::nextafter(a, std::numeric_limits<T>::max()) >= b;
} }
Matrix4x4 matrix_from_quat(Quaternion quat); Matrix4x4 matrix_from_quat(Quaternion quat);

View file

@ -5,15 +5,18 @@
// m = rows // m = rows
// n = columns // n = columns
// row major storage mode? // row major storage mode?
template<class T, std::size_t M, std::size_t N> template<class T, std::size_t M, std::size_t N> class Matrix {
class Matrix {
public: public:
constexpr Matrix(const T diagonal = T(1)) { constexpr Matrix(const T diagonal = T(1)) {
for (std::size_t i = 0; i < (M * N); i++) for (std::size_t i = 0; i < (M * N); i++)
unordered_data[i] = ((i / M) == (i % N) ? diagonal : T(0)); unordered_data[i] = ((i / M) == (i % N) ? diagonal : T(0));
} }
constexpr Matrix(const prism::float4 m1_, const prism::float4 m2_, const prism::float4 m3_, const prism::float4 m4_) { constexpr Matrix(
const prism::float4 m1_,
const prism::float4 m2_,
const prism::float4 m3_,
const prism::float4 m4_) {
columns[0] = m1_; columns[0] = m1_;
columns[1] = m2_; columns[1] = m2_;
columns[2] = m3_; columns[2] = m3_;
@ -24,8 +27,13 @@ public:
using VectorType = prism::Vector<N, T>; using VectorType = prism::Vector<N, T>;
constexpr VectorType& operator[](const size_t index) { return columns[index]; } constexpr VectorType& operator[](const size_t index) {
constexpr VectorType operator[](const size_t index) const { return columns[index]; } return columns[index];
}
constexpr VectorType operator[](const size_t index) const {
return columns[index];
}
union { union {
VectorType columns[M]; VectorType columns[M];
@ -84,4 +92,6 @@ constexpr inline Matrix4x4 operator*(const Matrix4x4 lhs, const float rhs) {
} }
template<typename T, std::size_t M, std::size_t N> template<typename T, std::size_t M, std::size_t N>
constexpr void Matrix<T, M, N>::operator*=(const Matrix<T, M, N> rhs) { *this = *this * rhs; } constexpr void Matrix<T, M, N>::operator*=(const Matrix<T, M, N> rhs) {
*this = *this * rhs;
}

View file

@ -9,9 +9,7 @@ struct Plane {
}; };
inline Plane normalize(const Plane& plane) { inline Plane normalize(const Plane& plane) {
const float magnitude = std::sqrt(plane.a * plane.a + const float magnitude = std::sqrt(plane.a * plane.a + plane.b * plane.b + plane.c * plane.c);
plane.b * plane.b +
plane.c * plane.c);
Plane normalized_plane = plane; Plane normalized_plane = plane;
normalized_plane.a = plane.a / magnitude; normalized_plane.a = plane.a / magnitude;
@ -23,8 +21,5 @@ inline Plane normalize(const Plane& plane) {
} }
inline float distance_to_point(const Plane& plane, const prism::float3& point) { inline float distance_to_point(const Plane& plane, const prism::float3& point) {
return plane.a * point.x + return plane.a * point.x + plane.b * point.y + plane.c * point.z + plane.d;
plane.b * point.y +
plane.c * point.z +
plane.d;
} }

View file

@ -70,10 +70,7 @@ constexpr inline Quaternion lerp(const Quaternion& a, const Quaternion& b, const
sclq = time; sclq = time;
} }
return {sclp * a.x + sclq * end.x, return {sclp * a.x + sclq * end.x, sclp * a.y + sclq * end.y, sclp * a.z + sclq * end.z, sclp * a.w + sclq * end.w};
sclp * a.y + sclq * end.y,
sclp * a.z + sclq * end.z,
sclp * a.w + sclq * end.w};
} }
constexpr inline Quaternion operator*(const Quaternion lhs, const Quaternion rhs) { constexpr inline Quaternion operator*(const Quaternion lhs, const Quaternion rhs) {

View file

@ -9,4 +9,4 @@ namespace prism {
}; };
float closest_distance_between_lines(ray& l1, ray& l2); float closest_distance_between_lines(ray& l1, ray& l2);
} } // namespace prism

View file

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "matrix.hpp" #include "matrix.hpp"
#include "vector.hpp"
#include "quaternion.hpp" #include "quaternion.hpp"
#include "vector.hpp"
namespace prism { namespace prism {
Matrix4x4 perspective(float field_of_view, float aspect, float z_near, float z_far); Matrix4x4 perspective(float field_of_view, float aspect, float z_near, float z_far);
@ -16,4 +16,4 @@ namespace prism {
Matrix4x4 translate(Matrix4x4 matrix, float3 translation); Matrix4x4 translate(Matrix4x4 matrix, float3 translation);
Matrix4x4 rotate(Matrix4x4 matrix, float angle, float3 axis); Matrix4x4 rotate(Matrix4x4 matrix, float angle, float3 axis);
Matrix4x4 scale(Matrix4x4 matrix, float3 scale); Matrix4x4 scale(Matrix4x4 matrix, float3 scale);
} } // namespace prism

View file

@ -1,9 +1,9 @@
#pragma once #pragma once
#include <array>
#include <cmath> #include <cmath>
#include <type_traits> #include <type_traits>
#include <typeinfo> #include <typeinfo>
#include <array>
namespace prism { namespace prism {
#define DEFINE_OPERATORS(Size) \ #define DEFINE_OPERATORS(Size) \
@ -11,12 +11,8 @@ namespace prism {
for (std::size_t i = 0; i < (Size); i++) \ for (std::size_t i = 0; i < (Size); i++) \
data[i] = scalar; \ data[i] = scalar; \
} \ } \
constexpr T& operator[](const size_t index) { \ constexpr T& operator[](const size_t index) { return data[index]; } \
return data[index]; \ constexpr T operator[](const size_t index) const { return data[index]; } \
} \
constexpr T operator[](const size_t index) const { \
return data[index]; \
} \
constexpr Vector& operator+=(const Vector rhs) { \ constexpr Vector& operator+=(const Vector rhs) { \
for (std::size_t i = 0; i < (Size); i++) \ for (std::size_t i = 0; i < (Size); i++) \
data[i] += rhs[i]; \ data[i] += rhs[i]; \
@ -37,12 +33,8 @@ namespace prism {
data[i] /= scalar; \ data[i] /= scalar; \
return *this; \ return *this; \
} \ } \
constexpr T* ptr() const { \ constexpr T* ptr() const { return data.data(); } \
return data.data(); \ constexpr T* ptr() { return data.data(); } \
} \
constexpr T* ptr() { \
return data.data(); \
} \
constexpr Vector operator-() const { \ constexpr Vector operator-() const { \
Vector vec; \ Vector vec; \
for (std::size_t i = 0; i < (Size); i++) \ for (std::size_t i = 0; i < (Size); i++) \
@ -50,13 +42,9 @@ namespace prism {
return vec; \ return vec; \
} }
template<std::size_t N, class T> template<std::size_t N, class T> struct Vector { std::array<T, N> data; };
struct Vector {
std::array<T, N> data;
};
template<class T> template<class T> struct Vector<2, T> {
struct Vector<2, T> {
constexpr Vector(const T x_, const T y_) { constexpr Vector(const T x_, const T y_) {
x = x_; x = x_;
y = y_; y = y_;
@ -73,8 +61,7 @@ namespace prism {
}; };
}; };
template<class T> template<class T> struct Vector<3, T> {
struct Vector<3, T> {
constexpr Vector(const T x_, const T y_, const T z_) { constexpr Vector(const T x_, const T y_, const T z_) {
x = x_; x = x_;
y = y_; y = y_;
@ -92,8 +79,7 @@ namespace prism {
}; };
}; };
template<class T> template<class T> struct alignas(16) Vector<4, T> {
struct alignas(16) Vector<4, T> {
constexpr Vector(const T x_, const T y_, const T z_, const T w_) { constexpr Vector(const T x_, const T y_, const T z_, const T w_) {
x = x_; x = x_;
y = y_; y = y_;
@ -123,8 +109,7 @@ namespace prism {
using float3 = Vector<3, float>; using float3 = Vector<3, float>;
using float4 = Vector<4, float>; using float4 = Vector<4, float>;
template<std::size_t N, class T> template<std::size_t N, class T> constexpr inline T dot(const Vector<N, T> lhs, const Vector<N, T> rhs) {
constexpr inline T dot(const Vector<N, T> lhs, const Vector<N, T> rhs) {
T product = T(0.0); T product = T(0.0);
for (std::size_t i = 0; i < N; i++) for (std::size_t i = 0; i < N; i++)
@ -133,8 +118,7 @@ namespace prism {
return product; return product;
} }
template<std::size_t N, class T> template<std::size_t N, class T> constexpr inline T length(const Vector<N, T> vec) {
constexpr inline T length(const Vector<N, T> vec) {
return sqrtf(dot(vec, vec)); return sqrtf(dot(vec, vec));
} }
@ -147,8 +131,7 @@ namespace prism {
return vec; return vec;
} }
template<std::size_t N, class T> template<std::size_t N, class T> constexpr inline Vector<N, T> normalize(const Vector<N, T> vec) {
constexpr inline Vector<N, T> normalize(const Vector<N, T> vec) {
Vector<N, T> result; Vector<N, T> result;
const float len = length(vec); const float len = length(vec);
@ -170,15 +153,14 @@ namespace prism {
return std::sqrt((diffX * diffX) + (diffY * diffY) + (diffZ * diffZ)); return std::sqrt((diffX * diffX) + (diffY * diffY) + (diffZ * diffZ));
} }
template<std::size_t N, class T> template<std::size_t N, class T> constexpr inline T norm(const Vector<N, T> vec) {
constexpr inline T norm(const Vector<N, T> vec) {
T val = T(0); T val = T(0);
for (std::size_t i = 0; i < N; i++) for (std::size_t i = 0; i < N; i++)
val += abs(vec[i]); val += abs(vec[i]);
return sqrtf(dot(vec, vec)); return sqrtf(dot(vec, vec));
} }
} } // namespace prism
template<std::size_t N, class T> template<std::size_t N, class T>
constexpr inline bool operator==(const prism::Vector<N, T> lhs, const prism::Vector<N, T> rhs) { constexpr inline bool operator==(const prism::Vector<N, T> lhs, const prism::Vector<N, T> rhs) {

View file

@ -1,11 +1,11 @@
#pragma once #pragma once
#include <fstream>
#include <string>
#include <vector>
#include <optional>
#include <array> #include <array>
#include <filesystem> #include <filesystem>
#include <fstream>
#include <optional>
#include <string>
#include <vector>
#include "log.hpp" #include "log.hpp"
#include "path.hpp" #include "path.hpp"
@ -21,10 +21,8 @@ namespace prism {
public: public:
explicit file(FILE* handle) : handle(handle) {} explicit file(FILE* handle) : handle(handle) {}
file(file&& f) noexcept : file(file&& f) noexcept
mem(std::move(f.mem)), : mem(std::move(f.mem)), handle(std::exchange(f.handle, nullptr)), data(std::move(f.data)) {}
handle(std::exchange(f.handle, nullptr)),
data(std::move(f.data)) {}
~file() { ~file() {
if (handle != nullptr) if (handle != nullptr)
@ -35,8 +33,7 @@ namespace prism {
@param t The pointer to the type. @param t The pointer to the type.
@param s If not 0, the size to load is derived from sizeof(T). @param s If not 0, the size to load is derived from sizeof(T).
*/ */
template<typename T> template<typename T> void read(T* t, const size_t s = 0) {
void read(T* t, const size_t s = 0) {
fread(t, s == 0 ? sizeof(T) : s, 1, handle); fread(t, s == 0 ? sizeof(T) : s, 1, handle);
} }
@ -67,8 +64,7 @@ namespace prism {
} }
/// If the file is loaded in memory, cast the underlying data. /// If the file is loaded in memory, cast the underlying data.
template<typename T> template<typename T> T* cast_data() {
T* cast_data() {
return reinterpret_cast<T*>(data.data()); return reinterpret_cast<T*>(data.data());
} }
@ -133,6 +129,6 @@ namespace prism {
path get_file_path(const path& path); path get_file_path(const path& path);
inline path base_domain = "/base", game_domain = "/game"; inline path base_domain = "/base", game_domain = "/game";
} } // namespace prism
inline std::array<std::string, 3> domain_data; inline std::array<std::string, 3> domain_data;

View file

@ -77,8 +77,8 @@ enum class PlatformTheme {
// note: a platform may be built with support for a specific context (e.g. ENABLE_VULKAN, ENABLE_DIRECTX, etc) // note: a platform may be built with support for a specific context (e.g. ENABLE_VULKAN, ENABLE_DIRECTX, etc)
// this only determines it at build-time, not at runtime. // this only determines it at build-time, not at runtime.
#ifdef ENABLE_VULKAN #ifdef ENABLE_VULKAN
#include <vulkan/vulkan.h>
#include <vector> #include <vector>
#include <vulkan/vulkan.h>
struct vulkan_information { struct vulkan_information {
std::vector<const char*> surface_extensions; std::vector<const char*> surface_extensions;
@ -140,9 +140,9 @@ namespace platform {
void initialize_context(GFXContext context); void initialize_context(GFXContext context);
/* /*
* This is used in specific cases where the gfx backend may need to know important information before window creation. * This is used in specific cases where the gfx backend may need to know important information before window
* A good example is the surface extension required by a specific window backend, but this is between initialize_context * creation. A good example is the surface extension required by a specific window backend, but this is between
* and create_surface calls. * initialize_context and create_surface calls.
* *
* the returned structs are in a naming scheme of X_information. * the returned structs are in a naming scheme of X_information.
*/ */
@ -152,8 +152,10 @@ namespace platform {
@param title The title of the window. @param title The title of the window.
@param rect The requested size and position of the window. @param rect The requested size and position of the window.
@param flags The requested window flags. @param flags The requested window flags.
@note Depending on the platform, some of these parameters might be unused. The best practice is to always assume that none of them may be used. @note Depending on the platform, some of these parameters might be unused. The best practice is to always assume
@note On platforms that do not support the Windowing feature, calling open_window more than once is not supported. In this case, the same identifier is returned. that none of them may be used.
@note On platforms that do not support the Windowing feature, calling open_window more than once is not supported.
In this case, the same identifier is returned.
@return A valid window identifier. @return A valid window identifier.
*/ */
window_ptr open_window(std::string_view title, prism::Rectangle rect, WindowFlags flags); window_ptr open_window(std::string_view title, prism::Rectangle rect, WindowFlags flags);
@ -171,8 +173,8 @@ namespace platform {
void* create_surface(window_ptr window, void* surface_creation_info); void* create_surface(window_ptr window, void* surface_creation_info);
/* /*
* This needs to be implemented under certain gfx contexts (such as metal) which calls [layer nextDrawable] underneath * This needs to be implemented under certain gfx contexts (such as metal) which calls [layer nextDrawable]
* can be no-op for contexts such as vulkan which can happen within it's own API. * underneath can be no-op for contexts such as vulkan which can happen within it's own API.
* *
* the return type is named as X_next_image. may be null. * the return type is named as X_next_image. may be null.
*/ */
@ -201,7 +203,8 @@ namespace platform {
/// Get the window size, note that in hidpi scenarios this is the non-scaled resolution. /// Get the window size, note that in hidpi scenarios this is the non-scaled resolution.
prism::Extent get_window_size(window_ptr window); prism::Extent get_window_size(window_ptr window);
/// Get the window's drawable size. Always use this instead of manually multiplying the window size by the content scale. /// Get the window's drawable size. Always use this instead of manually multiplying the window size by the content
/// scale.
prism::Extent get_window_drawable_size(window_ptr window); prism::Extent get_window_drawable_size(window_ptr window);
/// Query whether or not the window is focused. /// Query whether or not the window is focused.
@ -249,8 +252,9 @@ namespace platform {
/// On platforms that support moue capture, this will lock the mouse cursor to the window and hide it. /// On platforms that support moue capture, this will lock the mouse cursor to the window and hide it.
void capture_mouse(bool capture); void capture_mouse(bool capture);
// TODO: right now the OS intercepting and saying "We dont want text input anymore" ala software keyboards is NOT supported yet // TODO: right now the OS intercepting and saying "We dont want text input anymore" ala software keyboards is NOT
// supported yet
void begin_text_input(); void begin_text_input();
void end_text_input(); void end_text_input();
} } // namespace platform

View file

@ -2,13 +2,13 @@
#include <array> #include <array>
#include "aabb.hpp"
#include "asset_types.hpp"
#include "components.hpp"
#include "frustum.hpp" #include "frustum.hpp"
#include "matrix.hpp" #include "matrix.hpp"
#include "vector.hpp"
#include "components.hpp"
#include "aabb.hpp"
#include "plane.hpp" #include "plane.hpp"
#include "asset_types.hpp" #include "vector.hpp"
class Scene; class Scene;

View file

@ -2,8 +2,8 @@
#include <string_view> #include <string_view>
#include "pass.hpp"
#include "file.hpp" #include "file.hpp"
#include "pass.hpp"
class GFXBuffer; class GFXBuffer;
class GFXCommandBuffer; class GFXCommandBuffer;

View file

@ -15,11 +15,13 @@ constexpr int bone_buffer_index = 10;
class MaterialCompiler { class MaterialCompiler {
public: public:
GFXPipeline* create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only = false, bool cubemap = false); GFXPipeline*
create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only = false, bool cubemap = false);
GFXPipeline* create_skinned_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only = false); GFXPipeline* create_skinned_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only = false);
// generates static and skinned versions of the pipeline provided // generates static and skinned versions of the pipeline provided
std::tuple<GFXPipeline*, GFXPipeline*> create_pipeline_permutations(GFXGraphicsPipelineCreateInfo& createInfo, bool positions_only = false); std::tuple<GFXPipeline*, GFXPipeline*>
create_pipeline_permutations(GFXGraphicsPipelineCreateInfo& createInfo, bool positions_only = false);
ShaderSource compile_material_fragment(Material& material, bool use_ibl = true); ShaderSource compile_material_fragment(Material& material, bool use_ibl = true);
}; };

View file

@ -21,11 +21,14 @@ public:
virtual void create_render_target_resources([[maybe_unused]] RenderTarget& target) {} virtual void create_render_target_resources([[maybe_unused]] RenderTarget& target) {}
virtual void render_scene([[maybe_unused]] Scene& scene, virtual void render_scene([[maybe_unused]] Scene& scene, [[maybe_unused]] GFXCommandBuffer* commandBuffer) {}
[[maybe_unused]] GFXCommandBuffer* commandBuffer) {}
virtual void render_post([[maybe_unused]] GFXCommandBuffer* commandBuffer, virtual void render_post(
[[maybe_unused]] GFXCommandBuffer* commandBuffer,
[[maybe_unused]] RenderTarget& target, [[maybe_unused]] RenderTarget& target,
[[maybe_unused]] platform::window_ptr index) {} [[maybe_unused]] platform::window_ptr index) {}
virtual GFXTexture* get_requested_texture([[maybe_unused]] PassTextureType type) { return nullptr; } virtual GFXTexture* get_requested_texture([[maybe_unused]] PassTextureType type) {
return nullptr;
}
}; };

View file

@ -1,19 +1,19 @@
#pragma once #pragma once
#include <string_view>
#include <vector>
#include <cmath> #include <cmath>
#include <functional> #include <functional>
#include <string_view>
#include <vector>
#include "pass.hpp" #include "common.hpp"
#include "matrix.hpp" #include "matrix.hpp"
#include "object.hpp" #include "object.hpp"
#include "common.hpp" #include "pass.hpp"
#include "render_options.hpp"
#include "path.hpp" #include "path.hpp"
#include "shadercompiler.hpp"
#include "rendertarget.hpp"
#include "platform.hpp" #include "platform.hpp"
#include "render_options.hpp"
#include "rendertarget.hpp"
#include "shadercompiler.hpp"
class GFX; class GFX;
class GFXBuffer; class GFXBuffer;
@ -58,14 +58,19 @@ namespace prism {
void render(GFXCommandBuffer* command_buffer, Scene* scene, RenderTarget& target, platform::window_ptr index); void render(GFXCommandBuffer* command_buffer, Scene* scene, RenderTarget& target, platform::window_ptr index);
void render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Object camera_object, Camera& camera, void render_camera(
prism::Extent extent, RenderTarget& target, controller_continuity &continuity); GFXCommandBuffer* command_buffer,
Scene& scene,
Object camera_object,
Camera& camera,
prism::Extent extent,
RenderTarget& target,
controller_continuity& continuity);
void create_mesh_pipeline(Material& material) const; void create_mesh_pipeline(Material& material) const;
// passes // passes
template<class T, typename... Args> template<class T, typename... Args> T* addPass(Args&&... args) {
T* addPass(Args &&... args) {
auto t = std::make_unique<T>(args...); auto t = std::make_unique<T>(args...);
t->initialize(); t->initialize();
@ -151,4 +156,4 @@ namespace prism {
std::vector<std::unique_ptr<Pass>> passes; std::vector<std::unique_ptr<Pass>> passes;
}; };
} } // namespace prism

View file

@ -14,7 +14,8 @@ public:
prism::Extent extent; prism::Extent extent;
[[nodiscard]] prism::Extent get_render_extent() const { [[nodiscard]] prism::Extent get_render_extent() const {
return {static_cast<uint32_t>(std::max(int(extent.width * render_options.render_scale), 1)), return {
static_cast<uint32_t>(std::max(int(extent.width * render_options.render_scale), 1)),
static_cast<uint32_t>(std::max(int(extent.height * render_options.render_scale), 1))}; static_cast<uint32_t>(std::max(int(extent.height * render_options.render_scale), 1))};
} }

View file

@ -27,7 +27,8 @@ public:
GFXTexture* environmentCube = nullptr; GFXTexture* environmentCube = nullptr;
GFXTexture* offscreenTexture = nullptr, *irradianceOffscreenTexture = nullptr, *prefilteredOffscreenTexture = nullptr; GFXTexture *offscreenTexture = nullptr, *irradianceOffscreenTexture = nullptr,
*prefilteredOffscreenTexture = nullptr;
GFXTexture* offscreenDepth = nullptr; GFXTexture* offscreenDepth = nullptr;
GFXFramebuffer *offscreenFramebuffer = nullptr, *irradianceFramebuffer = nullptr, *prefilteredFramebuffer = nullptr; GFXFramebuffer *offscreenFramebuffer = nullptr, *irradianceFramebuffer = nullptr, *prefilteredFramebuffer = nullptr;

View file

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "components.hpp"
#include "math.hpp" #include "math.hpp"
#include "object.hpp" #include "object.hpp"
#include "components.hpp"
class GFX; class GFX;
class GFXCommandBuffer; class GFXCommandBuffer;
@ -24,7 +24,15 @@ public:
void render(GFXCommandBuffer* command_buffer, Scene& scene); void render(GFXCommandBuffer* command_buffer, Scene& scene);
private: private:
void render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, Matrix4x4 light_matrix, Matrix4x4 model, prism::float3 light_position, Light::Type type, const CameraFrustum& frustum, int base_instance); void render_meshes(
GFXCommandBuffer* command_buffer,
Scene& scene,
Matrix4x4 light_matrix,
Matrix4x4 model,
prism::float3 light_position,
Light::Type type,
const CameraFrustum& frustum,
int base_instance);
void render_sun(GFXCommandBuffer* command_buffer, Scene& scene, prism::Object light_object, Light& light); void render_sun(GFXCommandBuffer* command_buffer, Scene& scene, prism::Object light_object, Light& light);
void render_spot(GFXCommandBuffer* command_buffer, Scene& scene, prism::Object light_object, Light& light); void render_spot(GFXCommandBuffer* command_buffer, Scene& scene, prism::Object light_object, Light& light);

View file

@ -1,10 +1,10 @@
#include "dofpass.hpp" #include "dofpass.hpp"
#include "renderer.hpp" #include "asset.hpp"
#include "engine.hpp"
#include "gfx.hpp" #include "gfx.hpp"
#include "gfx_commandbuffer.hpp" #include "gfx_commandbuffer.hpp"
#include "engine.hpp" #include "renderer.hpp"
#include "asset.hpp"
AssetPtr<Texture> aperture_texture; AssetPtr<Texture> aperture_texture;
@ -36,12 +36,9 @@ DoFPass::DoFPass(GFX* gfx) {
{0, GFXBindingType::StorageImage}, {0, GFXBindingType::StorageImage},
{1, GFXBindingType::Texture}, {1, GFXBindingType::Texture},
{3, GFXBindingType::Texture}, {3, GFXBindingType::Texture},
{2, GFXBindingType::PushConstant} {2, GFXBindingType::PushConstant}};
};
create_info.shader_input.push_constants = { create_info.shader_input.push_constants = {{sizeof(prism::float4), 0}};
{sizeof(prism::float4), 0}
};
create_info.render_pass = renderpass; create_info.render_pass = renderpass;

View file

@ -2,11 +2,11 @@
#include <imgui.h> #include <imgui.h>
#include "assertions.hpp"
#include "engine.hpp" #include "engine.hpp"
#include "gfx.hpp" #include "gfx.hpp"
#include "gfx_commandbuffer.hpp" #include "gfx_commandbuffer.hpp"
#include "log.hpp" #include "log.hpp"
#include "assertions.hpp"
#include "renderer.hpp" #include "renderer.hpp"
void ImGuiPass::initialize() { void ImGuiPass::initialize() {
@ -57,14 +57,9 @@ void ImGuiPass::create_render_target_resources(RenderTarget& target) {
createInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha; createInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha;
createInfo.blending.dst_alpha = GFXBlendFactor::OneMinusSrcAlpha; createInfo.blending.dst_alpha = GFXBlendFactor::OneMinusSrcAlpha;
createInfo.shader_input.push_constants = { createInfo.shader_input.push_constants = {{sizeof(Matrix4x4), 0}};
{sizeof(Matrix4x4), 0}
};
createInfo.shader_input.bindings = { createInfo.shader_input.bindings = {{1, GFXBindingType::PushConstant}, {2, GFXBindingType::Texture}};
{1, GFXBindingType::PushConstant},
{2, GFXBindingType::Texture}
};
pipeline = engine->get_gfx()->create_graphics_pipeline(createInfo); pipeline = engine->get_gfx()->create_graphics_pipeline(createInfo);
} }
@ -94,7 +89,8 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ
if (draw_data->TotalVtxCount > 0) if (draw_data->TotalVtxCount > 0)
update_buffers(target, *draw_data); update_buffers(target, *draw_data);
const Matrix4x4 projection = prism::orthographic(draw_data->DisplayPos.x, const Matrix4x4 projection = prism::orthographic(
draw_data->DisplayPos.x,
draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x,
draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y + draw_data->DisplaySize.y,
draw_data->DisplayPos.y, draw_data->DisplayPos.y,
@ -119,14 +115,26 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ
if (pcmd->UserCallback != nullptr) { if (pcmd->UserCallback != nullptr) {
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} else { } else {
ImVec2 clip_min((pcmd->ClipRect.x - clip_offset.x) * clip_scale.x, (pcmd->ClipRect.y - clip_offset.y) * clip_scale.y); ImVec2 clip_min(
ImVec2 clip_max((pcmd->ClipRect.z - clip_offset.x) * clip_scale.x, (pcmd->ClipRect.w - clip_offset.y) * clip_scale.y); (pcmd->ClipRect.x - clip_offset.x) * clip_scale.x,
(pcmd->ClipRect.y - clip_offset.y) * clip_scale.y);
ImVec2 clip_max(
(pcmd->ClipRect.z - clip_offset.x) * clip_scale.x,
(pcmd->ClipRect.w - clip_offset.y) * clip_scale.y);
// Clamp to viewport as vkCmdSetScissor() won't accept values that are off bounds // Clamp to viewport as vkCmdSetScissor() won't accept values that are off bounds
if (clip_min.x < 0.0f) { clip_min.x = 0.0f; } if (clip_min.x < 0.0f) {
if (clip_min.y < 0.0f) { clip_min.y = 0.0f; } clip_min.x = 0.0f;
if (clip_max.x > framebuffer_width) { clip_max.x = (float)framebuffer_width; } }
if (clip_max.y > framebuffer_height) { clip_max.y = (float)framebuffer_height; } if (clip_min.y < 0.0f) {
clip_min.y = 0.0f;
}
if (clip_max.x > framebuffer_width) {
clip_max.x = (float)framebuffer_width;
}
if (clip_max.y > framebuffer_height) {
clip_max.y = (float)framebuffer_height;
}
if (clip_max.x < clip_min.x || clip_max.y < clip_min.y) if (clip_max.x < clip_min.x || clip_max.y < clip_min.y)
continue; continue;
@ -140,12 +148,12 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ
command_buffer->set_scissor(scissor); command_buffer->set_scissor(scissor);
command_buffer->set_vertex_buffer(target.vertex_buffer[target.current_frame], 0, 0); command_buffer->set_vertex_buffer(target.vertex_buffer[target.current_frame], 0, 0);
command_buffer->set_index_buffer(target.index_buffer[target.current_frame], sizeof(ImDrawIdx) == 2 ? IndexType::UINT16 : IndexType::UINT32); command_buffer->set_index_buffer(
target.index_buffer[target.current_frame],
command_buffer->draw_indexed(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? IndexType::UINT16 : IndexType::UINT32);
(index_offset + pcmd->IdxOffset),
(vertex_offset + pcmd->VtxOffset), 0);
command_buffer->draw_indexed(
pcmd->ElemCount, (index_offset + pcmd->IdxOffset), (vertex_offset + pcmd->VtxOffset), 0);
} }
} }
@ -166,7 +174,8 @@ void ImGuiPass::load_font(const std::string_view filename) {
font_file->read_all(); font_file->read_all();
io.Fonts->AddFontFromMemoryTTF(font_file->cast_data<unsigned char>(), font_file->size(), 15.0f * platform::get_monitor_dpi()); io.Fonts->AddFontFromMemoryTTF(
font_file->cast_data<unsigned char>(), font_file->size(), 15.0f * platform::get_monitor_dpi());
ImGui::GetIO().FontGlobalScale = 1.0f / platform::get_monitor_dpi(); ImGui::GetIO().FontGlobalScale = 1.0f / platform::get_monitor_dpi();
} else { } else {
prism::log("Failed to load font file for imgui!"); prism::log("Failed to load font file for imgui!");
@ -202,13 +211,17 @@ void ImGuiPass::update_buffers(RenderTarget& target, const ImDrawData& draw_data
Expects(new_vertex_size > 0); Expects(new_vertex_size > 0);
Expects(new_index_size > 0); Expects(new_index_size > 0);
if(target.vertex_buffer[target.current_frame] == nullptr || target.current_vertex_size[target.current_frame] < new_vertex_size) { if (target.vertex_buffer[target.current_frame] == nullptr ||
target.vertex_buffer[target.current_frame] = engine->get_gfx()->create_buffer(nullptr, new_vertex_size, true, GFXBufferUsage::Vertex); target.current_vertex_size[target.current_frame] < new_vertex_size) {
target.vertex_buffer[target.current_frame] =
engine->get_gfx()->create_buffer(nullptr, new_vertex_size, true, GFXBufferUsage::Vertex);
target.current_vertex_size[target.current_frame] = new_vertex_size; target.current_vertex_size[target.current_frame] = new_vertex_size;
} }
if(target.index_buffer[target.current_frame] == nullptr || target.current_index_size[target.current_frame] < new_index_size) { if (target.index_buffer[target.current_frame] == nullptr ||
target.index_buffer[target.current_frame] = engine->get_gfx()->create_buffer(nullptr, new_index_size, true, GFXBufferUsage::Index); target.current_index_size[target.current_frame] < new_index_size) {
target.index_buffer[target.current_frame] =
engine->get_gfx()->create_buffer(nullptr, new_index_size, true, GFXBufferUsage::Index);
target.current_index_size[target.current_frame] = new_index_size; target.current_index_size[target.current_frame] = new_index_size;
} }

View file

@ -1,11 +1,11 @@
#include "materialcompiler.hpp" #include "materialcompiler.hpp"
#include "engine.hpp"
#include "file.hpp" #include "file.hpp"
#include "log.hpp" #include "log.hpp"
#include "engine.hpp"
#include "string_utils.hpp"
#include "shadercompiler.hpp"
#include "renderer.hpp" #include "renderer.hpp"
#include "shadercompiler.hpp"
#include "string_utils.hpp"
ShaderSource get_shader(const std::string& filename, bool skinned, bool cubemap) { ShaderSource get_shader(const std::string& filename, bool skinned, bool cubemap) {
auto shader_file = prism::open_file(prism::base_domain / filename); auto shader_file = prism::open_file(prism::base_domain / filename);
@ -28,10 +28,16 @@ ShaderSource get_shader(const std::string& filename, bool skinned, bool cubemap)
if (cubemap) if (cubemap)
options.add_definition("CUBEMAP"); options.add_definition("CUBEMAP");
return *shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(shader_file->read_as_string()), engine->get_gfx()->accepted_shader_language(), options); return *shader_compiler.compile(
ShaderLanguage::GLSL,
stage,
ShaderSource(shader_file->read_as_string()),
engine->get_gfx()->accepted_shader_language(),
options);
} }
GFXPipeline* MaterialCompiler::create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only, bool cubemap) { GFXPipeline*
MaterialCompiler::create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only, bool cubemap) {
// take vertex src // take vertex src
const std::string vertex_path = fmt::format("{}.glsl", createInfo.shaders.vertex_src.as_path().string()); const std::string vertex_path = fmt::format("{}.glsl", createInfo.shaders.vertex_src.as_path().string());
@ -44,29 +50,23 @@ GFXPipeline* MaterialCompiler::create_static_pipeline(GFXGraphicsPipelineCreateI
createInfo.shaders.vertex_src = get_shader(vertex_path, false, cubemap); createInfo.shaders.vertex_src = get_shader(vertex_path, false, cubemap);
if (positions_only) { if (positions_only) {
createInfo.vertex_input.inputs = { createInfo.vertex_input.inputs = {{position_buffer_index, sizeof(prism::float3)}};
{position_buffer_index, sizeof(prism::float3)}
};
createInfo.vertex_input.attributes = { createInfo.vertex_input.attributes = {{position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3}};
{position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3}
};
} else { } else {
createInfo.vertex_input.inputs = { createInfo.vertex_input.inputs = {
{position_buffer_index, sizeof(prism::float3)}, {position_buffer_index, sizeof(prism::float3)},
{normal_buffer_index, sizeof(prism::float3)}, {normal_buffer_index, sizeof(prism::float3)},
{texcoord_buffer_index, sizeof(prism::float2)}, {texcoord_buffer_index, sizeof(prism::float2)},
{tangent_buffer_index, sizeof(prism::float3)}, {tangent_buffer_index, sizeof(prism::float3)},
{bitangent_buffer_index, sizeof(prism::float3)} {bitangent_buffer_index, sizeof(prism::float3)}};
};
createInfo.vertex_input.attributes = { createInfo.vertex_input.attributes = {
{position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3}, {position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3},
{normal_buffer_index, 1, 0, GFXVertexFormat::FLOAT3}, {normal_buffer_index, 1, 0, GFXVertexFormat::FLOAT3},
{texcoord_buffer_index, 2, 0, GFXVertexFormat::FLOAT2}, {texcoord_buffer_index, 2, 0, GFXVertexFormat::FLOAT2},
{tangent_buffer_index, 3, 0, GFXVertexFormat::FLOAT3}, {tangent_buffer_index, 3, 0, GFXVertexFormat::FLOAT3},
{bitangent_buffer_index, 4, 0, GFXVertexFormat::FLOAT3} {bitangent_buffer_index, 4, 0, GFXVertexFormat::FLOAT3}};
};
} }
return engine->get_gfx()->create_graphics_pipeline(createInfo); return engine->get_gfx()->create_graphics_pipeline(createInfo);
@ -84,15 +84,12 @@ GFXPipeline* MaterialCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreate
if (positions_only) { if (positions_only) {
createInfo.vertex_input.inputs = { createInfo.vertex_input.inputs = {
{position_buffer_index, sizeof(prism::float3)}, {position_buffer_index, sizeof(prism::float3)}, {bone_buffer_index, sizeof(BoneVertexData)}};
{bone_buffer_index, sizeof(BoneVertexData)}
};
createInfo.vertex_input.attributes = { createInfo.vertex_input.attributes = {
{position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3}, {position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3},
{bone_buffer_index, 4, offsetof(BoneVertexData, ids), GFXVertexFormat::INT4}, {bone_buffer_index, 4, offsetof(BoneVertexData, ids), GFXVertexFormat::INT4},
{bone_buffer_index, 5, offsetof(BoneVertexData, weights), GFXVertexFormat::FLOAT4} {bone_buffer_index, 5, offsetof(BoneVertexData, weights), GFXVertexFormat::FLOAT4}};
};
} else { } else {
createInfo.vertex_input.inputs = { createInfo.vertex_input.inputs = {
{position_buffer_index, sizeof(prism::float3)}, {position_buffer_index, sizeof(prism::float3)},
@ -100,8 +97,7 @@ GFXPipeline* MaterialCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreate
{texcoord_buffer_index, sizeof(prism::float2)}, {texcoord_buffer_index, sizeof(prism::float2)},
{tangent_buffer_index, sizeof(prism::float3)}, {tangent_buffer_index, sizeof(prism::float3)},
{bitangent_buffer_index, sizeof(prism::float3)}, {bitangent_buffer_index, sizeof(prism::float3)},
{bone_buffer_index, sizeof(BoneVertexData)} {bone_buffer_index, sizeof(BoneVertexData)}};
};
createInfo.vertex_input.attributes = { createInfo.vertex_input.attributes = {
{position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3}, {position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3},
@ -117,7 +113,8 @@ GFXPipeline* MaterialCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreate
return engine->get_gfx()->create_graphics_pipeline(createInfo); return engine->get_gfx()->create_graphics_pipeline(createInfo);
} }
std::tuple<GFXPipeline*, GFXPipeline*> MaterialCompiler::create_pipeline_permutations(GFXGraphicsPipelineCreateInfo& createInfo, bool positions_only) { std::tuple<GFXPipeline*, GFXPipeline*>
MaterialCompiler::create_pipeline_permutations(GFXGraphicsPipelineCreateInfo& createInfo, bool positions_only) {
auto st = create_static_pipeline(createInfo, positions_only); auto st = create_static_pipeline(createInfo, positions_only);
auto ss = create_skinned_pipeline(createInfo, positions_only); auto ss = create_skinned_pipeline(createInfo, positions_only);
@ -176,7 +173,8 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
break; break;
} }
format_to(std::back_inserter(src), format_to(
std::back_inserter(src),
R"(layout (location = 0) in vec3 in_frag_pos; R"(layout (location = 0) in vec3 in_frag_pos;
layout(location = 1) in vec3 in_normal; layout(location = 1) in vec3 in_normal;
layout(location = 2) in vec2 in_uv; layout(location = 2) in vec2 in_uv;
@ -184,7 +182,8 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
)"); )");
if (render_options.enable_point_shadows) { if (render_options.enable_point_shadows) {
format_to(std::back_inserter(src), format_to(
std::back_inserter(src),
R"(#define POINT_SHADOWS_SUPPORTED R"(#define POINT_SHADOWS_SUPPORTED
layout (binding = 3) uniform samplerCubeArray point_shadow; layout (binding = 3) uniform samplerCubeArray point_shadow;
)"); )");
@ -193,14 +192,16 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
format_to(std::back_inserter(src), struct_info); format_to(std::back_inserter(src), struct_info);
if (use_ibl) { if (use_ibl) {
format_to(std::back_inserter(src), format_to(
std::back_inserter(src),
R"(layout (binding = 7) uniform samplerCubeArray irrandianceSampler; R"(layout (binding = 7) uniform samplerCubeArray irrandianceSampler;
layout (binding = 8) uniform samplerCubeArray prefilterSampler; layout (binding = 8) uniform samplerCubeArray prefilterSampler;
layout (binding = 9) uniform sampler2D brdfSampler; layout (binding = 9) uniform sampler2D brdfSampler;
)"); )");
} }
format_to(std::back_inserter(src), format_to(
std::back_inserter(src),
R"(layout(location = 4) in vec4 fragPosLightSpace; R"(layout(location = 4) in vec4 fragPosLightSpace;
layout(location = 5) in mat3 in_tbn; layout(location = 5) in mat3 in_tbn;
layout(location = 14) in vec4 fragPostSpotLightSpace[max_spot_lights]; layout(location = 14) in vec4 fragPostSpotLightSpace[max_spot_lights];
@ -226,7 +227,8 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
} }
if (use_ibl) { if (use_ibl) {
format_to(std::back_inserter(src), format_to(
std::back_inserter(src),
R"(vec3 get_reflect(int i, vec3 final_normal) {{ R"(vec3 get_reflect(int i, vec3 final_normal) {{
const vec3 direction = normalize(in_frag_pos - scene.camPos.xyz); const vec3 direction = normalize(in_frag_pos - scene.camPos.xyz);
const vec3 reflection = reflect(direction, normalize(final_normal)); const vec3 reflection = reflect(direction, normalize(final_normal));
@ -244,7 +246,8 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
} }
if (render_options.enable_normal_shadowing) { if (render_options.enable_normal_shadowing) {
format_to(std::back_inserter(src), format_to(
std::back_inserter(src),
R"(float calculate_normal_lighting(in sampler2D normal_map, const vec3 normal, const vec3 light_dir) {{ R"(float calculate_normal_lighting(in sampler2D normal_map, const vec3 normal, const vec3 light_dir) {{
float height_scale = 0.8; float height_scale = 0.8;
float sample_count = 100.0; float sample_count = 100.0;
@ -279,7 +282,8 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
} }
if (use_ibl) { if (use_ibl) {
format_to(std::back_inserter(src), format_to(
std::back_inserter(src),
R"(vec3 ibl(const int probe, const ComputedSurfaceInfo surface_info, const float intensity) {{ R"(vec3 ibl(const int probe, const ComputedSurfaceInfo surface_info, const float intensity) {{
const vec3 F = fresnel_schlick_roughness(surface_info.NdotV, surface_info.F0, surface_info.roughness); const vec3 F = fresnel_schlick_roughness(surface_info.NdotV, surface_info.F0, surface_info.roughness);
const vec3 R = get_reflect(probe, surface_info.N); const vec3 R = get_reflect(probe, surface_info.N);
@ -296,21 +300,28 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
format_to(std::back_inserter(src), "void main() {{\n"); format_to(std::back_inserter(src), "void main() {{\n");
if (material.colorProperty.type == DataType::Vector3) { if (material.colorProperty.type == DataType::Vector3) {
format_to(std::back_inserter(src), "vec3 Color = vec3({}, {}, {});\n", material.colorProperty.value.x, material.colorProperty.value.y, material.colorProperty.value.z); format_to(
std::back_inserter(src),
"vec3 Color = vec3({}, {}, {});\n",
material.colorProperty.value.x,
material.colorProperty.value.y,
material.colorProperty.value.z);
} else if (material.colorProperty.type == DataType::AssetTexture) { } else if (material.colorProperty.type == DataType::AssetTexture) {
format_to(std::back_inserter(src), "vec3 Color = texture(colorTexture, in_uv).rgb;\n"); format_to(std::back_inserter(src), "vec3 Color = texture(colorTexture, in_uv).rgb;\n");
} else if (material.colorProperty.type == DataType::Float) { } else if (material.colorProperty.type == DataType::Float) {
format_to(std::back_inserter(src), "vec3 Color = vec3({}});\n", material.colorProperty.float_value); format_to(std::back_inserter(src), "vec3 Color = vec3({}});\n", material.colorProperty.float_value);
} }
format_to(std::back_inserter(src), format_to(
std::back_inserter(src),
R"(vec3 final_diffuse_color = from_srgb_to_linear(Color); R"(vec3 final_diffuse_color = from_srgb_to_linear(Color);
float final_roughness = scene.materials[inMaterialIndex].info.y; float final_roughness = scene.materials[inMaterialIndex].info.y;
float final_metallic = scene.materials[inMaterialIndex].info.x; float final_metallic = scene.materials[inMaterialIndex].info.x;
)"); )");
if (material.normalProperty.type == DataType::AssetTexture) { if (material.normalProperty.type == DataType::AssetTexture) {
format_to(std::back_inserter(src), format_to(
std::back_inserter(src),
R"(vec3 final_normal = texture(normalTexture, in_uv).rgb; R"(vec3 final_normal = texture(normalTexture, in_uv).rgb;
final_normal = final_normal * 2.0 - 1.0; final_normal = final_normal * 2.0 - 1.0;
final_normal = in_tbn * final_normal; final_normal = in_tbn * final_normal;
@ -319,7 +330,8 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
format_to(std::back_inserter(src), "vec3 final_normal = in_normal;\n"); format_to(std::back_inserter(src), "vec3 final_normal = in_normal;\n");
} }
format_to(std::back_inserter(src), format_to(
std::back_inserter(src),
R"(ComputedSurfaceInfo surface_info = compute_surface(final_diffuse_color.rgb, final_normal, final_metallic, final_roughness); R"(ComputedSurfaceInfo surface_info = compute_surface(final_diffuse_color.rgb, final_normal, final_metallic, final_roughness);
vec3 Lo = vec3(0); vec3 Lo = vec3(0);
for(int i = 0; i < scene.numLights; i++) {{ for(int i = 0; i < scene.numLights; i++) {{
@ -339,15 +351,21 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
SurfaceBRDF surface_brdf = brdf(light_info.direction, surface_info); SurfaceBRDF surface_brdf = brdf(light_info.direction, surface_info);
)"); )");
if(render_options.enable_normal_mapping && material.normalProperty.type == DataType::AssetTexture && render_options.enable_normal_shadowing) { if (render_options.enable_normal_mapping && material.normalProperty.type == DataType::AssetTexture &&
format_to(std::back_inserter(src), "light_info.radiance *= calculate_normal_lighting(normalTexture, final_normal, light_info.direction);\n"); render_options.enable_normal_shadowing) {
format_to(
std::back_inserter(src),
"light_info.radiance *= calculate_normal_lighting(normalTexture, final_normal, light_info.direction);\n");
} }
format_to(std::back_inserter(src), "Lo += ((surface_brdf.specular + surface_brdf.diffuse) * light_info.radiance * surface_brdf.NdotL) * scene.lights[i].colorSize.rgb;\n \ format_to(
std::back_inserter(src),
"Lo += ((surface_brdf.specular + surface_brdf.diffuse) * light_info.radiance * surface_brdf.NdotL) * scene.lights[i].colorSize.rgb;\n \
}}\n"); }}\n");
if (use_ibl) { if (use_ibl) {
format_to(std::back_inserter(src), format_to(
std::back_inserter(src),
R"(vec3 ambient = vec3(0.0); R"(vec3 ambient = vec3(0.0);
float sum = 0.0; float sum = 0.0;
for(int i = 0; i < max_probes; i++) {{ for(int i = 0; i < max_probes; i++) {{
@ -376,5 +394,9 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
format_to(std::back_inserter(src), "}}\n"); format_to(std::back_inserter(src), "}}\n");
return *shader_compiler.compile(ShaderLanguage::GLSL, ShaderStage::Fragment, ShaderSource(to_string(src)), engine->get_gfx()->accepted_shader_language()); return *shader_compiler.compile(
ShaderLanguage::GLSL,
ShaderStage::Fragment,
ShaderSource(to_string(src)),
engine->get_gfx()->accepted_shader_language());
} }

View file

@ -1,22 +1,22 @@
#include "renderer.hpp" #include "renderer.hpp"
#include "gfx_commandbuffer.hpp" #include "assertions.hpp"
#include "math.hpp" #include "debug.hpp"
#include "dofpass.hpp"
#include "file.hpp" #include "file.hpp"
#include "scene.hpp" #include "frustum.hpp"
#include "vector.hpp"
#include "imguipass.hpp"
#include "gfx.hpp" #include "gfx.hpp"
#include "gfx_commandbuffer.hpp"
#include "imguipass.hpp"
#include "materialcompiler.hpp"
#include "math.hpp"
#include "pass.hpp" #include "pass.hpp"
#include "scene.hpp"
#include "scenecapture.hpp"
#include "shadercompiler.hpp"
#include "shadowpass.hpp" #include "shadowpass.hpp"
#include "smaapass.hpp" #include "smaapass.hpp"
#include "scenecapture.hpp" #include "vector.hpp"
#include "materialcompiler.hpp"
#include "assertions.hpp"
#include "dofpass.hpp"
#include "frustum.hpp"
#include "shadercompiler.hpp"
#include "debug.hpp"
using prism::renderer; using prism::renderer;
@ -113,9 +113,7 @@ void renderer::resize_render_target(RenderTarget& target, const prism::Extent ex
pass->create_render_target_resources(target); pass->create_render_target_resources(target);
} }
void renderer::recreate_all_render_targets() { void renderer::recreate_all_render_targets() {}
}
void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarget& target, platform::window_ptr index) { void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarget& target, platform::window_ptr index) {
const auto extent = target.extent; const auto extent = target.extent;
@ -167,15 +165,15 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
for (auto& [obj, camera] : cameras) { for (auto& [obj, camera] : cameras) {
const bool requires_limited_perspective = render_options.enable_depth_of_field; const bool requires_limited_perspective = render_options.enable_depth_of_field;
if (requires_limited_perspective) { if (requires_limited_perspective) {
camera.perspective = prism::perspective(radians(camera.fov), camera.perspective = prism::perspective(
static_cast<float>(render_extent.width) / radians(camera.fov),
static_cast<float>(render_extent.height), static_cast<float>(render_extent.width) / static_cast<float>(render_extent.height),
camera.near, camera.near,
100.0f); 100.0f);
} else { } else {
camera.perspective = prism::infinite_perspective(radians(camera.fov), camera.perspective = prism::infinite_perspective(
static_cast<float>(render_extent.width) / radians(camera.fov),
static_cast<float>(render_extent.height), static_cast<float>(render_extent.width) / static_cast<float>(render_extent.height),
camera.near); camera.near);
} }
@ -209,33 +207,30 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
commandbuffer->set_compute_pipeline(histogram_pipeline); commandbuffer->set_compute_pipeline(histogram_pipeline);
commandbuffer->bind_texture(target.offscreenColorTexture, 0); commandbuffer->bind_texture(target.offscreenColorTexture, 0);
commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256);
sizeof(uint32_t) * 256);
const float lum_range = const float lum_range = render_options.max_luminance - render_options.min_luminance;
render_options.max_luminance - render_options.min_luminance;
prism::float4 params = prism::float4 params = prism::float4(
prism::float4(render_options.min_luminance, 1.0f / lum_range, render_options.min_luminance,
1.0f / lum_range,
static_cast<float>(render_extent.width), static_cast<float>(render_extent.width),
static_cast<float>(render_extent.height)); static_cast<float>(render_extent.height));
commandbuffer->set_push_constant(&params, sizeof(prism::float4)); commandbuffer->set_push_constant(&params, sizeof(prism::float4));
commandbuffer->dispatch( commandbuffer->dispatch(
static_cast<uint32_t>( static_cast<uint32_t>(std::ceil(static_cast<float>(render_extent.width) / 16.0f)),
std::ceil(static_cast<float>(render_extent.width) / 16.0f)), static_cast<uint32_t>(std::ceil(static_cast<float>(render_extent.height) / 16.0f)),
static_cast<uint32_t>(
std::ceil(static_cast<float>(render_extent.height) / 16.0f)),
1); 1);
commandbuffer->set_compute_pipeline(histogram_average_pipeline); commandbuffer->set_compute_pipeline(histogram_average_pipeline);
commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256);
sizeof(uint32_t) * 256);
params = prism::float4( params = prism::float4(
render_options.min_luminance, lum_range, render_options.min_luminance,
lum_range,
std::clamp(1.0f - std::exp(-(1.0f / 60.0f) * 1.1f), 0.0f, 1.0f), std::clamp(1.0f - std::exp(-(1.0f / 60.0f) * 1.1f), 0.0f, 1.0f),
static_cast<float>(render_extent.width * render_extent.height)); static_cast<float>(render_extent.width * render_extent.height));
@ -257,7 +252,11 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
pc.transform_ops.y = static_cast<float>(render_options.tonemapping); pc.transform_ops.y = static_cast<float>(render_options.tonemapping);
const auto [width, height] = render_extent; const auto [width, height] = render_extent;
pc.viewport = prism::float4(1.0f / static_cast<float>(width), 1.0f / static_cast<float>(height), static_cast<float>(width), static_cast<float>(height)); pc.viewport = prism::float4(
1.0f / static_cast<float>(width),
1.0f / static_cast<float>(height),
static_cast<float>(width),
static_cast<float>(height));
// continue post processing // continue post processing
// first we want to manually "expose" the scene, otherwise AA wouldn't work properly // first we want to manually "expose" the scene, otherwise AA wouldn't work properly
@ -347,7 +346,14 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
target.current_frame = (target.current_frame + 1) % RT_MAX_FRAMES_IN_FLIGHT; target.current_frame = (target.current_frame + 1) % RT_MAX_FRAMES_IN_FLIGHT;
} }
void renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Object camera_object, Camera& camera, prism::Extent extent, RenderTarget& target, controller_continuity& continuity) { void renderer::render_camera(
GFXCommandBuffer* command_buffer,
Scene& scene,
Object camera_object,
Camera& camera,
prism::Extent extent,
RenderTarget& target,
controller_continuity& continuity) {
// frustum test // frustum test
const auto frustum = normalize_frustum(camera_extract_frustum(scene, camera_object)); const auto frustum = normalize_frustum(camera_extract_frustum(scene, camera_object));
@ -355,7 +361,8 @@ void renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj
sceneInfo.lightspace = scene.lightSpace; sceneInfo.lightspace = scene.lightSpace;
sceneInfo.options = prism::float4(1, 0, 0, 0); sceneInfo.options = prism::float4(1, 0, 0, 0);
sceneInfo.camPos = scene.get<Transform>(camera_object).get_world_position(); sceneInfo.camPos = scene.get<Transform>(camera_object).get_world_position();
sceneInfo.camPos.w = 2.0f * camera.near * std::tan(camera.fov * 0.5f) * (static_cast<float>(extent.width) / static_cast<float>(extent.height)); sceneInfo.camPos.w = 2.0f * camera.near * std::tan(camera.fov * 0.5f) *
(static_cast<float>(extent.width) / static_cast<float>(extent.height));
sceneInfo.vp = camera.perspective * camera.view; sceneInfo.vp = camera.perspective * camera.view;
int last_point_light = 0; int last_point_light = 0;
@ -437,13 +444,17 @@ void renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj
if (material_index >= mesh.materials.size()) if (material_index >= mesh.materials.size())
continue; continue;
if(mesh.materials[material_index].handle == nullptr || mesh.materials[material_index]->static_pipeline == nullptr) if (mesh.materials[material_index].handle == nullptr ||
mesh.materials[material_index]->static_pipeline == nullptr)
continue; continue;
if(render_options.enable_frustum_culling && !test_aabb_frustum(frustum, get_aabb_for_part(scene.get<Transform>(obj), part))) if (render_options.enable_frustum_culling &&
!test_aabb_frustum(frustum, get_aabb_for_part(scene.get<Transform>(obj), part)))
continue; continue;
command_buffer->set_graphics_pipeline(mesh.mesh->bones.empty() ? mesh.materials[material_index]->static_pipeline : mesh.materials[material_index]->skinned_pipeline); command_buffer->set_graphics_pipeline(
mesh.mesh->bones.empty() ? mesh.materials[material_index]->static_pipeline
: mesh.materials[material_index]->skinned_pipeline);
command_buffer->bind_shader_buffer(target.sceneBuffer, 0, 1, sizeof(SceneInformation)); command_buffer->bind_shader_buffer(target.sceneBuffer, 0, 1, sizeof(SceneInformation));
@ -467,7 +478,11 @@ void renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj
command_buffer->bind_texture(texture_to_bind, index); command_buffer->bind_texture(texture_to_bind, index);
} }
command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, material_indices.at(*mesh.materials[material_index])); command_buffer->draw_indexed(
part.index_count,
part.index_offset,
part.vertex_offset,
material_indices.at(*mesh.materials[material_index]));
} }
} }
@ -519,12 +534,12 @@ void renderer::create_mesh_pipeline(Material& material) const {
pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/mesh.vert")); pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/mesh.vert"));
pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/mesh.frag")); pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/mesh.frag"));
pipelineInfo.shaders.vertex_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant}; pipelineInfo.shaders.vertex_constants = {
pipelineInfo.shaders.fragment_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant}; materials_constant, lights_constant, spot_lights_constant, probes_constant};
pipelineInfo.shaders.fragment_constants = {
materials_constant, lights_constant, spot_lights_constant, probes_constant};
pipelineInfo.shader_input.push_constants = { pipelineInfo.shader_input.push_constants = {{sizeof(Matrix4x4), 0}};
{sizeof(Matrix4x4), 0}
};
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {
{1, GFXBindingType::StorageBuffer}, {1, GFXBindingType::StorageBuffer},
@ -534,8 +549,7 @@ void renderer::create_mesh_pipeline(Material& material) const {
{6, GFXBindingType::Texture}, {6, GFXBindingType::Texture},
{7, GFXBindingType::Texture}, {7, GFXBindingType::Texture},
{8, GFXBindingType::Texture}, {8, GFXBindingType::Texture},
{9, GFXBindingType::Texture} {9, GFXBindingType::Texture}};
};
pipelineInfo.render_pass = offscreen_render_pass; pipelineInfo.render_pass = offscreen_render_pass;
pipelineInfo.depth.depth_mode = GFXDepthMode::Less; pipelineInfo.depth.depth_mode = GFXDepthMode::Less;
@ -560,7 +574,8 @@ void renderer::create_mesh_pipeline(Material& material) const {
pipelineInfo.render_pass = scene_capture->renderPass; pipelineInfo.render_pass = scene_capture->renderPass;
pipelineInfo.shaders.fragment_src = material_compiler.compile_material_fragment(material, false); // scene capture does not use IBL pipelineInfo.shaders.fragment_src =
material_compiler.compile_material_fragment(material, false); // scene capture does not use IBL
pipelineInfo.shader_input.push_constants[0].size += sizeof(Matrix4x4); pipelineInfo.shader_input.push_constants[0].size += sizeof(Matrix4x4);
@ -592,8 +607,7 @@ void renderer::create_render_target_resources(RenderTarget& target) {
textureInfo.width = extent.width; textureInfo.width = extent.width;
textureInfo.height = extent.height; textureInfo.height = extent.height;
textureInfo.format = GFXPixelFormat::RGBA_32F; textureInfo.format = GFXPixelFormat::RGBA_32F;
textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled | textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled | GFXTextureUsage::Storage;
GFXTextureUsage::Storage;
textureInfo.samplingMode = SamplingMode::ClampToEdge; textureInfo.samplingMode = SamplingMode::ClampToEdge;
target.offscreenColorTexture = gfx->create_texture(textureInfo); target.offscreenColorTexture = gfx->create_texture(textureInfo);
@ -648,9 +662,7 @@ void renderer::create_post_pipelines() {
{5, GFXBindingType::Texture} // sobelSampler {5, GFXBindingType::Texture} // sobelSampler
}; };
pipelineInfo.shader_input.push_constants = { pipelineInfo.shader_input.push_constants = {{sizeof(PostPushConstants), 0}};
{sizeof(PostPushConstants), 0}
};
post_pipeline = gfx->create_graphics_pipeline(pipelineInfo); post_pipeline = gfx->create_graphics_pipeline(pipelineInfo);
@ -677,13 +689,9 @@ void renderer::create_sky_pipeline() {
pipelineInfo.shaders.vertex_src = register_shader("shaders/sky.vert"); pipelineInfo.shaders.vertex_src = register_shader("shaders/sky.vert");
pipelineInfo.shaders.fragment_src = register_shader("shaders/sky.frag"); pipelineInfo.shaders.fragment_src = register_shader("shaders/sky.frag");
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {{0, GFXBindingType::PushConstant}};
{0, GFXBindingType::PushConstant}
};
pipelineInfo.shader_input.push_constants = { pipelineInfo.shader_input.push_constants = {{sizeof(SkyPushConstant), 0}};
{sizeof(SkyPushConstant), 0}
};
pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual; pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual;
@ -754,14 +762,9 @@ void renderer::create_histogram_resources() {
create_info.workgroup_size_y = 16; create_info.workgroup_size_y = 16;
create_info.shader_input.bindings = { create_info.shader_input.bindings = {
{0, GFXBindingType::StorageImage}, {0, GFXBindingType::StorageImage}, {1, GFXBindingType::StorageBuffer}, {2, GFXBindingType::PushConstant}};
{1, GFXBindingType::StorageBuffer},
{2, GFXBindingType::PushConstant}
};
create_info.shader_input.push_constants = { create_info.shader_input.push_constants = {{sizeof(prism::float4), 0}};
{sizeof(prism::float4), 0}
};
histogram_pipeline = gfx->create_compute_pipeline(create_info); histogram_pipeline = gfx->create_compute_pipeline(create_info);
@ -816,15 +819,22 @@ ShaderSource renderer::register_shader(const std::string_view shader_file) {
stage = ShaderStage::Fragment; stage = ShaderStage::Fragment;
if (found_shader_source.empty()) { if (found_shader_source.empty()) {
auto file = prism::open_file(base_shader_path / shader_path.replace_extension(shader_path.extension().string() + ".glsl")); auto file = prism::open_file(
base_shader_path / shader_path.replace_extension(shader_path.extension().string() + ".glsl"));
return shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(file->read_as_string()), gfx->accepted_shader_language()).value(); return shader_compiler
.compile(ShaderLanguage::GLSL, stage, ShaderSource(file->read_as_string()), gfx->accepted_shader_language())
.value();
} else { } else {
return shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(found_shader_source), gfx->accepted_shader_language()).value(); return shader_compiler
.compile(ShaderLanguage::GLSL, stage, ShaderSource(found_shader_source), gfx->accepted_shader_language())
.value();
} }
} }
void renderer::associate_shader_reload(const std::string_view shader_file, const std::function<void()>& reload_function) { void renderer::associate_shader_reload(
const std::string_view shader_file,
const std::function<void()>& reload_function) {
if (reloading_shader) if (reloading_shader)
return; return;

View file

@ -1,14 +1,14 @@
#include "scenecapture.hpp" #include "scenecapture.hpp"
#include "gfx_commandbuffer.hpp"
#include "scene.hpp"
#include "gfx.hpp"
#include "engine.hpp"
#include "renderer.hpp"
#include "shadowpass.hpp"
#include "materialcompiler.hpp"
#include "frustum.hpp"
#include "asset.hpp" #include "asset.hpp"
#include "engine.hpp"
#include "frustum.hpp"
#include "gfx.hpp"
#include "gfx_commandbuffer.hpp"
#include "materialcompiler.hpp"
#include "renderer.hpp"
#include "scene.hpp"
#include "shadowpass.hpp"
struct PushConstant { struct PushConstant {
Matrix4x4 m, v; Matrix4x4 m, v;
@ -110,7 +110,8 @@ SceneCapture::SceneCapture(GFX* gfx) {
cubeTextureInfo.width = scene_cubemap_resolution; cubeTextureInfo.width = scene_cubemap_resolution;
cubeTextureInfo.height = scene_cubemap_resolution; cubeTextureInfo.height = scene_cubemap_resolution;
cubeTextureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM; cubeTextureInfo.format = GFXPixelFormat::R8G8B8A8_UNORM;
cubeTextureInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst | GFXTextureUsage::TransferSrc; // dst used for cubemap copy, src used for mipmap gen cubeTextureInfo.usage = GFXTextureUsage::Sampled | GFXTextureUsage::TransferDst |
GFXTextureUsage::TransferSrc; // dst used for cubemap copy, src used for mipmap gen
cubeTextureInfo.samplingMode = SamplingMode::ClampToEdge; cubeTextureInfo.samplingMode = SamplingMode::ClampToEdge;
cubeTextureInfo.mip_count = mipLevels; cubeTextureInfo.mip_count = mipLevels;
@ -262,10 +263,12 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
if (material_index >= mesh.materials.size()) if (material_index >= mesh.materials.size())
continue; continue;
if(mesh.materials[material_index].handle == nullptr || mesh.materials[material_index]->static_pipeline == nullptr) if (mesh.materials[material_index].handle == nullptr ||
mesh.materials[material_index]->static_pipeline == nullptr)
continue; continue;
if(render_options.enable_frustum_culling && !test_aabb_frustum(frustum, get_aabb_for_part(scene->get<Transform>(obj), part))) if (render_options.enable_frustum_culling &&
!test_aabb_frustum(frustum, get_aabb_for_part(scene->get<Transform>(obj), part)))
continue; continue;
command_buffer->set_graphics_pipeline(mesh.materials[material_index]->capture_pipeline); command_buffer->set_graphics_pipeline(mesh.materials[material_index]->capture_pipeline);
@ -285,7 +288,8 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
command_buffer->bind_texture(texture_to_bind, index); command_buffer->bind_texture(texture_to_bind, index);
} }
command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, 0); command_buffer->draw_indexed(
part.index_count, part.index_offset, part.vertex_offset, 0);
} }
} }
} }
@ -299,7 +303,8 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
for (auto& [obj, light] : scene->get_all<Light>()) { for (auto& [obj, light] : scene->get_all<Light>()) {
if (light.type == Light::Type::Sun) if (light.type == Light::Type::Sun)
pc.sun_position_fov = prism::float4(scene->get<Transform>(obj).get_world_position(), radians(90.0f)); pc.sun_position_fov =
prism::float4(scene->get<Transform>(obj).get_world_position(), radians(90.0f));
} }
command_buffer->set_graphics_pipeline(skyPipeline); command_buffer->set_graphics_pipeline(skyPipeline);
@ -309,7 +314,8 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
command_buffer->draw(0, 4, 0, 1); command_buffer->draw(0, 4, 0, 1);
command_buffer->end_render_pass(); command_buffer->end_render_pass();
command_buffer->copy_texture(offscreenTexture, scene_cubemap_resolution, scene_cubemap_resolution, environmentCube, face, 0, 0); command_buffer->copy_texture(
offscreenTexture, scene_cubemap_resolution, scene_cubemap_resolution, environmentCube, face, 0, 0);
}; };
engine->get_gfx()->copy_buffer(sceneBuffer, &sceneInfo, 0, sizeof(SceneInformation)); engine->get_gfx()->copy_buffer(sceneBuffer, &sceneInfo, 0, sizeof(SceneInformation));
@ -347,7 +353,8 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0, 0); command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0, 0);
command_buffer->end_render_pass(); command_buffer->end_render_pass();
command_buffer->copy_texture(irradianceOffscreenTexture, command_buffer->copy_texture(
irradianceOffscreenTexture,
irradiance_cubemap_resolution, irradiance_cubemap_resolution,
irradiance_cubemap_resolution, irradiance_cubemap_resolution,
scene->irradianceCubeArray, scene->irradianceCubeArray,
@ -390,9 +397,14 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0, 0); command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0, 0);
command_buffer->end_render_pass(); command_buffer->end_render_pass();
command_buffer->copy_texture(prefilteredOffscreenTexture, command_buffer->copy_texture(
resolution, resolution, prefilteredOffscreenTexture,
scene->prefilteredCubeArray, face, last_probe, mip); resolution,
resolution,
scene->prefilteredCubeArray,
face,
last_probe,
mip);
}; };
for (int mip = 0; mip < mipLevels; mip++) { for (int mip = 0; mip < mipLevels; mip++) {
@ -415,13 +427,9 @@ void SceneCapture::createSkyResources() {
pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/sky.vert")); pipelineInfo.shaders.vertex_src = ShaderSource(prism::path("shaders/sky.vert"));
pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/sky.frag")); pipelineInfo.shaders.fragment_src = ShaderSource(prism::path("shaders/sky.frag"));
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {{0, GFXBindingType::PushConstant}};
{0, GFXBindingType::PushConstant}
};
pipelineInfo.shader_input.push_constants = { pipelineInfo.shader_input.push_constants = {{sizeof(SkyPushConstant), 0}};
{sizeof(SkyPushConstant), 0}
};
pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual; pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual;
@ -469,14 +477,9 @@ void SceneCapture::createIrradianceResources() {
pipelineInfo.vertex_input.attributes.push_back(positionAttribute); pipelineInfo.vertex_input.attributes.push_back(positionAttribute);
pipelineInfo.shader_input.push_constants = { pipelineInfo.shader_input.push_constants = {{sizeof(Matrix4x4), 0}};
{sizeof(Matrix4x4), 0}
};
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {{1, GFXBindingType::PushConstant}, {2, GFXBindingType::Texture}};
{1, GFXBindingType::PushConstant},
{2, GFXBindingType::Texture}
};
pipelineInfo.render_pass = irradianceRenderPass; pipelineInfo.render_pass = irradianceRenderPass;
@ -523,14 +526,9 @@ void SceneCapture::createPrefilterResources() {
pipelineInfo.vertex_input.attributes.push_back(positionAttribute); pipelineInfo.vertex_input.attributes.push_back(positionAttribute);
pipelineInfo.shader_input.push_constants = { pipelineInfo.shader_input.push_constants = {{sizeof(FilterPushConstant), 0}};
{sizeof(FilterPushConstant), 0}
};
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {{0, GFXBindingType::PushConstant}, {2, GFXBindingType::Texture}};
{0, GFXBindingType::PushConstant},
{2, GFXBindingType::Texture}
};
pipelineInfo.render_pass = irradianceRenderPass; pipelineInfo.render_pass = irradianceRenderPass;

View file

@ -1,13 +1,13 @@
#include "shadowpass.hpp" #include "shadowpass.hpp"
#include "gfx_commandbuffer.hpp"
#include "scene.hpp"
#include "gfx.hpp"
#include "engine.hpp"
#include "materialcompiler.hpp"
#include "assertions.hpp" #include "assertions.hpp"
#include "engine.hpp"
#include "frustum.hpp" #include "frustum.hpp"
#include "gfx.hpp"
#include "gfx_commandbuffer.hpp"
#include "materialcompiler.hpp"
#include "renderer.hpp" #include "renderer.hpp"
#include "scene.hpp"
struct PushConstant { struct PushConstant {
Matrix4x4 mvp, model; Matrix4x4 mvp, model;
@ -115,7 +115,15 @@ void ShadowPass::render(GFXCommandBuffer* command_buffer, Scene& scene) {
} }
} }
void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, const Matrix4x4 light_matrix, const Matrix4x4 model, const prism::float3, const Light::Type type, const CameraFrustum& frustum, const int base_instance) { void ShadowPass::render_meshes(
GFXCommandBuffer* command_buffer,
Scene& scene,
const Matrix4x4 light_matrix,
const Matrix4x4 model,
const prism::float3,
const Light::Type type,
const CameraFrustum& frustum,
const int base_instance) {
for (auto [obj, mesh] : scene.get_all<Renderable>()) { for (auto [obj, mesh] : scene.get_all<Renderable>()) {
if (!mesh.mesh) if (!mesh.mesh)
continue; continue;
@ -147,7 +155,8 @@ void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, c
command_buffer->set_depth_bias(1.25f, 0.00f, 1.75f); command_buffer->set_depth_bias(1.25f, 0.00f, 1.75f);
for (auto& part : mesh.mesh->parts) { for (auto& part : mesh.mesh->parts) {
if(render_options.enable_frustum_culling && !test_aabb_frustum(frustum, get_aabb_for_part(scene.get<Transform>(obj), part))) if (render_options.enable_frustum_culling &&
!test_aabb_frustum(frustum, get_aabb_for_part(scene.get<Transform>(obj), part)))
continue; continue;
command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, base_instance); command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, base_instance);
@ -173,7 +182,8 @@ void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, c
command_buffer->set_depth_bias(1.25f, 0.00f, 1.75f); command_buffer->set_depth_bias(1.25f, 0.00f, 1.75f);
for (auto& part : mesh.mesh->parts) { for (auto& part : mesh.mesh->parts) {
if(render_options.enable_frustum_culling && !test_aabb_frustum(frustum, get_aabb_for_part(scene.get<Transform>(obj), part))) if (render_options.enable_frustum_culling &&
!test_aabb_frustum(frustum, get_aabb_for_part(scene.get<Transform>(obj), part)))
continue; continue;
command_buffer->bind_shader_buffer(part.bone_batrix_buffer, 0, 14, sizeof(Matrix4x4) * 128); command_buffer->bind_shader_buffer(part.bone_batrix_buffer, 0, 14, sizeof(Matrix4x4) * 128);
@ -188,7 +198,9 @@ void ShadowPass::render_sun(GFXCommandBuffer* command_buffer, Scene& scene, pris
GFXRenderPassBeginInfo info = {}; GFXRenderPassBeginInfo info = {};
info.framebuffer = scene.framebuffer; info.framebuffer = scene.framebuffer;
info.render_pass = render_pass; info.render_pass = render_pass;
info.render_area.extent = {static_cast<uint32_t>(render_options.shadow_resolution), static_cast<uint32_t>(render_options.shadow_resolution)}; info.render_area.extent = {
static_cast<uint32_t>(render_options.shadow_resolution),
static_cast<uint32_t>(render_options.shadow_resolution)};
command_buffer->set_render_pass(info); command_buffer->set_render_pass(info);
@ -228,7 +240,9 @@ void ShadowPass::render_spot(GFXCommandBuffer* command_buffer, Scene& scene, pri
GFXRenderPassBeginInfo info = {}; GFXRenderPassBeginInfo info = {};
info.framebuffer = offscreen_framebuffer; info.framebuffer = offscreen_framebuffer;
info.render_pass = cube_render_pass; info.render_pass = cube_render_pass;
info.render_area.extent = {static_cast<uint32_t>(render_options.shadow_resolution), static_cast<uint32_t>(render_options.shadow_resolution)}; info.render_area.extent = {
static_cast<uint32_t>(render_options.shadow_resolution),
static_cast<uint32_t>(render_options.shadow_resolution)};
command_buffer->set_render_pass(info); command_buffer->set_render_pass(info);
@ -244,16 +258,33 @@ void ShadowPass::render_spot(GFXCommandBuffer* command_buffer, Scene& scene, pri
scene.spotLightSpaces[last_spot_light] = perspective; scene.spotLightSpaces[last_spot_light] = perspective;
scene.spotLightSpaces[last_spot_light][1][1] *= -1; scene.spotLightSpaces[last_spot_light][1][1] *= -1;
scene.spotLightSpaces[last_spot_light] = scene.spotLightSpaces[last_spot_light] * inverse(scene.get<Transform>(light_object).model); scene.spotLightSpaces[last_spot_light] =
scene.spotLightSpaces[last_spot_light] * inverse(scene.get<Transform>(light_object).model);
const auto frustum = normalize_frustum(extract_frustum(perspective * inverse(scene.get<Transform>(light_object).model))); const auto frustum =
normalize_frustum(extract_frustum(perspective * inverse(scene.get<Transform>(light_object).model)));
if (light.enable_shadows) if (light.enable_shadows)
render_meshes(command_buffer, scene, realMVP, Matrix4x4(), scene.get<Transform>(light_object).get_world_position(), Light::Type::Spot, frustum, 0); render_meshes(
command_buffer,
scene,
realMVP,
Matrix4x4(),
scene.get<Transform>(light_object).get_world_position(),
Light::Type::Spot,
frustum,
0);
command_buffer->end_render_pass(); command_buffer->end_render_pass();
command_buffer->copy_texture(offscreen_depth, render_options.shadow_resolution, render_options.shadow_resolution, scene.spotLightArray, 0, last_spot_light, 0); command_buffer->copy_texture(
offscreen_depth,
render_options.shadow_resolution,
render_options.shadow_resolution,
scene.spotLightArray,
0,
last_spot_light,
0);
scene.spot_light_dirty[last_spot_light] = false; scene.spot_light_dirty[last_spot_light] = false;
} }
@ -261,7 +292,11 @@ void ShadowPass::render_spot(GFXCommandBuffer* command_buffer, Scene& scene, pri
last_spot_light++; last_spot_light++;
} }
void ShadowPass::render_point(GFXCommandBuffer* command_buffer, Scene& scene, prism::Object light_object, Light& light) { void ShadowPass::render_point(
GFXCommandBuffer* command_buffer,
Scene& scene,
prism::Object light_object,
Light& light) {
if (!render_options.enable_point_shadows) if (!render_options.enable_point_shadows)
return; return;
@ -280,7 +315,9 @@ void ShadowPass::render_point(GFXCommandBuffer* command_buffer, Scene& scene, pr
GFXRenderPassBeginInfo info = {}; GFXRenderPassBeginInfo info = {};
info.framebuffer = offscreen_framebuffer; info.framebuffer = offscreen_framebuffer;
info.render_pass = cube_render_pass; info.render_pass = cube_render_pass;
info.render_area.extent = {static_cast<uint32_t>(render_options.shadow_resolution), static_cast<uint32_t>(render_options.shadow_resolution)}; info.render_area.extent = {
static_cast<uint32_t>(render_options.shadow_resolution),
static_cast<uint32_t>(render_options.shadow_resolution)};
command_buffer->set_render_pass(info); command_buffer->set_render_pass(info);
@ -295,11 +332,26 @@ void ShadowPass::render_point(GFXCommandBuffer* command_buffer, Scene& scene, pr
const auto frustum = normalize_frustum(extract_frustum(projection * shadowTransforms[face] * model)); const auto frustum = normalize_frustum(extract_frustum(projection * shadowTransforms[face] * model));
render_meshes(command_buffer, scene, projection * shadowTransforms[face], model, lightPos, Light::Type::Point, frustum, last_point_light); render_meshes(
command_buffer,
scene,
projection * shadowTransforms[face],
model,
lightPos,
Light::Type::Point,
frustum,
last_point_light);
command_buffer->end_render_pass(); command_buffer->end_render_pass();
command_buffer->copy_texture(offscreen_color_texture, render_options.shadow_resolution, render_options.shadow_resolution, scene.pointLightArray, face, last_point_light, 0); command_buffer->copy_texture(
offscreen_color_texture,
render_options.shadow_resolution,
render_options.shadow_resolution,
scene.pointLightArray,
face,
last_point_light,
0);
} }
scene.point_light_dirty[last_point_light] = false; scene.point_light_dirty[last_point_light] = false;
@ -338,14 +390,9 @@ void ShadowPass::create_pipelines() {
pipelineInfo.shaders.fragment_constants = {point_light_max_constant}; pipelineInfo.shaders.fragment_constants = {point_light_max_constant};
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {
{0, GFXBindingType::PushConstant}, {0, GFXBindingType::PushConstant}, {1, GFXBindingType::StorageBuffer}, {2, GFXBindingType::StorageBuffer}};
{1, GFXBindingType::StorageBuffer},
{2, GFXBindingType::StorageBuffer}
};
pipelineInfo.shader_input.push_constants = { pipelineInfo.shader_input.push_constants = {{sizeof(PushConstant), 0}};
{sizeof(PushConstant), 0}
};
pipelineInfo.render_pass = render_pass; pipelineInfo.render_pass = render_pass;
@ -415,6 +462,7 @@ void ShadowPass::create_offscreen_resources() {
offscreen_framebuffer = gfx->create_framebuffer(info); offscreen_framebuffer = gfx->create_framebuffer(info);
point_location_buffer = gfx->create_buffer(nullptr, sizeof(prism::float4) * max_point_shadows, false, GFXBufferUsage::Storage); point_location_buffer =
gfx->create_buffer(nullptr, sizeof(prism::float4) * max_point_shadows, false, GFXBufferUsage::Storage);
point_location_map = reinterpret_cast<prism::float4*>(gfx->get_buffer_contents(point_location_buffer)); point_location_map = reinterpret_cast<prism::float4*>(gfx->get_buffer_contents(point_location_buffer));
} }

View file

@ -1,10 +1,10 @@
#include "smaapass.hpp" #include "smaapass.hpp"
#include "gfx_commandbuffer.hpp" #include "assertions.hpp"
#include "renderer.hpp"
#include "engine.hpp" #include "engine.hpp"
#include "gfx.hpp" #include "gfx.hpp"
#include "assertions.hpp" #include "gfx_commandbuffer.hpp"
#include "renderer.hpp"
#include <AreaTex.h> #include <AreaTex.h>
#include <SearchTex.h> #include <SearchTex.h>
@ -52,7 +52,11 @@ void SMAAPass::render(GFXCommandBuffer* command_buffer, RenderTarget& target) {
prism::float4 viewport; prism::float4 viewport;
} pc; } pc;
pc.viewport = prism::float4(1.0f / static_cast<float>(target.extent.width), 1.0f / static_cast<float>(target.extent.height), target.extent.width, target.extent.height); pc.viewport = prism::float4(
1.0f / static_cast<float>(target.extent.width),
1.0f / static_cast<float>(target.extent.height),
target.extent.width,
target.extent.height);
// edge // edge
{ {
@ -147,15 +151,10 @@ void SMAAPass::create_pipelines() {
createInfo.render_pass = render_pass; createInfo.render_pass = render_pass;
createInfo.shader_input.push_constants = { createInfo.shader_input.push_constants = {{sizeof(prism::float4), 0}};
{sizeof(prism::float4), 0}
};
createInfo.shader_input.bindings = { createInfo.shader_input.bindings = {
{0, GFXBindingType::Texture}, {0, GFXBindingType::Texture}, {1, GFXBindingType::Texture}, {2, GFXBindingType::PushConstant}};
{1, GFXBindingType::Texture},
{2, GFXBindingType::PushConstant}
};
edge_pipeline = gfx->create_graphics_pipeline(createInfo); edge_pipeline = gfx->create_graphics_pipeline(createInfo);

View file

@ -1,10 +1,10 @@
#pragma once #pragma once
#include <variant>
#include <string>
#include <vector>
#include <string_view>
#include <optional> #include <optional>
#include <string>
#include <string_view>
#include <variant>
#include <vector>
#include "file.hpp" #include "file.hpp"
@ -41,8 +41,11 @@ public:
class ShaderSource { class ShaderSource {
public: public:
ShaderSource() : source(std::monostate()) {} ShaderSource() : source(std::monostate()) {}
explicit ShaderSource(const std::string& source_string) : source(source_string) {} explicit ShaderSource(const std::string& source_string) : source(source_string) {}
explicit ShaderSource(const std::vector<uint32_t>& source_bytecode) : source(source_bytecode) {} explicit ShaderSource(const std::vector<uint32_t>& source_bytecode) : source(source_bytecode) {}
explicit ShaderSource(const prism::path& shader_path) : source(shader_path) {} explicit ShaderSource(const prism::path& shader_path) : source(shader_path) {}
std::variant<std::monostate, prism::path, std::string, std::vector<uint32_t>> source; std::variant<std::monostate, prism::path, std::string, std::vector<uint32_t>> source;
@ -92,7 +95,12 @@ public:
@param options Optional compilation parameters. @param options Optional compilation parameters.
@note Right now, only GLSL is supported as a source shader language. @note Right now, only GLSL is supported as a source shader language.
*/ */
std::optional<ShaderSource> compile(ShaderLanguage from_language, ShaderStage shader_stage, const ShaderSource& shader_source, ShaderLanguage to_language, CompileOptions options = CompileOptions()); std::optional<ShaderSource> compile(
ShaderLanguage from_language,
ShaderStage shader_stage,
const ShaderSource& shader_source,
ShaderLanguage to_language,
CompileOptions options = CompileOptions());
}; };
static inline ShaderCompiler shader_compiler; static inline ShaderCompiler shader_compiler;

View file

@ -1,6 +1,5 @@
#pragma once #pragma once
const TBuiltInResource DefaultTBuiltInResource = { const TBuiltInResource DefaultTBuiltInResource = {
/* .MaxLights = */ 32, /* .MaxLights = */ 32,
/* .MaxClipPlanes = */ 6, /* .MaxClipPlanes = */ 6,
@ -96,7 +95,8 @@ const TBuiltInResource DefaultTBuiltInResource = {
/* .maxMeshViewCountNV = */ 4, /* .maxMeshViewCountNV = */ 4,
/* .maxDualSourceDrawBuffersEXT = */ 1, /* .maxDualSourceDrawBuffersEXT = */ 1,
/* .limits = */ { /* .limits = */
{
/* .nonInductiveForLoops = */ 1, /* .nonInductiveForLoops = */ 1,
/* .whileLoops = */ 1, /* .whileLoops = */ 1,
/* .doWhileLoops = */ 1, /* .doWhileLoops = */ 1,

View file

@ -36,10 +36,10 @@
#pragma once #pragma once
#include <vector>
#include <string>
#include <fstream>
#include <algorithm> #include <algorithm>
#include <fstream>
#include <string>
#include <vector>
#include <glslang/Public/ShaderLang.h> #include <glslang/Public/ShaderLang.h>
@ -50,17 +50,12 @@ class DirStackFileIncluder : public glslang::TShader::Includer {
public: public:
DirStackFileIncluder() : externalLocalDirectoryCount(0) {} DirStackFileIncluder() : externalLocalDirectoryCount(0) {}
IncludeResult* includeLocal(const char* headerName, IncludeResult* includeLocal(const char* headerName, const char* includerName, size_t inclusionDepth) override {
const char* includerName,
size_t inclusionDepth) override
{
return readLocalPath(headerName, includerName, (int)inclusionDepth); return readLocalPath(headerName, includerName, (int)inclusionDepth);
} }
IncludeResult* includeSystem(const char* headerName, IncludeResult*
const char* /*includerName*/, includeSystem(const char* headerName, const char* /*includerName*/, size_t /*inclusionDepth*/) override {
size_t /*inclusionDepth*/) override
{
return readSystemPath(headerName); return readSystemPath(headerName);
} }
@ -70,14 +65,12 @@ public:
// is checked. // is checked.
// - This only applies to the "local" form of #include. // - This only applies to the "local" form of #include.
// - Makes its own copy of the path. // - Makes its own copy of the path.
virtual void pushExternalLocalDirectory(const std::string& dir) virtual void pushExternalLocalDirectory(const std::string& dir) {
{
directoryStack.push_back(dir); directoryStack.push_back(dir);
externalLocalDirectoryCount = (int)directoryStack.size(); externalLocalDirectoryCount = (int)directoryStack.size();
} }
void releaseInclude(IncludeResult* result) override void releaseInclude(IncludeResult* result) override {
{
if (result != nullptr) { if (result != nullptr) {
delete[] static_cast<tUserDataElement*>(result->userData); delete[] static_cast<tUserDataElement*>(result->userData);
delete result; delete result;
@ -93,8 +86,7 @@ protected:
// Search for a valid "local" path based on combining the stack of include // Search for a valid "local" path based on combining the stack of include
// directories and the nominal name of the header. // directories and the nominal name of the header.
virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth) virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth) {
{
// Discard popped include directories, and // Discard popped include directories, and
// initialize when at parse-time first level. // initialize when at parse-time first level.
directoryStack.resize(depth + externalLocalDirectoryCount); directoryStack.resize(depth + externalLocalDirectoryCount);
@ -117,14 +109,12 @@ protected:
// Search for a valid <system> path. // Search for a valid <system> path.
// Not implemented yet; returning nullptr signals failure to find. // Not implemented yet; returning nullptr signals failure to find.
virtual IncludeResult* readSystemPath(const char* /*headerName*/) const virtual IncludeResult* readSystemPath(const char* /*headerName*/) const {
{
return nullptr; return nullptr;
} }
// Do actual reading of the file, filling in a new include result. // Do actual reading of the file, filling in a new include result.
virtual IncludeResult* newIncludeResult(const std::string& path, std::ifstream& file, int length) const virtual IncludeResult* newIncludeResult(const std::string& path, std::ifstream& file, int length) const {
{
char* content = new tUserDataElement[length]; char* content = new tUserDataElement[length];
file.seekg(0, file.beg); file.seekg(0, file.beg);
file.read(content, length); file.read(content, length);

View file

@ -1,13 +1,13 @@
#include "shadercompiler.hpp" #include "shadercompiler.hpp"
#include <spirv_msl.hpp>
#include <SPIRV/GlslangToSpv.h> #include <SPIRV/GlslangToSpv.h>
#include <spirv_msl.hpp>
#include "log.hpp"
#include "string_utils.hpp"
#include "includer.hpp"
#include "defaultresources.hpp" #include "defaultresources.hpp"
#include "includer.hpp"
#include "log.hpp"
#include "spirv_hlsl.hpp" #include "spirv_hlsl.hpp"
#include "string_utils.hpp"
static inline std::vector<std::string> include_path; static inline std::vector<std::string> include_path;
@ -19,7 +19,10 @@ void ShaderCompiler::set_include_path(const std::string_view path) {
include_path.emplace_back(path.data()); include_path.emplace_back(path.data());
} }
std::vector<uint32_t> compile_glsl_to_spv(const std::string_view source_string, const EShLanguage shader_language, const CompileOptions& options) { std::vector<uint32_t> compile_glsl_to_spv(
const std::string_view source_string,
const EShLanguage shader_language,
const CompileOptions& options) {
std::string newString = "#version 460 core\n"; std::string newString = "#version 460 core\n";
newString += "#extension GL_GOOGLE_include_directive : enable\n"; newString += "#extension GL_GOOGLE_include_directive : enable\n";
@ -39,10 +42,7 @@ std::vector<uint32_t> compile_glsl_to_spv(const std::string_view source_string,
int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100 int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100
shader.setEnvInput(glslang::EShSourceGlsl, shader.setEnvInput(glslang::EShSourceGlsl, shader_language, glslang::EShClientVulkan, ClientInputSemanticsVersion);
shader_language,
glslang::EShClientVulkan,
ClientInputSemanticsVersion);
// we are targeting vulkan 1.1, so that uses SPIR-V 1.3 // we are targeting vulkan 1.1, so that uses SPIR-V 1.3
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1); shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1);
@ -61,7 +61,8 @@ std::vector<uint32_t> compile_glsl_to_spv(const std::string_view source_string,
Program.addShader(&shader); Program.addShader(&shader);
if (!Program.link(EShMsgDefault)) { if (!Program.link(EShMsgDefault)) {
prism::log("Failed to link shader: {} {} {}", source_string.data(), shader.getInfoLog(), shader.getInfoDebugLog()); prism::log(
"Failed to link shader: {} {} {}", source_string.data(), shader.getInfoLog(), shader.getInfoDebugLog());
return {}; return {};
} }
@ -77,7 +78,12 @@ std::vector<uint32_t> compile_glsl_to_spv(const std::string_view source_string,
return SpirV; return SpirV;
} }
std::optional<ShaderSource> ShaderCompiler::compile(const ShaderLanguage from_language, const ShaderStage shader_stage, const ShaderSource& shader_source, const ShaderLanguage to_language, CompileOptions options) { std::optional<ShaderSource> ShaderCompiler::compile(
const ShaderLanguage from_language,
const ShaderStage shader_stage,
const ShaderSource& shader_source,
const ShaderLanguage to_language,
CompileOptions options) {
if (from_language != ShaderLanguage::GLSL) { if (from_language != ShaderLanguage::GLSL) {
prism::log("Non-supported input language!"); prism::log("Non-supported input language!");
return std::nullopt; return std::nullopt;

View file

@ -6,6 +6,7 @@ namespace prism {
/// A 2D extent. /// A 2D extent.
struct Extent { struct Extent {
Extent() : width(0), height(0) {} Extent() : width(0), height(0) {}
Extent(const uint32_t width, const uint32_t height) : width(width), height(height) {} Extent(const uint32_t width, const uint32_t height) : width(width), height(height) {}
uint32_t width = 0, height = 0; uint32_t width = 0, height = 0;
@ -14,6 +15,7 @@ namespace prism {
/// A 2D offset. /// A 2D offset.
struct Offset { struct Offset {
Offset() : x(0), y(0) {} Offset() : x(0), y(0) {}
Offset(const int32_t x, const int32_t y) : x(x), y(y) {} Offset(const int32_t x, const int32_t y) : x(x), y(y) {}
int32_t x = 0, y = 0; int32_t x = 0, y = 0;
@ -22,10 +24,13 @@ namespace prism {
/// A 2D rectangle defined by a offset and an etent. /// A 2D rectangle defined by a offset and an etent.
struct Rectangle { struct Rectangle {
Rectangle() = default; Rectangle() = default;
Rectangle(const Offset offset, const Extent extent) : offset(offset), extent(extent) {} Rectangle(const Offset offset, const Extent extent) : offset(offset), extent(extent) {}
Rectangle(const int32_t x, const int32_t y, const uint32_t width, const uint32_t height) : offset(x, y), extent(width, height) {}
Rectangle(const int32_t x, const int32_t y, const uint32_t width, const uint32_t height)
: offset(x, y), extent(width, height) {}
Offset offset; Offset offset;
Extent extent; Extent extent;
}; };
} } // namespace prism

View file

@ -2,8 +2,8 @@
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include "vector.hpp"
#include "quaternion.hpp" #include "quaternion.hpp"
#include "vector.hpp"
namespace prism { namespace prism {
inline void to_json(nlohmann::json& j, const float3& p) { inline void to_json(nlohmann::json& j, const float3& p) {
@ -17,7 +17,7 @@ namespace prism {
p.y = j["y"]; p.y = j["y"];
p.z = j["z"]; p.z = j["z"];
} }
} } // namespace prism
inline void to_json(nlohmann::json& j, const Quaternion& p) { inline void to_json(nlohmann::json& j, const Quaternion& p) {
j["x"] = p.x; j["x"] = p.x;

View file

@ -9,10 +9,9 @@ namespace prism {
// some stdlibs such as apple's clang fail to provide this :-/ // some stdlibs such as apple's clang fail to provide this :-/
namespace std { namespace std {
template <> template<> struct hash<prism::path> {
struct hash<prism::path> {
std::size_t operator()(const prism::path& k) const { std::size_t operator()(const prism::path& k) const {
return (std::hash<std::string>()(k.string())); return (std::hash<std::string>()(k.string()));
} }
}; };
} } // namespace std

View file

@ -3,34 +3,30 @@
#include <magic_enum.hpp> #include <magic_enum.hpp>
#include <algorithm> #include <algorithm>
#include <vector> #include <cmath>
#include <random> #include <random>
#include <unordered_map> #include <unordered_map>
#include <cmath> #include <vector>
#include "vector.hpp" #include "vector.hpp"
namespace utility { namespace utility {
template<class Enum> template<class Enum> std::string enum_to_string(const Enum e) {
std::string enum_to_string(const Enum e) {
const std::string_view name = magic_enum::enum_name(e); const std::string_view name = magic_enum::enum_name(e);
std::string s = name.data(); std::string s = name.data();
return s.substr(0, name.length()); return s.substr(0, name.length());
} }
template<class T, class F> template<class T, class F> void erase_if(std::vector<T>& vec, const F& f) {
void erase_if(std::vector<T>& vec, const F& f) {
vec.erase(std::remove_if(vec.begin(), vec.end(), f), vec.end()); vec.erase(std::remove_if(vec.begin(), vec.end(), f), vec.end());
} }
template<class T, class V> template<class T, class V> void erase(T& vec, const V& t) {
void erase(T& vec, const V& t) {
vec.erase(std::remove(vec.begin(), vec.end(), t), vec.end()); vec.erase(std::remove(vec.begin(), vec.end(), t), vec.end());
} }
template<class T> template<class T> void erase_at(std::vector<T>& vec, const int index) {
void erase_at(std::vector<T>& vec, const int index) {
vec.erase(vec.begin() + index); vec.erase(vec.begin() + index);
} }
@ -46,46 +42,60 @@ namespace utility {
return get_random(0, max); return get_random(0, max);
} }
template<class T> template<class T> inline auto get_random(const std::vector<T>& vec) {
inline auto get_random(const std::vector<T>& vec) {
return vec[get_random(static_cast<int>(vec.size() - 1))]; return vec[get_random(static_cast<int>(vec.size() - 1))];
} }
template<class T, size_t S> template<class T, size_t S> inline auto get_random(const std::array<T, S>& vec) {
inline auto get_random(const std::array<T, S>& vec) {
return vec[get_random(static_cast<int>(vec.size() - 1))]; return vec[get_random(static_cast<int>(vec.size() - 1))];
} }
template<class T, class V> template<class T, class V> inline auto get_random(const std::unordered_map<T, V>& map) {
inline auto get_random(const std::unordered_map<T, V>& map) {
const auto item = map.begin(); const auto item = map.begin();
std::advance(item, get_random(static_cast<int>(map.size() - 1))); std::advance(item, get_random(static_cast<int>(map.size() - 1)));
return item; return item;
} }
template<class T, class TIter = decltype(std::begin(std::declval<T>())), class = decltype(std::end(std::declval<T>()))> template<
constexpr auto enumerate(T&& iterable) class T,
{ class TIter = decltype(std::begin(std::declval<T>())),
class = decltype(std::end(std::declval<T>()))>
constexpr auto enumerate(T&& iterable) {
struct iterator { struct iterator {
size_t i; size_t i;
TIter iter; TIter iter;
bool operator != (const iterator & other) const { return iter != other.iter; }
void operator ++ () { ++i; ++iter; } bool operator!=(const iterator& other) const {
auto operator * () const { return std::tie(i, *iter); } return iter != other.iter;
}
void operator++() {
++i;
++iter;
}
auto operator*() const {
return std::tie(i, *iter);
}
}; };
struct iterable_wrapper { struct iterable_wrapper {
T iterable; T iterable;
auto begin() { return iterator{ 0, std::begin(iterable) }; }
auto end() { return iterator{ 0, std::end(iterable) }; } auto begin() {
return iterator{0, std::begin(iterable)};
}
auto end() {
return iterator{0, std::end(iterable)};
}
}; };
return iterable_wrapper{std::forward<T>(iterable)}; return iterable_wrapper{std::forward<T>(iterable)};
} }
template<class T, class V> template<class T, class V> inline bool contains(const std::vector<T>& vec, const V& val) {
inline bool contains(const std::vector<T>& vec, const V& val) {
return std::count(vec.begin(), vec.end(), val); return std::count(vec.begin(), vec.end(), val);
} }
@ -112,8 +122,7 @@ namespace utility {
return linear; return linear;
} }
template<typename T, typename F> template<typename T, typename F> inline void move_to_front(std::vector<T>& vec, F func) {
inline void move_to_front(std::vector<T>& vec, F func) {
auto result = std::find_if(vec.begin(), vec.end(), func); auto result = std::find_if(vec.begin(), vec.end(), func);
if (result != vec.end()) { if (result != vec.end()) {
auto value = *result; auto value = *result;
@ -121,4 +130,4 @@ namespace utility {
vec.insert(vec.begin(), value); vec.insert(vec.begin(), value);
} }
} }
} } // namespace utility

View file

@ -12,7 +12,8 @@ std::string remove_substring(const std::string_view string, const std::string_vi
return result; return result;
} }
std::string replace_substring(const std::string_view string, const std::string_view substring, const std::string_view replacement) { std::string
replace_substring(const std::string_view string, const std::string_view substring, const std::string_view replacement) {
std::string result(string); std::string result(string);
const auto substring_length = substring.length(); const auto substring_length = substring.length();
@ -31,12 +32,13 @@ bool string_contains(const std::string_view a, const std::string_view b) {
} }
bool string_starts_with(const std::string_view haystack, const std::string_view needle) { bool string_starts_with(const std::string_view haystack, const std::string_view needle) {
return needle.length() <= haystack.length() return needle.length() <= haystack.length() && std::equal(needle.begin(), needle.end(), haystack.begin());
&& std::equal(needle.begin(), needle.end(), haystack.begin());
} }
bool is_numeric(const std::string_view string) { bool is_numeric(const std::string_view string) {
return std::find_if(string.begin(), string.end(), [](unsigned char c) { return !std::isdigit(c); }) == string.end(); return std::find_if(string.begin(), string.end(), [](unsigned char c) {
return !std::isdigit(c);
}) == string.end();
} }
std::vector<std::string> tokenize(const std::string_view string, const std::string_view& delimiters) { std::vector<std::string> tokenize(const std::string_view string, const std::string_view& delimiters) {