metal clear swapchain with blue
This commit is contained in:
@@ -133,7 +133,9 @@ void CBrushRendering::Init()
|
||||
{"shaders/brush_vert.spv", SHADER_TYPE_VERTEX},
|
||||
{"shaders/brush_frag.spv", SHADER_TYPE_FRAGMENT},
|
||||
},
|
||||
{}, 64,
|
||||
{}, 64,
|
||||
20,
|
||||
{{0,0,EVertexFormat::VERTEX_FORMAT_X32Y32Z32}, {12,1,EVertexFormat::VERTEX_FORMAT_X32Y32}},
|
||||
{EImageFormat::IMAGE_FORMAT_R8G8B8A8}
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,24 +6,55 @@
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier0/platform.h"
|
||||
#include "rendering.h"
|
||||
#include "ml_video.h"
|
||||
|
||||
mat4 g_cameraView;
|
||||
|
||||
class CMlBuffer: public IBuffer
|
||||
{
|
||||
public:
|
||||
void *Map() override;
|
||||
void Unmap() override;
|
||||
MTL::Buffer *m_buffer;
|
||||
};
|
||||
|
||||
void *CMlBuffer::Map()
|
||||
{
|
||||
return m_buffer->contents();
|
||||
}
|
||||
|
||||
void CMlBuffer::Unmap()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IStorageBuffer *IRenderer::CreateStorageBuffer( uint32_t uSize )
|
||||
{
|
||||
CMlBuffer *pBuffer = new CMlBuffer;
|
||||
pBuffer->m_buffer = g_mlDevice->newBuffer(uSize, MTL::ResourceStorageModeShared);
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
IUniformBuffer *IRenderer::CreateUniformBuffer( uint32_t uSize )
|
||||
{
|
||||
CMlBuffer *pBuffer = new CMlBuffer;
|
||||
pBuffer->m_buffer = g_mlDevice->newBuffer(uSize, MTL::ResourceStorageModeShared);
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
|
||||
IVertexBuffer *IRenderer::CreateVertexBuffer( uint32_t uSize )
|
||||
{
|
||||
CMlBuffer *pBuffer = new CMlBuffer;
|
||||
pBuffer->m_buffer = g_mlDevice->newBuffer(uSize, MTL::ResourceStorageModeShared);
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
IIndexBuffer *IRenderer::CreateIndexBuffer( uint32_t uSize )
|
||||
{
|
||||
CMlBuffer *pBuffer = new CMlBuffer;
|
||||
pBuffer->m_buffer = g_mlDevice->newBuffer(uSize, MTL::ResourceStorageModeShared);
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +127,8 @@ IGraphicsPipeline *IRenderer::CreateGraphicsPipeline(
|
||||
CUtlVector<Shader_t> shaders,
|
||||
CUtlVector<ShaderInput_t> inputs,
|
||||
uint32_t nConstantsSize,
|
||||
uint32_t nVertexSize,
|
||||
CUtlVector<VertexAttribute_t> vertexFormat,
|
||||
CUtlVector<EImageFormat> outputFormats
|
||||
)
|
||||
{
|
||||
|
||||
12
engine/ml_video.h
Normal file
12
engine/ml_video.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef ML_VIDEO_H
|
||||
#define ML_VIDEO_H
|
||||
|
||||
#include "Metal/Metal.hpp"
|
||||
#include "QuartzCore/QuartzCore.hpp"
|
||||
|
||||
extern CA::MetalLayer *g_mlLayer;
|
||||
extern MTL::Device *g_mlDevice;
|
||||
extern MTL::CommandQueue *g_mlCommandQueue;
|
||||
extern NS::AutoreleasePool *g_mlPool;
|
||||
|
||||
#endif
|
||||
@@ -11,6 +11,7 @@
|
||||
#define CA_PRIVATE_IMPLEMENTATION
|
||||
|
||||
#include "tier0/minmax_off.h"
|
||||
#include "QuartzCore/CAMetalLayer.hpp"
|
||||
#include "Metal/Metal.hpp"
|
||||
|
||||
#include "SDL3/SDL.h"
|
||||
@@ -19,7 +20,30 @@
|
||||
#include "SDL3/SDL_events.h"
|
||||
#include "tier0/minmax.h"
|
||||
|
||||
char g_bConfigNotify = 0;
|
||||
uint32_t g_nWindowWidth = 1280;
|
||||
uint32_t g_nWindowHeight = 720;
|
||||
|
||||
SDL_Window *g_window;
|
||||
SDL_MetalView g_mlView;
|
||||
CA::MetalLayer *g_mlLayer;
|
||||
MTL::Device *g_mlDevice;
|
||||
MTL::CommandQueue *g_mlCommandQueue;
|
||||
NS::AutoreleasePool *g_mlPool;
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
#include "TargetConditionals.h"
|
||||
#if TARGET_OS_IPHONE
|
||||
// iOS
|
||||
#define SDL_METAL_VIEW UI::View
|
||||
#define STBI_NO_THREAD_LOCALS
|
||||
#else
|
||||
// macOS
|
||||
#define SDL_METAL_VIEW NS::View
|
||||
#endif
|
||||
#else
|
||||
// Other platforms
|
||||
#endif
|
||||
|
||||
void IInput::SetMouseMode( EMouseMode mode )
|
||||
{
|
||||
@@ -34,12 +58,131 @@ void IInput::SetMouseMode( EMouseMode mode )
|
||||
}
|
||||
}
|
||||
|
||||
EInputKey ISDL_KeyName(SDL_Keycode key)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case SDLK_ESCAPE: return KEY_ESCAPE;
|
||||
|
||||
case SDLK_1: return KEY_1;
|
||||
case SDLK_2: return KEY_2;
|
||||
case SDLK_3: return KEY_3;
|
||||
case SDLK_4: return KEY_4;
|
||||
case SDLK_5: return KEY_5;
|
||||
case SDLK_6: return KEY_6;
|
||||
case SDLK_7: return KEY_7;
|
||||
case SDLK_8: return KEY_8;
|
||||
case SDLK_9: return KEY_9;
|
||||
case SDLK_0: return KEY_0;
|
||||
|
||||
case SDLK_A: return KEY_A;
|
||||
case SDLK_B: return KEY_B;
|
||||
case SDLK_C: return KEY_C;
|
||||
case SDLK_D: return KEY_D;
|
||||
case SDLK_E: return KEY_E;
|
||||
case SDLK_F: return KEY_F;
|
||||
case SDLK_G: return KEY_G;
|
||||
case SDLK_H: return KEY_H;
|
||||
case SDLK_I: return KEY_I;
|
||||
case SDLK_J: return KEY_J;
|
||||
case SDLK_K: return KEY_K;
|
||||
case SDLK_L: return KEY_L;
|
||||
case SDLK_M: return KEY_M;
|
||||
case SDLK_N: return KEY_N;
|
||||
case SDLK_O: return KEY_O;
|
||||
case SDLK_P: return KEY_P;
|
||||
case SDLK_Q: return KEY_Q;
|
||||
case SDLK_R: return KEY_R;
|
||||
case SDLK_S: return KEY_S;
|
||||
case SDLK_T: return KEY_T;
|
||||
case SDLK_U: return KEY_U;
|
||||
case SDLK_V: return KEY_V;
|
||||
case SDLK_W: return KEY_W;
|
||||
case SDLK_X: return KEY_X;
|
||||
case SDLK_Y: return KEY_Y;
|
||||
case SDLK_Z: return KEY_Z;
|
||||
}
|
||||
return KEY_NONE;
|
||||
};
|
||||
|
||||
void IVideo_HandleEvents()
|
||||
{
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
SDL_KeyboardEvent *key = &event.key;
|
||||
SDL_MouseMotionEvent *motion = &event.motion;
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
g_nWindowWidth = event.window.data1;
|
||||
g_nWindowHeight = event.window.data2;
|
||||
g_bConfigNotify = 2;
|
||||
break;
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
if (!key->repeat)
|
||||
IInput::KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_DOWN);
|
||||
break;
|
||||
case SDL_EVENT_KEY_UP:
|
||||
key = &event.key;
|
||||
if (!key->repeat)
|
||||
IInput::KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_UP);
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
IInput::AxisEvent(AXIS_MOUSE_X, motion->yrel*0.022);
|
||||
IInput::AxisEvent(AXIS_MOUSE_Y, -motion->xrel*0.022);
|
||||
break;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void IVideo::Init()
|
||||
{
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS))
|
||||
V_printf("%s\n",SDL_GetError());
|
||||
g_window = SDL_CreateWindow("rtt", 1280, 720, SDL_WINDOW_VULKAN);
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
|
||||
g_window = SDL_CreateWindow("rtt", 1280, 720, SDL_WINDOW_METAL);
|
||||
g_mlView = SDL_Metal_CreateView(g_window);
|
||||
g_mlLayer = (CA::MetalLayer*)SDL_Metal_GetLayer(g_mlView);
|
||||
|
||||
g_mlDevice = MTL::CreateSystemDefaultDevice();
|
||||
|
||||
g_mlLayer->setDevice(g_mlDevice);
|
||||
g_mlLayer->setPixelFormat(MTL::PixelFormatBGRA8Unorm);
|
||||
|
||||
g_mlCommandQueue = g_mlDevice->newCommandQueue();
|
||||
|
||||
g_mlLayer->setDrawableSize(CGSizeMake(1280, 720));
|
||||
|
||||
}
|
||||
void IVideo::Frame( float fDelta )
|
||||
{
|
||||
IVideo_HandleEvents();
|
||||
|
||||
NS::AutoreleasePool *pool = NS::AutoreleasePool::alloc()->init();
|
||||
int w, h;
|
||||
SDL_GetWindowSizeInPixels(g_window, &w, &h);
|
||||
g_mlLayer->setDrawableSize(CGSizeMake(w, h));
|
||||
|
||||
CA::MetalDrawable *drawable = g_mlLayer->nextDrawable();
|
||||
if (!drawable)
|
||||
return;
|
||||
|
||||
MTL::CommandBuffer *commandBuffer = g_mlCommandQueue->commandBuffer();
|
||||
|
||||
MTL::RenderPassDescriptor *renderPass = MTL::RenderPassDescriptor::alloc()->init();
|
||||
renderPass->colorAttachments()->object(0)->setTexture(drawable->texture());
|
||||
renderPass->colorAttachments()->object(0)->setLoadAction(MTL::LoadActionClear);
|
||||
renderPass->colorAttachments()->object(0)->setStoreAction(MTL::StoreActionStore);
|
||||
renderPass->colorAttachments()->object(0)->setClearColor(MTL::ClearColor(0.0, 0, 1.0, 1.0));
|
||||
MTL::RenderCommandEncoder *renderEncoder = commandBuffer->renderCommandEncoder(renderPass);
|
||||
renderEncoder->endEncoding();
|
||||
|
||||
commandBuffer->presentDrawable(drawable);
|
||||
commandBuffer->commit();
|
||||
pool->release();
|
||||
}
|
||||
|
||||
void IVideo::Deinit()
|
||||
{
|
||||
g_mlCommandQueue->release();
|
||||
g_mlDevice->release();
|
||||
};
|
||||
|
||||
@@ -65,6 +65,35 @@ VkFormat IRenderer_FormatToVk( EImageFormat format )
|
||||
}
|
||||
};
|
||||
|
||||
VkFormat IRenderer_VertexToVk( EVertexFormat format )
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case VERTEX_FORMAT_X16: return VK_FORMAT_R16_SFLOAT;
|
||||
case VERTEX_FORMAT_X16Y16: return VK_FORMAT_R16G16_SFLOAT;
|
||||
case VERTEX_FORMAT_X16Y16Z16: return VK_FORMAT_R16G16B16_SFLOAT;
|
||||
case VERTEX_FORMAT_X16Y16Z16W16: return VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
case VERTEX_FORMAT_X32: return VK_FORMAT_R32_SFLOAT;
|
||||
case VERTEX_FORMAT_X32Y32: return VK_FORMAT_R32G32_SFLOAT;
|
||||
case VERTEX_FORMAT_X32Y32Z32: return VK_FORMAT_R32G32B32_SFLOAT;
|
||||
case VERTEX_FORMAT_X32Y32Z32W32: return VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
}
|
||||
};
|
||||
uint32_t IRenderer_VertexToSize( EVertexFormat format )
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case VERTEX_FORMAT_X16: return 2;
|
||||
case VERTEX_FORMAT_X16Y16: return 4;
|
||||
case VERTEX_FORMAT_X16Y16Z16: return 6;
|
||||
case VERTEX_FORMAT_X16Y16Z16W16: return 8;
|
||||
case VERTEX_FORMAT_X32: return 4;
|
||||
case VERTEX_FORMAT_X32Y32: return 8;
|
||||
case VERTEX_FORMAT_X32Y32Z32: return 12;
|
||||
case VERTEX_FORMAT_X32Y32Z32W32: return 16;
|
||||
}
|
||||
}
|
||||
|
||||
VkAttachmentLoadOp IRenderer_LoadOpVk( EAttachmentLoadMode mode )
|
||||
{
|
||||
switch (mode)
|
||||
@@ -228,11 +257,13 @@ void vk_shader_t::Destroy( void )
|
||||
|
||||
|
||||
void vk_tripipeline_t::Create(
|
||||
CUtlVector<vk_shader_t> &shaders,
|
||||
CUtlVector<VkDescriptorSetLayoutBinding> &bindings,
|
||||
uint32_t pushConstantSize,
|
||||
CUtlVector<VkFormat> formats
|
||||
)
|
||||
CUtlVector<vk_shader_t> &shaders,
|
||||
CUtlVector<VkDescriptorSetLayoutBinding> &bindings,
|
||||
uint32_t pushConstantSize,
|
||||
uint32_t nVertexSize,
|
||||
CUtlVector<VertexAttribute_t> vertexFormat,
|
||||
CUtlVector<VkFormat> formats
|
||||
)
|
||||
{
|
||||
VkPushConstantRange pushConstantRange = {};
|
||||
pushConstantRange.stageFlags = VK_SHADER_STAGE_ALL;
|
||||
@@ -295,11 +326,32 @@ void vk_tripipeline_t::Create(
|
||||
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
|
||||
};
|
||||
|
||||
VkVertexInputBindingDescription vibd = {
|
||||
.binding = 0,
|
||||
.stride = nVertexSize,
|
||||
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
||||
};
|
||||
|
||||
VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||
.dynamicStateCount = sizeof(dynamicStates)/sizeof(VkDynamicState),
|
||||
.pDynamicStates = dynamicStates,
|
||||
};
|
||||
CUtlVector<VkVertexInputAttributeDescription> viad(vertexFormat.GetSize());
|
||||
for ( uint32_t i = 0; i < viad.GetSize(); i++ )
|
||||
{
|
||||
viad[i].location = 0;
|
||||
viad[i].binding = vertexFormat[i].binding;
|
||||
viad[i].format = IRenderer_VertexToVk(vertexFormat[i].format);
|
||||
viad[i].offset = vertexFormat[i].offset;
|
||||
}
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo pvisci = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||
.vertexBindingDescriptionCount = 1,
|
||||
.pVertexBindingDescriptions = &vibd,
|
||||
.vertexAttributeDescriptionCount = (uint32_t)vertexFormat.GetSize(),
|
||||
};
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo piasci = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
||||
@@ -318,6 +370,7 @@ void vk_tripipeline_t::Create(
|
||||
|
||||
VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {};
|
||||
graphicsPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
graphicsPipelineCreateInfo.pVertexInputState = &pvisci;
|
||||
graphicsPipelineCreateInfo.pInputAssemblyState = &piasci;
|
||||
graphicsPipelineCreateInfo.layout = m_layout;
|
||||
graphicsPipelineCreateInfo.pDynamicState = &pipelineDynamicStateCreateInfo;
|
||||
@@ -808,6 +861,8 @@ IGraphicsPipeline *IRenderer::CreateGraphicsPipeline(
|
||||
CUtlVector<Shader_t> shaders,
|
||||
CUtlVector<ShaderInput_t> inputs,
|
||||
uint32_t nConstantsSize,
|
||||
uint32_t nVertexSize,
|
||||
CUtlVector<VertexAttribute_t> vertexFormats,
|
||||
CUtlVector<EImageFormat> outputFormats
|
||||
)
|
||||
{
|
||||
@@ -816,6 +871,7 @@ IGraphicsPipeline *IRenderer::CreateGraphicsPipeline(
|
||||
CUtlVector<vk_shader_t> vkshaders(shaders.GetSize());
|
||||
CUtlVector<VkDescriptorSetLayoutBinding> vkbindings(inputs.GetSize());
|
||||
CUtlVector<VkFormat> vkformats(outputFormats.GetSize());
|
||||
CUtlVector<VkVertexInputAttributeDescription> vkVertexFormats(vertexFormats.GetSize());
|
||||
|
||||
for ( uint32_t i = 0; i < vkshaders.GetSize(); i++ )
|
||||
{
|
||||
@@ -842,8 +898,9 @@ IGraphicsPipeline *IRenderer::CreateGraphicsPipeline(
|
||||
{
|
||||
vkformats[i] = IRenderer_FormatToVk(outputFormats[i]);
|
||||
}
|
||||
pipeline->m_pipeline.Create(vkshaders, vkbindings, nConstantsSize, vkformats);
|
||||
return 0;
|
||||
|
||||
pipeline->m_pipeline.Create(vkshaders, vkbindings, nConstantsSize, nVertexSize, vertexFormats, vkformats);
|
||||
return pipeline;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ struct vk_tripipeline_t
|
||||
CUtlVector<vk_shader_t> &shaders,
|
||||
CUtlVector<VkDescriptorSetLayoutBinding> &bindings,
|
||||
uint32_t pushConstantsSize,
|
||||
uint32_t nVertexSize,
|
||||
CUtlVector<VertexAttribute_t> vertexFormat,
|
||||
CUtlVector<VkFormat> formats
|
||||
/* the rest of the stuff is set by the dynamic state */
|
||||
/* literally */
|
||||
|
||||
@@ -232,8 +232,7 @@ EInputKey ISDL_KeyName(SDL_Keycode key)
|
||||
|
||||
void IVideo::Init()
|
||||
{
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS))
|
||||
V_printf("%s\n",SDL_GetError());
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
|
||||
g_window = SDL_CreateWindow("rtt", 1280, 720, SDL_WINDOW_VULKAN);
|
||||
|
||||
unsigned int nExtensionCount = 0;
|
||||
|
||||
Reference in New Issue
Block a user