Commit for 2020.08.16.7z

This commit is contained in:
mrq 2020-08-16 00:00:00 -05:00
parent d3d5465ba7
commit 1435868244
28 changed files with 538 additions and 308 deletions

View File

@ -78,9 +78,9 @@ void phong( Light light, vec4 albedoSpecular, inout vec3 i ) {
}
void main() {
vec4 albedoSpecular = subpassLoad(samplerAlbedo);
position.eye = subpassLoad(samplerPosition).rgb;
normal.eye = subpassLoad(samplerNormal).rgb;
vec4 albedoSpecular = subpassLoad(samplerAlbedo);
vec3 fragColor = albedoSpecular.rgb * ubo.ambient.rgb;
bool lit = false;

View File

@ -45,6 +45,9 @@ int main(int argc, char** argv){
throw e;
} catch ( std::exception& e ) {
uf::iostream << "EXCEPTION ERROR: " << e.what() << "\n";
std::abort();
raise(SIGSEGV);
throw e;
} catch ( bool handled ) {
if (!handled) uf::iostream << "UNHANDLED ERROR: " << "???" << "\n";
} catch ( ... ) {

View File

@ -34,6 +34,7 @@ namespace ext {
extern UF_API uint8_t renderPass;
extern UF_API float width, height;
extern UF_API bool enabled;
extern UF_API bool swapEyes;
bool UF_API initialize( int stage = 0 );
void UF_API tick();

View File

@ -64,6 +64,7 @@ namespace ext {
struct UF_API Graphic : public Buffers {
struct Descriptor {
std::string renderMode = "";
uint32_t renderTarget = 0;
uint32_t subpass = 0;
uf::BaseGeometry geometry;
@ -71,6 +72,7 @@ namespace ext {
VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
VkPolygonMode fill = VK_POLYGON_MODE_FILL;
VkCullModeFlags cullMode = VK_CULL_MODE_BACK_BIT;
float lineWidth = 1.0f;
VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE;
struct {
@ -97,6 +99,7 @@ namespace ext {
bool hasPipeline( Descriptor& descriptor );
void initializePipeline();
Pipeline& initializePipeline( Descriptor& descriptor, bool update = true );
Pipeline& getPipeline();
Pipeline& getPipeline( Descriptor& descriptor );
void record( VkCommandBuffer commandBuffer );

View File

@ -1,6 +1,7 @@
template<typename T, typename U>
void ext::vulkan::Graphic::initializeGeometry( uf::BaseMesh<T, U>& mesh ) {
if ( mesh.indices.empty() ) mesh.initialize();
mesh.updateDescriptor();
// already generated, check if we can just update
if ( descriptor.indices > 0 ) {

View File

@ -12,7 +12,7 @@ namespace ext {
pod::Vector4f clearColor = {0, 0, 0, 1};
Device* device = VK_NULL_HANDLE;
ext::vulkan::RenderTarget renderTarget;
RenderTarget renderTarget;
VkSemaphore renderCompleteSemaphore;
std::vector<VkFence> fences;
@ -22,6 +22,8 @@ namespace ext {
// RAII
virtual std::string getType() const;
const std::string& getName() const;
virtual RenderTarget& getRenderTarget(size_t = 0);
virtual const RenderTarget& getRenderTarget(size_t = 0) const;
virtual void initialize( Device& device );
virtual void createCommandBuffers();

View File

@ -6,7 +6,7 @@
namespace ext {
namespace vulkan {
struct UF_API DeferredRenderMode : public ext::vulkan::RenderMode {
ext::vulkan::DeferredRenderingGraphic blitter;
ext::vulkan::Graphic blitter;
// RAII
virtual std::string getType() const;

View File

@ -6,7 +6,7 @@
namespace ext {
namespace vulkan {
struct UF_API RenderTargetRenderMode : public ext::vulkan::RenderMode {
ext::vulkan::RenderTargetGraphic blitter;
ext::vulkan::Graphic blitter;
VkFence fence;
VkCommandBuffer commandBuffer;

View File

@ -11,14 +11,16 @@ namespace ext {
ext::vulkan::RenderTarget right;
} renderTargets;
struct {
ext::vulkan::DeferredRenderingGraphic left;
ext::vulkan::DeferredRenderingGraphic right;
ext::vulkan::Graphic left;
ext::vulkan::Graphic right;
} blitters;
ext::vulkan::DeferredRenderingGraphic blitter;
ext::vulkan::Graphic blitter;
StereoscopicDeferredRenderMode();
// RAII
virtual std::string getType() const;
virtual ext::vulkan::RenderTarget& getRenderTarget(size_t = 0);
virtual const ext::vulkan::RenderTarget& getRenderTarget(size_t = 0) const;
virtual void createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics );
virtual void initialize( Device& device );

View File

@ -3,10 +3,13 @@
#include <uf/ext/vulkan/device.h>
#include <uf/utils/image/image.h>
#include <uf/ext/vulkan/rendertarget.h>
namespace ext {
namespace vulkan {
struct UF_API Sampler {
Device* device = NULL;
VkSampler sampler;
VkDescriptorImageInfo descriptor;
VkFilter filter = VK_FILTER_LINEAR;
@ -16,6 +19,7 @@ namespace ext {
};
struct UF_API Texture {
Device* device = nullptr;
VkImage image;
VkImageView view;
VkImageLayout imageLayout;
@ -106,6 +110,7 @@ namespace ext {
VkQueue copyQueue,
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM
);
void aliasAttachment( const RenderTarget::Attachment& attachment, bool = true );
};
}
}

View File

@ -52,6 +52,18 @@ namespace pod {
}
bool operator!=( const Vertex_3F2F& that ) const { return !(*this == that); }
};
struct /*UF_API*/ Vertex_2F2F {
alignas(8) pod::Vector2f position;
alignas(8) pod::Vector2f uv;
static UF_API std::vector<ext::vulkan::VertexDescriptor> descriptor;
bool operator==( const Vertex_2F2F& that ) const {
return this->position == that.position &&
this->uv == that.uv;
}
bool operator!=( const Vertex_2F2F& that ) const { return !(*this == that); }
};
struct /*UF_API*/ Vertex_3F {
alignas(16) pod::Vector3f position;
@ -94,6 +106,15 @@ namespace std {
return seed;
}
};
template<> struct hash<pod::Vertex_2F2F> {
size_t operator()(pod::Vertex_2F2F const& vertex) const {
std::size_t seed = 2 + 2;
std::hash<float> hasher;
for ( size_t i = 0; i < 2; ++i ) seed ^= hasher( vertex.position[i] ) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
for ( size_t i = 0; i < 2; ++i ) seed ^= hasher( vertex.uv[i] ) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
return seed;
}
};
template<> struct hash<pod::Vertex_3F> {
size_t operator()(pod::Vertex_3F const& vertex) const {
std::size_t seed = 3;
@ -122,6 +143,7 @@ namespace uf {
~BaseMesh();
void initialize( bool compress = true );
void updateDescriptor();
void destroy();
};
}

View File

@ -1,9 +1,7 @@
template<typename T, typename U>
void uf::BaseMesh<T, U>::initialize( bool compress ) {
// this->destroy(false);
sizes.vertex = sizeof(vertex_t);
sizes.indices = sizeof(indices_t);
attributes = vertex_t::descriptor;
this->updateDescriptor();
if ( compress ) {
std::unordered_map<vertex_t, indices_t> unique;
@ -30,6 +28,12 @@ void uf::BaseMesh<T, U>::initialize( bool compress ) {
}
}
template<typename T, typename U>
void uf::BaseMesh<T, U>::updateDescriptor() {
sizes.vertex = sizeof(vertex_t);
sizes.indices = sizeof(indices_t);
attributes = vertex_t::descriptor;
}
template<typename T, typename U>
void uf::BaseMesh<T, U>::destroy() {
this->indices.clear();
this->vertices.clear();

View File

@ -13,6 +13,7 @@ uint8_t ext::openvr::renderPass = 0;
float ext::openvr::width = 0;
float ext::openvr::height = 0;
bool ext::openvr::enabled = false;
bool ext::openvr::swapEyes = false;
#define VR_CHECK_INPUT_RESULT(f)\
if ( f != vr::VRInputError_None ) {\
@ -71,7 +72,7 @@ namespace {
uf::Serializer state;
pod::Matrix4t<> matrix;
pod::Matrix4t<> tip;
uf::Graphic mesh;
uf::Graphic graphic;
} left, right;
} controllers;
} devices;
@ -186,30 +187,10 @@ bool ext::openvr::initialize( int stage ) {
split = uf::string::split( shortname, "." );
if ( split.front() == "hapticVibration" ) {
std::cout << "Registered hook for haptic: " << ("VR:Haptics."+split.back()) << std::endl;
uf::hooks.addHook( "VR:Haptics."+split.back(), [](const std::string& event)->std::string{
uf::hooks.addHook( "VR:Haptics."+split.back(), [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string name;
std::string side = json["side"].asString();
uf::Serializer manifest;
manifest.readFromFile(ext::openvr::driver.manifest);
{
for ( auto i = 0; i < manifest["actions"].size(); ++i ) {
std::string handleName = manifest["actions"][i]["name"].asString();
std::vector<std::string> split = uf::string::split( handleName, "/" );
std::string shortname = split.back();
if ( shortname != "hapticVibration." + side ) continue;
name = handleName;
break;
}
}
if ( name == "" ) return "false";
vr::VRActionHandle_t& handle = handles.actions[name];
auto err = vr::VRInput()->TriggerHapticVibrationAction( handle, json["delay"].asFloat(), json["duration"].asFloat(), json["frequency"].asFloat(), json["amplitude"].asFloat(), vr::k_ulInvalidInputValueHandle );
if ( err != vr::VRInputError_None ) {
std::cout << err << std::endl;
if ( vr::VRInputError_None != vr::VRInput()->TriggerHapticVibrationAction( handle, json["delay"].asFloat(), json["duration"].asFloat(), json["frequency"].asFloat(), json["amplitude"].asFloat(), vr::k_ulInvalidInputValueHandle ) )
return "false";
}
return "true";
});
}
@ -240,12 +221,8 @@ bool ext::openvr::initialize( int stage ) {
return true;
}
void ext::openvr::terminate() {
/*
::devices.controllers.left.mesh.graphic.destroy();
::devices.controllers.right.mesh.graphic.destroy();
::devices.controllers.left.mesh.destroy();
::devices.controllers.right.mesh.destroy();
*/
::devices.controllers.left.graphic.destroy();
::devices.controllers.right.graphic.destroy();
vr::VR_Shutdown();
ext::openvr::context = NULL;
}
@ -306,7 +283,7 @@ void ext::openvr::tick() {
}
// grab texture
size_t len = queued.texture->unWidth * queued.texture->unHeight * 4;
mesh.initialize();
graphic.initialize();
graphic.initializeGeometry(mesh);
auto& texture = graphic.material.textures.emplace_back();
@ -457,7 +434,7 @@ bool ext::openvr::requestRenderModel( const std::string& name ) {
::queuedRenderModels[name];
return false;
}
void ext::openvr::submit() { bool invert = false;
void ext::openvr::submit() { bool invert = swapEyes;
ext::vulkan::StereoscopicDeferredRenderMode* renderMode = (ext::vulkan::StereoscopicDeferredRenderMode*) &ext::vulkan::getRenderMode("");
@ -546,7 +523,17 @@ pod::Vector3f ext::openvr::hmdPosition( vr::Hmd_Eye eye ) {
return hmdPosition() + hmdEyePosition( eye );
}
pod::Quaternion<> ext::openvr::hmdQuaternion() {
return uf::quaternion::fromMatrix( hmdHeadPositionMatrix() ); // * pod::Vector4f{ 1, 1, -1, -1 };
pod::Matrix4t<> mat = hmdHeadPositionMatrix();
pod::Quaternion<> q;
q.w = sqrt(fmax(0, 1 + mat[(4*0)+0] + mat[(4*1)+1] + mat[(4*2)+2])) / 2;
q.x = sqrt(fmax(0, 1 + mat[(4*0)+0] - mat[(4*1)+1] - mat[(4*2)+2])) / 2;
q.y = sqrt(fmax(0, 1 - mat[(4*0)+0] + mat[(4*1)+1] - mat[(4*2)+2])) / 2;
q.z = sqrt(fmax(0, 1 - mat[(4*0)+0] - mat[(4*1)+1] + mat[(4*2)+2])) / 2;
q.x = copysign(q.x, mat[(4*1)+2] - mat[(4*2)+1]);
q.y = copysign(q.y, mat[(4*2)+0] - mat[(4*0)+2]);
q.z = copysign(q.z, mat[(4*0)+1] - mat[(4*1)+0]);
return q; // * pod::Vector4f{ 1, 1, -1, -1 };
}
pod::Matrix4t<> ext::openvr::hmdViewMatrix( vr::Hmd_Eye eye, const pod::Matrix4f& mv ) {
return hmdEyePositionMatrix( eye ) * uf::matrix::translate( uf::matrix::identity(), hmdPosition() ) * uf::matrix::inverse( uf::quaternion::matrix( ext::openvr::hmdQuaternion() * pod::Vector4f{ 1, 1, -1, -1 } ) ) * mv;
@ -641,7 +628,17 @@ pod::Vector3f ext::openvr::controllerPosition( vr::Controller_Hand hand, bool ti
};
}
pod::Quaternion<> ext::openvr::controllerQuaternion( vr::Controller_Hand hand, bool tip ) {
return uf::quaternion::fromMatrix( controllerMatrix( hand, tip ) ) * pod::Vector4f{ 1, 1, -1, 1 };
pod::Matrix4t<> mat = controllerMatrix( hand, tip );
pod::Quaternion<> q;
q.w = sqrt(fmax(0, 1 + mat[(4*0)+0] + mat[(4*1)+1] + mat[(4*2)+2])) / 2;
q.x = sqrt(fmax(0, 1 + mat[(4*0)+0] - mat[(4*1)+1] - mat[(4*2)+2])) / 2;
q.y = sqrt(fmax(0, 1 - mat[(4*0)+0] + mat[(4*1)+1] - mat[(4*2)+2])) / 2;
q.z = sqrt(fmax(0, 1 - mat[(4*0)+0] - mat[(4*1)+1] + mat[(4*2)+2])) / 2;
q.x = copysign(q.x, mat[(4*1)+2] - mat[(4*2)+1]);
q.y = copysign(q.y, mat[(4*2)+0] - mat[(4*0)+2]);
q.z = copysign(q.z, mat[(4*0)+1] - mat[(4*1)+0]);
return q * pod::Vector4f{ 1, 1, -1, 1 };
}
pod::Matrix4t<> ext::openvr::controllerTranslationMatrix( vr::Controller_Hand hand, bool tip ) {
return uf::matrix::translate( uf::matrix::identity(), controllerPosition( hand, tip ) );

View File

@ -158,9 +158,9 @@ void ext::vulkan::Buffers::destroy() {
}
size_t ext::vulkan::Buffers::initializeBuffer( void* data, VkDeviceSize length, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, bool stage ) {
Buffer buffer;
// Buffer buffer;
size_t index = buffers.size();
// Buffer& buffer = buffers.emplace_back();
Buffer& buffer = buffers.emplace_back();
// Stage
if ( !stage ) {
@ -170,9 +170,9 @@ size_t ext::vulkan::Buffers::initializeBuffer( void* data, VkDeviceSize length,
buffer,
length
));
size_t index = buffers.size();
buffers.push_back( std::move(buffer) );
this->updateBuffer( data, length, index, stage );
this->updateBuffer( data, length, buffer, stage );
// size_t index = buffers.size();
// buffers.push_back( std::move(buffer) );
return index;
}
@ -202,7 +202,7 @@ size_t ext::vulkan::Buffers::initializeBuffer( void* data, VkDeviceSize length,
device->flushCommandBuffer(copyCmd, queue, true);
staging.destroy();
buffers.push_back( std::move(buffer) );
// buffers.push_back( std::move(buffer) );
return index;
}
void ext::vulkan::Buffers::updateBuffer( void* data, VkDeviceSize length, size_t index, bool stage ) {
@ -210,6 +210,15 @@ void ext::vulkan::Buffers::updateBuffer( void* data, VkDeviceSize length, size_t
return updateBuffer( data, length, buffer, stage );
}
void ext::vulkan::Buffers::updateBuffer( void* data, VkDeviceSize length, Buffer& buffer, bool stage ) {
// assert(buffer.allocationInfo.size == length);
if ( buffer.allocationInfo.size != length ) {
// std::cout << "Mismatch buffer update: " << buffer.allocationInfo.size << " vs " << length << ", resetting for safety..." << std::endl;
// assert(buffer.allocationInfo.size > length);
length = buffer.allocationInfo.size;
}
if ( !stage ) {
VK_CHECK_RESULT(buffer.map());
memcpy(buffer.mapped, data, length);

View File

@ -1,6 +1,7 @@
#include <uf/ext/vulkan/graphic.h>
#include <uf/ext/vulkan/initializers.h>
#include <uf/ext/vulkan/vulkan.h>
#include <uf/ext/openvr/openvr.h>
#include <spirv_cross/spirv_cross.hpp>
#include <spirv_cross/spirv_glsl.hpp>
@ -20,6 +21,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
this->device = &device;
std::string spirv;
{
std::ifstream is(this->filename = filename, std::ios::binary | std::ios::in | std::ios::ate);
if ( !is.is_open() ) {
@ -31,6 +33,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
assert(spirv.size() > 0);
}
{
VkShaderModuleCreateInfo moduleCreateInfo = {};
@ -40,6 +43,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
VK_CHECK_RESULT(vkCreateShaderModule(device, &moduleCreateInfo, NULL, &module));
}
{
descriptor.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
descriptor.stage = stage;
@ -48,6 +52,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
assert(descriptor.module != VK_NULL_HANDLE);
}
// do reflection
{
spirv_cross::Compiler comp( (uint32_t*) &spirv[0], spirv.size() / 4 );
@ -55,6 +60,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
auto parseResource = [&]( const spirv_cross::Resource& resource, VkDescriptorType type ) {
// comp.get_decoration(resource.id, spv::DecorationDescriptorSet);
switch ( type ) {
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
} break;
@ -66,10 +72,11 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
} break;
}
descriptorSetLayoutBindings.push_back(ext::vulkan::initializers::descriptorSetLayoutBinding( type, stage, comp.get_decoration(resource.id, spv::DecorationBinding) ) );
};
// std::cout << "Found resource: "#type " with binding: " << comp.get_decoration(resource.id, spv::DecorationBinding) << std::endl;
#define LOOP_RESOURCES( key, type ) for ( const auto& resource : res.key ) {\
// std::cout << "Found resource: "#type " with binding: " << comp.get_decoration(resource.id, spv::DecorationBinding) << std::endl;
#define LOOP_RESOURCES( key, type ) for ( const auto& resource : res.key ) {\
parseResource( resource, type );\
}
LOOP_RESOURCES( sampled_images, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER );
@ -81,6 +88,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
LOOP_RESOURCES( storage_buffers, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER );
#undef LOOP_RESOURCES
for ( const auto& resource : res.push_constant_buffers ) {
auto& pushConstant = pushConstants.emplace_back();
const auto& type = comp.get_type(resource.base_type_id);
@ -88,12 +96,12 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
pushConstant.create( size );
}
size_t specializationSize = 0;
for ( const auto& constant : comp.get_specialization_constants() ) {
const auto& value = comp.get_constant(constant.id);
const auto& type = comp.get_type(value.constant_type);
size_t size = comp.get_declared_struct_size(type);
// default: value.scalar_i32()
size_t size = 4; //comp.get_declared_struct_size(type);
VkSpecializationMapEntry specializationMapEntry;
specializationMapEntry.constantID = constant.constant_id;
@ -105,19 +113,59 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
if ( specializationSize > 0 ) {
specializationConstants.create( specializationSize );
specializationInfo = {};
specializationInfo.dataSize = specializationSize;
specializationInfo.mapEntryCount = specializationMapEntries.size();
specializationInfo.pMapEntries = specializationMapEntries.data();
specializationInfo.pData = (void*) specializationConstants;
descriptor.pSpecializationInfo = &specializationInfo;
}
uint8_t* s = (uint8_t*) (void*) specializationConstants;
size_t offset = 0;
for ( const auto& constant : comp.get_specialization_constants() ) {
const auto& value = comp.get_constant(constant.id);
const auto& type = comp.get_type(value.constant_type);
size_t size = 4;
uint8_t buffer[size];
switch ( type.basetype ) {
case spirv_cross::SPIRType::UInt: {
auto v = value.scalar();
memcpy( &buffer[0], &v, sizeof(v) );
} break;
case spirv_cross::SPIRType::Int: {
auto v = value.scalar_i32();
memcpy( &buffer[0], &v, sizeof(v) );
} break;
case spirv_cross::SPIRType::Float: {
auto v = value.scalar_f32();
memcpy( &buffer[0], &v, sizeof(v) );
} break;
case spirv_cross::SPIRType::Boolean: {
auto v = value.scalar()!=0;
memcpy( &buffer[0], &v, sizeof(v) );
} break;
}
memcpy( &s[offset], &buffer, size );
offset += size;
}
{
specializationInfo = {};
specializationInfo.dataSize = specializationSize;
specializationInfo.mapEntryCount = specializationMapEntries.size();
specializationInfo.pMapEntries = specializationMapEntries.data();
specializationInfo.pData = s;
descriptor.pSpecializationInfo = &specializationInfo;
}
}
/*
*/
// LOOP_RESOURCES( stage_inputs, VkVertexInputAttributeDescription );
// LOOP_RESOURCES( stage_outputs, VkPipelineColorBlendAttachmentState );
}
// update uniform buffers
// organize layouts
{
std::sort( descriptorSetLayoutBindings.begin(), descriptorSetLayoutBindings.end(), [&]( const VkDescriptorSetLayoutBinding& l, const VkDescriptorSetLayoutBinding& r ){
return l.binding < r.binding;
} );
}
// update uniform buffers
for ( auto& uniform : uniforms ) {
pod::Userdata& userdata = uniform.data();
initializeBuffer(
@ -128,6 +176,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
false
);
}
}
void ext::vulkan::Shader::destroy() {
@ -150,7 +199,7 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) {
assert( graphic.material.shaders.size() > 0 );
RenderMode& renderMode = ext::vulkan::getRenderMode(graphic.descriptor.renderMode, true);
auto& renderTarget = renderMode.getRenderTarget( graphic.descriptor.renderTarget );
{
std::vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings;
std::vector<VkPushConstantRange> pushConstantRanges;
@ -217,19 +266,33 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) {
);
VkPipelineRasterizationStateCreateInfo rasterizationState = ext::vulkan::initializers::pipelineRasterizationStateCreateInfo(
graphic.descriptor.fill,
VK_CULL_MODE_BACK_BIT, // VK_CULL_MODE_NONE,
graphic.descriptor.cullMode, // VK_CULL_MODE_NONE,
graphic.descriptor.frontFace,
0
);
rasterizationState.lineWidth = graphic.descriptor.lineWidth;
std::vector<VkPipelineColorBlendAttachmentState> blendAttachmentStates;
auto& subpass = renderMode.renderTarget.passes[graphic.descriptor.subpass];
auto& subpass = renderTarget.passes[graphic.descriptor.subpass];
for ( auto& color : subpass.colors ) {
VkPipelineColorBlendAttachmentState blendAttachmentState = ext::vulkan::initializers::pipelineColorBlendAttachmentState(
0xf,
VK_FALSE
VK_TRUE
);
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
/*
if ( !blendAttachmentStates.empty() ) {
VkPipelineColorBlendAttachmentState blendAttachmentState = ext::vulkan::initializers::pipelineColorBlendAttachmentState(
0xf,
VK_FALSE
);
}
*/
blendAttachmentStates.push_back(blendAttachmentState);
}
VkPipelineColorBlendStateCreateInfo colorBlendState = ext::vulkan::initializers::pipelineColorBlendStateCreateInfo(
@ -292,7 +355,7 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic ) {
VkGraphicsPipelineCreateInfo pipelineCreateInfo = ext::vulkan::initializers::pipelineCreateInfo(
pipelineLayout,
renderMode.renderTarget.renderPass,
renderTarget.renderPass,
0
);
pipelineCreateInfo.pVertexInputState = &vertexInputState;
@ -314,9 +377,18 @@ void ext::vulkan::Pipeline::record( Graphic& graphic, VkCommandBuffer commandBuf
for ( auto& shader : graphic.material.shaders ) {
size_t offset = 0;
for ( auto& pushConstant : shader.pushConstants ) {
struct PushConstant {
uint32_t pass;
} p = { ext::openvr::renderPass };
/*
pod::Userdata& userdata = pushConstant.data();
{
pushConstant.get<PushConstant>() = { 0 };//ext::openvr::renderPass };
}
vkCmdPushConstants( commandBuffer, pipelineLayout, shader.descriptor.stage, offset, userdata.len, userdata.data );
offset += userdata.len;
*/
vkCmdPushConstants( commandBuffer, pipelineLayout, shader.descriptor.stage, 0, sizeof(p), &p );
}
}
// Bind descriptor sets describing shader binding points
@ -335,10 +407,12 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
}
RenderMode& renderMode = ext::vulkan::getRenderMode(graphic.descriptor.renderMode, true);
auto& subpass = renderMode.renderTarget.passes[graphic.descriptor.subpass];
auto& renderTarget = renderMode.getRenderTarget(graphic.descriptor.renderTarget );
auto& subpass = renderTarget.passes[graphic.descriptor.subpass];
for ( auto& input : subpass.inputs ) {
inputDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo(
renderMode.renderTarget.attachments[input.attachment].view,
renderTarget.attachments[input.attachment].view,
input.layout
));
}
@ -420,6 +494,7 @@ void ext::vulkan::Material::initialize( Device& device ) {
}
void ext::vulkan::Material::destroy() {
if ( aliased ) return;
for ( auto& texture : textures ) texture.destroy();
for ( auto& shader : shaders ) shader.destroy();
for ( auto& sampler : samplers ) sampler.destroy();
@ -431,20 +506,26 @@ void ext::vulkan::Material::destroy() {
void ext::vulkan::Material::attachShader( const std::string& filename, VkShaderStageFlagBits stage ) {
auto& shader = shaders.emplace_back();
shader.initialize( *device, filename, stage );
/*
Shader shader;
shader.initialize( *device, filename, stage );
shaders.push_back( std::move( shader ) );
*/
// check how many samplers requested
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
if ( layout.descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER ) continue;
Sampler& sampler = samplers.emplace_back();
sampler.initialize( *device );
}
}
void ext::vulkan::Material::initializeShaders( const std::vector<std::pair<std::string, VkShaderStageFlagBits>>& layout ) {
shaders.clear(); shaders.reserve( layout.size() );
for ( auto& request : layout ) attachShader( request.first, request.second );
for ( auto& request : layout ) {
attachShader( request.first, request.second );
}
}
void ext::vulkan::Graphic::initialize( const std::string& renderModeName ) {
RenderMode& renderMode = ext::vulkan::getRenderMode(renderModeName, true);
this->descriptor.renderMode = renderModeName;
material.initialize( *renderMode.device );
ext::vulkan::Buffers::initialize( *renderMode.device );
@ -468,14 +549,20 @@ ext::vulkan::Pipeline& ext::vulkan::Graphic::initializePipeline( Descriptor& des
bool ext::vulkan::Graphic::hasPipeline( Descriptor& descriptor ) {
return pipelines.count( descriptor.hash() ) > 0;
}
ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline() {
return getPipeline( descriptor );
}
ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline( Descriptor& descriptor ) {
if ( !hasPipeline(descriptor) ) return initializePipeline( descriptor );
return pipelines[descriptor.hash()];
}
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer ) {
if ( !this->hasPipeline( descriptor ) ) return;
if ( !this->hasPipeline( descriptor ) ) {
std::cout << this << ": has no valid pipeline" << std::endl;
return;
}
auto& pipeline = this->getPipeline( descriptor );
auto& pipeline = this->getPipeline();
assert( buffers.size() >= 2 );
Buffer& vertexBuffer = buffers.at(0);
@ -515,6 +602,7 @@ std::string ext::vulkan::Graphic::Descriptor::hash() const {
uf::Serializer serializer;
serializer["subpass"] = subpass;
serializer["renderTarget"] = renderTarget;
serializer["geometry"]["sizes"]["vertex"] = geometry.sizes.vertex;
serializer["geometry"]["sizes"]["indices"] = geometry.sizes.indices;
@ -527,6 +615,7 @@ std::string ext::vulkan::Graphic::Descriptor::hash() const {
}
}
serializer["topology"] = topology;
serializer["cullMode"] = cullMode;
serializer["fill"] = fill;
serializer["lineWidth"] = lineWidth;
serializer["frontFace"] = frontFace;
@ -534,7 +623,6 @@ std::string ext::vulkan::Graphic::Descriptor::hash() const {
serializer["depthTest"]["write"] = depthTest.write;
serializer["depthTest"]["operation"] = depthTest.operation;
// std::cout << this << ": " << indices << ": " << subpass << ": " << serializer << std::endl;
// std::cout << this << ": " << indices << ": " << renderMode << ": " << subpass << ": " << serializer << std::endl;
return uf::string::sha256( serializer.serialize() );
}

View File

@ -20,6 +20,12 @@ std::string ext::vulkan::RenderMode::getType() const {
const std::string& ext::vulkan::RenderMode::getName() const {
return this->name;
}
ext::vulkan::RenderTarget& ext::vulkan::RenderMode::getRenderTarget( size_t i ) {
return renderTarget;
}
const ext::vulkan::RenderTarget& ext::vulkan::RenderMode::getRenderTarget( size_t i ) const {
return renderTarget;
}
void ext::vulkan::RenderMode::createCommandBuffers() {
std::vector<ext::vulkan::Graphic*> graphics;

View File

@ -10,9 +10,6 @@
#include <uf/utils/math/transform.h>
#include <uf/ext/vulkan/graphic.h>
namespace {
ext::vulkan::Graphic newBlitter;
}
std::string ext::vulkan::DeferredRenderMode::getType() const {
return "Deferred";
@ -62,129 +59,75 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
}
}
renderTarget.initialize( device );
/*
{
::blitter.descriptor.subpass = 1;
::blitter.initialize();
::blitter.material.shader.initializeShaders({
uf::BaseMesh<pod::Vertex_2F2F, uint16_t> mesh;
/*
mesh.vertices = {
{ {-1.0f, 1.0f}, {0.0f, 0.0f}, },
{ {-1.0f, -1.0f}, {0.0f, 1.0f}, },
{ {1.0f, -1.0f}, {1.0f, 1.0f}, },
{ {-1.0f, 1.0f}, {0.0f, 0.0f}, },
{ {1.0f, -1.0f}, {1.0f, 1.0f}, },
{ {1.0f, 1.0f}, {1.0f, 0.0f}, }
};
*/
mesh.vertices = {
{ {-1.0f, 1.0f}, {0.0f, 0.0f}, },
{ {-1.0f, -1.0f}, {0.0f, 1.0f}, },
{ {1.0f, -1.0f}, {1.0f, 1.0f}, },
{ {1.0f, 1.0f}, {1.0f, 0.0f}, }
};
mesh.indices = {
0, 1, 2, 0, 2, 3
};
blitter.descriptor.subpass = 1;
blitter.descriptor.depthTest.test = false;
blitter.descriptor.depthTest.write = false;
blitter.initialize( this->getName() );
blitter.initializeGeometry( mesh );
blitter.material.initializeShaders({
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
blitter.initializePipeline();
}
*/
blitter.renderTarget = &renderTarget;
blitter.initializeShaders({
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
blitter.subpass = 1;
blitter.initialize( device, *this );
// update layer rendertargets descriptor sets
/*
{
std::vector<RenderMode*> layers = ext::vulkan::getRenderModes("RenderTarget", false); //{ &ext::vulkan::getRenderMode("Gui") };
for ( auto layer : layers ) {
RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer;
auto& blitter = rtLayer->blitter;
// blitter.subpass = 1;
blitter.initialize( device, *this );
for ( auto _ : layers ) {
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
blitter.initialize( this->getName() );
}
}
*/
}
void ext::vulkan::DeferredRenderMode::tick() {
ext::vulkan::RenderMode::tick();
std::vector<RenderMode*> layers = ext::vulkan::getRenderModes("RenderTarget", false);
for ( auto layer : layers ) {
RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer;
auto& blitter = rtLayer->blitter;
// update descriptor set
if ( !blitter.initialized ) {
// blitter.subpass = 1;
if ( blitter.renderTarget ) blitter.initialize( *device, *this );
}
}
if ( ext::vulkan::resized ) {
// destroy if exist
{
renderTarget.initialize( *renderTarget.device );
}
renderTarget.initialize( *renderTarget.device );
// update blitter descriptor set
if ( blitter.initialized ) {
std::vector<VkDescriptorImageInfo> inputDescriptors;
auto& subpass = renderTarget.passes[blitter.subpass];
for ( auto& input : subpass.inputs ) {
inputDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo(
renderTarget.attachments[input.attachment].view,
input.layout
));
}
// Set descriptor set
std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
// Binding 0 : Projection/View matrix uniform buffer
ext::vulkan::initializers::writeDescriptorSet(
blitter.descriptorSet,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0,
&(blitter.buffers.at(0).descriptor)
)
};
for ( size_t i = 0; i < inputDescriptors.size(); ++i ) {
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
blitter.descriptorSet,
VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
i + 1,
&inputDescriptors[i]
));
}
blitter.initializeDescriptorSet( writeDescriptorSets );
}
// update layer rendertargets descriptor sets
for ( auto layer : layers ) {
RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer;
auto& blitter = rtLayer->blitter;
auto& renderTarget = rtLayer->renderTarget;
// update descriptor set
if ( blitter.initialized ) {
renderTarget.initialize( *renderTarget.device );
VkDescriptorImageInfo samplerDescriptor; samplerDescriptor.sampler = blitter.sampler;
std::vector<VkDescriptorImageInfo> colorDescriptors;
for ( auto& attachment : renderTarget.attachments ) {
if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
colorDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo(
attachment.view,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
));
}
// Set descriptor set
std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
// Binding 0 : Projection/View matrix uniform buffer
ext::vulkan::initializers::writeDescriptorSet(
blitter.descriptorSet,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0,
&(blitter.buffers.at(0).descriptor)
),
// Binding 1 : Sampler
ext::vulkan::initializers::writeDescriptorSet(
blitter.descriptorSet,
VK_DESCRIPTOR_TYPE_SAMPLER,
1,
&samplerDescriptor
),
};
for ( size_t i = 0; i < colorDescriptors.size(); ++i ) {
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
blitter.descriptorSet,
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
i + 2,
&colorDescriptors[i]
));
}
vkUpdateDescriptorSets( *device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr );
}
// blitter.material.textures.clear();
auto& pipeline = blitter.getPipeline();
pipeline.update( blitter );
}
}
/*
std::vector<RenderMode*> layers = ext::vulkan::getRenderModes("RenderTarget", false);
for ( auto _ : layers ) {
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( blitter.initialized ) continue;
blitter.initialize( this->getName() );
blitter.initializePipeline();
}
*/
}
void ext::vulkan::DeferredRenderMode::destroy() {
ext::vulkan::RenderMode::destroy();
@ -279,22 +222,26 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
}
// render gui layer
{
for ( auto layer : layers ) {
RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer;
if ( !rtLayer->blitter.initialized ) continue;
if ( rtLayer->blitter.subpass != 0 ) continue;
rtLayer->blitter.createCommandBuffer(commands[i]);
for ( auto _ : layers ) {
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( !blitter.initialized ) continue;
if ( blitter.descriptor.subpass != 0 ) continue;
blitter.record(commands[i]);
}
}
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
blitter.createCommandBuffer(commands[i]);
{
blitter.record(commands[i]);
}
// render gui layer
{
for ( auto layer : layers ) {
RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer;
if ( !rtLayer->blitter.initialized ) continue;
if ( rtLayer->blitter.subpass != 1 ) continue;
rtLayer->blitter.createCommandBuffer(commands[i]);
for ( auto _ : layers ) {
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( !blitter.initialized ) continue;
if ( blitter.descriptor.subpass != 1 ) continue;
blitter.record(commands[i]);
}
}
vkCmdEndRenderPass(commands[i]);

View File

@ -68,17 +68,64 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
}
renderTarget.initialize( device );
blitter.renderTarget = &renderTarget;
blitter.initializeShaders({
{"./data/shaders/display.rendertarget.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"./data/shaders/display.rendertarget.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
// blitter.initialize();
{
uf::BaseMesh<pod::Vertex_2F2F, uint32_t> mesh;
mesh.vertices = {
{ {-1.0f, 1.0f}, {0.0f, 1.0f}, },
{ {-1.0f, -1.0f}, {0.0f, 0.0f}, },
{ {1.0f, -1.0f}, {1.0f, 0.0f}, },
{ {1.0f, 1.0f}, {1.0f, 1.0f}, }
};
mesh.indices = {
0, 1, 2, 2, 3, 0
};
/*
mesh.vertices = {
{ {-1.0f, 1.0f}, {0.0f, 0.0f}, },
{ {-1.0f, -1.0f}, {0.0f, 1.0f}, },
{ {1.0f, -1.0f}, {1.0f, 1.0f}, },
{ {-1.0f, 1.0f}, {0.0f, 0.0f}, },
{ {1.0f, -1.0f}, {1.0f, 1.0f}, },
{ {1.0f, 1.0f}, {1.0f, 0.0f}, }
};
*/
// blitter.descriptor.subpass = 1;
// blitter.descriptor.depthTest.test = false;
// blitter.descriptor.depthTest.write = false;
// blitter.initialize(this->getName());
blitter.device = &device;
blitter.material.device = &device;
blitter.initializeGeometry( mesh );
blitter.material.initializeShaders({
{"./data/shaders/display.renderTarget.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"./data/shaders/display.renderTarget.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
for ( auto& attachment : renderTarget.attachments ) {
if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
Texture2D& texture = blitter.material.textures.emplace_back();
texture.aliasAttachment(attachment);
}
// blitter.initializePipeline();
}
}
void ext::vulkan::RenderTargetRenderMode::tick() {
ext::vulkan::RenderMode::tick();
if ( ext::vulkan::resized ) {
renderTarget.initialize( *renderTarget.device );
blitter.material.textures.clear();
for ( auto& attachment : renderTarget.attachments ) {
if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
Texture2D& texture = blitter.material.textures.emplace_back();
texture.aliasAttachment(attachment);
}
auto& pipeline = blitter.getPipeline();
pipeline.update( blitter );
}
}
void ext::vulkan::RenderTargetRenderMode::destroy() {

View File

@ -16,25 +16,40 @@ namespace {
uint8_t DOMINANT_EYE = 0;
}
//ext::vulkan::StereoscopicDeferredRenderMode::StereoscopicDeferredRenderMode() : renderTargets({ renderTarget }), blitters({ blitter }) {
// ext::vulkan::StereoscopicDeferredRenderMode::StereoscopicDeferredRenderMode() : renderTargets({ renderTarget }), blitters({ blitter }) {
ext::vulkan::StereoscopicDeferredRenderMode::StereoscopicDeferredRenderMode() : renderTargets({ renderTarget }) {
}
std::string ext::vulkan::StereoscopicDeferredRenderMode::getType() const {
return "Deferred (Stereoscopic)";
}
ext::vulkan::RenderTarget& ext::vulkan::StereoscopicDeferredRenderMode::getRenderTarget( size_t i ) {
switch ( i ) {
case 0: return renderTargets.left;
case 1: return renderTargets.right;
default: return renderTarget;
}
}
const ext::vulkan::RenderTarget& ext::vulkan::StereoscopicDeferredRenderMode::getRenderTarget( size_t i ) const {
switch ( i ) {
case 0: return renderTargets.left;
case 1: return renderTargets.right;
default: return renderTarget;
}
}
void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
ext::vulkan::RenderMode::initialize( device );
struct EYES {
RenderTarget* renderTarget;
DeferredRenderingGraphic* blitter;
Graphic* blitter;
};
std::vector<EYES> eyes = {
{ &renderTargets.left, &blitters.left },
{ &renderTargets.right, &blitters.right },
};
std::size_t i = 0;
for ( auto& eye : eyes ) {
auto& renderTarget = *eye.renderTarget;
auto& blitter = *eye.blitter;
@ -81,18 +96,32 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
attachments.depth
);
}
// Third render pass: write to swapchain
/*
{
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.swapchain },
{ attachments.output },
attachments.depth
);
}
*/
renderTarget.initialize( device );
{
uf::BaseMesh<pod::Vertex_2F2F, uint16_t> mesh;
mesh.vertices = {
{ {-1.0f, 1.0f}, {0.0f, 0.0f}, },
{ {-1.0f, -1.0f}, {0.0f, 1.0f}, },
{ {1.0f, -1.0f}, {1.0f, 1.0f}, },
{ {1.0f, 1.0f}, {1.0f, 0.0f}, }
};
mesh.indices = {
0, 1, 2, 0, 2, 3
};
blitter.descriptor.subpass = 1;
blitter.descriptor.renderTarget = i++;
blitter.descriptor.depthTest.test = false;
blitter.descriptor.depthTest.write = false;
blitter.initialize( this->getName() );
blitter.initializeGeometry( mesh );
blitter.material.initializeShaders({
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
blitter.initializePipeline();
}
/*
blitter.renderTarget = &renderTarget;
blitter.initializeShaders({
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
@ -101,6 +130,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
blitter.subpass = 1;
blitter.initialize( device, *this );
*/
}
/*
{
@ -114,6 +144,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
}
*/
// update layer rendertargets descriptor sets
/*
{
std::vector<RenderMode*> layers = ext::vulkan::getRenderModes("RenderTarget", false); //{ &ext::vulkan::getRenderMode("Gui") };
for ( auto layer : layers ) {
@ -123,9 +154,31 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
blitter.initialize( device, *this );
}
}
*/
}
void ext::vulkan::StereoscopicDeferredRenderMode::tick() {
ext::vulkan::RenderMode::tick();
if ( ext::vulkan::resized ) {
struct EYES {
RenderTarget* renderTarget;
Graphic* blitter;
};
std::vector<EYES> eyes = {
{ &renderTargets.left, &blitters.left },
{ &renderTargets.right, &blitters.right },
};
for ( auto& eye : eyes ) {
auto& renderTarget = *eye.renderTarget;
auto& blitter = *eye.blitter;
renderTarget.initialize( *renderTarget.device );
if ( blitter.initialized ) {
auto& pipeline = blitter.getPipeline();
pipeline.update( blitter );
}
}
}
/*
std::vector<RenderMode*> layers = ext::vulkan::getRenderModes("RenderTarget", false);
for ( auto layer : layers ) {
RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer;
@ -139,7 +192,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::tick() {
if ( ext::vulkan::resized ) {
struct EYES {
RenderTarget* renderTarget;
DeferredRenderingGraphic* blitter;
Graphic* blitter;
};
std::vector<EYES> eyes = {
{ &renderTargets.left, &blitters.left },
@ -224,12 +277,6 @@ void ext::vulkan::StereoscopicDeferredRenderMode::tick() {
if ( blitter.initialized ) {
VkDescriptorImageInfo samplerDescriptor; samplerDescriptor.sampler = blitter.sampler;
std::vector<VkDescriptorImageInfo> colorDescriptors;
/*
colorDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo(
renderTarget.attachments[0].view,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
));
*/
for ( auto& attachment : renderTarget.attachments ) {
colorDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo(
@ -265,40 +312,17 @@ void ext::vulkan::StereoscopicDeferredRenderMode::tick() {
));
}
vkUpdateDescriptorSets( *device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr );
/*
VkDescriptorImageInfo renderTargetDescription = ext::vulkan::initializers::descriptorImageInfo(
renderTarget.attachments[0].view,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
blitter.sampler
);
std::vector<VkWriteDescriptorSet> writeDescriptorSets = {
// Binding 0 : Projection/View matrix uniform buffer
ext::vulkan::initializers::writeDescriptorSet(
blitter.descriptorSet,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0,
&(blitter.buffers.at(0).descriptor)
),
// Binding 1 : Albedo input attachment
ext::vulkan::initializers::writeDescriptorSet(
blitter.descriptorSet,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1,
&renderTargetDescription
),
};
vkUpdateDescriptorSets( *device, static_cast<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr );
*/
}
}
}
*/
}
void ext::vulkan::StereoscopicDeferredRenderMode::destroy() {
ext::vulkan::RenderMode::destroy();
renderTargets.right.destroy();
blitters.left.destroy();
blitters.right.destroy();
blitter.destroy();
// blitter.destroy();
}
void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
// destroy if exists
@ -325,7 +349,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
struct EYES {
RenderTarget* renderTarget;
DeferredRenderingGraphic* blitter;
Graphic* blitter;
};
std::vector<EYES> eyes = {
{ &renderTargets.left, &blitters.left },
@ -396,22 +420,24 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
}
// render gui layer
{
for ( auto layer : layers ) {
RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer;
if ( !rtLayer->blitter.initialized ) continue;
if ( rtLayer->blitter.subpass != 0 ) continue;
rtLayer->blitter.createCommandBuffer(commands[i]);
for ( auto _ : layers ) {
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( !blitter.initialized ) continue;
if ( blitter.descriptor.subpass != 0 ) continue;
blitter.record(commands[i]);
}
}
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
blitter.createCommandBuffer(commands[i]);
blitter.record(commands[i]);
// render gui layer
{
for ( auto layer : layers ) {
RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer;
if ( !rtLayer->blitter.initialized ) continue;
if ( rtLayer->blitter.subpass != 1 ) continue;
rtLayer->blitter.createCommandBuffer(commands[i]);
for ( auto _ : layers ) {
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( !blitter.initialized ) continue;
if ( blitter.descriptor.subpass != 1 ) continue;
blitter.record(commands[i]);
}
}
/*

View File

@ -50,6 +50,7 @@ bool ext::vulkan::Texture::generated() const {
}
void ext::vulkan::Texture::destroy() {
if ( !device ) return;
if ( view != VK_NULL_HANDLE ) {
vkDestroyImageView(device->logicalDevice, view, nullptr);
view = VK_NULL_HANDLE;
@ -546,5 +547,16 @@ void ext::vulkan::Texture2D::asRenderTarget( Device& device, uint32_t width, uin
VK_CHECK_RESULT(vkCreateImageView(device, &viewCreateInfo, nullptr, &view));
// Initialize a descriptor for later use
this->updateDescriptors();
}
void ext::vulkan::Texture2D::aliasAttachment( const RenderTarget::Attachment& attachment, bool createSampler ) {
image = attachment.image;
view = attachment.view;
imageLayout = attachment.layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : attachment.layout;
deviceMemory = attachment.mem;
// Create sampler
if ( createSampler ) sampler.initialize( ext::vulkan::device, sampler.filter );
this->updateDescriptors();
}

View File

@ -250,10 +250,10 @@ void uf::Camera::updateView() {
transform.orientation = uf::quaternion::identity();
pod::Transform<> flatten = uf::transform::flatten( transform );
pod::Matrix4t<> translation = uf::matrix::translate( uf::matrix::identity(), -position );
pod::Matrix4t<> translation = uf::matrix::translate( uf::matrix::identity(), position );
pod::Matrix4t<> rotation = uf::quaternion::matrix( flatten.orientation );
pod::Matrix4t<> view = rotation * translation; //uf::matrix::inverse( translation * rotation );
pod::Matrix4t<> view = uf::matrix::inverse( translation * rotation );
transform.orientation = ext::openvr::hmdQuaternion();
this->setView( ext::openvr::hmdViewMatrix(vr::Eye_Left, view ), 0 );
this->setView( ext::openvr::hmdViewMatrix(vr::Eye_Right, view ), 1 );

View File

@ -1,11 +1,5 @@
#include <uf/utils/graphic/mesh.h>
/*
uf::Graphic::~Graphic() {
this->destroy();
}
void uf::Graphic::destroy( bool clear ) {
}
*/
// Used for terrain
std::vector<ext::vulkan::VertexDescriptor> pod::Vertex_3F2F3F32B::descriptor = {
{
@ -51,6 +45,16 @@ std::vector<ext::vulkan::VertexDescriptor> pod::Vertex_3F2F::descriptor = {
offsetof(pod::Vertex_3F2F, uv)
}
};
std::vector<ext::vulkan::VertexDescriptor> pod::Vertex_2F2F::descriptor = {
{
VK_FORMAT_R32G32B32_SFLOAT,
offsetof(pod::Vertex_2F2F, position)
},
{
VK_FORMAT_R32G32_SFLOAT,
offsetof(pod::Vertex_2F2F, uv)
}
};
// Basic
std::vector<ext::vulkan::VertexDescriptor> pod::Vertex_3F::descriptor = {
{

View File

@ -1026,6 +1026,21 @@ void ext::Gui::render() {
if ( renderMode->getName() == "Gui" ) {
auto& blitter = renderMode->blitter;
auto& metadata = controller.getComponent<uf::Serializer>();
struct UniformDescriptor {
struct {
alignas(16) pod::Matrix4f models[2];
} matrices;
struct {
alignas(8) pod::Vector2f position = { 0.5f, 0.5f };
alignas(8) pod::Vector2f radius = { 0.1f, 0.1f };
alignas(16) pod::Vector4f color = { 1, 1, 1, 1 };
} cursor;
alignas(4) float alpha;
};
auto& shader = blitter.material.shaders.front();
auto& uniforms = shader.uniforms.front().get<UniformDescriptor>();
for ( std::size_t i = 0; i < 2; ++i ) {
pod::Transform<> transform;
if ( metadata["overlay"]["position"].isArray() )
@ -1050,37 +1065,37 @@ void ext::Gui::render() {
if ( ext::openvr::enabled && (metadata["overlay"]["enabled"].asBool() || ext::vulkan::getRenderMode("Stereoscopic Deferred", true).getType() == "Stereoscopic Deferred" )) {
if ( metadata["overlay"]["floating"].asBool() ) {
pod::Matrix4f model = uf::transform::model( transform );
blitter.uniforms.matrices.models[i] = camera.getProjection(i) * ext::openvr::hmdEyePositionMatrix( i == 0 ? vr::Eye_Left : vr::Eye_Right ) * model;
uniforms.matrices.models[i] = camera.getProjection(i) * ext::openvr::hmdEyePositionMatrix( i == 0 ? vr::Eye_Left : vr::Eye_Right ) * model;
} else {
auto translation = uf::matrix::translate( uf::matrix::identity(), camera.getTransform().position + controller.getComponent<pod::Transform<>>().position );
auto rotation = uf::quaternion::matrix( controller.getComponent<pod::Transform<>>().orientation * pod::Vector4f{1,1,1,-1} );
pod::Matrix4f model = translation * rotation * uf::transform::model( transform );
blitter.uniforms.matrices.models[i] = camera.getProjection(i) * camera.getView(i) * model;
uniforms.matrices.models[i] = camera.getProjection(i) * camera.getView(i) * model;
}
} else {
pod::Matrix4t<> model = uf::matrix::translate( uf::matrix::identity(), { 0, 0, 1 } );
blitter.uniforms.matrices.models[i] = model;
uniforms.matrices.models[i] = model;
}
blitter.uniforms.alpha = metadata["overlay"]["alpha"].asFloat();
uniforms.alpha = metadata["overlay"]["alpha"].asFloat();
blitter.uniforms.cursor.position.x = (metadata["overlay"]["cursor"]["position"][0].asFloat() + 1.0f) * 0.5f; //(::mouse.position.x + 1.0f) * 0.5f;
blitter.uniforms.cursor.position.y = (metadata["overlay"]["cursor"]["position"][1].asFloat() + 1.0f) * 0.5f; //(::mouse.position.y + 1.0f) * 0.5f;
uniforms.cursor.position.x = (metadata["overlay"]["cursor"]["position"][0].asFloat() + 1.0f) * 0.5f; //(::mouse.position.x + 1.0f) * 0.5f;
uniforms.cursor.position.y = (metadata["overlay"]["cursor"]["position"][1].asFloat() + 1.0f) * 0.5f; //(::mouse.position.y + 1.0f) * 0.5f;
pod::Vector3f cursorSize;
cursorSize.x = metadata["overlay"]["cursor"]["radius"].asFloat();
cursorSize.y = metadata["overlay"]["cursor"]["radius"].asFloat();
cursorSize = uf::matrix::multiply<float>( uf::matrix::inverse( uf::matrix::scale( uf::matrix::identity() , transform.scale) ), cursorSize );
blitter.uniforms.cursor.radius.x = cursorSize.x;
blitter.uniforms.cursor.radius.y = cursorSize.y;
uniforms.cursor.radius.x = cursorSize.x;
uniforms.cursor.radius.y = cursorSize.y;
blitter.uniforms.cursor.color.x = metadata["overlay"]["cursor"]["color"][0].asFloat();
blitter.uniforms.cursor.color.y = metadata["overlay"]["cursor"]["color"][1].asFloat();
blitter.uniforms.cursor.color.z = metadata["overlay"]["cursor"]["color"][2].asFloat();
blitter.uniforms.cursor.color.w = metadata["overlay"]["cursor"]["color"][3].asFloat();
uniforms.cursor.color.x = metadata["overlay"]["cursor"]["color"][0].asFloat();
uniforms.cursor.color.y = metadata["overlay"]["cursor"]["color"][1].asFloat();
uniforms.cursor.color.z = metadata["overlay"]["cursor"]["color"][2].asFloat();
uniforms.cursor.color.w = metadata["overlay"]["cursor"]["color"][3].asFloat();
}
blitter.updateBuffer( (void*) &blitter.uniforms, sizeof(blitter.uniforms), 0 );
shader.updateBuffer( (void*) &uniforms, sizeof(uniforms), 0 );
}
}
}

View File

@ -107,12 +107,13 @@ void EXT_API ext::initialize() {
ext::vulkan::DeferredRenderingGraphic::maxLights = ::config["engine"]["scenes"]["max lights"].asUInt();
//
ext::openvr::enabled = ::config["engine"]["ext"]["vr"]["enable"].asBool();
ext::openvr::swapEyes = ::config["engine"]["ext"]["vr"]["swap eyes"].asBool();
ext::openvr::driver.manifest = ::config["engine"]["ext"]["vr"]["manifest"].asString();
if ( ext::openvr::enabled ) {
::config["engine"]["render modes"]["stereo deferred"] = true;
ext::vulkan::validation = false;
if ( ::config["engine"]["ext"]["vr"]["invert winding order"].asBool() )
ext::vulkan::GraphicOld::DEFAULT_WINDING_ORDER = VK_FRONT_FACE_COUNTER_CLOCKWISE;
// ext::vulkan::validation = false;
// if ( ::config["engine"]["ext"]["vr"]["invert winding order"].asBool() )
// ext::vulkan::GraphicOld::DEFAULT_WINDING_ORDER = VK_FRONT_FACE_COUNTER_CLOCKWISE;
}
}
@ -124,7 +125,7 @@ void EXT_API ext::initialize() {
if ( ::config["engine"]["render modes"]["gui"].asBool() ) {
auto* renderMode = new ext::vulkan::RenderTargetRenderMode;
ext::vulkan::addRenderMode( renderMode, "Gui" );
renderMode->blitter.subpass = 1;
renderMode->blitter.descriptor.subpass = 1;
}
if ( ::config["engine"]["render modes"]["stereo deferred"].asBool() )
ext::vulkan::addRenderMode( new ext::vulkan::StereoscopicDeferredRenderMode, "" );

View File

@ -520,13 +520,12 @@ void ext::Marching::render() {
auto& root = this->getRootParent<uf::Scene>();
auto& player = *root.getController();
auto& camera = player.getComponent<uf::Camera>();
auto& transform = player.getComponent<pod::Transform<>>();
auto& transform = this->getComponent<pod::Transform<>>();
auto& model = this->getComponent<pod::Transform<>>();
if ( !graphic.initialized ) return;
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
// auto& uniforms = graphic.uniforms<uf::StereoMeshDescriptor>();
auto& uniforms = graphic.material.shaders.front().uniforms.front().get<uf::StereoMeshDescriptor>();
uniforms.matrices.model = uf::transform::model( this->getComponent<pod::Transform<>>() );
uniforms.matrices.model = uf::transform::model( transform );
for ( std::size_t i = 0; i < 2; ++i ) {
uniforms.matrices.view[i] = camera.getView( i );
uniforms.matrices.projection[i] = camera.getProjection( i );

View File

@ -126,6 +126,7 @@ void ext::Portal::render() {
{
auto& renderMode = this->getComponent<ext::vulkan::RenderTargetRenderMode>();
auto& blitter = renderMode.blitter;
auto& transform = this->getComponent<pod::Transform<>>();
auto& scene = uf::scene::getCurrentScene();
auto& controller = *scene.getController();
@ -133,25 +134,40 @@ void ext::Portal::render() {
auto& controllerCamera = controller.getComponent<uf::Camera>();
if ( !blitter.initialized ) return;
struct UniformDescriptor {
struct {
alignas(16) pod::Matrix4f models[2];
} matrices;
struct {
alignas(8) pod::Vector2f position = { 0.5f, 0.5f };
alignas(8) pod::Vector2f radius = { 0.1f, 0.1f };
alignas(16) pod::Vector4f color = { 1, 1, 1, 1 };
} cursor;
alignas(4) float alpha;
};
auto& shader = blitter.material.shaders.front();
auto& uniforms = shader.uniforms.front().get<UniformDescriptor>();
for ( std::size_t i = 0; i < 2; ++i ) {
pod::Matrix4f model = uf::transform::model( transform );
blitter.uniforms.matrices.models[i] = controllerCamera.getProjection(i) * controllerCamera.getView(i) * model;
uniforms.matrices.models[i] = controllerCamera.getProjection(i) * controllerCamera.getView(i) * model;
blitter.uniforms.alpha = 1.0f;
uniforms.alpha = 1.0f;
blitter.uniforms.cursor.position.x = -1.0f;
blitter.uniforms.cursor.position.y = -1.0f;
uniforms.cursor.position.x = -1.0f;
uniforms.cursor.position.y = -1.0f;
blitter.uniforms.cursor.radius.x = 0.0f;
blitter.uniforms.cursor.radius.y = 0.0f;
uniforms.cursor.radius.x = 0.0f;
uniforms.cursor.radius.y = 0.0f;
blitter.uniforms.cursor.color.x = 0.0f;
blitter.uniforms.cursor.color.y = 0.0f;
blitter.uniforms.cursor.color.z = 0.0f;
blitter.uniforms.cursor.color.w = 0.0f;
uniforms.cursor.color.x = 0.0f;
uniforms.cursor.color.y = 0.0f;
uniforms.cursor.color.z = 0.0f;
uniforms.cursor.color.w = 0.0f;
}
blitter.updateBuffer( (void*) &blitter.uniforms, sizeof(blitter.uniforms), 0 );
shader.updateBuffer( (void*) &uniforms, sizeof(uniforms), 0 );
}
}
void ext::Portal::destroy() {

View File

@ -304,6 +304,6 @@ void ext::Region::render( ) {
}
// graphic.updateBuffer( uniforms, 0, false );
graphic.material.shaders.front().updateBuffer( uniforms, 0, false );
graphic.material.shaders.front().updateBuffer( uniforms, 0, true );
}
}

View File

@ -301,7 +301,7 @@ void ext::World::render() {
/* Update lights */ {
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
auto& scene = *this;
std::vector<ext::vulkan::DeferredRenderingGraphic*> blitters;
std::vector<ext::vulkan::Graphic*> blitters;
auto& renderMode = ext::vulkan::getRenderMode("", true);
if ( renderMode.getType() == "Deferred (Stereoscopic)" ) {
auto* renderModePointer = (ext::vulkan::StereoscopicDeferredRenderMode*) &renderMode;
@ -325,9 +325,29 @@ void ext::World::render() {
alignas(16) pod::Vector4f color;
} lights;
};
struct SpecializationConstant {
int32_t maxLights = 32;
} specializationConstants;
for ( size_t _ = 0; _ < blitters.size(); ++_ ) {
auto& blitter = *blitters[_];
uint8_t* buffer = (uint8_t*) (void*) blitter.uniforms;
uint8_t* buffer;
size_t len;
auto* shader = &blitter.material.shaders.front();
for ( auto& _ : blitter.material.shaders ) {
if ( _.uniforms.empty() ) continue;
auto& userdata = _.uniforms.front();
buffer = (uint8_t*) (void*) userdata;
len = userdata.data().len;
shader = &_;
specializationConstants = _.specializationConstants.get<SpecializationConstant>();
}
if ( !buffer ) continue;
UniformDescriptor* uniforms = (UniformDescriptor*) buffer;
for ( std::size_t i = 0; i < 2; ++i ) {
uniforms->matrices.view[i] = camera.getView( i );
@ -340,7 +360,6 @@ void ext::World::render() {
uniforms->ambient.w = metadata["light"]["kexp"].asFloat();
}
{
size_t MAX_LIGHTS = blitter.maxLights;
std::vector<uf::Entity*> entities;
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
if ( !entity || entity->getName() != "Light" ) return;
@ -365,12 +384,12 @@ void ext::World::render() {
}
}
UniformDescriptor::Light* lights = (UniformDescriptor::Light*) &buffer[sizeof(UniformDescriptor) - sizeof(UniformDescriptor::Light)];
for ( size_t i = 0; i < MAX_LIGHTS; ++i ) {
for ( size_t i = 0; i < specializationConstants.maxLights; ++i ) {
UniformDescriptor::Light& light = lights[i];
light.position = { 0, 0, 0, 0 };
light.color = { 0, 0, 0, 0 };
}
for ( size_t i = 0; i < MAX_LIGHTS && i < entities.size(); ++i ) {
for ( size_t i = 0; i < specializationConstants.maxLights && i < entities.size(); ++i ) {
UniformDescriptor::Light& light = lights[i];
uf::Entity* entity = entities[i];
@ -394,7 +413,8 @@ void ext::World::render() {
light.color.w = metadata["light"]["radius"].asFloat();
}
}
blitter.updateBuffer( (void*) buffer, blitter.uniforms.data().len, 0, false );
// blitter.updateBuffer( (void*) buffer, blitter.uniforms.data().len, 0, false );
shader->updateBuffer( (void*) buffer, len, 0, false );
}
}
}