gpu rasterization works now
This commit is contained in:
parent
6907064be6
commit
11dc14ad4d
2 changed files with 175 additions and 71 deletions
|
@ -1,22 +1,39 @@
|
||||||
|
|
||||||
struct RasterVertexInput {
|
|
||||||
float2 position : POSITION;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RasterVertexOutput {
|
struct RasterVertexOutput {
|
||||||
float4 position : SV_Position;
|
float4 position : SV_Position;
|
||||||
|
float2 texcoord : TEXCOORD0;
|
||||||
};
|
};
|
||||||
|
|
||||||
RasterVertexOutput vertex(RasterVertexInput input) {
|
RasterVertexOutput vertex(uint vertexID : SV_VERTEXID)
|
||||||
|
{
|
||||||
RasterVertexOutput output;
|
RasterVertexOutput output;
|
||||||
output.position = float4(input.position, 0.0, 1.0);
|
output.texcoord = float2((vertexID << 1) & 2, vertexID & 2);
|
||||||
|
output.position = float4(output.texcoord * 2.0f - 1.0f, 0.0f, 1.0f);
|
||||||
|
output.position.y = -output.position.y;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PixelInput {
|
struct PixelInput {
|
||||||
float4 position: SV_Position;
|
float4 position: SV_Position;
|
||||||
|
float2 texcoord : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Bounds {
|
||||||
|
int2 origin;
|
||||||
|
int2 size;
|
||||||
|
};
|
||||||
|
|
||||||
|
Texture2D<float4> t_layer : register(t0);
|
||||||
|
SamplerState s_layer : register(s0);
|
||||||
|
|
||||||
|
cbuffer GlyphLayerTextureParams : register(b0) {
|
||||||
|
Bounds bounds;
|
||||||
|
float4 run_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
float4 pixel(PixelInput input): SV_Target {
|
float4 pixel(PixelInput input): SV_Target {
|
||||||
return float4(input.position.xy, 0.0, 1.0);
|
float3 sampled = t_layer.Sample(s_layer, input.texcoord.xy).rgb;
|
||||||
|
float alpha = (sampled.r + sampled.g + sampled.b) / 3;
|
||||||
|
|
||||||
|
return float4(run_color.rgb, alpha);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,16 +10,8 @@ use windows::{
|
||||||
Foundation::*,
|
Foundation::*,
|
||||||
Globalization::GetUserDefaultLocaleName,
|
Globalization::GetUserDefaultLocaleName,
|
||||||
Graphics::{
|
Graphics::{
|
||||||
Direct3D11::{
|
Direct3D::D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, Direct3D11::*, DirectWrite::*,
|
||||||
D3D11_BIND_SHADER_RESOURCE, D3D11_BUFFER_DESC, D3D11_CPU_ACCESS_WRITE,
|
Dxgi::Common::*, Gdi::LOGFONTW, Imaging::*,
|
||||||
D3D11_MAP_WRITE_DISCARD, D3D11_RESOURCE_MISC_BUFFER_STRUCTURED,
|
|
||||||
D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC, ID3D11Device,
|
|
||||||
ID3D11DeviceContext, ID3D11ShaderResourceView, ID3D11Texture2D,
|
|
||||||
},
|
|
||||||
DirectWrite::*,
|
|
||||||
Dxgi::Common::*,
|
|
||||||
Gdi::LOGFONTW,
|
|
||||||
Imaging::*,
|
|
||||||
},
|
},
|
||||||
System::SystemServices::LOCALE_NAME_MAX_LENGTH,
|
System::SystemServices::LOCALE_NAME_MAX_LENGTH,
|
||||||
UI::WindowsAndMessaging::*,
|
UI::WindowsAndMessaging::*,
|
||||||
|
@ -847,8 +839,8 @@ impl DirectWriteState {
|
||||||
measuring_mode,
|
measuring_mode,
|
||||||
&transform,
|
&transform,
|
||||||
point(baseline_origin_x, baseline_origin_y),
|
point(baseline_origin_x, baseline_origin_y),
|
||||||
size(DevicePixels(0), DevicePixels(0)),
|
bitmap_size,
|
||||||
size(0, 0),
|
size(texture_width, texture_height),
|
||||||
);
|
);
|
||||||
// // todo: support more glyph image formats for more exotic fonts, for now it should fallback to monochrome rendering
|
// // todo: support more glyph image formats for more exotic fonts, for now it should fallback to monochrome rendering
|
||||||
// let color_enumerator = unsafe {
|
// let color_enumerator = unsafe {
|
||||||
|
@ -1175,24 +1167,14 @@ impl DirectWriteState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let params = glyph_layers
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(index, e)| GlyphLayerTextureParams {
|
|
||||||
run_color: e.run_color,
|
|
||||||
bounds: e.bounds,
|
|
||||||
alpha_texture_index: index as u32,
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let params_buffer = {
|
let params_buffer = {
|
||||||
let desc = D3D11_BUFFER_DESC {
|
let desc = D3D11_BUFFER_DESC {
|
||||||
ByteWidth: (std::mem::size_of::<GlyphLayerTextureParams>() * params.len()) as u32,
|
ByteWidth: std::mem::size_of::<GlyphLayerTextureParams>() as u32,
|
||||||
Usage: D3D11_USAGE_DYNAMIC,
|
Usage: D3D11_USAGE_DYNAMIC,
|
||||||
BindFlags: D3D11_BIND_SHADER_RESOURCE.0 as u32,
|
BindFlags: D3D11_BIND_CONSTANT_BUFFER.0 as u32,
|
||||||
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE.0 as u32,
|
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE.0 as u32,
|
||||||
MiscFlags: D3D11_RESOURCE_MISC_BUFFER_STRUCTURED.0 as u32,
|
MiscFlags: 0,
|
||||||
StructureByteStride: std::mem::size_of::<GlyphLayerTextureParams>() as u32,
|
StructureByteStride: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut buffer = None;
|
let mut buffer = None;
|
||||||
|
@ -1201,37 +1183,8 @@ impl DirectWriteState {
|
||||||
.device
|
.device
|
||||||
.CreateBuffer(&desc, None, Some(&mut buffer))
|
.CreateBuffer(&desc, None, Some(&mut buffer))
|
||||||
}?;
|
}?;
|
||||||
buffer.unwrap()
|
[buffer]
|
||||||
};
|
};
|
||||||
let params_buffer_view = {
|
|
||||||
let mut view = None;
|
|
||||||
unsafe {
|
|
||||||
self.gpu_state.device.CreateShaderResourceView(
|
|
||||||
¶ms_buffer,
|
|
||||||
None,
|
|
||||||
Some(&mut view),
|
|
||||||
)
|
|
||||||
}?;
|
|
||||||
[view]
|
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let mut dest = std::mem::zeroed();
|
|
||||||
self.gpu_state.device_context.Map(
|
|
||||||
¶ms_buffer,
|
|
||||||
0,
|
|
||||||
D3D11_MAP_WRITE_DISCARD,
|
|
||||||
0,
|
|
||||||
Some(&mut dest),
|
|
||||||
)?;
|
|
||||||
std::ptr::copy_nonoverlapping(params.as_ptr(), dest.pData as *mut _, params.len());
|
|
||||||
self.gpu_state.device_context.Unmap(¶ms_buffer, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
let textures = glyph_layers
|
|
||||||
.iter()
|
|
||||||
.map(|layer| Some(layer.texture_view.clone()))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let vertex_shader = {
|
let vertex_shader = {
|
||||||
let source =
|
let source =
|
||||||
|
@ -1251,6 +1204,105 @@ impl DirectWriteState {
|
||||||
shader.unwrap()
|
shader.unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let render_target_texture = {
|
||||||
|
let mut texture = None;
|
||||||
|
let desc = D3D11_TEXTURE2D_DESC {
|
||||||
|
Width: bitmap_size.width.0 as u32,
|
||||||
|
Height: bitmap_size.height.0 as u32,
|
||||||
|
MipLevels: 1,
|
||||||
|
ArraySize: 1,
|
||||||
|
Format: DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
|
SampleDesc: DXGI_SAMPLE_DESC {
|
||||||
|
Count: 1,
|
||||||
|
Quality: 0,
|
||||||
|
},
|
||||||
|
Usage: D3D11_USAGE_DEFAULT,
|
||||||
|
BindFlags: D3D11_BIND_RENDER_TARGET.0 as u32,
|
||||||
|
CPUAccessFlags: D3D11_CPU_ACCESS_READ.0 as u32,
|
||||||
|
MiscFlags: 0,
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
self.gpu_state
|
||||||
|
.device
|
||||||
|
.CreateTexture2D(&desc, None, Some(&mut texture))
|
||||||
|
}?;
|
||||||
|
texture.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let render_target_view = {
|
||||||
|
let desc = D3D11_RENDER_TARGET_VIEW_DESC {
|
||||||
|
Format: DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
|
ViewDimension: D3D11_RTV_DIMENSION_TEXTURE2D,
|
||||||
|
Anonymous: D3D11_RENDER_TARGET_VIEW_DESC_0 {
|
||||||
|
Texture2D: D3D11_TEX2D_RTV { MipSlice: 0 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let mut rtv = None;
|
||||||
|
unsafe {
|
||||||
|
self.gpu_state.device.CreateRenderTargetView(
|
||||||
|
&render_target_texture,
|
||||||
|
Some(&desc),
|
||||||
|
Some(&mut rtv),
|
||||||
|
)
|
||||||
|
}?;
|
||||||
|
[rtv]
|
||||||
|
};
|
||||||
|
|
||||||
|
let blend_state = {
|
||||||
|
let mut blend_state = None;
|
||||||
|
let desc = D3D11_BLEND_DESC {
|
||||||
|
AlphaToCoverageEnable: false.into(),
|
||||||
|
IndependentBlendEnable: false.into(),
|
||||||
|
RenderTarget: [
|
||||||
|
D3D11_RENDER_TARGET_BLEND_DESC {
|
||||||
|
BlendEnable: true.into(),
|
||||||
|
SrcBlend: D3D11_BLEND_SRC_ALPHA,
|
||||||
|
DestBlend: D3D11_BLEND_INV_SRC_ALPHA,
|
||||||
|
BlendOp: D3D11_BLEND_OP_ADD,
|
||||||
|
SrcBlendAlpha: D3D11_BLEND_ONE,
|
||||||
|
DestBlendAlpha: D3D11_BLEND_INV_SRC_ALPHA,
|
||||||
|
BlendOpAlpha: D3D11_BLEND_OP_ADD,
|
||||||
|
RenderTargetWriteMask: D3D11_COLOR_WRITE_ENABLE_ALL.0 as u8,
|
||||||
|
},
|
||||||
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
self.gpu_state
|
||||||
|
.device
|
||||||
|
.CreateBlendState(&desc, Some(&mut blend_state))
|
||||||
|
}?;
|
||||||
|
blend_state.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let sampler = {
|
||||||
|
let mut sampler = None;
|
||||||
|
let desc = D3D11_SAMPLER_DESC {
|
||||||
|
Filter: D3D11_FILTER_MIN_MAG_MIP_POINT,
|
||||||
|
AddressU: D3D11_TEXTURE_ADDRESS_BORDER,
|
||||||
|
AddressV: D3D11_TEXTURE_ADDRESS_BORDER,
|
||||||
|
AddressW: D3D11_TEXTURE_ADDRESS_BORDER,
|
||||||
|
MipLODBias: 0.0,
|
||||||
|
MaxAnisotropy: 1,
|
||||||
|
ComparisonFunc: D3D11_COMPARISON_ALWAYS,
|
||||||
|
BorderColor: [0.0, 0.0, 0.0, 0.0],
|
||||||
|
MinLOD: 0.0,
|
||||||
|
MaxLOD: 0.0,
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
self.gpu_state
|
||||||
|
.device
|
||||||
|
.CreateSamplerState(&desc, Some(&mut sampler))
|
||||||
|
}?;
|
||||||
|
[sampler]
|
||||||
|
};
|
||||||
|
|
||||||
let pixel_shader = {
|
let pixel_shader = {
|
||||||
let source =
|
let source =
|
||||||
shader_resources::build_shader_blob("color_text_raster", "pixel", "ps_5_0")?;
|
shader_resources::build_shader_blob("color_text_raster", "pixel", "ps_5_0")?;
|
||||||
|
@ -1276,14 +1328,50 @@ impl DirectWriteState {
|
||||||
.start_frame_capture(std::ptr::null(), std::ptr::null());
|
.start_frame_capture(std::ptr::null(), std::ptr::null());
|
||||||
|
|
||||||
let device_context = &self.gpu_state.device_context;
|
let device_context = &self.gpu_state.device_context;
|
||||||
unsafe { device_context.VSSetShaderResources(0, Some(textures.as_slice())) };
|
unsafe { device_context.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP) };
|
||||||
unsafe { device_context.PSSetShaderResources(0, Some(textures.as_slice())) };
|
|
||||||
unsafe { device_context.VSSetShaderResources(1, Some(¶ms_buffer_view)) };
|
|
||||||
unsafe { device_context.PSSetShaderResources(1, Some(¶ms_buffer_view)) };
|
|
||||||
unsafe { device_context.VSSetShader(&vertex_shader, None) };
|
unsafe { device_context.VSSetShader(&vertex_shader, None) };
|
||||||
unsafe { device_context.PSSetShader(&pixel_shader, None) };
|
unsafe { device_context.PSSetShader(&pixel_shader, None) };
|
||||||
|
unsafe { device_context.VSSetConstantBuffers(0, Some(¶ms_buffer)) };
|
||||||
|
unsafe { device_context.PSSetConstantBuffers(0, Some(¶ms_buffer)) };
|
||||||
|
unsafe { device_context.OMSetRenderTargets(Some(&render_target_view), None) };
|
||||||
|
unsafe { device_context.PSSetSamplers(0, Some(&sampler)) };
|
||||||
|
unsafe { device_context.OMSetBlendState(&blend_state, None, 0xffffffff) };
|
||||||
|
|
||||||
unsafe { device_context.DrawInstanced(4, params.len() as u32, 0, 0) };
|
for layer in glyph_layers {
|
||||||
|
let params = GlyphLayerTextureParams {
|
||||||
|
run_color: layer.run_color,
|
||||||
|
bounds: layer.bounds,
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
let mut dest = std::mem::zeroed();
|
||||||
|
self.gpu_state.device_context.Map(
|
||||||
|
params_buffer[0].as_ref().unwrap(),
|
||||||
|
0,
|
||||||
|
D3D11_MAP_WRITE_DISCARD,
|
||||||
|
0,
|
||||||
|
Some(&mut dest),
|
||||||
|
)?;
|
||||||
|
std::ptr::copy_nonoverlapping(¶ms as *const _, dest.pData as *mut _, 1);
|
||||||
|
self.gpu_state
|
||||||
|
.device_context
|
||||||
|
.Unmap(params_buffer[0].as_ref().unwrap(), 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
let texture = [Some(layer.texture_view)];
|
||||||
|
unsafe { device_context.PSSetShaderResources(0, Some(&texture)) };
|
||||||
|
|
||||||
|
let viewport = [D3D11_VIEWPORT {
|
||||||
|
TopLeftX: layer.bounds.origin.x as f32,
|
||||||
|
TopLeftY: layer.bounds.origin.y as f32,
|
||||||
|
Width: layer.bounds.size.width as f32,
|
||||||
|
Height: layer.bounds.size.height as f32,
|
||||||
|
MinDepth: 0.0,
|
||||||
|
MaxDepth: 1.0,
|
||||||
|
}];
|
||||||
|
unsafe { device_context.RSSetViewports(Some(&viewport)) };
|
||||||
|
|
||||||
|
unsafe { device_context.Draw(4, 0) };
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "enable-renderdoc")]
|
#[cfg(feature = "enable-renderdoc")]
|
||||||
self.renderdoc
|
self.renderdoc
|
||||||
|
@ -1440,9 +1528,8 @@ impl GlyphLayerTexture {
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct GlyphLayerTextureParams {
|
struct GlyphLayerTextureParams {
|
||||||
run_color: Rgba,
|
|
||||||
bounds: Bounds<i32>,
|
bounds: Bounds<i32>,
|
||||||
alpha_texture_index: u32,
|
run_color: Rgba,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TextRendererWrapper(pub IDWriteTextRenderer);
|
struct TextRendererWrapper(pub IDWriteTextRenderer);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue