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 {
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
RasterVertexOutput vertex(RasterVertexInput input) {
|
||||
RasterVertexOutput vertex(uint vertexID : SV_VERTEXID)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
struct PixelInput {
|
||||
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 {
|
||||
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::*,
|
||||
Globalization::GetUserDefaultLocaleName,
|
||||
Graphics::{
|
||||
Direct3D11::{
|
||||
D3D11_BIND_SHADER_RESOURCE, D3D11_BUFFER_DESC, D3D11_CPU_ACCESS_WRITE,
|
||||
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::*,
|
||||
Direct3D::D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, Direct3D11::*, DirectWrite::*,
|
||||
Dxgi::Common::*, Gdi::LOGFONTW, Imaging::*,
|
||||
},
|
||||
System::SystemServices::LOCALE_NAME_MAX_LENGTH,
|
||||
UI::WindowsAndMessaging::*,
|
||||
|
@ -847,8 +839,8 @@ impl DirectWriteState {
|
|||
measuring_mode,
|
||||
&transform,
|
||||
point(baseline_origin_x, baseline_origin_y),
|
||||
size(DevicePixels(0), DevicePixels(0)),
|
||||
size(0, 0),
|
||||
bitmap_size,
|
||||
size(texture_width, texture_height),
|
||||
);
|
||||
// // todo: support more glyph image formats for more exotic fonts, for now it should fallback to monochrome rendering
|
||||
// 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 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,
|
||||
BindFlags: D3D11_BIND_SHADER_RESOURCE.0 as u32,
|
||||
BindFlags: D3D11_BIND_CONSTANT_BUFFER.0 as u32,
|
||||
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE.0 as u32,
|
||||
MiscFlags: D3D11_RESOURCE_MISC_BUFFER_STRUCTURED.0 as u32,
|
||||
StructureByteStride: std::mem::size_of::<GlyphLayerTextureParams>() as u32,
|
||||
MiscFlags: 0,
|
||||
StructureByteStride: 0,
|
||||
};
|
||||
|
||||
let mut buffer = None;
|
||||
|
@ -1201,37 +1183,8 @@ impl DirectWriteState {
|
|||
.device
|
||||
.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 source =
|
||||
|
@ -1251,6 +1204,105 @@ impl DirectWriteState {
|
|||
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 source =
|
||||
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());
|
||||
|
||||
let device_context = &self.gpu_state.device_context;
|
||||
unsafe { device_context.VSSetShaderResources(0, Some(textures.as_slice())) };
|
||||
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.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP) };
|
||||
unsafe { device_context.VSSetShader(&vertex_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")]
|
||||
self.renderdoc
|
||||
|
@ -1440,9 +1528,8 @@ impl GlyphLayerTexture {
|
|||
|
||||
#[repr(C)]
|
||||
struct GlyphLayerTextureParams {
|
||||
run_color: Rgba,
|
||||
bounds: Bounds<i32>,
|
||||
alpha_texture_index: u32,
|
||||
run_color: Rgba,
|
||||
}
|
||||
|
||||
struct TextRendererWrapper(pub IDWriteTextRenderer);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue