2019-10-01 12:31:49 -04:00
|
|
|
#include "GSH_VulkanDraw.h"
|
2019-11-22 17:59:32 -05:00
|
|
|
#include "GSH_VulkanMemoryUtils.h"
|
2019-10-01 12:31:49 -04:00
|
|
|
#include "MemStream.h"
|
|
|
|
#include "vulkan/StructDefs.h"
|
2019-10-03 18:06:59 -04:00
|
|
|
#include "vulkan/Utils.h"
|
2019-10-01 12:31:49 -04:00
|
|
|
#include "nuanceur/Builder.h"
|
|
|
|
#include "nuanceur/generators/SpirvShaderGenerator.h"
|
2019-11-28 20:17:10 -05:00
|
|
|
#include "../GSHandler.h"
|
2019-12-06 09:23:32 -05:00
|
|
|
#include "../GsPixelFormats.h"
|
2019-10-01 12:31:49 -04:00
|
|
|
|
|
|
|
using namespace GSH_Vulkan;
|
|
|
|
|
2019-11-21 13:16:48 -05:00
|
|
|
#define VERTEX_ATTRIB_LOCATION_POSITION 0
|
|
|
|
#define VERTEX_ATTRIB_LOCATION_DEPTH 1
|
|
|
|
#define VERTEX_ATTRIB_LOCATION_COLOR 2
|
|
|
|
#define VERTEX_ATTRIB_LOCATION_TEXCOORD 3
|
2020-02-02 11:33:34 -05:00
|
|
|
#define VERTEX_ATTRIB_LOCATION_FOG 4
|
2019-11-21 13:16:48 -05:00
|
|
|
|
2020-01-23 13:23:03 -05:00
|
|
|
#define MAX_VERTEX_COUNT 1024 * 512
|
2019-10-01 12:31:49 -04:00
|
|
|
|
2019-12-10 09:39:12 -05:00
|
|
|
CDraw::CDraw(const ContextPtr& context, const FrameCommandBufferPtr& frameCommandBuffer)
|
2019-12-13 23:21:59 -05:00
|
|
|
: m_context(context)
|
|
|
|
, m_frameCommandBuffer(frameCommandBuffer)
|
|
|
|
, m_pipelineCache(context->device)
|
2019-10-01 12:31:49 -04:00
|
|
|
{
|
2020-01-16 21:46:02 -05:00
|
|
|
for(auto& frame : m_frames)
|
|
|
|
{
|
|
|
|
frame.vertexBuffer = Framework::Vulkan::CBuffer(
|
2020-01-31 09:34:48 -05:00
|
|
|
m_context->device, m_context->physicalDeviceMemoryProperties,
|
2021-03-29 17:04:29 -04:00
|
|
|
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
|
|
|
sizeof(PRIM_VERTEX) * MAX_VERTEX_COUNT);
|
2019-12-13 23:21:59 -05:00
|
|
|
|
2020-01-16 21:46:02 -05:00
|
|
|
auto result = m_context->device.vkMapMemory(m_context->device, frame.vertexBuffer.GetMemory(),
|
2020-01-31 09:34:48 -05:00
|
|
|
0, VK_WHOLE_SIZE, 0, reinterpret_cast<void**>(&frame.vertexBufferPtr));
|
2020-01-16 21:46:02 -05:00
|
|
|
CHECKVULKANERROR(result);
|
|
|
|
}
|
2019-11-18 20:01:11 -05:00
|
|
|
|
2019-11-21 13:16:48 -05:00
|
|
|
m_pipelineCaps <<= 0;
|
2019-10-01 12:31:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
CDraw::~CDraw()
|
|
|
|
{
|
2020-01-16 21:46:02 -05:00
|
|
|
for(auto& frame : m_frames)
|
|
|
|
{
|
|
|
|
m_context->device.vkUnmapMemory(m_context->device, frame.vertexBuffer.GetMemory());
|
|
|
|
}
|
2019-10-01 12:31:49 -04:00
|
|
|
}
|
|
|
|
|
2019-11-21 13:16:48 -05:00
|
|
|
void CDraw::SetPipelineCaps(const PIPELINE_CAPS& caps)
|
2019-11-16 11:27:23 -05:00
|
|
|
{
|
2019-11-21 13:16:48 -05:00
|
|
|
bool changed = static_cast<uint64>(caps) != static_cast<uint64>(m_pipelineCaps);
|
|
|
|
if(!changed) return;
|
2021-04-12 15:38:30 -04:00
|
|
|
if(caps.textureUseMemoryCopy)
|
|
|
|
{
|
|
|
|
FlushRenderPass();
|
|
|
|
}
|
2019-11-21 13:16:48 -05:00
|
|
|
FlushVertices();
|
|
|
|
m_pipelineCaps = caps;
|
|
|
|
}
|
|
|
|
|
2020-01-07 13:09:58 -05:00
|
|
|
void CDraw::SetFramebufferParams(uint32 addr, uint32 width, uint32 writeMask)
|
2019-11-21 13:16:48 -05:00
|
|
|
{
|
2019-12-13 23:21:59 -05:00
|
|
|
bool changed =
|
|
|
|
(m_pushConstants.fbBufAddr != addr) ||
|
2020-01-07 13:09:58 -05:00
|
|
|
(m_pushConstants.fbBufWidth != width) ||
|
|
|
|
(m_pushConstants.fbWriteMask != writeMask);
|
2019-11-21 13:16:48 -05:00
|
|
|
if(!changed) return;
|
2019-12-02 09:48:00 -05:00
|
|
|
FlushVertices();
|
|
|
|
m_pushConstants.fbBufAddr = addr;
|
|
|
|
m_pushConstants.fbBufWidth = width;
|
2020-01-07 13:09:58 -05:00
|
|
|
m_pushConstants.fbWriteMask = writeMask;
|
2019-11-16 11:27:23 -05:00
|
|
|
}
|
|
|
|
|
2019-12-22 16:34:47 -05:00
|
|
|
void CDraw::SetDepthbufferParams(uint32 addr, uint32 width)
|
|
|
|
{
|
|
|
|
bool changed =
|
|
|
|
(m_pushConstants.depthBufAddr != addr) ||
|
|
|
|
(m_pushConstants.depthBufWidth != width);
|
|
|
|
if(!changed) return;
|
|
|
|
FlushVertices();
|
|
|
|
m_pushConstants.depthBufAddr = addr;
|
|
|
|
m_pushConstants.depthBufWidth = width;
|
|
|
|
}
|
|
|
|
|
2020-01-09 13:06:41 -05:00
|
|
|
void CDraw::SetTextureParams(uint32 bufAddr, uint32 bufWidth, uint32 width, uint32 height, uint32 csa)
|
2019-11-22 08:52:25 -05:00
|
|
|
{
|
2019-12-13 23:21:59 -05:00
|
|
|
bool changed =
|
|
|
|
(m_pushConstants.texBufAddr != bufAddr) ||
|
|
|
|
(m_pushConstants.texBufWidth != bufWidth) ||
|
|
|
|
(m_pushConstants.texWidth != width) ||
|
2020-01-09 13:06:41 -05:00
|
|
|
(m_pushConstants.texHeight != height) ||
|
|
|
|
(m_pushConstants.texCsa != csa);
|
2019-11-22 08:52:25 -05:00
|
|
|
if(!changed) return;
|
2019-12-02 09:48:00 -05:00
|
|
|
FlushVertices();
|
|
|
|
m_pushConstants.texBufAddr = bufAddr;
|
|
|
|
m_pushConstants.texBufWidth = bufWidth;
|
|
|
|
m_pushConstants.texWidth = width;
|
|
|
|
m_pushConstants.texHeight = height;
|
2020-01-09 13:06:41 -05:00
|
|
|
m_pushConstants.texCsa = csa;
|
2019-11-22 08:52:25 -05:00
|
|
|
}
|
|
|
|
|
2020-02-18 13:06:13 -05:00
|
|
|
void CDraw::SetClutBufferOffset(uint32 clutBufferOffset)
|
|
|
|
{
|
|
|
|
bool changed = m_clutBufferOffset != clutBufferOffset;
|
|
|
|
if(!changed) return;
|
|
|
|
FlushVertices();
|
|
|
|
m_clutBufferOffset = clutBufferOffset;
|
|
|
|
}
|
|
|
|
|
2020-01-14 13:25:09 -05:00
|
|
|
void CDraw::SetTextureAlphaParams(uint32 texA0, uint32 texA1)
|
|
|
|
{
|
|
|
|
bool changed =
|
|
|
|
(m_pushConstants.texA0 != texA0) ||
|
|
|
|
(m_pushConstants.texA1 != texA1);
|
|
|
|
if(!changed) return;
|
|
|
|
FlushVertices();
|
|
|
|
m_pushConstants.texA0 = texA0;
|
|
|
|
m_pushConstants.texA1 = texA1;
|
|
|
|
}
|
|
|
|
|
2020-01-20 12:53:09 -05:00
|
|
|
void CDraw::SetTextureClampParams(uint32 clampMinU, uint32 clampMinV, uint32 clampMaxU, uint32 clampMaxV)
|
|
|
|
{
|
|
|
|
bool changed =
|
|
|
|
(m_pushConstants.clampMin[0] != clampMinU) ||
|
|
|
|
(m_pushConstants.clampMin[1] != clampMinV) ||
|
|
|
|
(m_pushConstants.clampMax[0] != clampMaxU) ||
|
|
|
|
(m_pushConstants.clampMax[1] != clampMaxV);
|
|
|
|
if(!changed) return;
|
|
|
|
FlushVertices();
|
|
|
|
m_pushConstants.clampMin[0] = clampMinU;
|
|
|
|
m_pushConstants.clampMin[1] = clampMinV;
|
|
|
|
m_pushConstants.clampMax[0] = clampMaxU;
|
|
|
|
m_pushConstants.clampMax[1] = clampMaxV;
|
|
|
|
}
|
|
|
|
|
2020-02-02 11:33:34 -05:00
|
|
|
void CDraw::SetFogParams(float fogR, float fogG, float fogB)
|
|
|
|
{
|
|
|
|
bool changed =
|
|
|
|
(m_pushConstants.fogColor[0] != fogR) ||
|
|
|
|
(m_pushConstants.fogColor[1] != fogG) ||
|
|
|
|
(m_pushConstants.fogColor[2] != fogB);
|
|
|
|
if(!changed) return;
|
|
|
|
FlushVertices();
|
|
|
|
m_pushConstants.fogColor[0] = fogR;
|
|
|
|
m_pushConstants.fogColor[1] = fogG;
|
|
|
|
m_pushConstants.fogColor[2] = fogB;
|
|
|
|
m_pushConstants.fogColor[3] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDraw::SetAlphaTestParams(uint32 alphaRef)
|
|
|
|
{
|
|
|
|
bool changed = (m_pushConstants.alphaRef != alphaRef);
|
|
|
|
if(!changed) return;
|
|
|
|
FlushVertices();
|
|
|
|
m_pushConstants.alphaRef = alphaRef;
|
|
|
|
}
|
|
|
|
|
2020-01-08 12:51:47 -05:00
|
|
|
void CDraw::SetAlphaBlendingParams(uint32 alphaFix)
|
|
|
|
{
|
|
|
|
bool changed =
|
2020-01-31 09:34:48 -05:00
|
|
|
(m_pushConstants.alphaFix != alphaFix);
|
2020-01-08 12:51:47 -05:00
|
|
|
if(!changed) return;
|
|
|
|
FlushVertices();
|
|
|
|
m_pushConstants.alphaFix = alphaFix;
|
|
|
|
}
|
|
|
|
|
2019-12-12 13:24:06 -05:00
|
|
|
void CDraw::SetScissor(uint32 scissorX, uint32 scissorY, uint32 scissorWidth, uint32 scissorHeight)
|
|
|
|
{
|
2019-12-13 23:21:59 -05:00
|
|
|
bool changed =
|
|
|
|
(m_scissorX != scissorX) ||
|
|
|
|
(m_scissorY != scissorY) ||
|
|
|
|
(m_scissorWidth != scissorWidth) ||
|
|
|
|
(m_scissorHeight != scissorHeight);
|
2019-12-12 13:24:06 -05:00
|
|
|
if(!changed) return;
|
|
|
|
FlushVertices();
|
|
|
|
m_scissorX = scissorX;
|
|
|
|
m_scissorY = scissorY;
|
|
|
|
m_scissorWidth = scissorWidth;
|
|
|
|
m_scissorHeight = scissorHeight;
|
|
|
|
}
|
|
|
|
|
2021-04-12 15:39:33 -04:00
|
|
|
void CDraw::SetMemoryCopyParams(uint32 memoryCopyAddress, uint32 memoryCopySize)
|
|
|
|
{
|
2021-05-04 17:11:54 -04:00
|
|
|
bool changed =
|
|
|
|
(memoryCopyAddress != m_memoryCopyAddress) ||
|
|
|
|
(memoryCopySize != m_memoryCopySize);
|
|
|
|
if(!changed) return;
|
|
|
|
FlushRenderPass();
|
2021-04-12 15:39:33 -04:00
|
|
|
m_memoryCopyAddress = memoryCopyAddress;
|
|
|
|
m_memoryCopySize = memoryCopySize;
|
|
|
|
}
|
|
|
|
|
2019-10-01 12:31:49 -04:00
|
|
|
void CDraw::AddVertices(const PRIM_VERTEX* vertexBeginPtr, const PRIM_VERTEX* vertexEndPtr)
|
|
|
|
{
|
2019-10-03 18:06:59 -04:00
|
|
|
auto amount = vertexEndPtr - vertexBeginPtr;
|
2019-11-18 20:01:11 -05:00
|
|
|
if((m_passVertexEnd + amount) > MAX_VERTEX_COUNT)
|
2019-10-04 09:21:26 -04:00
|
|
|
{
|
2019-12-10 09:39:12 -05:00
|
|
|
m_frameCommandBuffer->Flush();
|
|
|
|
assert((m_passVertexEnd + amount) <= MAX_VERTEX_COUNT);
|
2019-10-04 09:21:26 -04:00
|
|
|
}
|
2021-04-12 11:42:42 -04:00
|
|
|
if(m_pipelineCaps.textureUseMemoryCopy)
|
|
|
|
{
|
2021-05-04 17:11:54 -04:00
|
|
|
//Check if sprite we are about to add overlaps with current region
|
|
|
|
//Some games use tiny sprites to do full screen effects that requires
|
|
|
|
//to keep a copy of RAM for texture sampling:
|
|
|
|
//- Metal Gear Solid 3
|
|
|
|
//- MK: Shaolin Monks
|
|
|
|
//- Tales of Legendia
|
|
|
|
const auto topLeftCorner = vertexBeginPtr;
|
|
|
|
const auto bottomRightCorner = vertexBeginPtr + 5;
|
|
|
|
CGsSpriteRect rect(topLeftCorner->x, topLeftCorner->y, bottomRightCorner->x, bottomRightCorner->y);
|
|
|
|
if(m_memoryCopyRegion.Intersects(rect))
|
|
|
|
{
|
|
|
|
FlushRenderPass();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_memoryCopyRegion.Insert(rect);
|
|
|
|
}
|
2021-04-12 11:42:42 -04:00
|
|
|
}
|
2021-05-04 17:11:54 -04:00
|
|
|
auto& frame = m_frames[m_frameCommandBuffer->GetCurrentFrame()];
|
|
|
|
memcpy(frame.vertexBufferPtr + m_passVertexEnd, vertexBeginPtr, amount * sizeof(PRIM_VERTEX));
|
|
|
|
m_passVertexEnd += amount;
|
2019-10-01 12:31:49 -04:00
|
|
|
}
|
|
|
|
|
2020-01-30 12:58:06 -05:00
|
|
|
void CDraw::PreFlushFrameCommandBuffer()
|
|
|
|
{
|
|
|
|
FlushRenderPass();
|
2019-12-10 09:39:12 -05:00
|
|
|
}
|
2019-11-18 20:01:11 -05:00
|
|
|
|
2019-12-10 09:39:12 -05:00
|
|
|
void CDraw::PostFlushFrameCommandBuffer()
|
|
|
|
{
|
2019-11-18 20:01:11 -05:00
|
|
|
m_passVertexStart = m_passVertexEnd = 0;
|
2019-10-01 12:31:49 -04:00
|
|
|
}
|
|
|
|
|
2021-09-14 17:24:42 -04:00
|
|
|
std::vector<VkVertexInputAttributeDescription> CDraw::GetVertexAttributes()
|
2019-11-16 11:27:23 -05:00
|
|
|
{
|
2019-10-01 12:31:49 -04:00
|
|
|
std::vector<VkVertexInputAttributeDescription> vertexAttributes;
|
|
|
|
|
|
|
|
{
|
2019-10-04 09:21:26 -04:00
|
|
|
VkVertexInputAttributeDescription vertexAttributeDesc = {};
|
|
|
|
vertexAttributeDesc.format = VK_FORMAT_R32G32_SFLOAT;
|
|
|
|
vertexAttributeDesc.offset = offsetof(PRIM_VERTEX, x);
|
2019-11-21 13:16:48 -05:00
|
|
|
vertexAttributeDesc.location = VERTEX_ATTRIB_LOCATION_POSITION;
|
2019-10-04 09:21:26 -04:00
|
|
|
vertexAttributes.push_back(vertexAttributeDesc);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
VkVertexInputAttributeDescription vertexAttributeDesc = {};
|
|
|
|
vertexAttributeDesc.format = VK_FORMAT_R32_UINT;
|
|
|
|
vertexAttributeDesc.offset = offsetof(PRIM_VERTEX, z);
|
2019-11-21 13:16:48 -05:00
|
|
|
vertexAttributeDesc.location = VERTEX_ATTRIB_LOCATION_DEPTH;
|
2019-10-04 09:21:26 -04:00
|
|
|
vertexAttributes.push_back(vertexAttributeDesc);
|
2019-10-01 12:31:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2019-10-04 09:21:26 -04:00
|
|
|
VkVertexInputAttributeDescription vertexAttributeDesc = {};
|
|
|
|
vertexAttributeDesc.format = VK_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
vertexAttributeDesc.offset = offsetof(PRIM_VERTEX, color);
|
2019-11-21 13:16:48 -05:00
|
|
|
vertexAttributeDesc.location = VERTEX_ATTRIB_LOCATION_COLOR;
|
|
|
|
vertexAttributes.push_back(vertexAttributeDesc);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
VkVertexInputAttributeDescription vertexAttributeDesc = {};
|
|
|
|
vertexAttributeDesc.format = VK_FORMAT_R32G32B32_SFLOAT;
|
|
|
|
vertexAttributeDesc.offset = offsetof(PRIM_VERTEX, s);
|
|
|
|
vertexAttributeDesc.location = VERTEX_ATTRIB_LOCATION_TEXCOORD;
|
2019-10-04 09:21:26 -04:00
|
|
|
vertexAttributes.push_back(vertexAttributeDesc);
|
2019-10-01 12:31:49 -04:00
|
|
|
}
|
|
|
|
|
2020-02-02 11:33:34 -05:00
|
|
|
{
|
|
|
|
VkVertexInputAttributeDescription vertexAttributeDesc = {};
|
|
|
|
vertexAttributeDesc.format = VK_FORMAT_R32_SFLOAT;
|
|
|
|
vertexAttributeDesc.offset = offsetof(PRIM_VERTEX, f);
|
|
|
|
vertexAttributeDesc.location = VERTEX_ATTRIB_LOCATION_FOG;
|
|
|
|
vertexAttributes.push_back(vertexAttributeDesc);
|
|
|
|
}
|
2021-09-16 13:55:50 -04:00
|
|
|
|
2021-09-14 17:24:42 -04:00
|
|
|
return vertexAttributes;
|
2019-10-01 12:31:49 -04:00
|
|
|
}
|
|
|
|
|
2021-07-14 14:07:46 -04:00
|
|
|
Framework::Vulkan::CShaderModule CDraw::CreateVertexShader(const PIPELINE_CAPS& caps)
|
2019-10-01 12:31:49 -04:00
|
|
|
{
|
|
|
|
using namespace Nuanceur;
|
2019-12-13 23:21:59 -05:00
|
|
|
|
2019-10-01 12:31:49 -04:00
|
|
|
auto b = CShaderBuilder();
|
2019-12-13 23:21:59 -05:00
|
|
|
|
2019-10-01 12:31:49 -04:00
|
|
|
{
|
2019-10-03 18:06:59 -04:00
|
|
|
//Vertex Inputs
|
2019-10-01 12:31:49 -04:00
|
|
|
auto inputPosition = CFloat4Lvalue(b.CreateInput(Nuanceur::SEMANTIC_POSITION));
|
2019-12-24 17:17:54 -05:00
|
|
|
auto inputDepth = CUint4Lvalue(b.CreateInputUint(Nuanceur::SEMANTIC_TEXCOORD, VERTEX_ATTRIB_LOCATION_DEPTH - 1));
|
2019-11-21 13:16:48 -05:00
|
|
|
auto inputColor = CFloat4Lvalue(b.CreateInput(Nuanceur::SEMANTIC_TEXCOORD, VERTEX_ATTRIB_LOCATION_COLOR - 1));
|
|
|
|
auto inputTexCoord = CFloat4Lvalue(b.CreateInput(Nuanceur::SEMANTIC_TEXCOORD, VERTEX_ATTRIB_LOCATION_TEXCOORD - 1));
|
2020-02-02 11:33:34 -05:00
|
|
|
auto inputFog = CFloat4Lvalue(b.CreateInput(Nuanceur::SEMANTIC_TEXCOORD, VERTEX_ATTRIB_LOCATION_FOG - 1));
|
2019-10-04 09:21:26 -04:00
|
|
|
|
2019-10-03 18:06:59 -04:00
|
|
|
//Outputs
|
2019-10-01 12:31:49 -04:00
|
|
|
auto outputPosition = CFloat4Lvalue(b.CreateOutput(Nuanceur::SEMANTIC_SYSTEM_POSITION));
|
2021-07-14 14:07:46 -04:00
|
|
|
auto outputPointSize = CFloatLvalue(b.CreateOutput(Nuanceur::SEMANTIC_SYSTEM_POINTSIZE));
|
2019-12-24 17:17:54 -05:00
|
|
|
auto outputDepth = CFloat4Lvalue(b.CreateOutput(Nuanceur::SEMANTIC_TEXCOORD, 1));
|
|
|
|
auto outputColor = CFloat4Lvalue(b.CreateOutput(Nuanceur::SEMANTIC_TEXCOORD, 2));
|
|
|
|
auto outputTexCoord = CFloat4Lvalue(b.CreateOutput(Nuanceur::SEMANTIC_TEXCOORD, 3));
|
2020-02-02 11:33:34 -05:00
|
|
|
auto outputFog = CFloat4Lvalue(b.CreateOutput(Nuanceur::SEMANTIC_TEXCOORD, 4));
|
2019-10-03 18:06:59 -04:00
|
|
|
|
2020-05-22 08:58:49 -04:00
|
|
|
auto position = ((inputPosition->xy() + NewFloat2(b, 0.5f, 0.5f)) * NewFloat2(b, 2.f / DRAW_AREA_SIZE, 2.f / DRAW_AREA_SIZE) + NewFloat2(b, -1, -1));
|
2019-10-03 18:06:59 -04:00
|
|
|
|
2020-01-18 21:05:52 -05:00
|
|
|
outputPosition = NewFloat4(position, NewFloat2(b, 0.f, 1.f));
|
2021-07-14 14:07:46 -04:00
|
|
|
if(caps.primitiveType == PIPELINE_PRIMITIVE_POINT)
|
|
|
|
{
|
|
|
|
outputPointSize = NewFloat(b, 1.0f);
|
|
|
|
}
|
2019-12-24 17:17:54 -05:00
|
|
|
outputDepth = ToFloat(inputDepth) / NewFloat4(b, DEPTH_MAX, DEPTH_MAX, DEPTH_MAX, DEPTH_MAX);
|
2019-10-04 09:21:26 -04:00
|
|
|
outputColor = inputColor->xyzw();
|
2019-11-21 13:16:48 -05:00
|
|
|
outputTexCoord = inputTexCoord->xyzw();
|
2020-02-02 11:33:34 -05:00
|
|
|
outputFog = inputFog->xyzw();
|
2019-10-01 12:31:49 -04:00
|
|
|
}
|
2019-12-13 23:21:59 -05:00
|
|
|
|
2019-10-01 12:31:49 -04:00
|
|
|
Framework::CMemStream shaderStream;
|
|
|
|
Nuanceur::CSpirvShaderGenerator::Generate(shaderStream, b, Nuanceur::CSpirvShaderGenerator::SHADER_TYPE_VERTEX);
|
|
|
|
shaderStream.Seek(0, Framework::STREAM_SEEK_SET);
|
2019-11-21 13:16:48 -05:00
|
|
|
return Framework::Vulkan::CShaderModule(m_context->device, shaderStream);
|
2019-10-01 12:31:49 -04:00
|
|
|
}
|