const SLANG_SHADERS: &[SlangShader] = &[
SlangShader { name: "basic" },
+ SlangShader { name: "block" },
SlangShader { name: "draw_2d" },
SlangShader { name: "composite" },
SlangShader { name: "radix_sort" },
--- /dev/null
+struct BlockConstants {
+ float4x4 clip_from_camera;
+}
+
+struct VertexAttributes {
+ float4 position : SV_Position;
+}
+
+struct PrimitiveAttributes {
+ float3 normal;
+ float3 color;
+}
+
+[shader("mesh")]
+[outputtopology("triangle")]
+[numthreads(32, 1, 1)]
+void mesh(uniform BlockConstants constants, OutputVertices<VertexAttributes, 32> vertices, OutputPrimitives<PrimitiveAttributes, 16> primitives, OutputIndices<uint3, 16> indices, uint thread_id_in_group: SV_GroupThreadID) {
+ SetMeshOutputCounts(4, 2);
+
+ static const float4 positions[4] = {
+ float4(-0.5, 0.0, -0.5, 1.0),
+ float4(-0.5, 0.0, 0.5, 1.0),
+ float4(0.5, 0.0, 0.5, 1.0),
+ float4(0.5, 0.0, -0.5, 1.0),
+ };
+
+ if (thread_id_in_group < 4) {
+ vertices[thread_id_in_group].position = mul(constants.clip_from_camera, positions[thread_id_in_group]);
+ }
+
+ if (thread_id_in_group < 2) {
+ primitives[thread_id_in_group].color = float3(0x9b / 255.0, 0x61 / 255.0, 0x56 / 255.0);
+ primitives[thread_id_in_group].normal = float3(0.0, 1.0, 0.0);
+ }
+
+ indices[0] = uint3(0, 1, 2);
+ indices[1] = uint3(2, 3, 0);
+}
+
+struct Fragment {
+ float4 color : SV_Target0;
+}
+
+[shader("fragment")]
+Fragment fragment(PrimitiveAttributes primitive, VertexAttributes vertex) {
+ let n_dot_l = max(dot(primitive.normal, float3(0.0, 1.0, 0.0)), 0.1);
+
+ Fragment output;
+ output.color = float4(primitive.color * n_dot_l, 1.0);
+ return output;
+}
ComputePipelineDesc, CullingMode, FrontFace, Gpu, GraphicsPipelineAttachments,
GraphicsPipelineDesc, ImageFormat, Pipeline, PipelineLayout, PolygonMode, PushConstantRange,
Sampler, SamplerAddressMode, SamplerDesc, SamplerFilter, ShaderDesc, ShaderStageFlags,
- SpecConstant, Topology,
+ SpecConstant, Topology, VertexOrMeshShader,
};
use narcissus_maths::{Mat4, Vec2};
pub transform_buffer_address: BufferAddress<'a>,
}
+#[repr(C)]
+pub struct BlockConstants {
+ pub clip_from_model: Mat4,
+}
+
#[repr(C)]
pub struct Draw2dClearConstants<'a> {
pub tile_resolution_x: u32,
pub compute_bind_group_layout: BindGroupLayout,
pub basic_pipeline: Pipeline,
+ pub block_pipeline: Pipeline,
pub draw_2d_bin_0_clear_pipeline: Pipeline,
pub draw_2d_bin_1_scatter_pipeline_workgroup_size: u32,
gpu.debug_name_bind_group_layout(compute_bind_group_layout, "compute");
let basic_pipeline = gpu.create_graphics_pipeline(&GraphicsPipelineDesc {
- vertex_shader: ShaderDesc {
+ vertex_or_mesh_shader: VertexOrMeshShader::Vertex(ShaderDesc {
code: crate::BASIC_SPV,
entry: c"vertex",
..default()
- },
+ }),
fragment_shader: ShaderDesc {
code: crate::BASIC_SPV,
entry: c"fragment",
gpu.debug_name_pipeline(basic_pipeline, "basic");
+ let block_pipeline = gpu.create_graphics_pipeline(&GraphicsPipelineDesc {
+ vertex_or_mesh_shader: VertexOrMeshShader::Mesh(ShaderDesc {
+ code: crate::BLOCK_SPV,
+ entry: c"mesh",
+ ..default()
+ }),
+ fragment_shader: ShaderDesc {
+ code: crate::BLOCK_SPV,
+ entry: c"fragment",
+ ..default()
+ },
+ layout: PipelineLayout {
+ bind_group_layouts: &[graphics_bind_group_layout],
+ push_constant_ranges: &[PushConstantRange {
+ stage_flags: ShaderStageFlags::MESH,
+ offset: 0,
+ size: std::mem::size_of::<BlockConstants>() as u32,
+ }],
+ },
+ attachments: GraphicsPipelineAttachments {
+ color_attachment_formats: &[ImageFormat::RGBA16_FLOAT],
+ depth_attachment_format: Some(ImageFormat::DEPTH_F32),
+ stencil_attachment_format: None,
+ },
+ topology: Topology::Triangles,
+ primitive_restart: false,
+ polygon_mode: PolygonMode::Fill,
+ culling_mode: CullingMode::Back,
+ front_face: FrontFace::CounterClockwise,
+ blend_mode: BlendMode::Opaque,
+ depth_bias: None,
+ depth_compare_op: CompareOp::GreaterOrEqual,
+ depth_test_enable: true,
+ depth_write_enable: true,
+ stencil_test_enable: false,
+ stencil_back: default(),
+ stencil_front: default(),
+ });
+
+ gpu.debug_name_pipeline(block_pipeline, "block");
+
let create_compute_pipeline_with_entry =
|code, entry, name, workgroup_size, require_full_subgroups, push_constant_size| {
let push_constant_range = PushConstantRange {
compute_bind_group_layout,
basic_pipeline,
+ block_pipeline,
draw_2d_bin_0_clear_pipeline,
draw_2d_bin_1_scatter_pipeline_workgroup_size,
use narcissus_core::dds;
use shark_shaders::pipelines::{
- BasicConstants, CompositeConstants, ComputeBinds, DRAW_2D_TILE_SIZE, Draw2dClearConstants,
- Draw2dRasterizeConstants, Draw2dResolveConstants, Draw2dScatterConstants, Draw2dSortConstants,
- GraphicsBinds, Pipelines, RadixSortDownsweepConstants, RadixSortUpsweepConstants,
- calculate_spine_size,
+ BasicConstants, BlockConstants, CompositeConstants, ComputeBinds, DRAW_2D_TILE_SIZE,
+ Draw2dClearConstants, Draw2dRasterizeConstants, Draw2dResolveConstants, Draw2dScatterConstants,
+ Draw2dSortConstants, GraphicsBinds, Pipelines, RadixSortDownsweepConstants,
+ RadixSortUpsweepConstants, calculate_spine_size,
};
use crate::helpers::load_obj;
}],
);
+ // Render blocks.
+ gpu.cmd_set_pipeline(cmd_encoder, self.pipelines.block_pipeline);
+ gpu.cmd_set_bind_group(cmd_encoder, 0, &graphics_bind_group);
+ gpu.cmd_push_constants_with_data(
+ cmd_encoder,
+ ShaderStageFlags::MESH,
+ 0,
+ &BlockConstants { clip_from_model },
+ );
+ gpu.cmd_draw_mesh_tasks(cmd_encoder, 1, 1, 1);
+
gpu.cmd_set_pipeline(cmd_encoder, self.pipelines.basic_pipeline);
gpu.cmd_set_bind_group(cmd_encoder, 0, &graphics_bind_group);
gpu.cmd_push_constants_with_data(