Renderer: Working compute implementation
This commit is contained in:
parent
4605eed0da
commit
fe8715f1fb
|
|
@ -12,7 +12,183 @@
|
|||
|
||||
NAZARA_REQUEST_DEDICATED_GPU()
|
||||
|
||||
const char shaderSource[] = R"(
|
||||
struct ComputePipeline
|
||||
{
|
||||
std::shared_ptr<Nz::RenderPipelineLayout> layout;
|
||||
std::shared_ptr<Nz::ComputePipeline> pipeline;
|
||||
};
|
||||
|
||||
struct SpriteRenderData
|
||||
{
|
||||
std::shared_ptr<Nz::RenderBuffer> vertexBuffer;
|
||||
std::shared_ptr<Nz::ShaderBinding> shaderBinding;
|
||||
};
|
||||
|
||||
struct SpriteRenderPipeline
|
||||
{
|
||||
std::shared_ptr<Nz::RenderPipeline> pipeline;
|
||||
std::shared_ptr<Nz::RenderPipelineLayout> pipelineLayout;
|
||||
|
||||
};
|
||||
|
||||
ComputePipeline BuildComputePipeline(Nz::RenderDevice& device);
|
||||
SpriteRenderPipeline BuildSpritePipeline(Nz::RenderDevice& device);
|
||||
SpriteRenderData BuildSpriteData(Nz::RenderDevice& device, const SpriteRenderPipeline& pipelineData, const Nz::Rectf& textureRect, const Nz::Vector2f& screenSize, const Nz::Texture& texture, const Nz::TextureSampler& sampler);
|
||||
|
||||
int main()
|
||||
{
|
||||
std::filesystem::path resourceDir = "assets/examples";
|
||||
if (!std::filesystem::is_directory(resourceDir) && std::filesystem::is_directory("../.." / resourceDir))
|
||||
resourceDir = "../.." / resourceDir;
|
||||
|
||||
Nz::Renderer::Config rendererConfig;
|
||||
std::cout << "Run using Vulkan? (y/n)" << std::endl;
|
||||
if (std::getchar() == 'y')
|
||||
rendererConfig.preferredAPI = Nz::RenderAPI::Vulkan;
|
||||
else
|
||||
rendererConfig.preferredAPI = Nz::RenderAPI::OpenGL;
|
||||
|
||||
Nz::Modules<Nz::Renderer> nazara(rendererConfig);
|
||||
|
||||
|
||||
Nz::RenderDeviceFeatures enabledFeatures;
|
||||
enabledFeatures.computeShaders = true;
|
||||
enabledFeatures.textureReadWrite = true;
|
||||
|
||||
std::shared_ptr<Nz::RenderDevice> device = Nz::Renderer::Instance()->InstanciateRenderDevice(0, enabledFeatures);
|
||||
|
||||
// Source texture
|
||||
Nz::TextureParams texParams;
|
||||
texParams.renderDevice = device;
|
||||
texParams.loadFormat = Nz::PixelFormat::RGBA8;
|
||||
texParams.usageFlags = Nz::TextureUsage::ShaderReadWrite | Nz::TextureUsage::ShaderSampling | Nz::TextureUsage::TransferDestination;
|
||||
|
||||
std::shared_ptr<Nz::Texture> texture = Nz::Texture::LoadFromFile(resourceDir / "lynix.jpg", texParams);
|
||||
|
||||
// Destination texture
|
||||
Nz::TextureInfo destTexParams = texture->GetTextureInfo();
|
||||
destTexParams.usageFlags = Nz::TextureUsage::ShaderReadWrite | Nz::TextureUsage::ShaderSampling;
|
||||
|
||||
std::shared_ptr<Nz::Texture> targetTexture = device->InstantiateTexture(destTexParams);
|
||||
std::shared_ptr<Nz::TextureSampler> textureSampler = device->InstantiateTextureSampler({});
|
||||
|
||||
// Compute part
|
||||
ComputePipeline computePipeline = BuildComputePipeline(*device);
|
||||
std::shared_ptr<Nz::ShaderBinding> computeBinding = computePipeline.layout->AllocateShaderBinding(0);
|
||||
computeBinding->Update({
|
||||
{
|
||||
0,
|
||||
Nz::ShaderBinding::TextureBinding {
|
||||
texture.get(),
|
||||
Nz::TextureAccess::ReadOnly
|
||||
}
|
||||
},
|
||||
{
|
||||
1,
|
||||
Nz::ShaderBinding::TextureBinding {
|
||||
targetTexture.get(),
|
||||
Nz::TextureAccess::WriteOnly
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
std::string windowTitle = "Compute test";
|
||||
|
||||
Nz::RenderWindow window;
|
||||
if (!window.Create(device, Nz::VideoMode(1280, 720, 32), windowTitle))
|
||||
{
|
||||
std::cout << "Failed to create Window" << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
Nz::Vector2ui windowSize = window.GetSize();
|
||||
constexpr float textureSize = 512.f;
|
||||
float margin = (windowSize.y - textureSize) * 0.5f;
|
||||
|
||||
SpriteRenderPipeline spriteRenderPipeline = BuildSpritePipeline(*device);
|
||||
SpriteRenderData spriteRenderData1 = BuildSpriteData(*device, spriteRenderPipeline, Nz::Rectf(margin, windowSize.y - margin - textureSize, textureSize, textureSize), Nz::Vector2f(windowSize), *texture, *textureSampler);
|
||||
SpriteRenderData spriteRenderData2 = BuildSpriteData(*device, spriteRenderPipeline, Nz::Rectf(windowSize.x - textureSize - margin, windowSize.y - margin - textureSize, textureSize, textureSize), Nz::Vector2f(windowSize), *targetTexture, *textureSampler);
|
||||
|
||||
Nz::Clock secondClock;
|
||||
unsigned int fps = 0;
|
||||
|
||||
while (window.IsOpen())
|
||||
{
|
||||
window.ProcessEvents();
|
||||
|
||||
Nz::RenderFrame frame = window.AcquireFrame();
|
||||
if (!frame)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
continue;
|
||||
}
|
||||
|
||||
const Nz::RenderTarget* windowRT = window.GetRenderTarget();
|
||||
frame.Execute([&](Nz::CommandBufferBuilder& builder)
|
||||
{
|
||||
builder.BeginDebugRegion("Compute part", Nz::Color::Blue);
|
||||
{
|
||||
builder.TextureBarrier(Nz::PipelineStage::FragmentShader, Nz::PipelineStage::ComputeShader, Nz::MemoryAccess::ShaderRead, Nz::MemoryAccess::ShaderRead, Nz::TextureLayout::ColorInput, Nz::TextureLayout::General, *texture);
|
||||
builder.TextureBarrier(Nz::PipelineStage::FragmentShader, Nz::PipelineStage::ComputeShader, Nz::MemoryAccess::ShaderRead, Nz::MemoryAccess::ShaderWrite, Nz::TextureLayout::Undefined, Nz::TextureLayout::General, *targetTexture);
|
||||
|
||||
builder.BindComputePipeline(*computePipeline.pipeline);
|
||||
builder.BindComputeShaderBinding(0, *computeBinding);
|
||||
builder.Dispatch(destTexParams.width / 32, destTexParams.height / 32, 1);
|
||||
|
||||
builder.TextureBarrier(Nz::PipelineStage::ComputeShader, Nz::PipelineStage::FragmentShader, Nz::MemoryAccess::ShaderRead, Nz::MemoryAccess::ShaderRead, Nz::TextureLayout::General, Nz::TextureLayout::ColorInput, *texture);
|
||||
builder.TextureBarrier(Nz::PipelineStage::ComputeShader, Nz::PipelineStage::FragmentShader, Nz::MemoryAccess::ShaderWrite, Nz::MemoryAccess::ShaderRead, Nz::TextureLayout::General, Nz::TextureLayout::ColorInput, *targetTexture);
|
||||
}
|
||||
builder.EndDebugRegion();
|
||||
|
||||
builder.BeginDebugRegion("Main window rendering", Nz::Color::Green);
|
||||
{
|
||||
Nz::Recti renderRect(0, 0, window.GetSize().x, window.GetSize().y);
|
||||
|
||||
Nz::CommandBufferBuilder::ClearValues clearValues[2];
|
||||
clearValues[0].color = Nz::Color::Gray;
|
||||
clearValues[1].depth = 1.f;
|
||||
clearValues[1].stencil = 0;
|
||||
|
||||
builder.BeginRenderPass(windowRT->GetFramebuffer(frame.GetFramebufferIndex()), windowRT->GetRenderPass(), renderRect, { clearValues[0], clearValues[1] });
|
||||
{
|
||||
builder.SetScissor(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) });
|
||||
builder.SetViewport(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) });
|
||||
|
||||
builder.BindRenderPipeline(*spriteRenderPipeline.pipeline);
|
||||
|
||||
builder.BindVertexBuffer(0, *spriteRenderData1.vertexBuffer);
|
||||
builder.BindRenderShaderBinding(0, *spriteRenderData1.shaderBinding);
|
||||
builder.Draw(4);
|
||||
|
||||
builder.BindVertexBuffer(0, *spriteRenderData2.vertexBuffer);
|
||||
builder.BindRenderShaderBinding(0, *spriteRenderData2.shaderBinding);
|
||||
builder.Draw(4);
|
||||
}
|
||||
builder.EndRenderPass();
|
||||
}
|
||||
builder.EndDebugRegion();
|
||||
|
||||
}, Nz::QueueType::Graphics);
|
||||
|
||||
frame.Present();
|
||||
|
||||
fps++;
|
||||
|
||||
if (secondClock.GetMilliseconds() >= 1000)
|
||||
{
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS");
|
||||
|
||||
fps = 0;
|
||||
|
||||
secondClock.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Edge detection, translated to NZSL from Sascha Willems compute shader example
|
||||
const char computeSource[] = R"(
|
||||
[nzsl_version("1.0")]
|
||||
module;
|
||||
|
||||
|
|
@ -28,26 +204,57 @@ struct Input
|
|||
}
|
||||
|
||||
[entry(compute)]
|
||||
[workgroup(16, 16, 1)]
|
||||
[workgroup(32, 32, 1)]
|
||||
fn main(input: Input)
|
||||
{
|
||||
let indices = vec2[i32](input.global_invocation_id.xy);
|
||||
let color = input_tex.Read(indices);
|
||||
output_tex.Write(indices, color);
|
||||
|
||||
// Fetch neighbouring texels
|
||||
let avg: array[f32, 9];
|
||||
|
||||
let n = 0;
|
||||
[unroll]
|
||||
for i in -1 -> 2
|
||||
{
|
||||
[unroll]
|
||||
for j in -1 -> 2
|
||||
{
|
||||
let rgb = input_tex.Read(indices + vec2[i32](i, j)).rgb;
|
||||
avg[n] = (rgb.r + rgb.b + rgb.b) / 3.0;
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let kernel: array[f32, 9];
|
||||
[unroll]
|
||||
for i in 0 -> 9
|
||||
{
|
||||
if (i == 4)
|
||||
kernel[i] = 1.0;
|
||||
else
|
||||
kernel[i] = -1.0/8.0;
|
||||
}
|
||||
|
||||
let res = vec4[f32](conv(kernel, avg, 0.1, 0.0).rrr, 1.0);
|
||||
output_tex.Write(indices, res);
|
||||
}
|
||||
|
||||
fn conv(kernel: array[f32, 9], data: array[f32, 9], denom: f32, offset: f32) -> f32
|
||||
{
|
||||
let res = 0.0;
|
||||
[unroll]
|
||||
for i in 0 -> 9
|
||||
res += kernel[i] * data[i];
|
||||
|
||||
return clamp(res/denom + offset, 0.0, 1.0);
|
||||
}
|
||||
)";
|
||||
|
||||
struct ComputePipeline
|
||||
{
|
||||
std::shared_ptr<Nz::RenderPipelineLayout> layout;
|
||||
std::shared_ptr<Nz::ComputePipeline> pipeline;
|
||||
};
|
||||
|
||||
ComputePipeline BuildComputePipeline(Nz::RenderDevice& device)
|
||||
{
|
||||
try
|
||||
{
|
||||
nzsl::Ast::ModulePtr shaderModule = nzsl::Parse(std::string_view(shaderSource, sizeof(shaderSource)));
|
||||
nzsl::Ast::ModulePtr shaderModule = nzsl::Parse(std::string_view(computeSource, sizeof(computeSource)));
|
||||
if (!shaderModule)
|
||||
{
|
||||
std::cout << "Failed to parse shader module" << std::endl;
|
||||
|
|
@ -103,30 +310,148 @@ ComputePipeline BuildComputePipeline(Nz::RenderDevice& device)
|
|||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
const char fragVertSource[] = R"(
|
||||
[nzsl_version("1.0")]
|
||||
module;
|
||||
|
||||
external
|
||||
{
|
||||
std::filesystem::path resourceDir = "assets/examples";
|
||||
if (!std::filesystem::is_directory(resourceDir) && std::filesystem::is_directory("../.." / resourceDir))
|
||||
resourceDir = "../.." / resourceDir;
|
||||
|
||||
Nz::Renderer::Config rendererConfig;
|
||||
std::cout << "Run using Vulkan? (y/n)" << std::endl;
|
||||
if (std::getchar() == 'y')
|
||||
rendererConfig.preferredAPI = Nz::RenderAPI::Vulkan;
|
||||
else
|
||||
rendererConfig.preferredAPI = Nz::RenderAPI::OpenGL;
|
||||
|
||||
Nz::Modules<Nz::Renderer> nazara(rendererConfig);
|
||||
|
||||
Nz::RenderDeviceFeatures enabledFeatures;
|
||||
enabledFeatures.computeShaders = true;
|
||||
enabledFeatures.textureRead = true;
|
||||
enabledFeatures.textureWrite = true;
|
||||
|
||||
std::shared_ptr<Nz::RenderDevice> device = Nz::Renderer::Instance()->InstanciateRenderDevice(0, enabledFeatures);
|
||||
|
||||
ComputePipeline result = BuildComputePipeline(*device);
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
[binding(0)] texture: sampler2D[f32]
|
||||
}
|
||||
|
||||
struct FragOut
|
||||
{
|
||||
[location(0)] color: vec4[f32]
|
||||
}
|
||||
|
||||
struct VertIn
|
||||
{
|
||||
[location(0)] pos: vec2[f32],
|
||||
[location(1)] uv: vec2[f32]
|
||||
}
|
||||
|
||||
struct VertOut
|
||||
{
|
||||
[location(0)] uv: vec2[f32],
|
||||
[builtin(position)] pos: vec4[f32]
|
||||
}
|
||||
|
||||
[entry(frag)]
|
||||
fn main(input: VertOut) -> FragOut
|
||||
{
|
||||
let output: FragOut;
|
||||
output.color = texture.Sample(input.uv);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
[entry(vert)]
|
||||
fn main(input: VertIn) -> VertOut
|
||||
{
|
||||
let output: VertOut;
|
||||
output.pos = vec4[f32](input.pos, 0.0, 1.0);
|
||||
output.uv = input.uv;
|
||||
return output;
|
||||
}
|
||||
)";
|
||||
|
||||
SpriteRenderPipeline BuildSpritePipeline(Nz::RenderDevice& device)
|
||||
{
|
||||
try
|
||||
{
|
||||
nzsl::Ast::ModulePtr shaderModule = nzsl::Parse(std::string_view(fragVertSource, sizeof(fragVertSource)));
|
||||
if (!shaderModule)
|
||||
{
|
||||
std::cout << "Failed to parse shader module" << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
nzsl::ShaderWriter::States states;
|
||||
states.optimize = true;
|
||||
|
||||
auto fragVertShader = device.InstantiateShaderModule(nzsl::ShaderStageType::Fragment | nzsl::ShaderStageType::Vertex, *shaderModule, states);
|
||||
if (!fragVertShader)
|
||||
{
|
||||
std::cout << "Failed to instantiate shader" << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
std::shared_ptr<Nz::VertexDeclaration> vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XY_UV);
|
||||
|
||||
SpriteRenderPipeline pipelineData;
|
||||
|
||||
Nz::RenderPipelineLayoutInfo pipelineLayoutInfo;
|
||||
pipelineLayoutInfo.bindings.push_back({
|
||||
0, 0, 1,
|
||||
Nz::ShaderBindingType::Sampler,
|
||||
nzsl::ShaderStageType::Fragment
|
||||
});
|
||||
|
||||
pipelineData.pipelineLayout = device.InstantiateRenderPipelineLayout(std::move(pipelineLayoutInfo));
|
||||
|
||||
Nz::RenderPipelineInfo pipelineInfo;
|
||||
pipelineInfo.primitiveMode = Nz::PrimitiveMode::TriangleStrip;
|
||||
pipelineInfo.pipelineLayout = pipelineData.pipelineLayout;
|
||||
pipelineInfo.shaderModules.push_back(fragVertShader);
|
||||
pipelineInfo.vertexBuffers.push_back({
|
||||
0, vertexDeclaration
|
||||
});
|
||||
|
||||
pipelineData.pipeline = device.InstantiateRenderPipeline(std::move(pipelineInfo));
|
||||
|
||||
return pipelineData;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
SpriteRenderData BuildSpriteData(Nz::RenderDevice& device, const SpriteRenderPipeline& pipelineData, const Nz::Rectf& textureRect, const Nz::Vector2f& screenSize, const Nz::Texture& texture, const Nz::TextureSampler& sampler)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto ToClipSpace = [&](Nz::Vector2f pos) -> Nz::Vector2f
|
||||
{
|
||||
// From 0..size to 0..1
|
||||
pos /= screenSize;
|
||||
// From 0..1 to -1..1
|
||||
pos *= 2.f;
|
||||
pos -= Nz::Vector2f(1.f, 1.f);
|
||||
// Reverse Y
|
||||
pos.y = -pos.y;
|
||||
return pos;
|
||||
};
|
||||
|
||||
std::array<Nz::VertexStruct_XY_UV, 4> pos;
|
||||
pos[0].position = ToClipSpace(textureRect.GetCorner(Nz::RectCorner::LeftBottom));
|
||||
pos[0].uv = Nz::Vector2f(0.f, 0.f);
|
||||
pos[1].position = ToClipSpace(textureRect.GetCorner(Nz::RectCorner::LeftTop));
|
||||
pos[1].uv = Nz::Vector2f(0.f, 1.f);
|
||||
pos[2].position = ToClipSpace(textureRect.GetCorner(Nz::RectCorner::RightBottom));
|
||||
pos[2].uv = Nz::Vector2f(1.f, 0.f);
|
||||
pos[3].position = ToClipSpace(textureRect.GetCorner(Nz::RectCorner::RightTop));
|
||||
pos[3].uv = Nz::Vector2f(1.f, 1.f);
|
||||
|
||||
SpriteRenderData renderData;
|
||||
renderData.vertexBuffer = device.InstantiateBuffer(Nz::BufferType::Vertex, 4 * 4 * sizeof(float), Nz::BufferUsage::DeviceLocal, pos.data());
|
||||
|
||||
renderData.shaderBinding = pipelineData.pipelineLayout->AllocateShaderBinding(0);
|
||||
renderData.shaderBinding->Update({
|
||||
{
|
||||
0,
|
||||
Nz::ShaderBinding::SampledTextureBinding {
|
||||
&texture, &sampler
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return renderData;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -831,11 +831,11 @@ int main()
|
|||
builder.BindIndexBuffer(*coneMeshGfx->GetIndexBuffer(0).get(), Nz::IndexType::U16);
|
||||
builder.BindVertexBuffer(0, *coneMeshGfx->GetVertexBuffer(0).get());
|
||||
|
||||
builder.BindShaderBinding(0, *gbufferShaderBinding);
|
||||
builder.BindRenderShaderBinding(0, *gbufferShaderBinding);
|
||||
|
||||
for (std::size_t i = 0; i < spotLights.size(); ++i)
|
||||
{
|
||||
builder.BindShaderBinding(1, *lightingShaderBindings[i]);
|
||||
builder.BindRenderShaderBinding(1, *lightingShaderBindings[i]);
|
||||
|
||||
builder.BindRenderPipeline(*stencilPipeline);
|
||||
builder.DrawIndexed(coneMeshGfx->GetIndexCount(0));
|
||||
|
|
@ -858,7 +858,7 @@ int main()
|
|||
builder.SetScissor(env.renderRect);
|
||||
builder.SetViewport(env.renderRect);
|
||||
|
||||
builder.BindShaderBinding(0, *skyboxShaderBinding);
|
||||
builder.BindRenderShaderBinding(0, *skyboxShaderBinding);
|
||||
|
||||
builder.BindIndexBuffer(*cubeMeshGfx->GetIndexBuffer(0), Nz::IndexType::U16);
|
||||
builder.BindVertexBuffer(0, *cubeMeshGfx->GetVertexBuffer(0));
|
||||
|
|
@ -930,7 +930,7 @@ int main()
|
|||
builder.SetScissor(env.renderRect);
|
||||
builder.SetViewport(env.renderRect);
|
||||
|
||||
builder.BindShaderBinding(0, *godRaysShaderBinding);
|
||||
builder.BindRenderShaderBinding(0, *godRaysShaderBinding);
|
||||
|
||||
builder.BindRenderPipeline(*godraysPipeline);
|
||||
|
||||
|
|
@ -946,7 +946,7 @@ int main()
|
|||
builder.SetScissor(env.renderRect);
|
||||
builder.SetViewport(env.renderRect);
|
||||
|
||||
builder.BindShaderBinding(0, *bloomBrightShaderBinding);
|
||||
builder.BindRenderShaderBinding(0, *bloomBrightShaderBinding);
|
||||
|
||||
builder.BindRenderPipeline(*bloomBrightPipeline);
|
||||
|
||||
|
|
@ -969,7 +969,7 @@ int main()
|
|||
builder.SetScissor(env.renderRect);
|
||||
builder.SetViewport(env.renderRect);
|
||||
|
||||
builder.BindShaderBinding(0, *gaussianBlurShaderBinding[i * 2 + 0]);
|
||||
builder.BindRenderShaderBinding(0, *gaussianBlurShaderBinding[i * 2 + 0]);
|
||||
builder.BindRenderPipeline(*gaussianBlurPipeline);
|
||||
|
||||
builder.Draw(3);
|
||||
|
|
@ -989,7 +989,7 @@ int main()
|
|||
builder.SetScissor(env.renderRect);
|
||||
builder.SetViewport(env.renderRect);
|
||||
|
||||
builder.BindShaderBinding(0, *gaussianBlurShaderBinding[i * 2 + 1]);
|
||||
builder.BindRenderShaderBinding(0, *gaussianBlurShaderBinding[i * 2 + 1]);
|
||||
builder.BindRenderPipeline(*gaussianBlurPipeline);
|
||||
|
||||
builder.Draw(3);
|
||||
|
|
@ -1014,12 +1014,12 @@ int main()
|
|||
builder.BindRenderPipeline(*bloomBlendPipeline);
|
||||
for (std::size_t i = 0; i < BloomSubdivisionCount; ++i)
|
||||
{
|
||||
builder.BindShaderBinding(0, *bloomBlendShaderBinding[i]);
|
||||
builder.BindRenderShaderBinding(0, *bloomBlendShaderBinding[i]);
|
||||
builder.Draw(3);
|
||||
}
|
||||
|
||||
// God rays
|
||||
builder.BindShaderBinding(0, *godRaysBlitShaderBinding);
|
||||
builder.BindRenderShaderBinding(0, *godRaysBlitShaderBinding);
|
||||
builder.Draw(3);
|
||||
});
|
||||
|
||||
|
|
@ -1045,7 +1045,7 @@ int main()
|
|||
builder.SetScissor(env.renderRect);
|
||||
builder.SetViewport(env.renderRect);
|
||||
|
||||
builder.BindShaderBinding(0, *toneMappingShaderBinding);
|
||||
builder.BindRenderShaderBinding(0, *toneMappingShaderBinding);
|
||||
builder.BindRenderPipeline(*toneMappingPipeline);
|
||||
|
||||
builder.Draw(3);
|
||||
|
|
@ -1547,7 +1547,7 @@ int main()
|
|||
builder.SetScissor(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) });
|
||||
builder.SetViewport(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) });
|
||||
|
||||
builder.BindShaderBinding(0, *finalBlitBinding);
|
||||
builder.BindRenderShaderBinding(0, *finalBlitBinding);
|
||||
builder.BindRenderPipeline(*fullscreenPipeline);
|
||||
|
||||
builder.Draw(3);
|
||||
|
|
|
|||
|
|
@ -391,8 +391,8 @@ int main()
|
|||
builder.BindIndexBuffer(*renderBufferIB, Nz::IndexType::U16);
|
||||
builder.BindRenderPipeline(*pipeline);
|
||||
builder.BindVertexBuffer(0, *renderBufferVB);
|
||||
builder.BindShaderBinding(0, *viewerShaderBinding);
|
||||
builder.BindShaderBinding(1, *textureShaderBinding);
|
||||
builder.BindRenderShaderBinding(0, *viewerShaderBinding);
|
||||
builder.BindRenderShaderBinding(1, *textureShaderBinding);
|
||||
|
||||
builder.SetScissor(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) });
|
||||
builder.SetViewport(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) });
|
||||
|
|
|
|||
|
|
@ -40,9 +40,10 @@ namespace Nz
|
|||
inline void BeginDebugRegion(const std::string_view& regionName, const Color& color);
|
||||
|
||||
inline void BindComputePipeline(const OpenGLComputePipeline* pipeline);
|
||||
inline void BindComputeShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding);
|
||||
inline void BindIndexBuffer(GLuint indexBuffer, IndexType indexType, UInt64 offset = 0);
|
||||
inline void BindRenderPipeline(const OpenGLRenderPipeline* pipeline);
|
||||
inline void BindShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding);
|
||||
inline void BindRenderShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding);
|
||||
inline void BindVertexBuffer(UInt32 binding, GLuint vertexBuffer, UInt64 offset = 0);
|
||||
inline void BlitTexture(const OpenGLTexture& source, const Boxui& sourceBox, const OpenGLTexture& target, const Boxui& targetBox, SamplerFilter filter = SamplerFilter::Nearest);
|
||||
|
||||
|
|
@ -63,6 +64,8 @@ namespace Nz
|
|||
inline std::size_t GetPoolIndex() const;
|
||||
inline const OpenGLCommandPool& GetOwner() const;
|
||||
|
||||
inline void InsertMemoryBarrier(GLbitfield barriers);
|
||||
|
||||
inline void SetFramebuffer(const OpenGLFramebuffer& framebuffer, const OpenGLRenderPass& renderPass, const CommandBufferBuilder::ClearValues* clearValues, std::size_t clearValueCount);
|
||||
inline void SetScissor(const Recti& scissorRegion);
|
||||
inline void SetViewport(const Recti& viewportRegion);
|
||||
|
|
@ -74,7 +77,9 @@ namespace Nz
|
|||
|
||||
private:
|
||||
struct DrawStates;
|
||||
struct ShaderBindings;
|
||||
|
||||
void ApplyBindings(const GL::Context& context, const ShaderBindings& bindings);
|
||||
void ApplyStates(const GL::Context& context, const DrawStates& states);
|
||||
void Release() override;
|
||||
|
||||
|
|
@ -123,9 +128,15 @@ namespace Nz
|
|||
UInt64 targetOffset;
|
||||
};
|
||||
|
||||
struct ShaderBindings
|
||||
{
|
||||
std::vector<std::pair<const OpenGLRenderPipelineLayout*, const OpenGLShaderBinding*>> shaderBindings;
|
||||
};
|
||||
|
||||
struct DispatchData
|
||||
{
|
||||
ComputeStates states;
|
||||
ShaderBindings bindings;
|
||||
UInt32 numGroupsX;
|
||||
UInt32 numGroupsY;
|
||||
UInt32 numGroupsZ;
|
||||
|
|
@ -145,7 +156,6 @@ namespace Nz
|
|||
IndexType indexBufferType;
|
||||
std::optional<Recti> scissorRegion;
|
||||
std::optional<Recti> viewportRegion;
|
||||
std::vector<std::pair<const OpenGLRenderPipelineLayout*, const OpenGLShaderBinding*>> shaderBindings;
|
||||
std::vector<VertexBuffer> vertexBuffers;
|
||||
bool shouldFlipY = false;
|
||||
};
|
||||
|
|
@ -153,6 +163,7 @@ namespace Nz
|
|||
struct DrawData
|
||||
{
|
||||
DrawStates states;
|
||||
ShaderBindings bindings;
|
||||
UInt32 firstInstance;
|
||||
UInt32 firstVertex;
|
||||
UInt32 instanceCount;
|
||||
|
|
@ -162,6 +173,7 @@ namespace Nz
|
|||
struct DrawIndexedData
|
||||
{
|
||||
DrawStates states;
|
||||
ShaderBindings bindings;
|
||||
UInt32 firstIndex;
|
||||
UInt32 firstInstance;
|
||||
UInt32 indexCount;
|
||||
|
|
@ -172,6 +184,11 @@ namespace Nz
|
|||
{
|
||||
};
|
||||
|
||||
struct MemoryBarrier
|
||||
{
|
||||
GLbitfield barriers;
|
||||
};
|
||||
|
||||
struct SetFrameBufferData
|
||||
{
|
||||
std::array<CommandBufferBuilder::ClearValues, 16> clearValues; //< TODO: Remove hard limit?
|
||||
|
|
@ -189,11 +206,15 @@ namespace Nz
|
|||
DrawData,
|
||||
DrawIndexedData,
|
||||
EndDebugRegionData,
|
||||
MemoryBarrier,
|
||||
SetFrameBufferData
|
||||
>;
|
||||
|
||||
ComputeStates m_currentComputeStates;
|
||||
DrawStates m_currentDrawStates;
|
||||
ShaderBindings m_currentComputeShaderBindings;
|
||||
ShaderBindings m_currentGraphicsShaderBindings;
|
||||
std::optional<MemoryBarrier> m_pendingBarrier;
|
||||
std::size_t m_bindingIndex;
|
||||
std::size_t m_maxColorBufferCount;
|
||||
std::size_t m_poolIndex;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,14 @@ namespace Nz
|
|||
m_currentComputeStates.pipeline = pipeline;
|
||||
}
|
||||
|
||||
inline void OpenGLCommandBuffer::BindComputeShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding)
|
||||
{
|
||||
if (set >= m_currentComputeShaderBindings.shaderBindings.size())
|
||||
m_currentComputeShaderBindings.shaderBindings.resize(set + 1);
|
||||
|
||||
m_currentComputeShaderBindings.shaderBindings[set] = std::make_pair(&pipelineLayout, binding);
|
||||
}
|
||||
|
||||
inline void OpenGLCommandBuffer::BindIndexBuffer(GLuint indexBuffer, IndexType indexType, UInt64 offset)
|
||||
{
|
||||
m_currentDrawStates.indexBuffer = indexBuffer;
|
||||
|
|
@ -50,12 +58,12 @@ namespace Nz
|
|||
m_currentDrawStates.pipeline = pipeline;
|
||||
}
|
||||
|
||||
inline void OpenGLCommandBuffer::BindShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding)
|
||||
inline void OpenGLCommandBuffer::BindRenderShaderBinding(const OpenGLRenderPipelineLayout& pipelineLayout, UInt32 set, const OpenGLShaderBinding* binding)
|
||||
{
|
||||
if (set >= m_currentDrawStates.shaderBindings.size())
|
||||
m_currentDrawStates.shaderBindings.resize(set + 1);
|
||||
if (set >= m_currentGraphicsShaderBindings.shaderBindings.size())
|
||||
m_currentGraphicsShaderBindings.shaderBindings.resize(set + 1);
|
||||
|
||||
m_currentDrawStates.shaderBindings[set] = std::make_pair(&pipelineLayout, binding);
|
||||
m_currentGraphicsShaderBindings.shaderBindings[set] = std::make_pair(&pipelineLayout, binding);
|
||||
}
|
||||
|
||||
inline void OpenGLCommandBuffer::BindVertexBuffer(UInt32 binding, GLuint vertexBuffer, UInt64 offset)
|
||||
|
|
@ -124,6 +132,7 @@ namespace Nz
|
|||
throw std::runtime_error("no pipeline bound");
|
||||
|
||||
DispatchData dispatch;
|
||||
dispatch.bindings = m_currentComputeShaderBindings;
|
||||
dispatch.states = m_currentComputeStates;
|
||||
dispatch.numGroupsX = numGroupsX;
|
||||
dispatch.numGroupsY = numGroupsY;
|
||||
|
|
@ -138,6 +147,7 @@ namespace Nz
|
|||
throw std::runtime_error("no pipeline bound");
|
||||
|
||||
DrawData draw;
|
||||
draw.bindings = m_currentGraphicsShaderBindings;
|
||||
draw.states = m_currentDrawStates;
|
||||
draw.firstInstance = firstInstance;
|
||||
draw.firstVertex = firstVertex;
|
||||
|
|
@ -153,6 +163,7 @@ namespace Nz
|
|||
throw std::runtime_error("no pipeline bound");
|
||||
|
||||
DrawIndexedData draw;
|
||||
draw.bindings = m_currentGraphicsShaderBindings;
|
||||
draw.states = m_currentDrawStates;
|
||||
draw.firstIndex = firstIndex;
|
||||
draw.firstInstance = firstInstance;
|
||||
|
|
@ -183,6 +194,23 @@ namespace Nz
|
|||
return *m_owner;
|
||||
}
|
||||
|
||||
inline void OpenGLCommandBuffer::InsertMemoryBarrier(GLbitfield barriers)
|
||||
{
|
||||
// Merge with previous barrier, if any (may happen because memory barriers are not relative to a texture with OpenGL)
|
||||
if (!m_commands.empty() && std::holds_alternative<MemoryBarrier>(m_commands.back()))
|
||||
{
|
||||
MemoryBarrier& memBarrier = std::get<MemoryBarrier>(m_commands.back());
|
||||
memBarrier.barriers |= barriers;
|
||||
}
|
||||
else
|
||||
{
|
||||
MemoryBarrier memBarrier;
|
||||
memBarrier.barriers = barriers;
|
||||
|
||||
m_commands.emplace_back(std::move(memBarrier));
|
||||
}
|
||||
}
|
||||
|
||||
inline void OpenGLCommandBuffer::SetFramebuffer(const OpenGLFramebuffer& framebuffer, const OpenGLRenderPass& renderPass, const CommandBufferBuilder::ClearValues* clearValues, std::size_t clearValueCount)
|
||||
{
|
||||
m_maxColorBufferCount = std::max(m_maxColorBufferCount, framebuffer.GetColorBufferCount());
|
||||
|
|
|
|||
|
|
@ -28,10 +28,12 @@ namespace Nz
|
|||
void BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, const Recti& renderRect, const ClearValues* clearValues, std::size_t clearValueCount) override;
|
||||
|
||||
void BindComputePipeline(const ComputePipeline& pipeline) override;
|
||||
void BindComputeShaderBinding(UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindComputeShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset = 0) override;
|
||||
void BindRenderPipeline(const RenderPipeline& pipeline) override;
|
||||
void BindShaderBinding(UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindRenderShaderBinding(UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindRenderShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindVertexBuffer(UInt32 binding, const RenderBuffer& vertexBuffer, UInt64 offset = 0) override;
|
||||
|
||||
void BlitTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout fromLayout, const Texture& toTexture, const Boxui& toBox, TextureLayout toLayout, SamplerFilter filter) override;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_OPENGLRENDERER_API OpenGLTexture : public Texture
|
||||
class NAZARA_OPENGLRENDERER_API OpenGLTexture final : public Texture
|
||||
{
|
||||
public:
|
||||
OpenGLTexture(OpenGLDevice& device, const TextureInfo& textureInfo);
|
||||
|
|
@ -28,13 +28,14 @@ namespace Nz
|
|||
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
|
||||
std::shared_ptr<Texture> CreateView(const TextureViewInfo& viewInfo) override;
|
||||
|
||||
PixelFormat GetFormat() const override;
|
||||
UInt8 GetLevelCount() const override;
|
||||
OpenGLTexture* GetParentTexture() const override;
|
||||
Vector3ui GetSize(UInt8 level = 0) const override;
|
||||
inline PixelFormat GetFormat() const override;
|
||||
inline UInt8 GetLevelCount() const override;
|
||||
inline OpenGLTexture* GetParentTexture() const override;
|
||||
inline Vector3ui GetSize(UInt8 level = 0) const override;
|
||||
inline const GL::Texture& GetTexture() const;
|
||||
inline const TextureInfo& GetTextureInfo() const override;
|
||||
inline const TextureViewInfo& GetTextureViewInfo() const;
|
||||
ImageType GetType() const override;
|
||||
inline ImageType GetType() const override;
|
||||
|
||||
inline bool RequiresTextureViewEmulation() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,17 +8,47 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline PixelFormat OpenGLTexture::GetFormat() const
|
||||
{
|
||||
return m_textureInfo.pixelFormat;
|
||||
}
|
||||
|
||||
inline UInt8 OpenGLTexture::GetLevelCount() const
|
||||
{
|
||||
return m_textureInfo.levelCount;
|
||||
}
|
||||
|
||||
inline OpenGLTexture* OpenGLTexture::GetParentTexture() const
|
||||
{
|
||||
return m_parentTexture.get();
|
||||
}
|
||||
|
||||
inline Vector3ui OpenGLTexture::GetSize(UInt8 level) const
|
||||
{
|
||||
return Vector3ui(GetLevelSize(m_textureInfo.width, level), GetLevelSize(m_textureInfo.height, level), GetLevelSize(m_textureInfo.depth, level));
|
||||
}
|
||||
|
||||
inline const GL::Texture& OpenGLTexture::GetTexture() const
|
||||
{
|
||||
return m_texture;
|
||||
}
|
||||
|
||||
inline const TextureInfo& OpenGLTexture::GetTextureInfo() const
|
||||
{
|
||||
return m_textureInfo;
|
||||
}
|
||||
|
||||
inline const TextureViewInfo& OpenGLTexture::GetTextureViewInfo() const
|
||||
{
|
||||
assert(m_viewInfo);
|
||||
return *m_viewInfo;
|
||||
}
|
||||
|
||||
inline ImageType OpenGLTexture::GetType() const
|
||||
{
|
||||
return m_textureInfo.type;
|
||||
}
|
||||
|
||||
inline bool OpenGLTexture::RequiresTextureViewEmulation() const
|
||||
{
|
||||
return m_viewInfo.has_value() && !m_texture.IsValid();
|
||||
|
|
|
|||
|
|
@ -44,10 +44,12 @@ namespace Nz
|
|||
inline void BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, const Recti& renderRect, std::initializer_list<ClearValues> clearValues);
|
||||
|
||||
virtual void BindComputePipeline(const ComputePipeline& pipeline) = 0;
|
||||
virtual void BindComputeShaderBinding(UInt32 set, const ShaderBinding& binding) = 0;
|
||||
virtual void BindComputeShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) = 0;
|
||||
virtual void BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset = 0) = 0;
|
||||
virtual void BindRenderPipeline(const RenderPipeline& pipeline) = 0;
|
||||
virtual void BindShaderBinding(UInt32 set, const ShaderBinding& binding) = 0;
|
||||
virtual void BindShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) = 0;
|
||||
virtual void BindRenderShaderBinding(UInt32 set, const ShaderBinding& binding) = 0;
|
||||
virtual void BindRenderShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) = 0;
|
||||
virtual void BindVertexBuffer(UInt32 binding, const RenderBuffer& vertexBuffer, UInt64 offset = 0) = 0;
|
||||
|
||||
virtual void BlitTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout fromLayout, const Texture& toTexture, const Boxui& toBox, TextureLayout toLayout, SamplerFilter filter) = 0;
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ namespace Nz
|
|||
TopOfPipe,
|
||||
|
||||
ColorOutput,
|
||||
ComputeShader,
|
||||
DrawIndirect,
|
||||
FragmentShader,
|
||||
FragmentTestsEarly,
|
||||
|
|
@ -196,6 +197,7 @@ namespace Nz
|
|||
ColorOutput,
|
||||
DepthStencilReadOnly,
|
||||
DepthStencilReadWrite,
|
||||
General,
|
||||
Present,
|
||||
TransferSource,
|
||||
TransferDestination,
|
||||
|
|
|
|||
|
|
@ -21,9 +21,8 @@ namespace Nz
|
|||
bool depthClamping = false;
|
||||
bool nonSolidFaceFilling = false;
|
||||
bool storageBuffers = false;
|
||||
bool textureRead = false;
|
||||
bool textureReadWithoutFormat = false;
|
||||
bool textureWrite = false;
|
||||
bool textureReadWrite = false;
|
||||
bool textureWriteWithoutFormat = false;
|
||||
bool unrestrictedTextureViews = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -68,11 +68,8 @@ namespace Nz
|
|||
virtual bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos = Vector3ui::Zero()) = 0;
|
||||
virtual std::shared_ptr<Texture> CreateView(const TextureViewInfo& viewInfo) = 0;
|
||||
|
||||
virtual PixelFormat GetFormat() const = 0;
|
||||
virtual UInt8 GetLevelCount() const = 0;
|
||||
virtual Texture* GetParentTexture() const = 0;
|
||||
virtual Vector3ui GetSize(UInt8 level = 0) const = 0;
|
||||
virtual ImageType GetType() const = 0;
|
||||
virtual const TextureInfo& GetTextureInfo() const = 0;
|
||||
|
||||
virtual void UpdateDebugName(std::string_view name) = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ namespace Nz
|
|||
{
|
||||
case PipelineStage::TopOfPipe: return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
case PipelineStage::ColorOutput: return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
case PipelineStage::ComputeShader: return VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
case PipelineStage::DrawIndirect: return VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
|
||||
case PipelineStage::FragmentShader: return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
case PipelineStage::FragmentTestsEarly: return VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||
|
|
@ -444,6 +445,7 @@ namespace Nz
|
|||
case TextureLayout::ColorOutput: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
case TextureLayout::DepthStencilReadOnly: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||
case TextureLayout::DepthStencilReadWrite: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
case TextureLayout::General: return VK_IMAGE_LAYOUT_GENERAL;
|
||||
case TextureLayout::Present: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
case TextureLayout::TransferSource: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
case TextureLayout::TransferDestination: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
|
|
|
|||
|
|
@ -28,10 +28,12 @@ namespace Nz
|
|||
void BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, const Recti& renderRect, const ClearValues* clearValues, std::size_t clearValueCount) override;
|
||||
|
||||
void BindComputePipeline(const ComputePipeline& pipeline) override;
|
||||
void BindComputeShaderBinding(UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindComputeShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset = 0) override;
|
||||
void BindRenderPipeline(const RenderPipeline& pipeline) override;
|
||||
void BindShaderBinding(UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindRenderShaderBinding(UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindRenderShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding) override;
|
||||
void BindVertexBuffer(UInt32 binding, const RenderBuffer& vertexBuffer, UInt64 offset = 0) override;
|
||||
|
||||
void BlitTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout fromLayout, const Texture& toTexture, const Boxui& toBox, TextureLayout toLayout, SamplerFilter filter) override;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_VULKANRENDERER_API VulkanTexture : public Texture
|
||||
class NAZARA_VULKANRENDERER_API VulkanTexture final : public Texture
|
||||
{
|
||||
public:
|
||||
VulkanTexture(Vk::Device& device, const TextureInfo& textureInfo);
|
||||
|
|
@ -28,14 +28,15 @@ namespace Nz
|
|||
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
|
||||
std::shared_ptr<Texture> CreateView(const TextureViewInfo& viewInfo) override;
|
||||
|
||||
PixelFormat GetFormat() const override;
|
||||
inline PixelFormat GetFormat() const override;
|
||||
inline VkImage GetImage() const;
|
||||
inline VkImageView GetImageView() const;
|
||||
UInt8 GetLevelCount() const override;
|
||||
VulkanTexture* GetParentTexture() const override;
|
||||
Vector3ui GetSize(UInt8 level = 0) const override;
|
||||
inline UInt8 GetLevelCount() const override;
|
||||
inline VulkanTexture* GetParentTexture() const override;
|
||||
inline Vector3ui GetSize(UInt8 level = 0) const override;
|
||||
inline const VkImageSubresourceRange& GetSubresourceRange() const;
|
||||
ImageType GetType() const override;
|
||||
inline const TextureInfo& GetTextureInfo() const override;
|
||||
inline ImageType GetType() const override;
|
||||
|
||||
using Texture::Update;
|
||||
bool Update(const void* ptr, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level) override;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline PixelFormat VulkanTexture::GetFormat() const
|
||||
{
|
||||
return m_textureInfo.pixelFormat;
|
||||
}
|
||||
|
||||
inline VkImage VulkanTexture::GetImage() const
|
||||
{
|
||||
return m_image;
|
||||
|
|
@ -17,10 +22,35 @@ namespace Nz
|
|||
return m_imageView;
|
||||
}
|
||||
|
||||
inline UInt8 VulkanTexture::GetLevelCount() const
|
||||
{
|
||||
return m_textureInfo.levelCount;
|
||||
}
|
||||
|
||||
inline VulkanTexture* VulkanTexture::GetParentTexture() const
|
||||
{
|
||||
return m_parentTexture.get();
|
||||
}
|
||||
|
||||
inline Vector3ui VulkanTexture::GetSize(UInt8 level) const
|
||||
{
|
||||
return Vector3ui(GetLevelSize(m_textureInfo.width, level), GetLevelSize(m_textureInfo.height, level), GetLevelSize(m_textureInfo.depth, level));
|
||||
}
|
||||
|
||||
inline const VkImageSubresourceRange& VulkanTexture::GetSubresourceRange() const
|
||||
{
|
||||
return m_imageRange;
|
||||
}
|
||||
|
||||
inline const TextureInfo& VulkanTexture::GetTextureInfo() const
|
||||
{
|
||||
return m_textureInfo;
|
||||
}
|
||||
|
||||
inline ImageType VulkanTexture::GetType() const
|
||||
{
|
||||
return m_textureInfo.type;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/VulkanRenderer/DebugOff.hpp>
|
||||
|
|
|
|||
|
|
@ -458,7 +458,7 @@ namespace Nz
|
|||
builder.SetViewport(renderRegion);
|
||||
builder.BindRenderPipeline(*graphics->GetBlitPipeline(false));
|
||||
|
||||
builder.BindShaderBinding(0, *data.blitShaderBinding);
|
||||
builder.BindRenderShaderBinding(0, *data.blitShaderBinding);
|
||||
builder.Draw(3);
|
||||
}
|
||||
builder.EndDebugRegion();
|
||||
|
|
@ -652,7 +652,7 @@ namespace Nz
|
|||
{
|
||||
const ShaderBindingPtr& blitShaderBinding = viewerData->blitShaderBinding;
|
||||
|
||||
builder.BindShaderBinding(0, *blitShaderBinding);
|
||||
builder.BindRenderShaderBinding(0, *blitShaderBinding);
|
||||
builder.Draw(3);
|
||||
|
||||
if (first)
|
||||
|
|
|
|||
|
|
@ -112,9 +112,8 @@ namespace Nz
|
|||
enabledFeatures.depthClamping = !config.forceDisableFeatures.depthClamping && renderDeviceInfo[bestRenderDeviceIndex].features.depthClamping;
|
||||
enabledFeatures.nonSolidFaceFilling = !config.forceDisableFeatures.nonSolidFaceFilling && renderDeviceInfo[bestRenderDeviceIndex].features.nonSolidFaceFilling;
|
||||
enabledFeatures.storageBuffers = !config.forceDisableFeatures.storageBuffers && renderDeviceInfo[bestRenderDeviceIndex].features.storageBuffers;
|
||||
enabledFeatures.textureRead = !config.forceDisableFeatures.textureRead && renderDeviceInfo[bestRenderDeviceIndex].features.textureRead;
|
||||
enabledFeatures.textureReadWithoutFormat = !config.forceDisableFeatures.textureReadWithoutFormat && renderDeviceInfo[bestRenderDeviceIndex].features.textureReadWithoutFormat;
|
||||
enabledFeatures.textureWrite = !config.forceDisableFeatures.textureWrite && renderDeviceInfo[bestRenderDeviceIndex].features.textureWrite;
|
||||
enabledFeatures.textureReadWrite = !config.forceDisableFeatures.textureReadWrite && renderDeviceInfo[bestRenderDeviceIndex].features.textureReadWrite;
|
||||
enabledFeatures.textureWriteWithoutFormat = !config.forceDisableFeatures.textureWriteWithoutFormat && renderDeviceInfo[bestRenderDeviceIndex].features.textureWriteWithoutFormat;
|
||||
enabledFeatures.unrestrictedTextureViews = !config.forceDisableFeatures.unrestrictedTextureViews && renderDeviceInfo[bestRenderDeviceIndex].features.unrestrictedTextureViews;
|
||||
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ namespace Nz
|
|||
|
||||
if (currentShaderBinding != drawData.shaderBinding)
|
||||
{
|
||||
commandBuffer.BindShaderBinding(0, *drawData.shaderBinding);
|
||||
commandBuffer.BindRenderShaderBinding(0, *drawData.shaderBinding);
|
||||
currentShaderBinding = drawData.shaderBinding;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ namespace Nz
|
|||
|
||||
if (currentShaderBinding != drawData.shaderBinding)
|
||||
{
|
||||
commandBuffer.BindShaderBinding(0, *drawData.shaderBinding);
|
||||
commandBuffer.BindRenderShaderBinding(0, *drawData.shaderBinding);
|
||||
currentShaderBinding = drawData.shaderBinding;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,11 +100,13 @@ namespace Nz
|
|||
throw std::runtime_error("compute shaders are not supported on this device");
|
||||
|
||||
command.states.pipeline->Apply(*context);
|
||||
ApplyBindings(*context, command.bindings);
|
||||
context->glDispatchCompute(command.numGroupsX, command.numGroupsY, command.numGroupsZ);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, DrawData>)
|
||||
{
|
||||
ApplyStates(*context, command.states);
|
||||
ApplyBindings(*context, command.bindings);
|
||||
context->glDrawArraysInstanced(ToOpenGL(command.states.pipeline->GetPipelineInfo().primitiveMode), command.firstVertex, command.vertexCount, command.instanceCount);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, DrawIndexedData>)
|
||||
|
|
@ -120,6 +122,7 @@ namespace Nz
|
|||
}
|
||||
|
||||
ApplyStates(*context, command.states);
|
||||
ApplyBindings(*context, command.bindings);
|
||||
context->glDrawElementsInstanced(ToOpenGL(command.states.pipeline->GetPipelineInfo().primitiveMode), command.indexCount, ToOpenGL(command.states.indexBufferType), origin, command.instanceCount);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, EndDebugRegionData>)
|
||||
|
|
@ -127,6 +130,11 @@ namespace Nz
|
|||
if (context->glPopDebugGroup)
|
||||
context->glPopDebugGroup();
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, MemoryBarrier>)
|
||||
{
|
||||
if (context->glMemoryBarrier)
|
||||
context->glMemoryBarrier(command.barriers);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, SetFrameBufferData>)
|
||||
{
|
||||
command.framebuffer->Activate();
|
||||
|
|
@ -329,10 +337,8 @@ namespace Nz
|
|||
// No OpenGL object to name
|
||||
}
|
||||
|
||||
void OpenGLCommandBuffer::ApplyStates(const GL::Context& context, const DrawStates& states)
|
||||
void OpenGLCommandBuffer::ApplyBindings(const GL::Context& context, const ShaderBindings& states)
|
||||
{
|
||||
states.pipeline->Apply(context, states.shouldFlipY);
|
||||
|
||||
unsigned int setIndex = 0;
|
||||
for (const auto& [pipelineLayout, shaderBinding] : states.shaderBindings)
|
||||
{
|
||||
|
|
@ -343,6 +349,11 @@ namespace Nz
|
|||
|
||||
setIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLCommandBuffer::ApplyStates(const GL::Context& context, const DrawStates& states)
|
||||
{
|
||||
states.pipeline->Apply(context, states.shouldFlipY);
|
||||
|
||||
if (states.scissorRegion)
|
||||
context.SetScissorBox(states.scissorRegion->x, states.scissorRegion->y, states.scissorRegion->width, states.scissorRegion->height);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,21 @@ namespace Nz
|
|||
m_commandBuffer.BindComputePipeline(&glPipeline);
|
||||
}
|
||||
|
||||
void OpenGLCommandBufferBuilder::BindComputeShaderBinding(UInt32 set, const ShaderBinding& binding)
|
||||
{
|
||||
const OpenGLShaderBinding& glBinding = static_cast<const OpenGLShaderBinding&>(binding);
|
||||
|
||||
m_commandBuffer.BindComputeShaderBinding(glBinding.GetOwner(), set, &glBinding);
|
||||
}
|
||||
|
||||
void OpenGLCommandBufferBuilder::BindComputeShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding)
|
||||
{
|
||||
const OpenGLRenderPipelineLayout& glPipelineLayout = static_cast<const OpenGLRenderPipelineLayout&>(pipelineLayout);
|
||||
const OpenGLShaderBinding& glBinding = static_cast<const OpenGLShaderBinding&>(binding);
|
||||
|
||||
m_commandBuffer.BindComputeShaderBinding(glPipelineLayout, set, &glBinding);
|
||||
}
|
||||
|
||||
void OpenGLCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset)
|
||||
{
|
||||
const OpenGLBuffer& glBuffer = static_cast<const OpenGLBuffer&>(indexBuffer);
|
||||
|
|
@ -48,19 +63,19 @@ namespace Nz
|
|||
m_commandBuffer.BindRenderPipeline(&glPipeline);
|
||||
}
|
||||
|
||||
void OpenGLCommandBufferBuilder::BindShaderBinding(UInt32 set, const ShaderBinding& binding)
|
||||
void OpenGLCommandBufferBuilder::BindRenderShaderBinding(UInt32 set, const ShaderBinding& binding)
|
||||
{
|
||||
const OpenGLShaderBinding& glBinding = static_cast<const OpenGLShaderBinding&>(binding);
|
||||
|
||||
m_commandBuffer.BindShaderBinding(glBinding.GetOwner(), set, &glBinding);
|
||||
m_commandBuffer.BindRenderShaderBinding(glBinding.GetOwner(), set, &glBinding);
|
||||
}
|
||||
|
||||
void OpenGLCommandBufferBuilder::BindShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding)
|
||||
void OpenGLCommandBufferBuilder::BindRenderShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding)
|
||||
{
|
||||
const OpenGLRenderPipelineLayout& glPipelineLayout = static_cast<const OpenGLRenderPipelineLayout&>(pipelineLayout);
|
||||
const OpenGLShaderBinding& glBinding = static_cast<const OpenGLShaderBinding&>(binding);
|
||||
|
||||
m_commandBuffer.BindShaderBinding(glPipelineLayout, set, &glBinding);
|
||||
m_commandBuffer.BindRenderShaderBinding(glPipelineLayout, set, &glBinding);
|
||||
}
|
||||
|
||||
void OpenGLCommandBufferBuilder::BindVertexBuffer(UInt32 binding, const RenderBuffer& vertexBuffer, UInt64 offset)
|
||||
|
|
@ -151,8 +166,23 @@ namespace Nz
|
|||
m_commandBuffer.SetViewport(viewportRegion);
|
||||
}
|
||||
|
||||
void OpenGLCommandBufferBuilder::TextureBarrier(PipelineStageFlags /*srcStageMask*/, PipelineStageFlags /*dstStageMask*/, MemoryAccessFlags /*srcAccessMask*/, MemoryAccessFlags /*dstAccessMask*/, TextureLayout /*oldLayout*/, TextureLayout /*newLayout*/, const Texture& /*texture*/)
|
||||
void OpenGLCommandBufferBuilder::TextureBarrier(PipelineStageFlags /*srcStageMask*/, PipelineStageFlags /*dstStageMask*/, MemoryAccessFlags srcAccessMask, MemoryAccessFlags dstAccessMask, TextureLayout /*oldLayout*/, TextureLayout /*newLayout*/, const Texture& /*texture*/)
|
||||
{
|
||||
/* nothing to do */
|
||||
if (srcAccessMask.Test(MemoryAccess::ShaderWrite))
|
||||
{
|
||||
GLbitfield barriers = 0;
|
||||
|
||||
if (dstAccessMask.Test(MemoryAccess::ColorRead))
|
||||
barriers |= GL_TEXTURE_FETCH_BARRIER_BIT;
|
||||
|
||||
if (dstAccessMask.Test(MemoryAccess::ShaderRead))
|
||||
barriers |= GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
|
||||
|
||||
if (dstAccessMask.Test(MemoryAccess::ShaderWrite))
|
||||
barriers |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
|
||||
|
||||
if (barriers != 0)
|
||||
m_commandBuffer.InsertMemoryBarrier(barriers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,8 +77,7 @@ namespace Nz
|
|||
|
||||
if (m_referenceContext->IsExtensionSupported(GL::Extension::ShaderImageLoadStore))
|
||||
{
|
||||
m_deviceInfo.features.textureRead = true;
|
||||
m_deviceInfo.features.textureWrite = true;
|
||||
m_deviceInfo.features.textureReadWrite = true;
|
||||
m_deviceInfo.features.textureWriteWithoutFormat = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,26 +117,22 @@ namespace Nz
|
|||
auto& textureDescriptor = m_owner.GetTextureDescriptor(m_poolIndex, m_bindingIndex, binding.bindingIndex);
|
||||
if (const OpenGLTexture* glTexture = static_cast<const OpenGLTexture*>(arg.texture))
|
||||
{
|
||||
const TextureViewInfo& viewInfo = glTexture->GetTextureViewInfo();
|
||||
|
||||
std::optional<GLTextureFormat> format = DescribeTextureFormat(viewInfo.reinterpretFormat);
|
||||
std::optional<GLTextureFormat> format = DescribeTextureFormat(glTexture->GetFormat());
|
||||
if (!format)
|
||||
throw std::runtime_error("unexpected texture format");
|
||||
|
||||
textureDescriptor.access = ToOpenGL(arg.access);
|
||||
textureDescriptor.format = format->internalFormat;
|
||||
if (viewInfo.layerCount > 1)
|
||||
{
|
||||
textureDescriptor.layered = true;
|
||||
textureDescriptor.layer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
textureDescriptor.layered = false;
|
||||
textureDescriptor.layer = viewInfo.baseArrayLayer;
|
||||
}
|
||||
|
||||
textureDescriptor.level = viewInfo.baseMipLevel;
|
||||
// Don't bother emulating texture views as their support is virtually guaranteed when compute shaders are available
|
||||
if (Nz::ImageType imageType = glTexture->GetType(); imageType == ImageType::Cubemap || imageType == ImageType::E1D_Array || imageType == ImageType::E2D_Array)
|
||||
textureDescriptor.layered = true;
|
||||
else
|
||||
textureDescriptor.layered = false;
|
||||
|
||||
textureDescriptor.level = 0;
|
||||
textureDescriptor.layer = 0;
|
||||
|
||||
textureDescriptor.texture = glTexture->GetTexture().GetObjectId();
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -117,31 +117,6 @@ namespace Nz
|
|||
return std::make_shared<OpenGLTexture>(std::static_pointer_cast<OpenGLTexture>(shared_from_this()), viewInfo);
|
||||
}
|
||||
|
||||
PixelFormat OpenGLTexture::GetFormat() const
|
||||
{
|
||||
return m_textureInfo.pixelFormat;
|
||||
}
|
||||
|
||||
UInt8 OpenGLTexture::GetLevelCount() const
|
||||
{
|
||||
return m_textureInfo.levelCount;
|
||||
}
|
||||
|
||||
OpenGLTexture* OpenGLTexture::GetParentTexture() const
|
||||
{
|
||||
return m_parentTexture.get();
|
||||
}
|
||||
|
||||
Vector3ui OpenGLTexture::GetSize(UInt8 level) const
|
||||
{
|
||||
return Vector3ui(GetLevelSize(m_textureInfo.width, level), GetLevelSize(m_textureInfo.height, level), GetLevelSize(m_textureInfo.depth, level));
|
||||
}
|
||||
|
||||
ImageType OpenGLTexture::GetType() const
|
||||
{
|
||||
return m_textureInfo.type;
|
||||
}
|
||||
|
||||
bool OpenGLTexture::Update(const void* ptr, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level)
|
||||
{
|
||||
auto format = DescribeTextureFormat(m_textureInfo.pixelFormat);
|
||||
|
|
|
|||
|
|
@ -633,6 +633,13 @@ namespace Nz::GL
|
|||
assert(maxUniformBufferUnits > 0);
|
||||
m_state.uboUnits.resize(maxUniformBufferUnits);
|
||||
|
||||
if (IsExtensionSupported(Extension::ShaderImageLoadStore))
|
||||
{
|
||||
unsigned int maxImageUnits = GetInteger<unsigned int>(GL_MAX_IMAGE_UNITS);
|
||||
assert(maxImageUnits > 0);
|
||||
m_state.imageUnits.resize(maxImageUnits);
|
||||
}
|
||||
|
||||
if (IsExtensionSupported(Extension::StorageBuffers))
|
||||
{
|
||||
unsigned int maxStorageBufferUnits = GetInteger<unsigned int>(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ namespace Nz
|
|||
if (m_drawCalls.empty())
|
||||
return;
|
||||
|
||||
builder.BindShaderBinding(0, *m_currentViewerData.binding);
|
||||
builder.BindRenderShaderBinding(0, *m_currentViewerData.binding);
|
||||
builder.BindRenderPipeline(*m_renderPipeline);
|
||||
|
||||
for (auto& drawCall : m_drawCalls)
|
||||
|
|
|
|||
|
|
@ -46,9 +46,8 @@ namespace Nz
|
|||
NzValidateFeature(depthClamping, "depth clamping feature")
|
||||
NzValidateFeature(nonSolidFaceFilling, "non-solid face filling feature")
|
||||
NzValidateFeature(storageBuffers, "storage buffers support")
|
||||
NzValidateFeature(textureRead, "texture read")
|
||||
NzValidateFeature(textureReadWithoutFormat, "texture read without format")
|
||||
NzValidateFeature(textureWrite, "texture write")
|
||||
NzValidateFeature(textureReadWrite, "texture read/write")
|
||||
NzValidateFeature(textureWriteWithoutFormat, "texture write without format")
|
||||
NzValidateFeature(unrestrictedTextureViews, "unrestricted texture view support")
|
||||
|
||||
|
|
|
|||
|
|
@ -58,9 +58,8 @@ namespace Nz
|
|||
deviceInfo.features.depthClamping = physDevice.features.depthClamp;
|
||||
deviceInfo.features.nonSolidFaceFilling = physDevice.features.fillModeNonSolid;
|
||||
deviceInfo.features.storageBuffers = true;
|
||||
deviceInfo.features.textureRead = true;
|
||||
deviceInfo.features.textureReadWithoutFormat = physDevice.features.shaderStorageImageReadWithoutFormat;
|
||||
deviceInfo.features.textureWrite = true;
|
||||
deviceInfo.features.textureReadWrite = true;
|
||||
deviceInfo.features.textureWriteWithoutFormat = physDevice.features.shaderStorageImageWriteWithoutFormat;
|
||||
deviceInfo.features.unrestrictedTextureViews = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,22 @@ namespace Nz
|
|||
m_commandBuffer.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vkPipeline.GetPipeline());
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::BindComputeShaderBinding(UInt32 set, const ShaderBinding& binding)
|
||||
{
|
||||
const VulkanShaderBinding& vkBinding = static_cast<const VulkanShaderBinding&>(binding);
|
||||
const VulkanRenderPipelineLayout& pipelineLayout = vkBinding.GetOwner();
|
||||
|
||||
m_commandBuffer.BindDescriptorSet(VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout.GetPipelineLayout(), set, vkBinding.GetDescriptorSet());
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::BindComputeShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding)
|
||||
{
|
||||
const VulkanRenderPipelineLayout& vkPipelineLayout = static_cast<const VulkanRenderPipelineLayout&>(pipelineLayout);
|
||||
const VulkanShaderBinding& vkBinding = static_cast<const VulkanShaderBinding&>(binding);
|
||||
|
||||
m_commandBuffer.BindDescriptorSet(VK_PIPELINE_BIND_POINT_COMPUTE, vkPipelineLayout.GetPipelineLayout(), set, vkBinding.GetDescriptorSet());
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset)
|
||||
{
|
||||
const VulkanBuffer& vkBuffer = static_cast<const VulkanBuffer&>(indexBuffer);
|
||||
|
|
@ -97,7 +113,7 @@ namespace Nz
|
|||
m_commandBuffer.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, vkPipeline.Get(*m_currentRenderPass, m_currentSubpassIndex));
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::BindShaderBinding(UInt32 set, const ShaderBinding& binding)
|
||||
void VulkanCommandBufferBuilder::BindRenderShaderBinding(UInt32 set, const ShaderBinding& binding)
|
||||
{
|
||||
const VulkanShaderBinding& vkBinding = static_cast<const VulkanShaderBinding&>(binding);
|
||||
const VulkanRenderPipelineLayout& pipelineLayout = vkBinding.GetOwner();
|
||||
|
|
@ -105,7 +121,7 @@ namespace Nz
|
|||
m_commandBuffer.BindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.GetPipelineLayout(), set, vkBinding.GetDescriptorSet());
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::BindShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding)
|
||||
void VulkanCommandBufferBuilder::BindRenderShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding)
|
||||
{
|
||||
const VulkanRenderPipelineLayout& vkPipelineLayout = static_cast<const VulkanRenderPipelineLayout&>(pipelineLayout);
|
||||
const VulkanShaderBinding& vkBinding = static_cast<const VulkanShaderBinding&>(binding);
|
||||
|
|
|
|||
|
|
@ -294,31 +294,6 @@ namespace Nz
|
|||
return std::make_shared<VulkanTexture>(std::static_pointer_cast<VulkanTexture>(shared_from_this()), viewInfo);
|
||||
}
|
||||
|
||||
PixelFormat VulkanTexture::GetFormat() const
|
||||
{
|
||||
return m_textureInfo.pixelFormat;
|
||||
}
|
||||
|
||||
UInt8 VulkanTexture::GetLevelCount() const
|
||||
{
|
||||
return m_textureInfo.levelCount;
|
||||
}
|
||||
|
||||
VulkanTexture* VulkanTexture::GetParentTexture() const
|
||||
{
|
||||
return m_parentTexture.get();
|
||||
}
|
||||
|
||||
Vector3ui VulkanTexture::GetSize(UInt8 level) const
|
||||
{
|
||||
return Vector3ui(GetLevelSize(m_textureInfo.width, level), GetLevelSize(m_textureInfo.height, level), GetLevelSize(m_textureInfo.depth, level));
|
||||
}
|
||||
|
||||
ImageType VulkanTexture::GetType() const
|
||||
{
|
||||
return m_textureInfo.type;
|
||||
}
|
||||
|
||||
bool VulkanTexture::Update(const void* ptr, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level)
|
||||
{
|
||||
std::size_t textureSize = box.width * box.height * box.depth * PixelFormatInfo::GetBytesPerPixel(m_textureInfo.pixelFormat);
|
||||
|
|
|
|||
Loading…
Reference in New Issue