Okay, reformat the rest of the engine code!
This commit is contained in:
parent
100e1d7434
commit
b00a39c474
75 changed files with 3059 additions and 2975 deletions
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <dxgi1_6.h>
|
||||
#include <d3dcompiler.h>
|
||||
#include <dxgi1_6.h>
|
||||
#include <wrl.h>
|
||||
|
||||
#include "gfx.hpp"
|
||||
|
@ -11,9 +11,18 @@ using namespace Microsoft::WRL;
|
|||
|
||||
class gfx_dx12 : public GFX {
|
||||
public:
|
||||
bool is_supported() override { return true; }
|
||||
ShaderLanguage accepted_shader_language() override { return ShaderLanguage::HLSL; }
|
||||
GFXContext required_context() override { return GFXContext::DirectX; }
|
||||
bool is_supported() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
ShaderLanguage accepted_shader_language() override {
|
||||
return ShaderLanguage::HLSL;
|
||||
}
|
||||
|
||||
GFXContext required_context() override {
|
||||
return GFXContext::DirectX;
|
||||
}
|
||||
|
||||
bool initialize(const GFXCreateInfo& info) override;
|
||||
|
||||
const char* get_name() override;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#include "gfx_dx12.hpp"
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <dxgi1_6.h>
|
||||
#include <d3dcompiler.h>
|
||||
#include <dxgi1_6.h>
|
||||
|
||||
#include <wrl.h>
|
||||
#include <codecvt>
|
||||
#include <wrl.h>
|
||||
|
||||
// from https://stackoverflow.com/a/18374698
|
||||
std::string ws2s(const std::wstring& wstr) {
|
||||
|
|
|
@ -8,15 +8,23 @@
|
|||
class GFXMetal : public GFX {
|
||||
public:
|
||||
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;
|
||||
|
||||
bool supports_feature(GFXFeature feature) 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;
|
||||
|
||||
// buffer operations
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
#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 "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 "utility.hpp"
|
||||
#include "string_utils.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
static inline bool debug_enabled = false;
|
||||
|
||||
|
@ -69,8 +69,7 @@ MTL::SamplerAddressMode toSamplingMode(SamplingMode mode) {
|
|||
return MTL::SamplerAddressModeRepeat;
|
||||
case SamplingMode::ClampToEdge:
|
||||
return MTL::SamplerAddressModeClampToEdge;
|
||||
case SamplingMode::ClampToBorder:
|
||||
{
|
||||
case SamplingMode::ClampToBorder: {
|
||||
#if defined(PLATFORM_IOS) || defined(PLATFORM_TVOS)
|
||||
return MTL::SamplerAddressModeRepeat;
|
||||
#else
|
||||
|
@ -168,7 +167,11 @@ bool GFXMetal::supports_feature(const GFXFeature feature) {
|
|||
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();
|
||||
native->identifier = identifier;
|
||||
|
||||
|
@ -230,18 +233,14 @@ GFXTexture* GFXMetal::create_texture(const GFXTextureCreateInfo& info) {
|
|||
case GFXTextureType::Array2D:
|
||||
textureDescriptor->setTextureType(MTL::TextureType2DArray);
|
||||
break;
|
||||
case GFXTextureType::Cubemap:
|
||||
{
|
||||
case GFXTextureType::Cubemap: {
|
||||
textureDescriptor->setTextureType(MTL::TextureTypeCube);
|
||||
texture->is_cubemap = true;
|
||||
}
|
||||
break;
|
||||
case GFXTextureType::CubemapArray:
|
||||
{
|
||||
} break;
|
||||
case GFXTextureType::CubemapArray: {
|
||||
textureDescriptor->setTextureType(MTL::TextureTypeCubeArray);
|
||||
texture->is_cubemap = true;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
|
||||
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::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();
|
||||
commandBuffer->commit();
|
||||
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)
|
||||
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);
|
||||
|
||||
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())
|
||||
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);
|
||||
}
|
||||
|
@ -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)
|
||||
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);
|
||||
|
||||
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())
|
||||
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);
|
||||
}
|
||||
|
@ -543,7 +551,8 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
|||
unsigned int i = 0;
|
||||
for (const auto& attachment : metalRenderPass->attachments) {
|
||||
if (attachment != MTL::PixelFormatDepth32Float) {
|
||||
MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = pipelineDescriptor->colorAttachments()->object(i++);
|
||||
MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor =
|
||||
pipelineDescriptor->colorAttachments()->object(i++);
|
||||
|
||||
colorAttachmentDescriptor->setPixelFormat(attachment);
|
||||
colorAttachmentDescriptor->setBlendingEnabled(info.blending.enable_blending);
|
||||
|
@ -558,7 +567,8 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
|||
}
|
||||
}
|
||||
} else {
|
||||
MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = pipelineDescriptor->colorAttachments()->object(0);
|
||||
MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor =
|
||||
pipelineDescriptor->colorAttachments()->object(0);
|
||||
|
||||
colorAttachmentDescriptor->setPixelFormat(nativeViews[0]->format);
|
||||
colorAttachmentDescriptor->setBlendingEnabled(info.blending.enable_blending);
|
||||
|
@ -577,7 +587,8 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
|||
|
||||
pipeline->handle = device->newRenderPipelineState(pipelineDescriptor, &error);
|
||||
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) {
|
||||
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)
|
||||
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));
|
||||
|
@ -666,7 +679,8 @@ GFXPipeline* GFXMetal::create_compute_pipeline(const GFXComputePipelineCreateInf
|
|||
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)
|
||||
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) {
|
||||
case CurrentEncoder::None:
|
||||
break;
|
||||
case CurrentEncoder::Render:
|
||||
{
|
||||
case CurrentEncoder::Render: {
|
||||
MTL::RenderPassDescriptor* descriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||
|
||||
if (currentRenderPass != nullptr && currentFramebuffer != nullptr) {
|
||||
|
@ -768,7 +781,8 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
depthAttachment->setLoadAction(MTL::LoadActionClear);
|
||||
depthAttachment->setStoreAction(MTL::StoreActionStore);
|
||||
} else {
|
||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = descriptor->colorAttachments()->object(i);
|
||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment =
|
||||
descriptor->colorAttachments()->object(i);
|
||||
|
||||
colorAttachment->setTexture(attachment->handle);
|
||||
colorAttachment->setLoadAction(MTL::LoadActionClear);
|
||||
|
@ -777,7 +791,8 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
}
|
||||
}
|
||||
} else {
|
||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = descriptor->colorAttachments()->object(0);
|
||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment =
|
||||
descriptor->colorAttachments()->object(0);
|
||||
|
||||
colorAttachment->setTexture(drawable->texture());
|
||||
colorAttachment->setLoadAction(MTL::LoadActionClear);
|
||||
|
@ -791,18 +806,13 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
renderEncoder->setViewport(currentViewport);
|
||||
|
||||
descriptor->release();
|
||||
}
|
||||
break;
|
||||
case CurrentEncoder::Compute:
|
||||
{
|
||||
} break;
|
||||
case CurrentEncoder::Compute: {
|
||||
computeEncoder = commandBuffer->computeCommandEncoder();
|
||||
}
|
||||
break;
|
||||
case CurrentEncoder::Blit:
|
||||
{
|
||||
} break;
|
||||
case CurrentEncoder::Blit: {
|
||||
blitEncoder = commandBuffer->blitCommandEncoder();
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
|
||||
current_encoder = encoder;
|
||||
|
@ -812,9 +822,9 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
switch (command.type) {
|
||||
case GFXCommandType::Invalid:
|
||||
break;
|
||||
case GFXCommandType::SetRenderPass:
|
||||
{
|
||||
currentClearColor = MTL::ClearColor(command.data.set_render_pass.clear_color.r,
|
||||
case GFXCommandType::SetRenderPass: {
|
||||
currentClearColor = MTL::ClearColor(
|
||||
command.data.set_render_pass.clear_color.r,
|
||||
command.data.set_render_pass.clear_color.g,
|
||||
command.data.set_render_pass.clear_color.b,
|
||||
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();
|
||||
|
||||
needEncoder(CurrentEncoder::Render, true);
|
||||
}
|
||||
break;
|
||||
case GFXCommandType::SetGraphicsPipeline:
|
||||
{
|
||||
} break;
|
||||
case GFXCommandType::SetGraphicsPipeline: {
|
||||
needEncoder(CurrentEncoder::Render);
|
||||
|
||||
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->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)
|
||||
renderEncoder->setTriangleFillMode(MTL::TriangleFillModeLines);
|
||||
else
|
||||
renderEncoder->setTriangleFillMode(MTL::TriangleFillModeFill);
|
||||
}
|
||||
break;
|
||||
case GFXCommandType::SetComputePipeline:
|
||||
{
|
||||
} break;
|
||||
case GFXCommandType::SetComputePipeline: {
|
||||
needEncoder(CurrentEncoder::Compute);
|
||||
|
||||
currentPipeline = (GFXMetalPipeline*)command.data.set_compute_pipeline.pipeline;
|
||||
|
||||
computeEncoder->setComputePipelineState(((GFXMetalPipeline*)command.data.set_compute_pipeline.pipeline)->compute_handle);
|
||||
}
|
||||
break;
|
||||
case GFXCommandType::SetVertexBuffer:
|
||||
{
|
||||
computeEncoder->setComputePipelineState(
|
||||
((GFXMetalPipeline*)command.data.set_compute_pipeline.pipeline)->compute_handle);
|
||||
} break;
|
||||
case GFXCommandType::SetVertexBuffer: {
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case GFXCommandType::SetIndexBuffer:
|
||||
{
|
||||
renderEncoder->setVertexBuffer(
|
||||
((GFXMetalBuffer*)command.data.set_vertex_buffer.buffer)->handle,
|
||||
command.data.set_vertex_buffer.offset,
|
||||
30 - command.data.set_vertex_buffer.index);
|
||||
} break;
|
||||
case GFXCommandType::SetIndexBuffer: {
|
||||
needEncoder(CurrentEncoder::Render);
|
||||
|
||||
currentIndexBuffer = (GFXMetalBuffer*)command.data.set_index_buffer.buffer;
|
||||
currentIndextype = command.data.set_index_buffer.index_type;
|
||||
}
|
||||
break;
|
||||
case GFXCommandType::SetPushConstant:
|
||||
{
|
||||
} break;
|
||||
case GFXCommandType::SetPushConstant: {
|
||||
if (current_encoder == CurrentEncoder::Render) {
|
||||
renderEncoder->setVertexBytes(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);
|
||||
renderEncoder->setVertexBytes(
|
||||
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) {
|
||||
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;
|
||||
case GFXCommandType::BindShaderBuffer:
|
||||
{
|
||||
} break;
|
||||
case GFXCommandType::BindShaderBuffer: {
|
||||
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->setFragmentBuffer(((GFXMetalBuffer*)command.data.bind_shader_buffer.buffer)->handle, command.data.bind_shader_buffer.offset, command.data.bind_shader_buffer.index);
|
||||
renderEncoder->setVertexBuffer(
|
||||
((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) {
|
||||
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;
|
||||
case GFXCommandType::BindTexture:
|
||||
{
|
||||
} break;
|
||||
case GFXCommandType::BindTexture: {
|
||||
if (current_encoder == CurrentEncoder::Render) {
|
||||
if (command.data.bind_texture.texture != nullptr) {
|
||||
renderEncoder->setVertexTexture(((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->setVertexTexture(
|
||||
((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->setFragmentSamplerState(((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->setFragmentSamplerState(
|
||||
((GFXMetalTexture*)command.data.bind_texture.texture)->sampler,
|
||||
command.data.bind_texture.index);
|
||||
} else {
|
||||
renderEncoder->setVertexTexture(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);
|
||||
}
|
||||
} 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;
|
||||
case GFXCommandType::BindSampler:
|
||||
{
|
||||
} break;
|
||||
case GFXCommandType::BindSampler: {
|
||||
needEncoder(CurrentEncoder::Render);
|
||||
|
||||
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 {
|
||||
renderEncoder->setFragmentSamplerState(nullptr, command.data.bind_sampler.index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GFXCommandType::Draw:
|
||||
{
|
||||
} break;
|
||||
case GFXCommandType::Draw: {
|
||||
needEncoder(CurrentEncoder::Render);
|
||||
|
||||
if (currentPipeline == nullptr)
|
||||
continue;
|
||||
|
||||
renderEncoder->drawPrimitives(currentPipeline->primitiveType,
|
||||
renderEncoder->drawPrimitives(
|
||||
currentPipeline->primitiveType,
|
||||
command.data.draw.vertex_offset,
|
||||
command.data.draw.vertex_count,
|
||||
command.data.draw.instance_count,
|
||||
command.data.draw.base_instance);
|
||||
}
|
||||
break;
|
||||
case GFXCommandType::DrawIndexed:
|
||||
{
|
||||
} break;
|
||||
case GFXCommandType::DrawIndexed: {
|
||||
needEncoder(CurrentEncoder::Render);
|
||||
|
||||
if (currentIndexBuffer == nullptr)
|
||||
|
@ -946,49 +971,46 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
MTL::IndexType indexType;
|
||||
int indexSize;
|
||||
switch (currentIndextype) {
|
||||
case IndexType::UINT16:
|
||||
{
|
||||
case IndexType::UINT16: {
|
||||
indexType = MTL::IndexTypeUInt16;
|
||||
indexSize = sizeof(uint16_t);
|
||||
}
|
||||
break;
|
||||
case IndexType::UINT32:
|
||||
{
|
||||
} break;
|
||||
case IndexType::UINT32: {
|
||||
indexType = MTL::IndexTypeUInt32;
|
||||
indexSize = sizeof(uint32_t);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
|
||||
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,
|
||||
indexType,
|
||||
currentIndexBuffer->handle,
|
||||
command.data.draw_indexed.first_index * indexSize);
|
||||
}
|
||||
break;
|
||||
case GFXCommandType::MemoryBarrier:
|
||||
{
|
||||
} break;
|
||||
case GFXCommandType::MemoryBarrier: {
|
||||
needEncoder(CurrentEncoder::Render);
|
||||
|
||||
#ifdef PLATFORM_MACOS
|
||||
renderEncoder->memoryBarrier(MTL::BarrierScopeTextures, MTL::RenderStageFragment, MTL::RenderStageFragment);
|
||||
renderEncoder->memoryBarrier(
|
||||
MTL::BarrierScopeTextures, MTL::RenderStageFragment, MTL::RenderStageFragment);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case GFXCommandType::CopyTexture:
|
||||
{
|
||||
} break;
|
||||
case GFXCommandType::CopyTexture: {
|
||||
needEncoder(CurrentEncoder::Blit);
|
||||
|
||||
auto metalFromTexture = (GFXMetalTexture*)command.data.copy_texture.src;
|
||||
auto metalToTexture = (GFXMetalTexture*)command.data.copy_texture.dst;
|
||||
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,
|
||||
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,
|
||||
MTL::Origin(0, 0, 0));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GFXCommandType::SetViewport:
|
||||
{
|
||||
} break;
|
||||
case GFXCommandType::SetViewport: {
|
||||
needEncoder(CurrentEncoder::Render);
|
||||
|
||||
MTL::Viewport viewport = {};
|
||||
|
@ -1014,10 +1034,8 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
|
||||
renderEncoder->setViewport(viewport);
|
||||
currentViewport = viewport;
|
||||
}
|
||||
break;
|
||||
case GFXCommandType::SetScissor:
|
||||
{
|
||||
} break;
|
||||
case GFXCommandType::SetScissor: {
|
||||
needEncoder(CurrentEncoder::Render);
|
||||
|
||||
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;
|
||||
|
||||
renderEncoder->setScissorRect(rect);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case GFXCommandType::GenerateMipmaps: {
|
||||
needEncoder(CurrentEncoder::Blit);
|
||||
|
||||
auto metalTexture = (GFXMetalTexture*)command.data.generate_mipmaps.texture;
|
||||
|
||||
blitEncoder->generateMipmaps(metalTexture->handle);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case GFXCommandType::SetDepthBias: {
|
||||
needEncoder(CurrentEncoder::Render);
|
||||
|
||||
renderEncoder->setDepthBias(command.data.set_depth_bias.constant, command.data.set_depth_bias.slope_factor, command.data.set_depth_bias.clamp);
|
||||
}
|
||||
break;
|
||||
renderEncoder->setDepthBias(
|
||||
command.data.set_depth_bias.constant,
|
||||
command.data.set_depth_bias.slope_factor,
|
||||
command.data.set_depth_bias.clamp);
|
||||
} break;
|
||||
case GFXCommandType::PushGroup: {
|
||||
commandBuffer->pushDebugGroup(NS::String::string(command.data.push_group.name.data(), NS::ASCIIStringEncoding));
|
||||
}
|
||||
break;
|
||||
commandBuffer->pushDebugGroup(
|
||||
NS::String::string(command.data.push_group.name.data(), NS::ASCIIStringEncoding));
|
||||
} break;
|
||||
case GFXCommandType::PopGroup: {
|
||||
commandBuffer->popDebugGroup();
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case GFXCommandType::InsertLabel: {
|
||||
switch (current_encoder) {
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case GFXCommandType::Dispatch: {
|
||||
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);
|
||||
}
|
||||
break;
|
||||
computeEncoder->dispatchThreadgroups(
|
||||
MTL::Size(
|
||||
command.data.dispatch.group_count_x,
|
||||
command.data.dispatch.group_count_y,
|
||||
command.data.dispatch.group_count_z),
|
||||
currentPipeline->threadGroupSize);
|
||||
} break;
|
||||
case GFXCommandType::EndRenderPass: {
|
||||
currentFramebuffer = nullptr;
|
||||
currentRenderPass = nullptr;
|
||||
currentPipeline = nullptr;
|
||||
renderEncoder->endEncoding();
|
||||
renderEncoder = nullptr;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "shadercompiler.hpp"
|
||||
#include "platform.hpp"
|
||||
#include "gfx_context.hpp"
|
||||
#include "platform.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
|
||||
class GFXBuffer;
|
||||
class GFXPipeline;
|
||||
|
@ -293,69 +293,112 @@ enum class GFXFeature {
|
|||
class GFX {
|
||||
public:
|
||||
// check for runtime support
|
||||
virtual bool is_supported() { 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 is_supported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
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 uint32_t width,
|
||||
[[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 height) {}
|
||||
|
||||
virtual void remove_view([[maybe_unused]] const platform::window_ptr identifier) {}
|
||||
|
||||
// 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 bool is_dynamic,
|
||||
[[maybe_unused]] const GFXBufferUsage usage) { return nullptr; }
|
||||
virtual void copy_buffer([[maybe_unused]] GFXBuffer* buffer,
|
||||
[[maybe_unused]] const GFXBufferUsage usage) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual void copy_buffer(
|
||||
[[maybe_unused]] GFXBuffer* buffer,
|
||||
[[maybe_unused]] void* data,
|
||||
[[maybe_unused]] const GFXSize offset,
|
||||
[[maybe_unused]] const GFXSize size) {}
|
||||
|
||||
virtual void* get_buffer_contents([[maybe_unused]] GFXBuffer* buffer) { return nullptr; }
|
||||
virtual void release_buffer_contents([[maybe_unused]] GFXBuffer* buffer,
|
||||
[[maybe_unused]] void* handle) {}
|
||||
virtual void* get_buffer_contents([[maybe_unused]] GFXBuffer* buffer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual void release_buffer_contents([[maybe_unused]] GFXBuffer* buffer, [[maybe_unused]] void* handle) {}
|
||||
|
||||
// texture operations
|
||||
virtual GFXTexture* create_texture([[maybe_unused]] const GFXTextureCreateInfo& info) { return nullptr; }
|
||||
virtual void copy_texture([[maybe_unused]] GFXTexture* texture,
|
||||
virtual GFXTexture* create_texture([[maybe_unused]] const GFXTextureCreateInfo& info) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual void copy_texture(
|
||||
[[maybe_unused]] GFXTexture* texture,
|
||||
[[maybe_unused]] void* data,
|
||||
[[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]] GFXBuffer* 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) {}
|
||||
|
||||
// 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
|
||||
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
|
||||
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
|
||||
virtual GFXPipeline* create_graphics_pipeline([[maybe_unused]] const GFXGraphicsPipelineCreateInfo& info) { return nullptr; }
|
||||
virtual GFXPipeline* create_compute_pipeline([[maybe_unused]] const GFXComputePipelineCreateInfo& info) { return nullptr; }
|
||||
virtual GFXPipeline* create_graphics_pipeline([[maybe_unused]] const GFXGraphicsPipelineCreateInfo& info) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual GFXPipeline* create_compute_pipeline([[maybe_unused]] const GFXComputePipelineCreateInfo& info) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 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,
|
||||
[[maybe_unused]] const platform::window_ptr window) {}
|
||||
virtual void
|
||||
submit([[maybe_unused]] GFXCommandBuffer* command_buffer, [[maybe_unused]] const platform::window_ptr window) {}
|
||||
};
|
||||
|
|
|
@ -4,5 +4,4 @@
|
|||
|
||||
class GFXBuffer : public GFXObject {
|
||||
public:
|
||||
|
||||
};
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
|
@ -230,7 +230,6 @@ public:
|
|||
command.data.bind_shader_buffer.index = index;
|
||||
command.data.bind_shader_buffer.size = size;
|
||||
|
||||
|
||||
commands.push_back(command);
|
||||
}
|
||||
|
||||
|
@ -252,7 +251,8 @@ public:
|
|||
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;
|
||||
command.type = GFXCommandType::Draw;
|
||||
command.data.draw.vertex_offset = offset;
|
||||
|
@ -263,7 +263,11 @@ public:
|
|||
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;
|
||||
command.type = GFXCommandType::DrawIndexed;
|
||||
command.data.draw_indexed.vertex_offset = vertexOffset;
|
||||
|
@ -281,7 +285,8 @@ public:
|
|||
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;
|
||||
command.type = GFXCommandType::CopyTexture;
|
||||
command.data.copy_texture.src = src;
|
||||
|
|
|
@ -4,5 +4,4 @@
|
|||
|
||||
class GFXFramebuffer : public GFXObject {
|
||||
public:
|
||||
|
||||
};
|
||||
|
|
|
@ -4,5 +4,4 @@
|
|||
|
||||
class GFXRenderPass : public GFXObject {
|
||||
public:
|
||||
|
||||
};
|
||||
|
|
|
@ -4,5 +4,4 @@
|
|||
|
||||
class GFXSampler : public GFXObject {
|
||||
public:
|
||||
|
||||
};
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include <map>
|
||||
#include <array>
|
||||
#include <map>
|
||||
|
||||
#include "gfx.hpp"
|
||||
#include "gfx_vulkan_constants.hpp"
|
||||
|
@ -37,16 +37,26 @@ class GFXVulkanPipeline;
|
|||
|
||||
class GFXVulkan : public GFX {
|
||||
public:
|
||||
bool is_supported() override { return true; }
|
||||
ShaderLanguage accepted_shader_language() override { return ShaderLanguage::SPIRV; }
|
||||
GFXContext required_context() override { return GFXContext::Vulkan; }
|
||||
bool is_supported() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
ShaderLanguage accepted_shader_language() override {
|
||||
return ShaderLanguage::SPIRV;
|
||||
}
|
||||
|
||||
GFXContext required_context() override {
|
||||
return GFXContext::Vulkan;
|
||||
}
|
||||
|
||||
const char* get_name() override;
|
||||
|
||||
bool supports_feature(GFXFeature feature) 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;
|
||||
|
||||
// buffer operations
|
||||
|
@ -95,8 +105,15 @@ private:
|
|||
uint64_t getDescriptorHash(GFXVulkanPipeline* pipeline);
|
||||
|
||||
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
|
||||
void transitionImageLayout(VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageSubresourceRange range, VkImageLayout oldLayout, VkImageLayout newLayout);
|
||||
void inlineTransitionImageLayout(VkCommandBuffer command_buffer,
|
||||
void transitionImageLayout(
|
||||
VkImage image,
|
||||
VkFormat format,
|
||||
VkImageAspectFlags aspect,
|
||||
VkImageSubresourceRange range,
|
||||
VkImageLayout oldLayout,
|
||||
VkImageLayout newLayout);
|
||||
void inlineTransitionImageLayout(
|
||||
VkCommandBuffer command_buffer,
|
||||
VkImage image,
|
||||
VkFormat format,
|
||||
VkImageAspectFlags aspect,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,8 +11,7 @@ namespace prism {
|
|||
log_output += str + "\n";
|
||||
}
|
||||
|
||||
template <typename S, typename... Args>
|
||||
inline void log(const S& format, Args&&... args) {
|
||||
template<typename S, typename... Args> inline void log(const S& format, Args&&... args) {
|
||||
vlog(format, fmt::make_args_checked<Args...>(format, args...));
|
||||
}
|
||||
}
|
||||
} // namespace prism
|
|
@ -22,4 +22,4 @@ namespace prism {
|
|||
float3(aabb.min.x, aabb.max.y, aabb.max.z),
|
||||
float3(aabb.max.x, aabb.max.y, aabb.max.z)};
|
||||
}
|
||||
}
|
||||
} // namespace prism
|
|
@ -1,26 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include "matrix.hpp"
|
||||
#include "ray.hpp"
|
||||
#include "transform.hpp"
|
||||
#include "vector.hpp"
|
||||
#include "ray.hpp"
|
||||
|
||||
constexpr double PI = 3.141592653589793;
|
||||
|
||||
template<typename T>
|
||||
constexpr inline T radians(const T degrees) {
|
||||
template<typename T> constexpr inline T radians(const T degrees) {
|
||||
return degrees / static_cast<T>(180) * static_cast<T>(PI);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr inline T degrees(const T radians) {
|
||||
template<typename T> constexpr inline T degrees(const T radians) {
|
||||
return radians / static_cast<T>(PI) * static_cast<T>(180);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr inline bool nearly_equal(const T a, const T b) {
|
||||
return std::nextafter(a, std::numeric_limits<T>::lowest()) <= b
|
||||
&& std::nextafter(a, std::numeric_limits<T>::max()) >= b;
|
||||
template<typename T> constexpr inline bool nearly_equal(const T a, const T b) {
|
||||
return std::nextafter(a, std::numeric_limits<T>::lowest()) <= b &&
|
||||
std::nextafter(a, std::numeric_limits<T>::max()) >= b;
|
||||
}
|
||||
|
||||
Matrix4x4 matrix_from_quat(Quaternion quat);
|
||||
|
|
|
@ -5,15 +5,18 @@
|
|||
// m = rows
|
||||
// n = columns
|
||||
// row major storage mode?
|
||||
template<class T, std::size_t M, std::size_t N>
|
||||
class Matrix {
|
||||
template<class T, std::size_t M, std::size_t N> class Matrix {
|
||||
public:
|
||||
constexpr Matrix(const T diagonal = T(1)) {
|
||||
for (std::size_t i = 0; i < (M * N); i++)
|
||||
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[1] = m2_;
|
||||
columns[2] = m3_;
|
||||
|
@ -24,8 +27,13 @@ public:
|
|||
|
||||
using VectorType = prism::Vector<N, T>;
|
||||
|
||||
constexpr VectorType& operator[](const size_t index) { return columns[index]; }
|
||||
constexpr VectorType operator[](const size_t index) const { return columns[index]; }
|
||||
constexpr VectorType& operator[](const size_t index) {
|
||||
return columns[index];
|
||||
}
|
||||
|
||||
constexpr VectorType operator[](const size_t index) const {
|
||||
return columns[index];
|
||||
}
|
||||
|
||||
union {
|
||||
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>
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -9,9 +9,7 @@ struct Plane {
|
|||
};
|
||||
|
||||
inline Plane normalize(const Plane& plane) {
|
||||
const float magnitude = std::sqrt(plane.a * plane.a +
|
||||
plane.b * plane.b +
|
||||
plane.c * plane.c);
|
||||
const float magnitude = std::sqrt(plane.a * plane.a + plane.b * plane.b + plane.c * plane.c);
|
||||
|
||||
Plane normalized_plane = plane;
|
||||
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) {
|
||||
return plane.a * point.x +
|
||||
plane.b * point.y +
|
||||
plane.c * point.z +
|
||||
plane.d;
|
||||
return plane.a * point.x + plane.b * point.y + plane.c * point.z + plane.d;
|
||||
}
|
||||
|
|
|
@ -70,10 +70,7 @@ constexpr inline Quaternion lerp(const Quaternion& a, const Quaternion& b, const
|
|||
sclq = time;
|
||||
}
|
||||
|
||||
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};
|
||||
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};
|
||||
}
|
||||
|
||||
constexpr inline Quaternion operator*(const Quaternion lhs, const Quaternion rhs) {
|
||||
|
|
|
@ -9,4 +9,4 @@ namespace prism {
|
|||
};
|
||||
|
||||
float closest_distance_between_lines(ray& l1, ray& l2);
|
||||
}
|
||||
} // namespace prism
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "matrix.hpp"
|
||||
#include "vector.hpp"
|
||||
#include "quaternion.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
namespace prism {
|
||||
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 rotate(Matrix4x4 matrix, float angle, float3 axis);
|
||||
Matrix4x4 scale(Matrix4x4 matrix, float3 scale);
|
||||
}
|
||||
} // namespace prism
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <array>
|
||||
|
||||
namespace prism {
|
||||
#define DEFINE_OPERATORS(Size) \
|
||||
|
@ -11,12 +11,8 @@ namespace prism {
|
|||
for (std::size_t i = 0; i < (Size); i++) \
|
||||
data[i] = scalar; \
|
||||
} \
|
||||
constexpr T& operator[](const size_t index) { \
|
||||
return data[index]; \
|
||||
} \
|
||||
constexpr T operator[](const size_t index) const { \
|
||||
return data[index]; \
|
||||
} \
|
||||
constexpr T& operator[](const size_t index) { return data[index]; } \
|
||||
constexpr T operator[](const size_t index) const { return data[index]; } \
|
||||
constexpr Vector& operator+=(const Vector rhs) { \
|
||||
for (std::size_t i = 0; i < (Size); i++) \
|
||||
data[i] += rhs[i]; \
|
||||
|
@ -37,12 +33,8 @@ namespace prism {
|
|||
data[i] /= scalar; \
|
||||
return *this; \
|
||||
} \
|
||||
constexpr T* ptr() const { \
|
||||
return data.data(); \
|
||||
} \
|
||||
constexpr T* ptr() { \
|
||||
return data.data(); \
|
||||
} \
|
||||
constexpr T* ptr() const { return data.data(); } \
|
||||
constexpr T* ptr() { return data.data(); } \
|
||||
constexpr Vector operator-() const { \
|
||||
Vector vec; \
|
||||
for (std::size_t i = 0; i < (Size); i++) \
|
||||
|
@ -50,13 +42,9 @@ namespace prism {
|
|||
return vec; \
|
||||
}
|
||||
|
||||
template<std::size_t N, class T>
|
||||
struct Vector {
|
||||
std::array<T, N> data;
|
||||
};
|
||||
template<std::size_t N, class T> struct Vector { std::array<T, N> data; };
|
||||
|
||||
template<class T>
|
||||
struct Vector<2, T> {
|
||||
template<class T> struct Vector<2, T> {
|
||||
constexpr Vector(const T x_, const T y_) {
|
||||
x = x_;
|
||||
y = y_;
|
||||
|
@ -73,8 +61,7 @@ namespace prism {
|
|||
};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct Vector<3, T> {
|
||||
template<class T> struct Vector<3, T> {
|
||||
constexpr Vector(const T x_, const T y_, const T z_) {
|
||||
x = x_;
|
||||
y = y_;
|
||||
|
@ -92,8 +79,7 @@ namespace prism {
|
|||
};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct alignas(16) Vector<4, T> {
|
||||
template<class T> struct alignas(16) Vector<4, T> {
|
||||
constexpr Vector(const T x_, const T y_, const T z_, const T w_) {
|
||||
x = x_;
|
||||
y = y_;
|
||||
|
@ -123,8 +109,7 @@ namespace prism {
|
|||
using float3 = Vector<3, float>;
|
||||
using float4 = Vector<4, float>;
|
||||
|
||||
template<std::size_t N, class T>
|
||||
constexpr inline T dot(const Vector<N, T> lhs, const Vector<N, T> rhs) {
|
||||
template<std::size_t N, class T> constexpr inline T dot(const Vector<N, T> lhs, const Vector<N, T> rhs) {
|
||||
T product = T(0.0);
|
||||
|
||||
for (std::size_t i = 0; i < N; i++)
|
||||
|
@ -133,8 +118,7 @@ namespace prism {
|
|||
return product;
|
||||
}
|
||||
|
||||
template<std::size_t N, class T>
|
||||
constexpr inline T length(const Vector<N, T> vec) {
|
||||
template<std::size_t N, class T> constexpr inline T length(const Vector<N, T> vec) {
|
||||
return sqrtf(dot(vec, vec));
|
||||
}
|
||||
|
||||
|
@ -147,8 +131,7 @@ namespace prism {
|
|||
return vec;
|
||||
}
|
||||
|
||||
template<std::size_t N, class T>
|
||||
constexpr inline Vector<N, T> normalize(const Vector<N, T> vec) {
|
||||
template<std::size_t N, class T> constexpr inline Vector<N, T> normalize(const Vector<N, T> vec) {
|
||||
Vector<N, T> result;
|
||||
|
||||
const float len = length(vec);
|
||||
|
@ -170,15 +153,14 @@ namespace prism {
|
|||
return std::sqrt((diffX * diffX) + (diffY * diffY) + (diffZ * diffZ));
|
||||
}
|
||||
|
||||
template<std::size_t N, class T>
|
||||
constexpr inline T norm(const Vector<N, T> vec) {
|
||||
template<std::size_t N, class T> constexpr inline T norm(const Vector<N, T> vec) {
|
||||
T val = T(0);
|
||||
for (std::size_t i = 0; i < N; i++)
|
||||
val += abs(vec[i]);
|
||||
|
||||
return sqrtf(dot(vec, vec));
|
||||
}
|
||||
}
|
||||
} // namespace prism
|
||||
|
||||
template<std::size_t N, class T>
|
||||
constexpr inline bool operator==(const prism::Vector<N, T> lhs, const prism::Vector<N, T> rhs) {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "log.hpp"
|
||||
#include "path.hpp"
|
||||
|
@ -21,10 +21,8 @@ namespace prism {
|
|||
public:
|
||||
explicit file(FILE* handle) : handle(handle) {}
|
||||
|
||||
file(file&& f) noexcept :
|
||||
mem(std::move(f.mem)),
|
||||
handle(std::exchange(f.handle, nullptr)),
|
||||
data(std::move(f.data)) {}
|
||||
file(file&& f) noexcept
|
||||
: mem(std::move(f.mem)), handle(std::exchange(f.handle, nullptr)), data(std::move(f.data)) {}
|
||||
|
||||
~file() {
|
||||
if (handle != nullptr)
|
||||
|
@ -35,8 +33,7 @@ namespace prism {
|
|||
@param t The pointer to the type.
|
||||
@param s If not 0, the size to load is derived from sizeof(T).
|
||||
*/
|
||||
template<typename T>
|
||||
void read(T* t, const size_t s = 0) {
|
||||
template<typename T> void read(T* t, const size_t s = 0) {
|
||||
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.
|
||||
template<typename T>
|
||||
T* cast_data() {
|
||||
template<typename T> T* cast_data() {
|
||||
return reinterpret_cast<T*>(data.data());
|
||||
}
|
||||
|
||||
|
@ -133,6 +129,6 @@ namespace prism {
|
|||
path get_file_path(const path& path);
|
||||
|
||||
inline path base_domain = "/base", game_domain = "/game";
|
||||
}
|
||||
} // namespace prism
|
||||
|
||||
inline std::array<std::string, 3> domain_data;
|
||||
|
|
|
@ -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)
|
||||
// this only determines it at build-time, not at runtime.
|
||||
#ifdef ENABLE_VULKAN
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <vector>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
struct vulkan_information {
|
||||
std::vector<const char*> surface_extensions;
|
||||
|
@ -140,9 +140,9 @@ namespace platform {
|
|||
void initialize_context(GFXContext context);
|
||||
|
||||
/*
|
||||
* This is used in specific cases where the gfx backend may need to know important information before window creation.
|
||||
* A good example is the surface extension required by a specific window backend, but this is between initialize_context
|
||||
* and create_surface calls.
|
||||
* This is used in specific cases where the gfx backend may need to know important information before window
|
||||
* creation. A good example is the surface extension required by a specific window backend, but this is between
|
||||
* initialize_context and create_surface calls.
|
||||
*
|
||||
* 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 rect The requested size and position of the window.
|
||||
@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 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.
|
||||
@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 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.
|
||||
*/
|
||||
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);
|
||||
|
||||
/*
|
||||
* This needs to be implemented under certain gfx contexts (such as metal) which calls [layer nextDrawable] underneath
|
||||
* can be no-op for contexts such as vulkan which can happen within it's own API.
|
||||
* This needs to be implemented under certain gfx contexts (such as metal) which calls [layer nextDrawable]
|
||||
* 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.
|
||||
*/
|
||||
|
@ -201,7 +203,8 @@ namespace platform {
|
|||
/// Get the window size, note that in hidpi scenarios this is the non-scaled resolution.
|
||||
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);
|
||||
|
||||
/// 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.
|
||||
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 end_text_input();
|
||||
}
|
||||
} // namespace platform
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
#include "aabb.hpp"
|
||||
#include "asset_types.hpp"
|
||||
#include "components.hpp"
|
||||
#include "frustum.hpp"
|
||||
#include "matrix.hpp"
|
||||
#include "vector.hpp"
|
||||
#include "components.hpp"
|
||||
#include "aabb.hpp"
|
||||
#include "plane.hpp"
|
||||
#include "asset_types.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
class Scene;
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
#include <string_view>
|
||||
|
||||
#include "pass.hpp"
|
||||
#include "file.hpp"
|
||||
#include "pass.hpp"
|
||||
|
||||
class GFXBuffer;
|
||||
class GFXCommandBuffer;
|
||||
|
|
|
@ -15,11 +15,13 @@ constexpr int bone_buffer_index = 10;
|
|||
|
||||
class MaterialCompiler {
|
||||
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);
|
||||
|
||||
// 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);
|
||||
};
|
||||
|
|
|
@ -21,11 +21,14 @@ public:
|
|||
|
||||
virtual void create_render_target_resources([[maybe_unused]] RenderTarget& target) {}
|
||||
|
||||
virtual void render_scene([[maybe_unused]] Scene& scene,
|
||||
[[maybe_unused]] GFXCommandBuffer* commandBuffer) {}
|
||||
virtual void render_post([[maybe_unused]] GFXCommandBuffer* commandBuffer,
|
||||
virtual void render_scene([[maybe_unused]] Scene& scene, [[maybe_unused]] GFXCommandBuffer* commandBuffer) {}
|
||||
|
||||
virtual void render_post(
|
||||
[[maybe_unused]] GFXCommandBuffer* commandBuffer,
|
||||
[[maybe_unused]] RenderTarget& target,
|
||||
[[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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "pass.hpp"
|
||||
#include "common.hpp"
|
||||
#include "matrix.hpp"
|
||||
#include "object.hpp"
|
||||
#include "common.hpp"
|
||||
#include "render_options.hpp"
|
||||
#include "pass.hpp"
|
||||
#include "path.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
#include "rendertarget.hpp"
|
||||
#include "platform.hpp"
|
||||
#include "render_options.hpp"
|
||||
#include "rendertarget.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
|
||||
class GFX;
|
||||
class GFXBuffer;
|
||||
|
@ -58,14 +58,19 @@ namespace prism {
|
|||
|
||||
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,
|
||||
prism::Extent extent, RenderTarget& target, controller_continuity &continuity);
|
||||
void render_camera(
|
||||
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;
|
||||
|
||||
// passes
|
||||
template<class T, typename... Args>
|
||||
T* addPass(Args &&... args) {
|
||||
template<class T, typename... Args> T* addPass(Args&&... args) {
|
||||
auto t = std::make_unique<T>(args...);
|
||||
t->initialize();
|
||||
|
||||
|
@ -151,4 +156,4 @@ namespace prism {
|
|||
|
||||
std::vector<std::unique_ptr<Pass>> passes;
|
||||
};
|
||||
}
|
||||
} // namespace prism
|
|
@ -14,7 +14,8 @@ public:
|
|||
prism::Extent extent;
|
||||
|
||||
[[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))};
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@ public:
|
|||
|
||||
GFXTexture* environmentCube = nullptr;
|
||||
|
||||
GFXTexture* offscreenTexture = nullptr, *irradianceOffscreenTexture = nullptr, *prefilteredOffscreenTexture = nullptr;
|
||||
GFXTexture *offscreenTexture = nullptr, *irradianceOffscreenTexture = nullptr,
|
||||
*prefilteredOffscreenTexture = nullptr;
|
||||
GFXTexture* offscreenDepth = nullptr;
|
||||
GFXFramebuffer *offscreenFramebuffer = nullptr, *irradianceFramebuffer = nullptr, *prefilteredFramebuffer = nullptr;
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "components.hpp"
|
||||
#include "math.hpp"
|
||||
#include "object.hpp"
|
||||
#include "components.hpp"
|
||||
|
||||
class GFX;
|
||||
class GFXCommandBuffer;
|
||||
|
@ -24,7 +24,15 @@ public:
|
|||
void render(GFXCommandBuffer* command_buffer, Scene& scene);
|
||||
|
||||
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_spot(GFXCommandBuffer* command_buffer, Scene& scene, prism::Object light_object, Light& light);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "dofpass.hpp"
|
||||
|
||||
#include "renderer.hpp"
|
||||
#include "asset.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "gfx_commandbuffer.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "asset.hpp"
|
||||
#include "renderer.hpp"
|
||||
|
||||
AssetPtr<Texture> aperture_texture;
|
||||
|
||||
|
@ -36,12 +36,9 @@ DoFPass::DoFPass(GFX* gfx) {
|
|||
{0, GFXBindingType::StorageImage},
|
||||
{1, GFXBindingType::Texture},
|
||||
{3, GFXBindingType::Texture},
|
||||
{2, GFXBindingType::PushConstant}
|
||||
};
|
||||
{2, GFXBindingType::PushConstant}};
|
||||
|
||||
create_info.shader_input.push_constants = {
|
||||
{sizeof(prism::float4), 0}
|
||||
};
|
||||
create_info.shader_input.push_constants = {{sizeof(prism::float4), 0}};
|
||||
|
||||
create_info.render_pass = renderpass;
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "assertions.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "gfx_commandbuffer.hpp"
|
||||
#include "log.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "renderer.hpp"
|
||||
|
||||
void ImGuiPass::initialize() {
|
||||
|
@ -57,14 +57,9 @@ void ImGuiPass::create_render_target_resources(RenderTarget& target) {
|
|||
createInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha;
|
||||
createInfo.blending.dst_alpha = GFXBlendFactor::OneMinusSrcAlpha;
|
||||
|
||||
createInfo.shader_input.push_constants = {
|
||||
{sizeof(Matrix4x4), 0}
|
||||
};
|
||||
createInfo.shader_input.push_constants = {{sizeof(Matrix4x4), 0}};
|
||||
|
||||
createInfo.shader_input.bindings = {
|
||||
{1, GFXBindingType::PushConstant},
|
||||
{2, GFXBindingType::Texture}
|
||||
};
|
||||
createInfo.shader_input.bindings = {{1, GFXBindingType::PushConstant}, {2, GFXBindingType::Texture}};
|
||||
|
||||
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)
|
||||
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.y + draw_data->DisplaySize.y,
|
||||
draw_data->DisplayPos.y,
|
||||
|
@ -119,14 +115,26 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ
|
|||
if (pcmd->UserCallback != nullptr) {
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
} else {
|
||||
ImVec2 clip_min((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);
|
||||
ImVec2 clip_min(
|
||||
(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
|
||||
if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
|
||||
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_min.x < 0.0f) {
|
||||
clip_min.x = 0.0f;
|
||||
}
|
||||
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)
|
||||
continue;
|
||||
|
||||
|
@ -140,12 +148,12 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ
|
|||
command_buffer->set_scissor(scissor);
|
||||
|
||||
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->draw_indexed(pcmd->ElemCount,
|
||||
(index_offset + pcmd->IdxOffset),
|
||||
(vertex_offset + pcmd->VtxOffset), 0);
|
||||
command_buffer->set_index_buffer(
|
||||
target.index_buffer[target.current_frame],
|
||||
sizeof(ImDrawIdx) == 2 ? IndexType::UINT16 : IndexType::UINT32);
|
||||
|
||||
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();
|
||||
|
||||
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();
|
||||
} else {
|
||||
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_index_size > 0);
|
||||
|
||||
if(target.vertex_buffer[target.current_frame] == nullptr || 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);
|
||||
if (target.vertex_buffer[target.current_frame] == nullptr ||
|
||||
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;
|
||||
}
|
||||
|
||||
if(target.index_buffer[target.current_frame] == nullptr || 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);
|
||||
if (target.index_buffer[target.current_frame] == nullptr ||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#include "materialcompiler.hpp"
|
||||
|
||||
#include "engine.hpp"
|
||||
#include "file.hpp"
|
||||
#include "log.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "string_utils.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
#include "string_utils.hpp"
|
||||
|
||||
ShaderSource get_shader(const std::string& filename, bool skinned, bool cubemap) {
|
||||
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)
|
||||
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
|
||||
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);
|
||||
|
||||
if (positions_only) {
|
||||
createInfo.vertex_input.inputs = {
|
||||
{position_buffer_index, sizeof(prism::float3)}
|
||||
};
|
||||
createInfo.vertex_input.inputs = {{position_buffer_index, sizeof(prism::float3)}};
|
||||
|
||||
createInfo.vertex_input.attributes = {
|
||||
{position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3}
|
||||
};
|
||||
createInfo.vertex_input.attributes = {{position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3}};
|
||||
} else {
|
||||
createInfo.vertex_input.inputs = {
|
||||
{position_buffer_index, sizeof(prism::float3)},
|
||||
{normal_buffer_index, sizeof(prism::float3)},
|
||||
{texcoord_buffer_index, sizeof(prism::float2)},
|
||||
{tangent_buffer_index, sizeof(prism::float3)},
|
||||
{bitangent_buffer_index, sizeof(prism::float3)}
|
||||
};
|
||||
{bitangent_buffer_index, sizeof(prism::float3)}};
|
||||
|
||||
createInfo.vertex_input.attributes = {
|
||||
{position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3},
|
||||
{normal_buffer_index, 1, 0, GFXVertexFormat::FLOAT3},
|
||||
{texcoord_buffer_index, 2, 0, GFXVertexFormat::FLOAT2},
|
||||
{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);
|
||||
|
@ -84,15 +84,12 @@ GFXPipeline* MaterialCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreate
|
|||
|
||||
if (positions_only) {
|
||||
createInfo.vertex_input.inputs = {
|
||||
{position_buffer_index, sizeof(prism::float3)},
|
||||
{bone_buffer_index, sizeof(BoneVertexData)}
|
||||
};
|
||||
{position_buffer_index, sizeof(prism::float3)}, {bone_buffer_index, sizeof(BoneVertexData)}};
|
||||
|
||||
createInfo.vertex_input.attributes = {
|
||||
{position_buffer_index, 0, 0, GFXVertexFormat::FLOAT3},
|
||||
{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 {
|
||||
createInfo.vertex_input.inputs = {
|
||||
{position_buffer_index, sizeof(prism::float3)},
|
||||
|
@ -100,8 +97,7 @@ GFXPipeline* MaterialCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreate
|
|||
{texcoord_buffer_index, sizeof(prism::float2)},
|
||||
{tangent_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 = {
|
||||
{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);
|
||||
}
|
||||
|
||||
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 ss = create_skinned_pipeline(createInfo, positions_only);
|
||||
|
||||
|
@ -176,7 +173,8 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
|
|||
break;
|
||||
}
|
||||
|
||||
format_to(std::back_inserter(src),
|
||||
format_to(
|
||||
std::back_inserter(src),
|
||||
R"(layout (location = 0) in vec3 in_frag_pos;
|
||||
layout(location = 1) in vec3 in_normal;
|
||||
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) {
|
||||
format_to(std::back_inserter(src),
|
||||
format_to(
|
||||
std::back_inserter(src),
|
||||
R"(#define POINT_SHADOWS_SUPPORTED
|
||||
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);
|
||||
|
||||
if (use_ibl) {
|
||||
format_to(std::back_inserter(src),
|
||||
format_to(
|
||||
std::back_inserter(src),
|
||||
R"(layout (binding = 7) uniform samplerCubeArray irrandianceSampler;
|
||||
layout (binding = 8) uniform samplerCubeArray prefilterSampler;
|
||||
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;
|
||||
layout(location = 5) in mat3 in_tbn;
|
||||
layout(location = 14) in vec4 fragPostSpotLightSpace[max_spot_lights];
|
||||
|
@ -226,7 +227,8 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
|
|||
}
|
||||
|
||||
if (use_ibl) {
|
||||
format_to(std::back_inserter(src),
|
||||
format_to(
|
||||
std::back_inserter(src),
|
||||
R"(vec3 get_reflect(int i, vec3 final_normal) {{
|
||||
const vec3 direction = normalize(in_frag_pos - scene.camPos.xyz);
|
||||
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) {
|
||||
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) {{
|
||||
float height_scale = 0.8;
|
||||
float sample_count = 100.0;
|
||||
|
@ -279,7 +282,8 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo
|
|||
}
|
||||
|
||||
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) {{
|
||||
const vec3 F = fresnel_schlick_roughness(surface_info.NdotV, surface_info.F0, surface_info.roughness);
|
||||
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");
|
||||
|
||||
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) {
|
||||
format_to(std::back_inserter(src), "vec3 Color = texture(colorTexture, in_uv).rgb;\n");
|
||||
} 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),
|
||||
format_to(
|
||||
std::back_inserter(src),
|
||||
R"(vec3 final_diffuse_color = from_srgb_to_linear(Color);
|
||||
float final_roughness = scene.materials[inMaterialIndex].info.y;
|
||||
float final_metallic = scene.materials[inMaterialIndex].info.x;
|
||||
)");
|
||||
|
||||
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;
|
||||
final_normal = final_normal * 2.0 - 1.0;
|
||||
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),
|
||||
format_to(
|
||||
std::back_inserter(src),
|
||||
R"(ComputedSurfaceInfo surface_info = compute_surface(final_diffuse_color.rgb, final_normal, final_metallic, final_roughness);
|
||||
vec3 Lo = vec3(0);
|
||||
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);
|
||||
)");
|
||||
|
||||
if(render_options.enable_normal_mapping && material.normalProperty.type == DataType::AssetTexture && render_options.enable_normal_shadowing) {
|
||||
format_to(std::back_inserter(src), "light_info.radiance *= calculate_normal_lighting(normalTexture, final_normal, light_info.direction);\n");
|
||||
if (render_options.enable_normal_mapping && material.normalProperty.type == DataType::AssetTexture &&
|
||||
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");
|
||||
|
||||
if (use_ibl) {
|
||||
format_to(std::back_inserter(src),
|
||||
format_to(
|
||||
std::back_inserter(src),
|
||||
R"(vec3 ambient = vec3(0.0);
|
||||
float sum = 0.0;
|
||||
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");
|
||||
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
#include "renderer.hpp"
|
||||
|
||||
#include "gfx_commandbuffer.hpp"
|
||||
#include "math.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "debug.hpp"
|
||||
#include "dofpass.hpp"
|
||||
#include "file.hpp"
|
||||
#include "scene.hpp"
|
||||
#include "vector.hpp"
|
||||
#include "imguipass.hpp"
|
||||
#include "frustum.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "gfx_commandbuffer.hpp"
|
||||
#include "imguipass.hpp"
|
||||
#include "materialcompiler.hpp"
|
||||
#include "math.hpp"
|
||||
#include "pass.hpp"
|
||||
#include "scene.hpp"
|
||||
#include "scenecapture.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
#include "shadowpass.hpp"
|
||||
#include "smaapass.hpp"
|
||||
#include "scenecapture.hpp"
|
||||
#include "materialcompiler.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "dofpass.hpp"
|
||||
#include "frustum.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
#include "debug.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
using prism::renderer;
|
||||
|
||||
|
@ -113,9 +113,7 @@ void renderer::resize_render_target(RenderTarget& target, const prism::Extent ex
|
|||
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) {
|
||||
const auto extent = target.extent;
|
||||
|
@ -167,15 +165,15 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
|
|||
for (auto& [obj, camera] : cameras) {
|
||||
const bool requires_limited_perspective = render_options.enable_depth_of_field;
|
||||
if (requires_limited_perspective) {
|
||||
camera.perspective = prism::perspective(radians(camera.fov),
|
||||
static_cast<float>(render_extent.width) /
|
||||
static_cast<float>(render_extent.height),
|
||||
camera.perspective = prism::perspective(
|
||||
radians(camera.fov),
|
||||
static_cast<float>(render_extent.width) / static_cast<float>(render_extent.height),
|
||||
camera.near,
|
||||
100.0f);
|
||||
} else {
|
||||
camera.perspective = prism::infinite_perspective(radians(camera.fov),
|
||||
static_cast<float>(render_extent.width) /
|
||||
static_cast<float>(render_extent.height),
|
||||
camera.perspective = prism::infinite_perspective(
|
||||
radians(camera.fov),
|
||||
static_cast<float>(render_extent.width) / static_cast<float>(render_extent.height),
|
||||
camera.near);
|
||||
}
|
||||
|
||||
|
@ -209,33 +207,30 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
|
|||
commandbuffer->set_compute_pipeline(histogram_pipeline);
|
||||
|
||||
commandbuffer->bind_texture(target.offscreenColorTexture, 0);
|
||||
commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1,
|
||||
sizeof(uint32_t) * 256);
|
||||
commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256);
|
||||
|
||||
const float lum_range =
|
||||
render_options.max_luminance - render_options.min_luminance;
|
||||
const float lum_range = render_options.max_luminance - render_options.min_luminance;
|
||||
|
||||
prism::float4 params =
|
||||
prism::float4(render_options.min_luminance, 1.0f / lum_range,
|
||||
prism::float4 params = prism::float4(
|
||||
render_options.min_luminance,
|
||||
1.0f / lum_range,
|
||||
static_cast<float>(render_extent.width),
|
||||
static_cast<float>(render_extent.height));
|
||||
|
||||
commandbuffer->set_push_constant(¶ms, sizeof(prism::float4));
|
||||
|
||||
commandbuffer->dispatch(
|
||||
static_cast<uint32_t>(
|
||||
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.width) / 16.0f)),
|
||||
static_cast<uint32_t>(std::ceil(static_cast<float>(render_extent.height) / 16.0f)),
|
||||
1);
|
||||
|
||||
commandbuffer->set_compute_pipeline(histogram_average_pipeline);
|
||||
|
||||
commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1,
|
||||
sizeof(uint32_t) * 256);
|
||||
commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256);
|
||||
|
||||
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),
|
||||
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);
|
||||
|
||||
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
|
||||
// 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;
|
||||
}
|
||||
|
||||
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
|
||||
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.options = prism::float4(1, 0, 0, 0);
|
||||
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;
|
||||
|
||||
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())
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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));
|
||||
|
||||
|
@ -467,7 +478,11 @@ void renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj
|
|||
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.fragment_src = ShaderSource(prism::path("shaders/mesh.frag"));
|
||||
|
||||
pipelineInfo.shaders.vertex_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant};
|
||||
pipelineInfo.shaders.fragment_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant};
|
||||
pipelineInfo.shaders.vertex_constants = {
|
||||
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 = {
|
||||
{sizeof(Matrix4x4), 0}
|
||||
};
|
||||
pipelineInfo.shader_input.push_constants = {{sizeof(Matrix4x4), 0}};
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{1, GFXBindingType::StorageBuffer},
|
||||
|
@ -534,8 +549,7 @@ void renderer::create_mesh_pipeline(Material& material) const {
|
|||
{6, GFXBindingType::Texture},
|
||||
{7, GFXBindingType::Texture},
|
||||
{8, GFXBindingType::Texture},
|
||||
{9, GFXBindingType::Texture}
|
||||
};
|
||||
{9, GFXBindingType::Texture}};
|
||||
|
||||
pipelineInfo.render_pass = offscreen_render_pass;
|
||||
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.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);
|
||||
|
||||
|
@ -592,8 +607,7 @@ void renderer::create_render_target_resources(RenderTarget& target) {
|
|||
textureInfo.width = extent.width;
|
||||
textureInfo.height = extent.height;
|
||||
textureInfo.format = GFXPixelFormat::RGBA_32F;
|
||||
textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled |
|
||||
GFXTextureUsage::Storage;
|
||||
textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled | GFXTextureUsage::Storage;
|
||||
textureInfo.samplingMode = SamplingMode::ClampToEdge;
|
||||
|
||||
target.offscreenColorTexture = gfx->create_texture(textureInfo);
|
||||
|
@ -648,9 +662,7 @@ void renderer::create_post_pipelines() {
|
|||
{5, GFXBindingType::Texture} // sobelSampler
|
||||
};
|
||||
|
||||
pipelineInfo.shader_input.push_constants = {
|
||||
{sizeof(PostPushConstants), 0}
|
||||
};
|
||||
pipelineInfo.shader_input.push_constants = {{sizeof(PostPushConstants), 0}};
|
||||
|
||||
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.fragment_src = register_shader("shaders/sky.frag");
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{0, GFXBindingType::PushConstant}
|
||||
};
|
||||
pipelineInfo.shader_input.bindings = {{0, GFXBindingType::PushConstant}};
|
||||
|
||||
pipelineInfo.shader_input.push_constants = {
|
||||
{sizeof(SkyPushConstant), 0}
|
||||
};
|
||||
pipelineInfo.shader_input.push_constants = {{sizeof(SkyPushConstant), 0}};
|
||||
|
||||
pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual;
|
||||
|
||||
|
@ -754,14 +762,9 @@ void renderer::create_histogram_resources() {
|
|||
create_info.workgroup_size_y = 16;
|
||||
|
||||
create_info.shader_input.bindings = {
|
||||
{0, GFXBindingType::StorageImage},
|
||||
{1, GFXBindingType::StorageBuffer},
|
||||
{2, GFXBindingType::PushConstant}
|
||||
};
|
||||
{0, GFXBindingType::StorageImage}, {1, GFXBindingType::StorageBuffer}, {2, GFXBindingType::PushConstant}};
|
||||
|
||||
create_info.shader_input.push_constants = {
|
||||
{sizeof(prism::float4), 0}
|
||||
};
|
||||
create_info.shader_input.push_constants = {{sizeof(prism::float4), 0}};
|
||||
|
||||
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;
|
||||
|
||||
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 {
|
||||
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)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#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 "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 {
|
||||
Matrix4x4 m, v;
|
||||
|
@ -110,7 +110,8 @@ SceneCapture::SceneCapture(GFX* gfx) {
|
|||
cubeTextureInfo.width = scene_cubemap_resolution;
|
||||
cubeTextureInfo.height = scene_cubemap_resolution;
|
||||
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.mip_count = mipLevels;
|
||||
|
||||
|
@ -262,10 +263,12 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
|
|||
if (material_index >= mesh.materials.size())
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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->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>()) {
|
||||
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);
|
||||
|
@ -309,7 +314,8 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
|
|||
command_buffer->draw(0, 4, 0, 1);
|
||||
|
||||
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));
|
||||
|
@ -347,7 +353,8 @@ void SceneCapture::render(GFXCommandBuffer* command_buffer, Scene* scene) {
|
|||
command_buffer->draw_indexed(cubeMesh->num_indices, 0, 0, 0);
|
||||
|
||||
command_buffer->end_render_pass();
|
||||
command_buffer->copy_texture(irradianceOffscreenTexture,
|
||||
command_buffer->copy_texture(
|
||||
irradianceOffscreenTexture,
|
||||
irradiance_cubemap_resolution,
|
||||
irradiance_cubemap_resolution,
|
||||
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->end_render_pass();
|
||||
command_buffer->copy_texture(prefilteredOffscreenTexture,
|
||||
resolution, resolution,
|
||||
scene->prefilteredCubeArray, face, last_probe, mip);
|
||||
command_buffer->copy_texture(
|
||||
prefilteredOffscreenTexture,
|
||||
resolution,
|
||||
resolution,
|
||||
scene->prefilteredCubeArray,
|
||||
face,
|
||||
last_probe,
|
||||
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.fragment_src = ShaderSource(prism::path("shaders/sky.frag"));
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{0, GFXBindingType::PushConstant}
|
||||
};
|
||||
pipelineInfo.shader_input.bindings = {{0, GFXBindingType::PushConstant}};
|
||||
|
||||
pipelineInfo.shader_input.push_constants = {
|
||||
{sizeof(SkyPushConstant), 0}
|
||||
};
|
||||
pipelineInfo.shader_input.push_constants = {{sizeof(SkyPushConstant), 0}};
|
||||
|
||||
pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual;
|
||||
|
||||
|
@ -469,14 +477,9 @@ void SceneCapture::createIrradianceResources() {
|
|||
|
||||
pipelineInfo.vertex_input.attributes.push_back(positionAttribute);
|
||||
|
||||
pipelineInfo.shader_input.push_constants = {
|
||||
{sizeof(Matrix4x4), 0}
|
||||
};
|
||||
pipelineInfo.shader_input.push_constants = {{sizeof(Matrix4x4), 0}};
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{1, GFXBindingType::PushConstant},
|
||||
{2, GFXBindingType::Texture}
|
||||
};
|
||||
pipelineInfo.shader_input.bindings = {{1, GFXBindingType::PushConstant}, {2, GFXBindingType::Texture}};
|
||||
|
||||
pipelineInfo.render_pass = irradianceRenderPass;
|
||||
|
||||
|
@ -523,14 +526,9 @@ void SceneCapture::createPrefilterResources() {
|
|||
|
||||
pipelineInfo.vertex_input.attributes.push_back(positionAttribute);
|
||||
|
||||
pipelineInfo.shader_input.push_constants = {
|
||||
{sizeof(FilterPushConstant), 0}
|
||||
};
|
||||
pipelineInfo.shader_input.push_constants = {{sizeof(FilterPushConstant), 0}};
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{0, GFXBindingType::PushConstant},
|
||||
{2, GFXBindingType::Texture}
|
||||
};
|
||||
pipelineInfo.shader_input.bindings = {{0, GFXBindingType::PushConstant}, {2, GFXBindingType::Texture}};
|
||||
|
||||
pipelineInfo.render_pass = irradianceRenderPass;
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#include "shadowpass.hpp"
|
||||
|
||||
#include "gfx_commandbuffer.hpp"
|
||||
#include "scene.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "materialcompiler.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "frustum.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "gfx_commandbuffer.hpp"
|
||||
#include "materialcompiler.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "scene.hpp"
|
||||
|
||||
struct PushConstant {
|
||||
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>()) {
|
||||
if (!mesh.mesh)
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
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 = {};
|
||||
info.framebuffer = scene.framebuffer;
|
||||
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);
|
||||
|
||||
|
@ -228,7 +240,9 @@ void ShadowPass::render_spot(GFXCommandBuffer* command_buffer, Scene& scene, pri
|
|||
GFXRenderPassBeginInfo info = {};
|
||||
info.framebuffer = offscreen_framebuffer;
|
||||
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);
|
||||
|
||||
|
@ -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][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)
|
||||
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->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;
|
||||
}
|
||||
|
@ -261,7 +292,11 @@ void ShadowPass::render_spot(GFXCommandBuffer* command_buffer, Scene& scene, pri
|
|||
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)
|
||||
return;
|
||||
|
||||
|
@ -280,7 +315,9 @@ void ShadowPass::render_point(GFXCommandBuffer* command_buffer, Scene& scene, pr
|
|||
GFXRenderPassBeginInfo info = {};
|
||||
info.framebuffer = offscreen_framebuffer;
|
||||
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);
|
||||
|
||||
|
@ -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));
|
||||
|
||||
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->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;
|
||||
|
@ -338,14 +390,9 @@ void ShadowPass::create_pipelines() {
|
|||
pipelineInfo.shaders.fragment_constants = {point_light_max_constant};
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{0, GFXBindingType::PushConstant},
|
||||
{1, GFXBindingType::StorageBuffer},
|
||||
{2, GFXBindingType::StorageBuffer}
|
||||
};
|
||||
{0, GFXBindingType::PushConstant}, {1, GFXBindingType::StorageBuffer}, {2, GFXBindingType::StorageBuffer}};
|
||||
|
||||
pipelineInfo.shader_input.push_constants = {
|
||||
{sizeof(PushConstant), 0}
|
||||
};
|
||||
pipelineInfo.shader_input.push_constants = {{sizeof(PushConstant), 0}};
|
||||
|
||||
pipelineInfo.render_pass = render_pass;
|
||||
|
||||
|
@ -415,6 +462,7 @@ void ShadowPass::create_offscreen_resources() {
|
|||
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "smaapass.hpp"
|
||||
|
||||
#include "gfx_commandbuffer.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "gfx_commandbuffer.hpp"
|
||||
#include "renderer.hpp"
|
||||
|
||||
#include <AreaTex.h>
|
||||
#include <SearchTex.h>
|
||||
|
@ -52,7 +52,11 @@ void SMAAPass::render(GFXCommandBuffer* command_buffer, RenderTarget& target) {
|
|||
prism::float4 viewport;
|
||||
} 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
|
||||
{
|
||||
|
@ -147,15 +151,10 @@ void SMAAPass::create_pipelines() {
|
|||
|
||||
createInfo.render_pass = render_pass;
|
||||
|
||||
createInfo.shader_input.push_constants = {
|
||||
{sizeof(prism::float4), 0}
|
||||
};
|
||||
createInfo.shader_input.push_constants = {{sizeof(prism::float4), 0}};
|
||||
|
||||
createInfo.shader_input.bindings = {
|
||||
{0, GFXBindingType::Texture},
|
||||
{1, GFXBindingType::Texture},
|
||||
{2, GFXBindingType::PushConstant}
|
||||
};
|
||||
{0, GFXBindingType::Texture}, {1, GFXBindingType::Texture}, {2, GFXBindingType::PushConstant}};
|
||||
|
||||
edge_pipeline = gfx->create_graphics_pipeline(createInfo);
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <variant>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <string_view>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "file.hpp"
|
||||
|
||||
|
@ -41,8 +41,11 @@ public:
|
|||
class ShaderSource {
|
||||
public:
|
||||
ShaderSource() : source(std::monostate()) {}
|
||||
|
||||
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 prism::path& shader_path) : source(shader_path) {}
|
||||
|
||||
std::variant<std::monostate, prism::path, std::string, std::vector<uint32_t>> source;
|
||||
|
@ -92,7 +95,12 @@ public:
|
|||
@param options Optional compilation parameters.
|
||||
@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;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
const TBuiltInResource DefaultTBuiltInResource = {
|
||||
/* .MaxLights = */ 32,
|
||||
/* .MaxClipPlanes = */ 6,
|
||||
|
@ -96,7 +95,8 @@ const TBuiltInResource DefaultTBuiltInResource = {
|
|||
/* .maxMeshViewCountNV = */ 4,
|
||||
/* .maxDualSourceDrawBuffersEXT = */ 1,
|
||||
|
||||
/* .limits = */ {
|
||||
/* .limits = */
|
||||
{
|
||||
/* .nonInductiveForLoops = */ 1,
|
||||
/* .whileLoops = */ 1,
|
||||
/* .doWhileLoops = */ 1,
|
||||
|
|
|
@ -36,10 +36,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <glslang/Public/ShaderLang.h>
|
||||
|
||||
|
@ -50,17 +50,12 @@ class DirStackFileIncluder : public glslang::TShader::Includer {
|
|||
public:
|
||||
DirStackFileIncluder() : externalLocalDirectoryCount(0) {}
|
||||
|
||||
IncludeResult* includeLocal(const char* headerName,
|
||||
const char* includerName,
|
||||
size_t inclusionDepth) override
|
||||
{
|
||||
IncludeResult* includeLocal(const char* headerName, const char* includerName, size_t inclusionDepth) override {
|
||||
return readLocalPath(headerName, includerName, (int)inclusionDepth);
|
||||
}
|
||||
|
||||
IncludeResult* includeSystem(const char* headerName,
|
||||
const char* /*includerName*/,
|
||||
size_t /*inclusionDepth*/) override
|
||||
{
|
||||
IncludeResult*
|
||||
includeSystem(const char* headerName, const char* /*includerName*/, size_t /*inclusionDepth*/) override {
|
||||
return readSystemPath(headerName);
|
||||
}
|
||||
|
||||
|
@ -70,14 +65,12 @@ public:
|
|||
// is checked.
|
||||
// - This only applies to the "local" form of #include.
|
||||
// - 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);
|
||||
externalLocalDirectoryCount = (int)directoryStack.size();
|
||||
}
|
||||
|
||||
void releaseInclude(IncludeResult* result) override
|
||||
{
|
||||
void releaseInclude(IncludeResult* result) override {
|
||||
if (result != nullptr) {
|
||||
delete[] static_cast<tUserDataElement*>(result->userData);
|
||||
delete result;
|
||||
|
@ -93,8 +86,7 @@ protected:
|
|||
|
||||
// Search for a valid "local" path based on combining the stack of include
|
||||
// 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
|
||||
// initialize when at parse-time first level.
|
||||
directoryStack.resize(depth + externalLocalDirectoryCount);
|
||||
|
@ -117,14 +109,12 @@ protected:
|
|||
|
||||
// Search for a valid <system> path.
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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];
|
||||
file.seekg(0, file.beg);
|
||||
file.read(content, length);
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#include "shadercompiler.hpp"
|
||||
|
||||
#include <spirv_msl.hpp>
|
||||
#include <SPIRV/GlslangToSpv.h>
|
||||
#include <spirv_msl.hpp>
|
||||
|
||||
#include "log.hpp"
|
||||
#include "string_utils.hpp"
|
||||
#include "includer.hpp"
|
||||
#include "defaultresources.hpp"
|
||||
#include "includer.hpp"
|
||||
#include "log.hpp"
|
||||
#include "spirv_hlsl.hpp"
|
||||
#include "string_utils.hpp"
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
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
|
||||
|
||||
shader.setEnvInput(glslang::EShSourceGlsl,
|
||||
shader_language,
|
||||
glslang::EShClientVulkan,
|
||||
ClientInputSemanticsVersion);
|
||||
shader.setEnvInput(glslang::EShSourceGlsl, shader_language, glslang::EShClientVulkan, ClientInputSemanticsVersion);
|
||||
|
||||
// we are targeting vulkan 1.1, so that uses SPIR-V 1.3
|
||||
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);
|
||||
|
||||
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 {};
|
||||
}
|
||||
|
@ -77,7 +78,12 @@ std::vector<uint32_t> compile_glsl_to_spv(const std::string_view source_string,
|
|||
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) {
|
||||
prism::log("Non-supported input language!");
|
||||
return std::nullopt;
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace prism {
|
|||
/// A 2D extent.
|
||||
struct Extent {
|
||||
Extent() : width(0), height(0) {}
|
||||
|
||||
Extent(const uint32_t width, const uint32_t height) : width(width), height(height) {}
|
||||
|
||||
uint32_t width = 0, height = 0;
|
||||
|
@ -14,6 +15,7 @@ namespace prism {
|
|||
/// A 2D offset.
|
||||
struct Offset {
|
||||
Offset() : x(0), y(0) {}
|
||||
|
||||
Offset(const int32_t x, const int32_t y) : x(x), y(y) {}
|
||||
|
||||
int32_t x = 0, y = 0;
|
||||
|
@ -22,10 +24,13 @@ namespace prism {
|
|||
/// A 2D rectangle defined by a offset and an etent.
|
||||
struct Rectangle {
|
||||
Rectangle() = default;
|
||||
|
||||
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;
|
||||
Extent extent;
|
||||
};
|
||||
}
|
||||
} // namespace prism
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "quaternion.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
namespace prism {
|
||||
inline void to_json(nlohmann::json& j, const float3& p) {
|
||||
|
@ -17,7 +17,7 @@ namespace prism {
|
|||
p.y = j["y"];
|
||||
p.z = j["z"];
|
||||
}
|
||||
}
|
||||
} // namespace prism
|
||||
|
||||
inline void to_json(nlohmann::json& j, const Quaternion& p) {
|
||||
j["x"] = p.x;
|
||||
|
|
|
@ -9,10 +9,9 @@ namespace prism {
|
|||
|
||||
// some stdlibs such as apple's clang fail to provide this :-/
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<prism::path> {
|
||||
template<> struct hash<prism::path> {
|
||||
std::size_t operator()(const prism::path& k) const {
|
||||
return (std::hash<std::string>()(k.string()));
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace std
|
|
@ -3,34 +3,30 @@
|
|||
#include <magic_enum.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
#include <unordered_map>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
#include "vector.hpp"
|
||||
|
||||
namespace utility {
|
||||
template<class Enum>
|
||||
std::string enum_to_string(const Enum e) {
|
||||
template<class Enum> std::string enum_to_string(const Enum e) {
|
||||
const std::string_view name = magic_enum::enum_name(e);
|
||||
|
||||
std::string s = name.data();
|
||||
return s.substr(0, name.length());
|
||||
}
|
||||
|
||||
template<class T, class F>
|
||||
void erase_if(std::vector<T>& vec, const F& f) {
|
||||
template<class T, class F> void erase_if(std::vector<T>& vec, const F& f) {
|
||||
vec.erase(std::remove_if(vec.begin(), vec.end(), f), vec.end());
|
||||
}
|
||||
|
||||
template<class T, class V>
|
||||
void erase(T& vec, const V& t) {
|
||||
template<class T, class V> void erase(T& vec, const V& t) {
|
||||
vec.erase(std::remove(vec.begin(), vec.end(), t), vec.end());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void erase_at(std::vector<T>& vec, const int index) {
|
||||
template<class T> void erase_at(std::vector<T>& vec, const int index) {
|
||||
vec.erase(vec.begin() + index);
|
||||
}
|
||||
|
||||
|
@ -46,46 +42,60 @@ namespace utility {
|
|||
return get_random(0, max);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline auto get_random(const std::vector<T>& vec) {
|
||||
template<class T> inline auto get_random(const std::vector<T>& vec) {
|
||||
return vec[get_random(static_cast<int>(vec.size() - 1))];
|
||||
}
|
||||
|
||||
template<class T, size_t S>
|
||||
inline auto get_random(const std::array<T, S>& vec) {
|
||||
template<class T, size_t S> inline auto get_random(const std::array<T, S>& vec) {
|
||||
return vec[get_random(static_cast<int>(vec.size() - 1))];
|
||||
}
|
||||
|
||||
template<class T, class V>
|
||||
inline auto get_random(const std::unordered_map<T, V>& map) {
|
||||
template<class T, class V> inline auto get_random(const std::unordered_map<T, V>& map) {
|
||||
const auto item = map.begin();
|
||||
std::advance(item, get_random(static_cast<int>(map.size() - 1)));
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
template<class T, class TIter = decltype(std::begin(std::declval<T>())), class = decltype(std::end(std::declval<T>()))>
|
||||
constexpr auto enumerate(T&& iterable)
|
||||
{
|
||||
template<
|
||||
class T,
|
||||
class TIter = decltype(std::begin(std::declval<T>())),
|
||||
class = decltype(std::end(std::declval<T>()))>
|
||||
constexpr auto enumerate(T&& iterable) {
|
||||
struct iterator {
|
||||
size_t i;
|
||||
TIter iter;
|
||||
bool operator != (const iterator & other) const { return iter != other.iter; }
|
||||
void operator ++ () { ++i; ++iter; }
|
||||
auto operator * () const { return std::tie(i, *iter); }
|
||||
|
||||
bool operator!=(const iterator& other) const {
|
||||
return iter != other.iter;
|
||||
}
|
||||
|
||||
void operator++() {
|
||||
++i;
|
||||
++iter;
|
||||
}
|
||||
|
||||
auto operator*() const {
|
||||
return std::tie(i, *iter);
|
||||
}
|
||||
};
|
||||
|
||||
struct iterable_wrapper {
|
||||
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)};
|
||||
}
|
||||
|
||||
template<class T, class V>
|
||||
inline bool contains(const std::vector<T>& vec, const V& val) {
|
||||
template<class T, class V> inline bool contains(const std::vector<T>& vec, const V& val) {
|
||||
return std::count(vec.begin(), vec.end(), val);
|
||||
}
|
||||
|
||||
|
@ -112,8 +122,7 @@ namespace utility {
|
|||
return linear;
|
||||
}
|
||||
|
||||
template<typename T, typename F>
|
||||
inline void move_to_front(std::vector<T>& vec, F func) {
|
||||
template<typename T, typename F> inline void move_to_front(std::vector<T>& vec, F func) {
|
||||
auto result = std::find_if(vec.begin(), vec.end(), func);
|
||||
if (result != vec.end()) {
|
||||
auto value = *result;
|
||||
|
@ -121,4 +130,4 @@ namespace utility {
|
|||
vec.insert(vec.begin(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace utility
|
||||
|
|
|
@ -12,7 +12,8 @@ std::string remove_substring(const std::string_view string, const std::string_vi
|
|||
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);
|
||||
|
||||
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) {
|
||||
return needle.length() <= haystack.length()
|
||||
&& std::equal(needle.begin(), needle.end(), haystack.begin());
|
||||
return needle.length() <= haystack.length() && std::equal(needle.begin(), needle.end(), haystack.begin());
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
Reference in a new issue