Renderer: Working compute implementation

This commit is contained in:
SirLynix 2022-12-25 16:08:35 +01:00 committed by Jérôme Leclercq
parent 4605eed0da
commit fe8715f1fb
31 changed files with 615 additions and 167 deletions

View File

@ -12,7 +12,183 @@
NAZARA_REQUEST_DEDICATED_GPU() 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")] [nzsl_version("1.0")]
module; module;
@ -28,26 +204,57 @@ struct Input
} }
[entry(compute)] [entry(compute)]
[workgroup(16, 16, 1)] [workgroup(32, 32, 1)]
fn main(input: Input) fn main(input: Input)
{ {
let indices = vec2[i32](input.global_invocation_id.xy); 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) ComputePipeline BuildComputePipeline(Nz::RenderDevice& device)
{ {
try 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) if (!shaderModule)
{ {
std::cout << "Failed to parse shader module" << std::endl; 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"; [binding(0)] texture: sampler2D[f32]
if (!std::filesystem::is_directory(resourceDir) && std::filesystem::is_directory("../.." / resourceDir)) }
resourceDir = "../.." / resourceDir;
struct FragOut
Nz::Renderer::Config rendererConfig; {
std::cout << "Run using Vulkan? (y/n)" << std::endl; [location(0)] color: vec4[f32]
if (std::getchar() == 'y') }
rendererConfig.preferredAPI = Nz::RenderAPI::Vulkan;
else struct VertIn
rendererConfig.preferredAPI = Nz::RenderAPI::OpenGL; {
[location(0)] pos: vec2[f32],
Nz::Modules<Nz::Renderer> nazara(rendererConfig); [location(1)] uv: vec2[f32]
}
Nz::RenderDeviceFeatures enabledFeatures;
enabledFeatures.computeShaders = true; struct VertOut
enabledFeatures.textureRead = true; {
enabledFeatures.textureWrite = true; [location(0)] uv: vec2[f32],
[builtin(position)] pos: vec4[f32]
std::shared_ptr<Nz::RenderDevice> device = Nz::Renderer::Instance()->InstanciateRenderDevice(0, enabledFeatures); }
ComputePipeline result = BuildComputePipeline(*device); [entry(frag)]
fn main(input: VertOut) -> FragOut
{
return EXIT_SUCCESS; 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();
}
} }

View File

@ -831,11 +831,11 @@ int main()
builder.BindIndexBuffer(*coneMeshGfx->GetIndexBuffer(0).get(), Nz::IndexType::U16); builder.BindIndexBuffer(*coneMeshGfx->GetIndexBuffer(0).get(), Nz::IndexType::U16);
builder.BindVertexBuffer(0, *coneMeshGfx->GetVertexBuffer(0).get()); 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) for (std::size_t i = 0; i < spotLights.size(); ++i)
{ {
builder.BindShaderBinding(1, *lightingShaderBindings[i]); builder.BindRenderShaderBinding(1, *lightingShaderBindings[i]);
builder.BindRenderPipeline(*stencilPipeline); builder.BindRenderPipeline(*stencilPipeline);
builder.DrawIndexed(coneMeshGfx->GetIndexCount(0)); builder.DrawIndexed(coneMeshGfx->GetIndexCount(0));
@ -858,7 +858,7 @@ int main()
builder.SetScissor(env.renderRect); builder.SetScissor(env.renderRect);
builder.SetViewport(env.renderRect); builder.SetViewport(env.renderRect);
builder.BindShaderBinding(0, *skyboxShaderBinding); builder.BindRenderShaderBinding(0, *skyboxShaderBinding);
builder.BindIndexBuffer(*cubeMeshGfx->GetIndexBuffer(0), Nz::IndexType::U16); builder.BindIndexBuffer(*cubeMeshGfx->GetIndexBuffer(0), Nz::IndexType::U16);
builder.BindVertexBuffer(0, *cubeMeshGfx->GetVertexBuffer(0)); builder.BindVertexBuffer(0, *cubeMeshGfx->GetVertexBuffer(0));
@ -930,7 +930,7 @@ int main()
builder.SetScissor(env.renderRect); builder.SetScissor(env.renderRect);
builder.SetViewport(env.renderRect); builder.SetViewport(env.renderRect);
builder.BindShaderBinding(0, *godRaysShaderBinding); builder.BindRenderShaderBinding(0, *godRaysShaderBinding);
builder.BindRenderPipeline(*godraysPipeline); builder.BindRenderPipeline(*godraysPipeline);
@ -946,7 +946,7 @@ int main()
builder.SetScissor(env.renderRect); builder.SetScissor(env.renderRect);
builder.SetViewport(env.renderRect); builder.SetViewport(env.renderRect);
builder.BindShaderBinding(0, *bloomBrightShaderBinding); builder.BindRenderShaderBinding(0, *bloomBrightShaderBinding);
builder.BindRenderPipeline(*bloomBrightPipeline); builder.BindRenderPipeline(*bloomBrightPipeline);
@ -969,7 +969,7 @@ int main()
builder.SetScissor(env.renderRect); builder.SetScissor(env.renderRect);
builder.SetViewport(env.renderRect); builder.SetViewport(env.renderRect);
builder.BindShaderBinding(0, *gaussianBlurShaderBinding[i * 2 + 0]); builder.BindRenderShaderBinding(0, *gaussianBlurShaderBinding[i * 2 + 0]);
builder.BindRenderPipeline(*gaussianBlurPipeline); builder.BindRenderPipeline(*gaussianBlurPipeline);
builder.Draw(3); builder.Draw(3);
@ -989,7 +989,7 @@ int main()
builder.SetScissor(env.renderRect); builder.SetScissor(env.renderRect);
builder.SetViewport(env.renderRect); builder.SetViewport(env.renderRect);
builder.BindShaderBinding(0, *gaussianBlurShaderBinding[i * 2 + 1]); builder.BindRenderShaderBinding(0, *gaussianBlurShaderBinding[i * 2 + 1]);
builder.BindRenderPipeline(*gaussianBlurPipeline); builder.BindRenderPipeline(*gaussianBlurPipeline);
builder.Draw(3); builder.Draw(3);
@ -1014,12 +1014,12 @@ int main()
builder.BindRenderPipeline(*bloomBlendPipeline); builder.BindRenderPipeline(*bloomBlendPipeline);
for (std::size_t i = 0; i < BloomSubdivisionCount; ++i) for (std::size_t i = 0; i < BloomSubdivisionCount; ++i)
{ {
builder.BindShaderBinding(0, *bloomBlendShaderBinding[i]); builder.BindRenderShaderBinding(0, *bloomBlendShaderBinding[i]);
builder.Draw(3); builder.Draw(3);
} }
// God rays // God rays
builder.BindShaderBinding(0, *godRaysBlitShaderBinding); builder.BindRenderShaderBinding(0, *godRaysBlitShaderBinding);
builder.Draw(3); builder.Draw(3);
}); });
@ -1045,7 +1045,7 @@ int main()
builder.SetScissor(env.renderRect); builder.SetScissor(env.renderRect);
builder.SetViewport(env.renderRect); builder.SetViewport(env.renderRect);
builder.BindShaderBinding(0, *toneMappingShaderBinding); builder.BindRenderShaderBinding(0, *toneMappingShaderBinding);
builder.BindRenderPipeline(*toneMappingPipeline); builder.BindRenderPipeline(*toneMappingPipeline);
builder.Draw(3); builder.Draw(3);
@ -1547,7 +1547,7 @@ int main()
builder.SetScissor(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) }); 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.SetViewport(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) });
builder.BindShaderBinding(0, *finalBlitBinding); builder.BindRenderShaderBinding(0, *finalBlitBinding);
builder.BindRenderPipeline(*fullscreenPipeline); builder.BindRenderPipeline(*fullscreenPipeline);
builder.Draw(3); builder.Draw(3);

View File

@ -391,8 +391,8 @@ int main()
builder.BindIndexBuffer(*renderBufferIB, Nz::IndexType::U16); builder.BindIndexBuffer(*renderBufferIB, Nz::IndexType::U16);
builder.BindRenderPipeline(*pipeline); builder.BindRenderPipeline(*pipeline);
builder.BindVertexBuffer(0, *renderBufferVB); builder.BindVertexBuffer(0, *renderBufferVB);
builder.BindShaderBinding(0, *viewerShaderBinding); builder.BindRenderShaderBinding(0, *viewerShaderBinding);
builder.BindShaderBinding(1, *textureShaderBinding); builder.BindRenderShaderBinding(1, *textureShaderBinding);
builder.SetScissor(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) }); 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.SetViewport(Nz::Recti{ 0, 0, int(windowSize.x), int(windowSize.y) });

View File

@ -40,9 +40,10 @@ namespace Nz
inline void BeginDebugRegion(const std::string_view& regionName, const Color& color); inline void BeginDebugRegion(const std::string_view& regionName, const Color& color);
inline void BindComputePipeline(const OpenGLComputePipeline* pipeline); 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 BindIndexBuffer(GLuint indexBuffer, IndexType indexType, UInt64 offset = 0);
inline void BindRenderPipeline(const OpenGLRenderPipeline* pipeline); 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 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); 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 std::size_t GetPoolIndex() const;
inline const OpenGLCommandPool& GetOwner() 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 SetFramebuffer(const OpenGLFramebuffer& framebuffer, const OpenGLRenderPass& renderPass, const CommandBufferBuilder::ClearValues* clearValues, std::size_t clearValueCount);
inline void SetScissor(const Recti& scissorRegion); inline void SetScissor(const Recti& scissorRegion);
inline void SetViewport(const Recti& viewportRegion); inline void SetViewport(const Recti& viewportRegion);
@ -74,7 +77,9 @@ namespace Nz
private: private:
struct DrawStates; struct DrawStates;
struct ShaderBindings;
void ApplyBindings(const GL::Context& context, const ShaderBindings& bindings);
void ApplyStates(const GL::Context& context, const DrawStates& states); void ApplyStates(const GL::Context& context, const DrawStates& states);
void Release() override; void Release() override;
@ -123,9 +128,15 @@ namespace Nz
UInt64 targetOffset; UInt64 targetOffset;
}; };
struct ShaderBindings
{
std::vector<std::pair<const OpenGLRenderPipelineLayout*, const OpenGLShaderBinding*>> shaderBindings;
};
struct DispatchData struct DispatchData
{ {
ComputeStates states; ComputeStates states;
ShaderBindings bindings;
UInt32 numGroupsX; UInt32 numGroupsX;
UInt32 numGroupsY; UInt32 numGroupsY;
UInt32 numGroupsZ; UInt32 numGroupsZ;
@ -145,7 +156,6 @@ namespace Nz
IndexType indexBufferType; IndexType indexBufferType;
std::optional<Recti> scissorRegion; std::optional<Recti> scissorRegion;
std::optional<Recti> viewportRegion; std::optional<Recti> viewportRegion;
std::vector<std::pair<const OpenGLRenderPipelineLayout*, const OpenGLShaderBinding*>> shaderBindings;
std::vector<VertexBuffer> vertexBuffers; std::vector<VertexBuffer> vertexBuffers;
bool shouldFlipY = false; bool shouldFlipY = false;
}; };
@ -153,6 +163,7 @@ namespace Nz
struct DrawData struct DrawData
{ {
DrawStates states; DrawStates states;
ShaderBindings bindings;
UInt32 firstInstance; UInt32 firstInstance;
UInt32 firstVertex; UInt32 firstVertex;
UInt32 instanceCount; UInt32 instanceCount;
@ -162,6 +173,7 @@ namespace Nz
struct DrawIndexedData struct DrawIndexedData
{ {
DrawStates states; DrawStates states;
ShaderBindings bindings;
UInt32 firstIndex; UInt32 firstIndex;
UInt32 firstInstance; UInt32 firstInstance;
UInt32 indexCount; UInt32 indexCount;
@ -172,6 +184,11 @@ namespace Nz
{ {
}; };
struct MemoryBarrier
{
GLbitfield barriers;
};
struct SetFrameBufferData struct SetFrameBufferData
{ {
std::array<CommandBufferBuilder::ClearValues, 16> clearValues; //< TODO: Remove hard limit? std::array<CommandBufferBuilder::ClearValues, 16> clearValues; //< TODO: Remove hard limit?
@ -189,11 +206,15 @@ namespace Nz
DrawData, DrawData,
DrawIndexedData, DrawIndexedData,
EndDebugRegionData, EndDebugRegionData,
MemoryBarrier,
SetFrameBufferData SetFrameBufferData
>; >;
ComputeStates m_currentComputeStates; ComputeStates m_currentComputeStates;
DrawStates m_currentDrawStates; DrawStates m_currentDrawStates;
ShaderBindings m_currentComputeShaderBindings;
ShaderBindings m_currentGraphicsShaderBindings;
std::optional<MemoryBarrier> m_pendingBarrier;
std::size_t m_bindingIndex; std::size_t m_bindingIndex;
std::size_t m_maxColorBufferCount; std::size_t m_maxColorBufferCount;
std::size_t m_poolIndex; std::size_t m_poolIndex;

View File

@ -38,6 +38,14 @@ namespace Nz
m_currentComputeStates.pipeline = pipeline; 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) inline void OpenGLCommandBuffer::BindIndexBuffer(GLuint indexBuffer, IndexType indexType, UInt64 offset)
{ {
m_currentDrawStates.indexBuffer = indexBuffer; m_currentDrawStates.indexBuffer = indexBuffer;
@ -50,12 +58,12 @@ namespace Nz
m_currentDrawStates.pipeline = pipeline; 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()) if (set >= m_currentGraphicsShaderBindings.shaderBindings.size())
m_currentDrawStates.shaderBindings.resize(set + 1); 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) inline void OpenGLCommandBuffer::BindVertexBuffer(UInt32 binding, GLuint vertexBuffer, UInt64 offset)
@ -124,6 +132,7 @@ namespace Nz
throw std::runtime_error("no pipeline bound"); throw std::runtime_error("no pipeline bound");
DispatchData dispatch; DispatchData dispatch;
dispatch.bindings = m_currentComputeShaderBindings;
dispatch.states = m_currentComputeStates; dispatch.states = m_currentComputeStates;
dispatch.numGroupsX = numGroupsX; dispatch.numGroupsX = numGroupsX;
dispatch.numGroupsY = numGroupsY; dispatch.numGroupsY = numGroupsY;
@ -138,6 +147,7 @@ namespace Nz
throw std::runtime_error("no pipeline bound"); throw std::runtime_error("no pipeline bound");
DrawData draw; DrawData draw;
draw.bindings = m_currentGraphicsShaderBindings;
draw.states = m_currentDrawStates; draw.states = m_currentDrawStates;
draw.firstInstance = firstInstance; draw.firstInstance = firstInstance;
draw.firstVertex = firstVertex; draw.firstVertex = firstVertex;
@ -153,6 +163,7 @@ namespace Nz
throw std::runtime_error("no pipeline bound"); throw std::runtime_error("no pipeline bound");
DrawIndexedData draw; DrawIndexedData draw;
draw.bindings = m_currentGraphicsShaderBindings;
draw.states = m_currentDrawStates; draw.states = m_currentDrawStates;
draw.firstIndex = firstIndex; draw.firstIndex = firstIndex;
draw.firstInstance = firstInstance; draw.firstInstance = firstInstance;
@ -183,6 +194,23 @@ namespace Nz
return *m_owner; 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) 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()); m_maxColorBufferCount = std::max(m_maxColorBufferCount, framebuffer.GetColorBufferCount());

View File

@ -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 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 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 BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset = 0) override;
void BindRenderPipeline(const RenderPipeline& pipeline) override; void BindRenderPipeline(const RenderPipeline& pipeline) override;
void BindShaderBinding(UInt32 set, const ShaderBinding& binding) override; void BindRenderShaderBinding(UInt32 set, const ShaderBinding& binding) override;
void BindShaderBinding(const RenderPipelineLayout& pipelineLayout, 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 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; void BlitTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout fromLayout, const Texture& toTexture, const Boxui& toBox, TextureLayout toLayout, SamplerFilter filter) override;

View File

@ -16,7 +16,7 @@
namespace Nz namespace Nz
{ {
class NAZARA_OPENGLRENDERER_API OpenGLTexture : public Texture class NAZARA_OPENGLRENDERER_API OpenGLTexture final : public Texture
{ {
public: public:
OpenGLTexture(OpenGLDevice& device, const TextureInfo& textureInfo); OpenGLTexture(OpenGLDevice& device, const TextureInfo& textureInfo);
@ -28,13 +28,14 @@ namespace Nz
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override; bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
std::shared_ptr<Texture> CreateView(const TextureViewInfo& viewInfo) override; std::shared_ptr<Texture> CreateView(const TextureViewInfo& viewInfo) override;
PixelFormat GetFormat() const override; inline PixelFormat GetFormat() const override;
UInt8 GetLevelCount() const override; inline UInt8 GetLevelCount() const override;
OpenGLTexture* GetParentTexture() const override; inline OpenGLTexture* GetParentTexture() const override;
Vector3ui GetSize(UInt8 level = 0) const override; inline Vector3ui GetSize(UInt8 level = 0) const override;
inline const GL::Texture& GetTexture() const; inline const GL::Texture& GetTexture() const;
inline const TextureInfo& GetTextureInfo() const override;
inline const TextureViewInfo& GetTextureViewInfo() const; inline const TextureViewInfo& GetTextureViewInfo() const;
ImageType GetType() const override; inline ImageType GetType() const override;
inline bool RequiresTextureViewEmulation() const; inline bool RequiresTextureViewEmulation() const;

View File

@ -8,17 +8,47 @@
namespace Nz 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 inline const GL::Texture& OpenGLTexture::GetTexture() const
{ {
return m_texture; return m_texture;
} }
inline const TextureInfo& OpenGLTexture::GetTextureInfo() const
{
return m_textureInfo;
}
inline const TextureViewInfo& OpenGLTexture::GetTextureViewInfo() const inline const TextureViewInfo& OpenGLTexture::GetTextureViewInfo() const
{ {
assert(m_viewInfo); assert(m_viewInfo);
return *m_viewInfo; return *m_viewInfo;
} }
inline ImageType OpenGLTexture::GetType() const
{
return m_textureInfo.type;
}
inline bool OpenGLTexture::RequiresTextureViewEmulation() const inline bool OpenGLTexture::RequiresTextureViewEmulation() const
{ {
return m_viewInfo.has_value() && !m_texture.IsValid(); return m_viewInfo.has_value() && !m_texture.IsValid();

View File

@ -44,10 +44,12 @@ namespace Nz
inline void BeginRenderPass(const Framebuffer& framebuffer, const RenderPass& renderPass, const Recti& renderRect, std::initializer_list<ClearValues> clearValues); 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 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 BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset = 0) = 0;
virtual void BindRenderPipeline(const RenderPipeline& pipeline) = 0; virtual void BindRenderPipeline(const RenderPipeline& pipeline) = 0;
virtual void BindShaderBinding(UInt32 set, const ShaderBinding& binding) = 0; virtual void BindRenderShaderBinding(UInt32 set, const ShaderBinding& binding) = 0;
virtual void BindShaderBinding(const RenderPipelineLayout& pipelineLayout, 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 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; virtual void BlitTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout fromLayout, const Texture& toTexture, const Boxui& toBox, TextureLayout toLayout, SamplerFilter filter) = 0;

View File

@ -83,6 +83,7 @@ namespace Nz
TopOfPipe, TopOfPipe,
ColorOutput, ColorOutput,
ComputeShader,
DrawIndirect, DrawIndirect,
FragmentShader, FragmentShader,
FragmentTestsEarly, FragmentTestsEarly,
@ -196,6 +197,7 @@ namespace Nz
ColorOutput, ColorOutput,
DepthStencilReadOnly, DepthStencilReadOnly,
DepthStencilReadWrite, DepthStencilReadWrite,
General,
Present, Present,
TransferSource, TransferSource,
TransferDestination, TransferDestination,

View File

@ -21,9 +21,8 @@ namespace Nz
bool depthClamping = false; bool depthClamping = false;
bool nonSolidFaceFilling = false; bool nonSolidFaceFilling = false;
bool storageBuffers = false; bool storageBuffers = false;
bool textureRead = false;
bool textureReadWithoutFormat = false; bool textureReadWithoutFormat = false;
bool textureWrite = false; bool textureReadWrite = false;
bool textureWriteWithoutFormat = false; bool textureWriteWithoutFormat = false;
bool unrestrictedTextureViews = false; bool unrestrictedTextureViews = false;
}; };

View File

@ -68,11 +68,8 @@ namespace Nz
virtual bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos = Vector3ui::Zero()) = 0; 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 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 Texture* GetParentTexture() const = 0;
virtual Vector3ui GetSize(UInt8 level = 0) const = 0; virtual const TextureInfo& GetTextureInfo() const = 0;
virtual ImageType GetType() const = 0;
virtual void UpdateDebugName(std::string_view name) = 0; virtual void UpdateDebugName(std::string_view name) = 0;

View File

@ -227,6 +227,7 @@ namespace Nz
{ {
case PipelineStage::TopOfPipe: return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; case PipelineStage::TopOfPipe: return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
case PipelineStage::ColorOutput: return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_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::DrawIndirect: return VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
case PipelineStage::FragmentShader: return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; case PipelineStage::FragmentShader: return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
case PipelineStage::FragmentTestsEarly: return VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_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::ColorOutput: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
case TextureLayout::DepthStencilReadOnly: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_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::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::Present: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
case TextureLayout::TransferSource: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; case TextureLayout::TransferSource: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
case TextureLayout::TransferDestination: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; case TextureLayout::TransferDestination: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;

View File

@ -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 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 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 BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset = 0) override;
void BindRenderPipeline(const RenderPipeline& pipeline) override; void BindRenderPipeline(const RenderPipeline& pipeline) override;
void BindShaderBinding(UInt32 set, const ShaderBinding& binding) override; void BindRenderShaderBinding(UInt32 set, const ShaderBinding& binding) override;
void BindShaderBinding(const RenderPipelineLayout& pipelineLayout, 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 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; void BlitTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout fromLayout, const Texture& toTexture, const Boxui& toBox, TextureLayout toLayout, SamplerFilter filter) override;

View File

@ -16,7 +16,7 @@
namespace Nz namespace Nz
{ {
class NAZARA_VULKANRENDERER_API VulkanTexture : public Texture class NAZARA_VULKANRENDERER_API VulkanTexture final : public Texture
{ {
public: public:
VulkanTexture(Vk::Device& device, const TextureInfo& textureInfo); 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; bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
std::shared_ptr<Texture> CreateView(const TextureViewInfo& viewInfo) override; std::shared_ptr<Texture> CreateView(const TextureViewInfo& viewInfo) override;
PixelFormat GetFormat() const override; inline PixelFormat GetFormat() const override;
inline VkImage GetImage() const; inline VkImage GetImage() const;
inline VkImageView GetImageView() const; inline VkImageView GetImageView() const;
UInt8 GetLevelCount() const override; inline UInt8 GetLevelCount() const override;
VulkanTexture* GetParentTexture() const override; inline VulkanTexture* GetParentTexture() const override;
Vector3ui GetSize(UInt8 level = 0) const override; inline Vector3ui GetSize(UInt8 level = 0) const override;
inline const VkImageSubresourceRange& GetSubresourceRange() const; inline const VkImageSubresourceRange& GetSubresourceRange() const;
ImageType GetType() const override; inline const TextureInfo& GetTextureInfo() const override;
inline ImageType GetType() const override;
using Texture::Update; using Texture::Update;
bool Update(const void* ptr, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level) override; bool Update(const void* ptr, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level) override;

View File

@ -7,6 +7,11 @@
namespace Nz namespace Nz
{ {
inline PixelFormat VulkanTexture::GetFormat() const
{
return m_textureInfo.pixelFormat;
}
inline VkImage VulkanTexture::GetImage() const inline VkImage VulkanTexture::GetImage() const
{ {
return m_image; return m_image;
@ -17,10 +22,35 @@ namespace Nz
return m_imageView; 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 inline const VkImageSubresourceRange& VulkanTexture::GetSubresourceRange() const
{ {
return m_imageRange; 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> #include <Nazara/VulkanRenderer/DebugOff.hpp>

View File

@ -458,7 +458,7 @@ namespace Nz
builder.SetViewport(renderRegion); builder.SetViewport(renderRegion);
builder.BindRenderPipeline(*graphics->GetBlitPipeline(false)); builder.BindRenderPipeline(*graphics->GetBlitPipeline(false));
builder.BindShaderBinding(0, *data.blitShaderBinding); builder.BindRenderShaderBinding(0, *data.blitShaderBinding);
builder.Draw(3); builder.Draw(3);
} }
builder.EndDebugRegion(); builder.EndDebugRegion();
@ -652,7 +652,7 @@ namespace Nz
{ {
const ShaderBindingPtr& blitShaderBinding = viewerData->blitShaderBinding; const ShaderBindingPtr& blitShaderBinding = viewerData->blitShaderBinding;
builder.BindShaderBinding(0, *blitShaderBinding); builder.BindRenderShaderBinding(0, *blitShaderBinding);
builder.Draw(3); builder.Draw(3);
if (first) if (first)

View File

@ -112,9 +112,8 @@ namespace Nz
enabledFeatures.depthClamping = !config.forceDisableFeatures.depthClamping && renderDeviceInfo[bestRenderDeviceIndex].features.depthClamping; enabledFeatures.depthClamping = !config.forceDisableFeatures.depthClamping && renderDeviceInfo[bestRenderDeviceIndex].features.depthClamping;
enabledFeatures.nonSolidFaceFilling = !config.forceDisableFeatures.nonSolidFaceFilling && renderDeviceInfo[bestRenderDeviceIndex].features.nonSolidFaceFilling; enabledFeatures.nonSolidFaceFilling = !config.forceDisableFeatures.nonSolidFaceFilling && renderDeviceInfo[bestRenderDeviceIndex].features.nonSolidFaceFilling;
enabledFeatures.storageBuffers = !config.forceDisableFeatures.storageBuffers && renderDeviceInfo[bestRenderDeviceIndex].features.storageBuffers; 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.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.textureWriteWithoutFormat = !config.forceDisableFeatures.textureWriteWithoutFormat && renderDeviceInfo[bestRenderDeviceIndex].features.textureWriteWithoutFormat;
enabledFeatures.unrestrictedTextureViews = !config.forceDisableFeatures.unrestrictedTextureViews && renderDeviceInfo[bestRenderDeviceIndex].features.unrestrictedTextureViews; enabledFeatures.unrestrictedTextureViews = !config.forceDisableFeatures.unrestrictedTextureViews && renderDeviceInfo[bestRenderDeviceIndex].features.unrestrictedTextureViews;

View File

@ -316,7 +316,7 @@ namespace Nz
if (currentShaderBinding != drawData.shaderBinding) if (currentShaderBinding != drawData.shaderBinding)
{ {
commandBuffer.BindShaderBinding(0, *drawData.shaderBinding); commandBuffer.BindRenderShaderBinding(0, *drawData.shaderBinding);
currentShaderBinding = drawData.shaderBinding; currentShaderBinding = drawData.shaderBinding;
} }

View File

@ -291,7 +291,7 @@ namespace Nz
if (currentShaderBinding != drawData.shaderBinding) if (currentShaderBinding != drawData.shaderBinding)
{ {
commandBuffer.BindShaderBinding(0, *drawData.shaderBinding); commandBuffer.BindRenderShaderBinding(0, *drawData.shaderBinding);
currentShaderBinding = drawData.shaderBinding; currentShaderBinding = drawData.shaderBinding;
} }

View File

@ -100,11 +100,13 @@ namespace Nz
throw std::runtime_error("compute shaders are not supported on this device"); throw std::runtime_error("compute shaders are not supported on this device");
command.states.pipeline->Apply(*context); command.states.pipeline->Apply(*context);
ApplyBindings(*context, command.bindings);
context->glDispatchCompute(command.numGroupsX, command.numGroupsY, command.numGroupsZ); context->glDispatchCompute(command.numGroupsX, command.numGroupsY, command.numGroupsZ);
} }
else if constexpr (std::is_same_v<T, DrawData>) else if constexpr (std::is_same_v<T, DrawData>)
{ {
ApplyStates(*context, command.states); ApplyStates(*context, command.states);
ApplyBindings(*context, command.bindings);
context->glDrawArraysInstanced(ToOpenGL(command.states.pipeline->GetPipelineInfo().primitiveMode), command.firstVertex, command.vertexCount, command.instanceCount); context->glDrawArraysInstanced(ToOpenGL(command.states.pipeline->GetPipelineInfo().primitiveMode), command.firstVertex, command.vertexCount, command.instanceCount);
} }
else if constexpr (std::is_same_v<T, DrawIndexedData>) else if constexpr (std::is_same_v<T, DrawIndexedData>)
@ -120,6 +122,7 @@ namespace Nz
} }
ApplyStates(*context, command.states); 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); 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>) else if constexpr (std::is_same_v<T, EndDebugRegionData>)
@ -127,6 +130,11 @@ namespace Nz
if (context->glPopDebugGroup) if (context->glPopDebugGroup)
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>) else if constexpr (std::is_same_v<T, SetFrameBufferData>)
{ {
command.framebuffer->Activate(); command.framebuffer->Activate();
@ -329,10 +337,8 @@ namespace Nz
// No OpenGL object to name // 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; unsigned int setIndex = 0;
for (const auto& [pipelineLayout, shaderBinding] : states.shaderBindings) for (const auto& [pipelineLayout, shaderBinding] : states.shaderBindings)
{ {
@ -343,6 +349,11 @@ namespace Nz
setIndex++; setIndex++;
} }
}
void OpenGLCommandBuffer::ApplyStates(const GL::Context& context, const DrawStates& states)
{
states.pipeline->Apply(context, states.shouldFlipY);
if (states.scissorRegion) if (states.scissorRegion)
context.SetScissorBox(states.scissorRegion->x, states.scissorRegion->y, states.scissorRegion->width, states.scissorRegion->height); context.SetScissorBox(states.scissorRegion->x, states.scissorRegion->y, states.scissorRegion->width, states.scissorRegion->height);

View File

@ -34,6 +34,21 @@ namespace Nz
m_commandBuffer.BindComputePipeline(&glPipeline); 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) void OpenGLCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset)
{ {
const OpenGLBuffer& glBuffer = static_cast<const OpenGLBuffer&>(indexBuffer); const OpenGLBuffer& glBuffer = static_cast<const OpenGLBuffer&>(indexBuffer);
@ -48,19 +63,19 @@ namespace Nz
m_commandBuffer.BindRenderPipeline(&glPipeline); 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); 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 OpenGLRenderPipelineLayout& glPipelineLayout = static_cast<const OpenGLRenderPipelineLayout&>(pipelineLayout);
const OpenGLShaderBinding& glBinding = static_cast<const OpenGLShaderBinding&>(binding); 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) void OpenGLCommandBufferBuilder::BindVertexBuffer(UInt32 binding, const RenderBuffer& vertexBuffer, UInt64 offset)
@ -151,8 +166,23 @@ namespace Nz
m_commandBuffer.SetViewport(viewportRegion); 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);
}
} }
} }

View File

@ -77,8 +77,7 @@ namespace Nz
if (m_referenceContext->IsExtensionSupported(GL::Extension::ShaderImageLoadStore)) if (m_referenceContext->IsExtensionSupported(GL::Extension::ShaderImageLoadStore))
{ {
m_deviceInfo.features.textureRead = true; m_deviceInfo.features.textureReadWrite = true;
m_deviceInfo.features.textureWrite = true;
m_deviceInfo.features.textureWriteWithoutFormat = true; m_deviceInfo.features.textureWriteWithoutFormat = true;
} }

View File

@ -117,26 +117,22 @@ namespace Nz
auto& textureDescriptor = m_owner.GetTextureDescriptor(m_poolIndex, m_bindingIndex, binding.bindingIndex); auto& textureDescriptor = m_owner.GetTextureDescriptor(m_poolIndex, m_bindingIndex, binding.bindingIndex);
if (const OpenGLTexture* glTexture = static_cast<const OpenGLTexture*>(arg.texture)) if (const OpenGLTexture* glTexture = static_cast<const OpenGLTexture*>(arg.texture))
{ {
const TextureViewInfo& viewInfo = glTexture->GetTextureViewInfo(); std::optional<GLTextureFormat> format = DescribeTextureFormat(glTexture->GetFormat());
std::optional<GLTextureFormat> format = DescribeTextureFormat(viewInfo.reinterpretFormat);
if (!format) if (!format)
throw std::runtime_error("unexpected texture format"); throw std::runtime_error("unexpected texture format");
textureDescriptor.access = ToOpenGL(arg.access); textureDescriptor.access = ToOpenGL(arg.access);
textureDescriptor.format = format->internalFormat; 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(); textureDescriptor.texture = glTexture->GetTexture().GetObjectId();
} }
else else

View File

@ -117,31 +117,6 @@ namespace Nz
return std::make_shared<OpenGLTexture>(std::static_pointer_cast<OpenGLTexture>(shared_from_this()), viewInfo); 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) bool OpenGLTexture::Update(const void* ptr, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level)
{ {
auto format = DescribeTextureFormat(m_textureInfo.pixelFormat); auto format = DescribeTextureFormat(m_textureInfo.pixelFormat);

View File

@ -633,6 +633,13 @@ namespace Nz::GL
assert(maxUniformBufferUnits > 0); assert(maxUniformBufferUnits > 0);
m_state.uboUnits.resize(maxUniformBufferUnits); 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)) if (IsExtensionSupported(Extension::StorageBuffers))
{ {
unsigned int maxStorageBufferUnits = GetInteger<unsigned int>(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS); unsigned int maxStorageBufferUnits = GetInteger<unsigned int>(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);

View File

@ -82,7 +82,7 @@ namespace Nz
if (m_drawCalls.empty()) if (m_drawCalls.empty())
return; return;
builder.BindShaderBinding(0, *m_currentViewerData.binding); builder.BindRenderShaderBinding(0, *m_currentViewerData.binding);
builder.BindRenderPipeline(*m_renderPipeline); builder.BindRenderPipeline(*m_renderPipeline);
for (auto& drawCall : m_drawCalls) for (auto& drawCall : m_drawCalls)

View File

@ -46,9 +46,8 @@ namespace Nz
NzValidateFeature(depthClamping, "depth clamping feature") NzValidateFeature(depthClamping, "depth clamping feature")
NzValidateFeature(nonSolidFaceFilling, "non-solid face filling feature") NzValidateFeature(nonSolidFaceFilling, "non-solid face filling feature")
NzValidateFeature(storageBuffers, "storage buffers support") NzValidateFeature(storageBuffers, "storage buffers support")
NzValidateFeature(textureRead, "texture read")
NzValidateFeature(textureReadWithoutFormat, "texture read without format") NzValidateFeature(textureReadWithoutFormat, "texture read without format")
NzValidateFeature(textureWrite, "texture write") NzValidateFeature(textureReadWrite, "texture read/write")
NzValidateFeature(textureWriteWithoutFormat, "texture write without format") NzValidateFeature(textureWriteWithoutFormat, "texture write without format")
NzValidateFeature(unrestrictedTextureViews, "unrestricted texture view support") NzValidateFeature(unrestrictedTextureViews, "unrestricted texture view support")

View File

@ -58,9 +58,8 @@ namespace Nz
deviceInfo.features.depthClamping = physDevice.features.depthClamp; deviceInfo.features.depthClamping = physDevice.features.depthClamp;
deviceInfo.features.nonSolidFaceFilling = physDevice.features.fillModeNonSolid; deviceInfo.features.nonSolidFaceFilling = physDevice.features.fillModeNonSolid;
deviceInfo.features.storageBuffers = true; deviceInfo.features.storageBuffers = true;
deviceInfo.features.textureRead = true;
deviceInfo.features.textureReadWithoutFormat = physDevice.features.shaderStorageImageReadWithoutFormat; deviceInfo.features.textureReadWithoutFormat = physDevice.features.shaderStorageImageReadWithoutFormat;
deviceInfo.features.textureWrite = true; deviceInfo.features.textureReadWrite = true;
deviceInfo.features.textureWriteWithoutFormat = physDevice.features.shaderStorageImageWriteWithoutFormat; deviceInfo.features.textureWriteWithoutFormat = physDevice.features.shaderStorageImageWriteWithoutFormat;
deviceInfo.features.unrestrictedTextureViews = true; deviceInfo.features.unrestrictedTextureViews = true;

View File

@ -80,6 +80,22 @@ namespace Nz
m_commandBuffer.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vkPipeline.GetPipeline()); 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) void VulkanCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset)
{ {
const VulkanBuffer& vkBuffer = static_cast<const VulkanBuffer&>(indexBuffer); 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)); 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 VulkanShaderBinding& vkBinding = static_cast<const VulkanShaderBinding&>(binding);
const VulkanRenderPipelineLayout& pipelineLayout = vkBinding.GetOwner(); const VulkanRenderPipelineLayout& pipelineLayout = vkBinding.GetOwner();
@ -105,7 +121,7 @@ namespace Nz
m_commandBuffer.BindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.GetPipelineLayout(), set, vkBinding.GetDescriptorSet()); 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 VulkanRenderPipelineLayout& vkPipelineLayout = static_cast<const VulkanRenderPipelineLayout&>(pipelineLayout);
const VulkanShaderBinding& vkBinding = static_cast<const VulkanShaderBinding&>(binding); const VulkanShaderBinding& vkBinding = static_cast<const VulkanShaderBinding&>(binding);

View File

@ -294,31 +294,6 @@ namespace Nz
return std::make_shared<VulkanTexture>(std::static_pointer_cast<VulkanTexture>(shared_from_this()), viewInfo); 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) 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); std::size_t textureSize = box.width * box.height * box.depth * PixelFormatInfo::GetBytesPerPixel(m_textureInfo.pixelFormat);