Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions demo/common/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ App::App(const std::shared_ptr<Device> &_device,
canvas = std::make_shared<Canvas>(device, queue);

// TEST: Clip path.
if (false) {
if (true) {
Path2d path;
path.add_rect(RectF(Vec2F(0.0, 0.0), Vec2F(360.0, 360.0)));

Expand Down Expand Up @@ -87,7 +87,7 @@ App::App(const std::shared_ptr<Device> &_device,
svg_scene.load_from_string(std::string(svg_input.begin(), svg_input.end()), *canvas);

// TEST: Replace scene.
// canvas->set_scene(svg_scene.get_scene());
// canvas->set_scene(svg_scene.get_scene());

// TEST: Append scene.
canvas->get_scene()->append_scene(*svg_scene.get_scene(), Transform2::from_scale({1.0, 1.0}));
Expand Down
78 changes: 46 additions & 32 deletions src/core/d3d11/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,7 @@ RendererD3D11::RendererD3D11(const std::shared_ptr<Pathfinder::Device> &device,
fill_ub_id = allocator->allocate_buffer(4 * sizeof(int32_t), BufferType::Uniform, "Fill uniform buffer");
propagate_ub_id = allocator->allocate_buffer(4 * sizeof(int32_t), BufferType::Uniform, "Propagate uniform buffer");
sort_ub_id = allocator->allocate_buffer(4 * sizeof(int32_t), BufferType::Uniform, "Sort uniform buffer");
tile_ub0_id = allocator->allocate_buffer(8 * sizeof(float), BufferType::Uniform, "Tile uniform buffer 0");
tile_ub1_id = allocator->allocate_buffer(8 * sizeof(int32_t), BufferType::Uniform, "Tile uniform buffer 1");

// Unlike D3D9, we use RGBA8 instead of RGBA16F for the mask texture.
mask_texture_id = allocator->allocate_texture({MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT},
TextureFormat::Rgba8Unorm,
"Mask texture");
tile_ub_id = allocator->allocate_buffer(sizeof(TileUniformDx11), BufferType::Uniform, "Tile uniform buffer");
}

void RendererD3D11::set_up_pipelines() {
Expand Down Expand Up @@ -214,7 +208,7 @@ void RendererD3D11::set_up_pipelines() {
Descriptor::storage(0, ShaderStage::Compute), // Read only.
Descriptor::storage(1, ShaderStage::Compute), // Read only.
Descriptor::storage(2, ShaderStage::Compute), // Read only.
Descriptor::image(3, ShaderStage::Compute, "uDest", allocator->get_texture(mask_texture_id)),
Descriptor::image(3, ShaderStage::Compute, "uDest"),
Descriptor::sampled(4,
ShaderStage::Compute,
"uAreaLUT",
Expand All @@ -230,20 +224,14 @@ void RendererD3D11::set_up_pipelines() {
Descriptor::sampled(2, ShaderStage::Compute, "uTextureMetadata"),
Descriptor::sampled(3, ShaderStage::Compute, "uZBuffer"),
Descriptor::sampled(4, ShaderStage::Compute, "uColorTexture0"),
Descriptor::sampled(5,
ShaderStage::Compute,
"uMaskTexture0",
allocator->get_texture(mask_texture_id),
default_sampler),
Descriptor::sampled(5, ShaderStage::Compute, "uMaskTexture0"),
Descriptor::sampled(6,
ShaderStage::Compute,
"uGammaLUT",
allocator->get_texture(dummy_texture_id),
default_sampler), // Unused binding.
Descriptor::image(7, ShaderStage::Compute, "uDestImage"),
Descriptor::uniform(8, ShaderStage::Compute, "bConstantsUniform", allocator->get_buffer(constants_ub_id)),
Descriptor::uniform(9, ShaderStage::Compute, "bUniform0", allocator->get_buffer(tile_ub0_id)),
Descriptor::uniform(10, ShaderStage::Compute, "bUniform1", allocator->get_buffer(tile_ub1_id)),
Descriptor::uniform(8, ShaderStage::Compute, "bUniform", allocator->get_buffer(tile_ub_id)),
});

// These pipelines will be called by order.
Expand Down Expand Up @@ -362,25 +350,20 @@ void RendererD3D11::draw_tiles(uint64_t tiles_d3d11_buffer_id,
Vec2F color_texture_size = color_texture->get_size().to_f32();

// Update uniform buffers.
std::array<float, 8> ubo_data0 = {0,
0,
0,
0, // uClearColor
color_texture_size.x,
color_texture_size.y, // uColorTextureSize0
(float)target_size.x,
(float)target_size.y}; // uFramebufferSize

std::array<int32_t, 5> ubo_data1 = {0,
0, // uZBufferSize
(int32_t)framebuffer_tile_size0.x,
(int32_t)framebuffer_tile_size0.y, // uFramebufferTileSize
clear_op}; // uLoadAction
TileUniformDx11 uniform_data;
std::memset(uniform_data.clear_color, 0, 4 * sizeof(float));
uniform_data.load_action = clear_op;
uniform_data.tile_size = {TILE_WIDTH, TILE_HEIGHT};
uniform_data.color_texture_size = color_texture_size.to_f32();
uniform_data.framebuffer_size = target_size.to_f32();
uniform_data.framebuffer_tile_size = framebuffer_tile_size0;
uniform_data.mask_texture_size = {MASK_FRAMEBUFFER_WIDTH,
(float)(MASK_FRAMEBUFFER_HEIGHT * mask_storage.allocated_page_count)};
uniform_data.texture_metadata_size = {TEXTURE_METADATA_TEXTURE_WIDTH, TEXTURE_METADATA_TEXTURE_HEIGHT};

auto encoder = device->create_command_encoder("Draw tiles");

encoder->write_buffer(allocator->get_buffer(tile_ub0_id), 0, 8 * sizeof(float), ubo_data0.data());
encoder->write_buffer(allocator->get_buffer(tile_ub1_id), 0, 5 * sizeof(int32_t), ubo_data1.data());
encoder->write_buffer(allocator->get_buffer(tile_ub_id), 0, sizeof(TileUniformDx11), &uniform_data);

// Update descriptor set.
tile_descriptor_set->add_or_update({
Expand All @@ -399,6 +382,11 @@ void RendererD3D11::draw_tiles(uint64_t tiles_d3d11_buffer_id,
allocator->get_texture(dummy_texture_id),
default_sampler),
Descriptor::sampled(4, ShaderStage::Compute, "uColorTexture0", color_texture, color_texture_sampler),
Descriptor::sampled(5,
ShaderStage::Compute,
"uMaskTexture0",
allocator->get_texture(mask_storage.framebuffer_id),
default_sampler),
Descriptor::image(7, ShaderStage::Compute, "uDestImage", target_texture),
});

Expand Down Expand Up @@ -562,6 +550,8 @@ void RendererD3D11::prepare_tiles(TileBatchDataD3D11 &batch) {
// Free buffer.
allocator->free_buffer(propagate_metadata_buffer_ids.backdrops);

reallocate_alpha_tile_pages_if_necessary();

draw_fills(*fill_buffer_info, tiles_d3d11_buffer_id, alpha_tiles_buffer_id, propagate_tiles_info);

// Free buffers.
Expand Down Expand Up @@ -952,6 +942,7 @@ void RendererD3D11::draw_fills(FillBufferInfoD3D11 &fill_storage_info,
Descriptor::storage(1, ShaderStage::Compute, tiles_d3d11_buffer),
// Read only.
Descriptor::storage(2, ShaderStage::Compute, alpha_tiles_buffer),
Descriptor::image(3, ShaderStage::Compute, "uDest", allocator->get_texture(mask_storage.framebuffer_id)),
});

encoder->begin_compute_pass();
Expand Down Expand Up @@ -1021,6 +1012,29 @@ void RendererD3D11::free_tile_batch_buffers() {
}
}

TextureFormat RendererD3D11::mask_texture_format() const {
// Unlike D3D9, we use RGBA8 instead of RGBA16F for the mask texture.
return TextureFormat::Rgba8Unorm;
}

void RendererD3D11::reallocate_alpha_tile_pages_if_necessary() {
uint32_t alpha_tile_pages_needed = (alpha_tile_count + 0xffff) >> 16;

if (alpha_tile_pages_needed <= mask_storage.allocated_page_count) {
return;
}

auto new_size = Vec2I(MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT * alpha_tile_pages_needed);
auto format = mask_texture_format();

auto mask_texture_id = allocator->allocate_texture(new_size, format, "Mask texture");

mask_storage = MaskStorage{
mask_texture_id,
alpha_tile_pages_needed,
};
}

} // namespace Pathfinder

#endif
26 changes: 18 additions & 8 deletions src/core/d3d11/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,24 @@ struct PropagateTilesInfoD3D11 {
Range alpha_tile_range;
};

struct MaskStorage {
uint64_t framebuffer_id;
uint32_t allocated_page_count;
};

struct ClipBufferIDs {
/// Optional
uint64_t metadata;

uint64_t tiles;
};

struct TileUniformDx11 {
float clear_color[4]{};
int32_t load_action{}, pad0, pad1, pad2;
Vec2F tile_size;
Vec2F texture_metadata_size;
Vec2F framebuffer_size;
Vec2I framebuffer_tile_size;
Vec2F mask_texture_size;
Vec2F color_texture_size;
};

class RendererD3D11 : public Renderer {
public:
explicit RendererD3D11(const std::shared_ptr<Pathfinder::Device> &device, const std::shared_ptr<Queue> &queue);
Expand Down Expand Up @@ -179,17 +185,21 @@ class RendererD3D11 : public Renderer {

void free_tile_batch_buffers();

TextureFormat mask_texture_format() const override;

void reallocate_alpha_tile_pages_if_necessary();

private:
// Unlike D3D9, we only need mask/dest textures instead of mask/dest framebuffers.
std::shared_ptr<Texture> dest_texture;
uint64_t mask_texture_id;

MaskStorage mask_storage;

std::shared_ptr<ComputePipeline> bound_pipeline, dice_pipeline, bin_pipeline, propagate_pipeline, sort_pipeline,
fill_pipeline, tile_pipeline;

/// Uniform buffers.
uint64_t bin_ub_id, bound_ub_id, dice_ub0_id, dice_ub1_id, fill_ub_id, propagate_ub_id, sort_ub_id, tile_ub0_id,
tile_ub1_id;
uint64_t bin_ub_id, bound_ub_id, dice_ub0_id, dice_ub1_id, fill_ub_id, propagate_ub_id, sort_ub_id, tile_ub_id;

std::shared_ptr<DescriptorSet> bound_descriptor_set, dice_descriptor_set, bin_descriptor_set,
propagate_descriptor_set, sort_descriptor_set, fill_descriptor_set, tile_descriptor_set;
Expand Down
Loading