mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
GpuShader entity
- a step toward render pipeline object
This commit is contained in:
+220
-191
@@ -21,15 +21,17 @@
|
||||
use crate::{
|
||||
core::log::{Log, MessageKind},
|
||||
error::FrameworkError,
|
||||
gl::server::{GlGraphicsServer, GlKind},
|
||||
gl::{
|
||||
server::{GlGraphicsServer, GlKind},
|
||||
ToGlConstant,
|
||||
},
|
||||
gpu_program::{
|
||||
GpuProgramTrait, SamplerKind, ShaderPropertyKind, ShaderResourceDefinition,
|
||||
ShaderResourceKind,
|
||||
GpuProgramTrait, GpuShaderTrait, SamplerKind, ShaderKind, ShaderPropertyKind,
|
||||
ShaderResourceDefinition, ShaderResourceKind,
|
||||
},
|
||||
};
|
||||
use glow::HasContext;
|
||||
use std::ops::Range;
|
||||
use std::{marker::PhantomData, rc::Weak};
|
||||
use std::{marker::PhantomData, ops::Range, rc::Weak};
|
||||
|
||||
impl SamplerKind {
|
||||
pub fn glsl_name(&self) -> &str {
|
||||
@@ -114,49 +116,206 @@ fn patch_error_message(vendor: Vendor, src: &mut String, line_offset: isize) {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn create_shader(
|
||||
server: &GlGraphicsServer,
|
||||
name: String,
|
||||
actual_type: u32,
|
||||
source: &str,
|
||||
mut line_offset: isize,
|
||||
gl_kind: GlKind,
|
||||
) -> Result<glow::Shader, FrameworkError> {
|
||||
let initial_lines_count = count_lines(source);
|
||||
let merged_source = prepare_source_code(source, gl_kind);
|
||||
line_offset -= count_lines(&merged_source) - initial_lines_count;
|
||||
pub struct GlShader {
|
||||
state: Weak<GlGraphicsServer>,
|
||||
pub id: glow::Shader,
|
||||
}
|
||||
|
||||
let shader = server.gl.create_shader(actual_type)?;
|
||||
server.gl.shader_source(shader, &merged_source);
|
||||
server.gl.compile_shader(shader);
|
||||
impl ToGlConstant for ShaderKind {
|
||||
fn into_gl(self) -> u32 {
|
||||
match self {
|
||||
ShaderKind::Vertex => glow::VERTEX_SHADER,
|
||||
ShaderKind::Fragment => glow::FRAGMENT_SHADER,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let status = server.gl.get_shader_compile_status(shader);
|
||||
let mut compilation_message = server.gl.get_shader_info_log(shader);
|
||||
impl GpuShaderTrait for GlShader {}
|
||||
|
||||
if !status {
|
||||
let vendor_str = unsafe { server.gl.get_parameter_string(glow::VENDOR).to_lowercase() };
|
||||
let vendor = Vendor::from_str(vendor_str);
|
||||
patch_error_message(vendor, &mut compilation_message, line_offset);
|
||||
Log::writeln(
|
||||
MessageKind::Error,
|
||||
format!("Failed to compile {name} shader:\n{compilation_message}"),
|
||||
);
|
||||
Err(FrameworkError::ShaderCompilationFailed {
|
||||
shader_name: name,
|
||||
error_message: compilation_message,
|
||||
})
|
||||
} else {
|
||||
let msg = if compilation_message.is_empty()
|
||||
|| compilation_message.chars().all(|c| c.is_whitespace())
|
||||
{
|
||||
format!("Shader {name} compiled successfully!")
|
||||
} else {
|
||||
format!("Shader {name} compiled successfully!\nAdditional info: {compilation_message}")
|
||||
};
|
||||
impl GlShader {
|
||||
pub fn new(
|
||||
server: &GlGraphicsServer,
|
||||
name: String,
|
||||
kind: ShaderKind,
|
||||
mut source: String,
|
||||
resources: &[ShaderResourceDefinition],
|
||||
mut line_offset: isize,
|
||||
) -> Result<Self, FrameworkError> {
|
||||
// Initial validation. The program will be validated once more by the compiler.
|
||||
for resource in resources {
|
||||
for other_resource in resources {
|
||||
if std::ptr::eq(resource, other_resource) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Log::writeln(MessageKind::Information, msg);
|
||||
if std::mem::discriminant(&resource.kind)
|
||||
== std::mem::discriminant(&other_resource.kind)
|
||||
{
|
||||
if resource.binding == other_resource.binding {
|
||||
return Err(FrameworkError::Custom(format!(
|
||||
"Resource {} and {} using the same binding point {} \
|
||||
in the {name} GPU program.",
|
||||
resource.name, other_resource.name, resource.binding
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(shader)
|
||||
if resource.name == other_resource.name {
|
||||
return Err(FrameworkError::Custom(format!(
|
||||
"There are two or more resources with same name {} \
|
||||
in the {name} GPU program.",
|
||||
resource.name
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate appropriate texture binding points and uniform blocks for the specified properties.
|
||||
|
||||
let mut texture_bindings = String::new();
|
||||
|
||||
for property in resources {
|
||||
let resource_name = &property.name;
|
||||
match property.kind {
|
||||
ShaderResourceKind::Texture { kind, .. } => {
|
||||
let glsl_name = kind.glsl_name();
|
||||
texture_bindings += &format!("uniform {glsl_name} {resource_name};\n");
|
||||
}
|
||||
ShaderResourceKind::PropertyGroup(ref fields) => {
|
||||
if fields.is_empty() {
|
||||
Log::warn(format!(
|
||||
"Uniform block {resource_name} is empty and will be ignored!"
|
||||
));
|
||||
continue;
|
||||
}
|
||||
let mut block = format!("struct T{resource_name}{{\n");
|
||||
for field in fields {
|
||||
let field_name = &field.name;
|
||||
match field.kind {
|
||||
ShaderPropertyKind::Float { .. } => {
|
||||
block += &format!("\tfloat {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::FloatArray { max_len, .. } => {
|
||||
block += &format!("\tfloat {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Int { .. } => {
|
||||
block += &format!("\tint {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::IntArray { max_len, .. } => {
|
||||
block += &format!("\tint {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::UInt { .. } => {
|
||||
block += &format!("\tuint {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::UIntArray { max_len, .. } => {
|
||||
block += &format!("\tuint {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Bool { .. } => {
|
||||
block += &format!("\tbool {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Vector2 { .. } => {
|
||||
block += &format!("\tvec2 {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Vector2Array { max_len, .. } => {
|
||||
block += &format!("\tvec2 {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Vector3 { .. } => {
|
||||
block += &format!("\tvec3 {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Vector3Array { max_len, .. } => {
|
||||
block += &format!("\tvec3 {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Vector4 { .. } => {
|
||||
block += &format!("\tvec4 {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Vector4Array { max_len, .. } => {
|
||||
block += &format!("\tvec4 {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Matrix2 { .. } => {
|
||||
block += &format!("\tmat2 {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Matrix2Array { max_len, .. } => {
|
||||
block += &format!("\tmat2 {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Matrix3 { .. } => {
|
||||
block += &format!("\tmat3 {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Matrix3Array { max_len, .. } => {
|
||||
block += &format!("\tmat3 {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Matrix4 { .. } => {
|
||||
block += &format!("\tmat4 {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Matrix4Array { max_len, .. } => {
|
||||
block += &format!("\tmat4 {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Color { .. } => {
|
||||
block += &format!("\tvec4 {field_name};\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
block += "};\n";
|
||||
block += &format!("layout(std140) uniform U{resource_name} {{ T{resource_name} {resource_name}; }};\n");
|
||||
source.insert_str(0, &block);
|
||||
line_offset -= count_lines(&block);
|
||||
}
|
||||
}
|
||||
}
|
||||
source.insert_str(0, &texture_bindings);
|
||||
line_offset -= count_lines(&texture_bindings);
|
||||
|
||||
unsafe {
|
||||
let gl_kind = server.gl_kind();
|
||||
let initial_lines_count = count_lines(&source);
|
||||
let merged_source = prepare_source_code(&source, gl_kind);
|
||||
line_offset -= count_lines(&merged_source) - initial_lines_count;
|
||||
|
||||
let shader = server.gl.create_shader(kind.into_gl())?;
|
||||
server.gl.shader_source(shader, &merged_source);
|
||||
server.gl.compile_shader(shader);
|
||||
|
||||
let status = server.gl.get_shader_compile_status(shader);
|
||||
let mut compilation_message = server.gl.get_shader_info_log(shader);
|
||||
|
||||
if !status {
|
||||
let vendor_str = server.gl.get_parameter_string(glow::VENDOR).to_lowercase();
|
||||
let vendor = Vendor::from_str(vendor_str);
|
||||
patch_error_message(vendor, &mut compilation_message, line_offset);
|
||||
Log::writeln(
|
||||
MessageKind::Error,
|
||||
format!("Failed to compile {name} shader:\n{compilation_message}"),
|
||||
);
|
||||
Err(FrameworkError::ShaderCompilationFailed {
|
||||
shader_name: name,
|
||||
error_message: compilation_message,
|
||||
})
|
||||
} else {
|
||||
let msg = if compilation_message.is_empty()
|
||||
|| compilation_message.chars().all(|c| c.is_whitespace())
|
||||
{
|
||||
format!("Shader {name} compiled successfully!")
|
||||
} else {
|
||||
format!("Shader {name} compiled successfully!\nAdditional info: {compilation_message}")
|
||||
};
|
||||
|
||||
Log::writeln(MessageKind::Information, msg);
|
||||
|
||||
Ok(Self {
|
||||
id: shader,
|
||||
state: server.weak(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for GlShader {
|
||||
fn drop(&mut self) {
|
||||
if let Some(state) = self.state.upgrade() {
|
||||
unsafe {
|
||||
state.gl.delete_shader(self.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,149 +357,20 @@ impl GlProgram {
|
||||
pub fn from_source_and_resources(
|
||||
server: &GlGraphicsServer,
|
||||
program_name: &str,
|
||||
vertex_source: &str,
|
||||
mut vertex_source_line_offset: isize,
|
||||
fragment_source: &str,
|
||||
mut fragment_source_line_offset: isize,
|
||||
vertex_source: String,
|
||||
vertex_source_line_offset: isize,
|
||||
fragment_source: String,
|
||||
fragment_source_line_offset: isize,
|
||||
resources: &[ShaderResourceDefinition],
|
||||
) -> Result<GlProgram, FrameworkError> {
|
||||
let mut vertex_source = vertex_source.to_string();
|
||||
let mut fragment_source = fragment_source.to_string();
|
||||
|
||||
// Initial validation. The program will be validated once more by the compiler.
|
||||
for resource in resources {
|
||||
for other_resource in resources {
|
||||
if std::ptr::eq(resource, other_resource) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if std::mem::discriminant(&resource.kind)
|
||||
== std::mem::discriminant(&other_resource.kind)
|
||||
{
|
||||
if resource.binding == other_resource.binding {
|
||||
return Err(FrameworkError::Custom(format!(
|
||||
"Resource {} and {} using the same binding point {} \
|
||||
in the {program_name} GPU program.",
|
||||
resource.name, other_resource.name, resource.binding
|
||||
)));
|
||||
}
|
||||
|
||||
if resource.name == other_resource.name {
|
||||
return Err(FrameworkError::Custom(format!(
|
||||
"There are two or more resources with same name {} \
|
||||
in the {program_name} GPU program.",
|
||||
resource.name
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate appropriate texture binding points and uniform blocks for the specified properties.
|
||||
for (offset, initial_source) in [
|
||||
(&mut vertex_source_line_offset, &mut vertex_source),
|
||||
(&mut fragment_source_line_offset, &mut fragment_source),
|
||||
] {
|
||||
let mut texture_bindings = String::new();
|
||||
|
||||
for property in resources {
|
||||
let resource_name = &property.name;
|
||||
match property.kind {
|
||||
ShaderResourceKind::Texture { kind, .. } => {
|
||||
let glsl_name = kind.glsl_name();
|
||||
texture_bindings += &format!("uniform {glsl_name} {resource_name};\n");
|
||||
}
|
||||
ShaderResourceKind::PropertyGroup(ref fields) => {
|
||||
if fields.is_empty() {
|
||||
Log::warn(format!(
|
||||
"Uniform block {resource_name} is empty and will be ignored!"
|
||||
));
|
||||
continue;
|
||||
}
|
||||
let mut block = format!("struct T{resource_name}{{\n");
|
||||
for field in fields {
|
||||
let field_name = &field.name;
|
||||
match field.kind {
|
||||
ShaderPropertyKind::Float { .. } => {
|
||||
block += &format!("\tfloat {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::FloatArray { max_len, .. } => {
|
||||
block += &format!("\tfloat {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Int { .. } => {
|
||||
block += &format!("\tint {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::IntArray { max_len, .. } => {
|
||||
block += &format!("\tint {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::UInt { .. } => {
|
||||
block += &format!("\tuint {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::UIntArray { max_len, .. } => {
|
||||
block += &format!("\tuint {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Bool { .. } => {
|
||||
block += &format!("\tbool {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Vector2 { .. } => {
|
||||
block += &format!("\tvec2 {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Vector2Array { max_len, .. } => {
|
||||
block += &format!("\tvec2 {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Vector3 { .. } => {
|
||||
block += &format!("\tvec3 {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Vector3Array { max_len, .. } => {
|
||||
block += &format!("\tvec3 {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Vector4 { .. } => {
|
||||
block += &format!("\tvec4 {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Vector4Array { max_len, .. } => {
|
||||
block += &format!("\tvec4 {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Matrix2 { .. } => {
|
||||
block += &format!("\tmat2 {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Matrix2Array { max_len, .. } => {
|
||||
block += &format!("\tmat2 {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Matrix3 { .. } => {
|
||||
block += &format!("\tmat3 {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Matrix3Array { max_len, .. } => {
|
||||
block += &format!("\tmat3 {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Matrix4 { .. } => {
|
||||
block += &format!("\tmat4 {field_name};\n");
|
||||
}
|
||||
ShaderPropertyKind::Matrix4Array { max_len, .. } => {
|
||||
block += &format!("\tmat4 {field_name}[{max_len}];\n");
|
||||
}
|
||||
ShaderPropertyKind::Color { .. } => {
|
||||
block += &format!("\tvec4 {field_name};\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
block += "};\n";
|
||||
block += &format!("layout(std140) uniform U{resource_name} {{ T{resource_name} {resource_name}; }};\n");
|
||||
initial_source.insert_str(0, &block);
|
||||
*offset -= count_lines(&block);
|
||||
}
|
||||
}
|
||||
}
|
||||
initial_source.insert_str(0, &texture_bindings);
|
||||
*offset -= count_lines(&texture_bindings);
|
||||
}
|
||||
|
||||
let program = Self::from_source(
|
||||
server,
|
||||
program_name,
|
||||
&vertex_source,
|
||||
vertex_source,
|
||||
vertex_source_line_offset,
|
||||
&fragment_source,
|
||||
fragment_source,
|
||||
fragment_source_line_offset,
|
||||
resources,
|
||||
)?;
|
||||
|
||||
unsafe {
|
||||
@@ -384,33 +414,32 @@ impl GlProgram {
|
||||
fn from_source(
|
||||
server: &GlGraphicsServer,
|
||||
name: &str,
|
||||
vertex_source: &str,
|
||||
vertex_source: String,
|
||||
vertex_source_line_offset: isize,
|
||||
fragment_source: &str,
|
||||
fragment_source: String,
|
||||
fragment_source_line_offset: isize,
|
||||
resources: &[ShaderResourceDefinition],
|
||||
) -> Result<GlProgram, FrameworkError> {
|
||||
unsafe {
|
||||
let vertex_shader = create_shader(
|
||||
let vertex_shader = GlShader::new(
|
||||
server,
|
||||
format!("{name}_VertexShader"),
|
||||
glow::VERTEX_SHADER,
|
||||
ShaderKind::Vertex,
|
||||
vertex_source,
|
||||
resources,
|
||||
vertex_source_line_offset,
|
||||
server.gl_kind(),
|
||||
)?;
|
||||
let fragment_shader = create_shader(
|
||||
let fragment_shader = GlShader::new(
|
||||
server,
|
||||
format!("{name}_FragmentShader"),
|
||||
glow::FRAGMENT_SHADER,
|
||||
ShaderKind::Fragment,
|
||||
fragment_source,
|
||||
resources,
|
||||
fragment_source_line_offset,
|
||||
server.gl_kind(),
|
||||
)?;
|
||||
let program = server.gl.create_program()?;
|
||||
server.gl.attach_shader(program, vertex_shader);
|
||||
server.gl.delete_shader(vertex_shader);
|
||||
server.gl.attach_shader(program, fragment_shader);
|
||||
server.gl.delete_shader(fragment_shader);
|
||||
server.gl.attach_shader(program, vertex_shader.id);
|
||||
server.gl.attach_shader(program, fragment_shader.id);
|
||||
server.gl.link_program(program);
|
||||
let status = server.gl.get_program_link_status(program);
|
||||
let link_message = server.gl.get_program_info_log(program);
|
||||
|
||||
@@ -25,11 +25,17 @@ use crate::{
|
||||
framebuffer::{Attachment, GpuFrameBuffer},
|
||||
geometry_buffer::{GeometryBufferDescriptor, GpuGeometryBuffer},
|
||||
gl::{
|
||||
self, framebuffer::GlFrameBuffer, geometry_buffer::GlGeometryBuffer, program::GlProgram,
|
||||
query::GlQuery, read_buffer::GlAsyncReadBuffer, sampler::GlSampler, texture::GlTexture,
|
||||
self,
|
||||
framebuffer::GlFrameBuffer,
|
||||
geometry_buffer::GlGeometryBuffer,
|
||||
program::{GlProgram, GlShader},
|
||||
query::GlQuery,
|
||||
read_buffer::GlAsyncReadBuffer,
|
||||
sampler::GlSampler,
|
||||
texture::GlTexture,
|
||||
ToGlConstant,
|
||||
},
|
||||
gpu_program::{GpuProgram, ShaderResourceDefinition},
|
||||
gpu_program::{GpuProgram, GpuShader, ShaderKind, ShaderResourceDefinition},
|
||||
gpu_texture::{GpuTexture, GpuTextureDescriptor},
|
||||
query::GpuQuery,
|
||||
read_buffer::GpuAsyncReadBuffer,
|
||||
@@ -1031,12 +1037,30 @@ impl GraphicsServer for GlGraphicsServer {
|
||||
Ok(GpuQuery(Rc::new(GlQuery::new(self)?)))
|
||||
}
|
||||
|
||||
fn create_shader(
|
||||
&self,
|
||||
name: String,
|
||||
kind: ShaderKind,
|
||||
source: String,
|
||||
resources: &[ShaderResourceDefinition],
|
||||
line_offset: isize,
|
||||
) -> Result<GpuShader, FrameworkError> {
|
||||
Ok(GpuShader(Rc::new(GlShader::new(
|
||||
self,
|
||||
name,
|
||||
kind,
|
||||
source,
|
||||
resources,
|
||||
line_offset,
|
||||
)?)))
|
||||
}
|
||||
|
||||
fn create_program(
|
||||
&self,
|
||||
name: &str,
|
||||
vertex_source: &str,
|
||||
vertex_source: String,
|
||||
vertex_source_line_offset: isize,
|
||||
fragment_source: &str,
|
||||
fragment_source: String,
|
||||
fragment_source_line_offset: isize,
|
||||
resources: &[ShaderResourceDefinition],
|
||||
) -> Result<GpuProgram, FrameworkError> {
|
||||
|
||||
@@ -33,8 +33,17 @@ use serde::{Deserialize, Serialize};
|
||||
use strum_macros::{AsRefStr, EnumString, VariantNames};
|
||||
|
||||
define_as_any_trait!(GpuProgramAsAny => GpuProgramTrait);
|
||||
|
||||
pub trait GpuProgramTrait: GpuProgramAsAny {}
|
||||
define_shared_wrapper!(GpuProgram<dyn GpuProgramTrait>);
|
||||
|
||||
pub enum ShaderKind {
|
||||
Vertex,
|
||||
Fragment,
|
||||
}
|
||||
|
||||
define_as_any_trait!(GpuShaderAsAny => GpuShaderTrait);
|
||||
pub trait GpuShaderTrait: GpuShaderAsAny {}
|
||||
define_shared_wrapper!(GpuShader<dyn GpuShaderTrait>);
|
||||
|
||||
/// A fallback value for the sampler.
|
||||
///
|
||||
@@ -310,5 +319,3 @@ impl ShaderResourceDefinition {
|
||||
self.name.starts_with("fyrox_")
|
||||
}
|
||||
}
|
||||
|
||||
define_shared_wrapper!(GpuProgram<dyn GpuProgramTrait>);
|
||||
|
||||
@@ -28,7 +28,7 @@ use crate::{
|
||||
error::FrameworkError,
|
||||
framebuffer::{Attachment, GpuFrameBuffer},
|
||||
geometry_buffer::{GeometryBufferDescriptor, GpuGeometryBuffer},
|
||||
gpu_program::{GpuProgram, ShaderResourceDefinition},
|
||||
gpu_program::{GpuProgram, GpuShader, ShaderKind, ShaderResourceDefinition},
|
||||
gpu_texture::{GpuTexture, GpuTextureDescriptor, GpuTextureKind, PixelKind},
|
||||
query::GpuQuery,
|
||||
read_buffer::GpuAsyncReadBuffer,
|
||||
@@ -94,15 +94,27 @@ pub trait GraphicsServer: GraphicsServerAsAny {
|
||||
/// is used to create occlusion queries.
|
||||
fn create_query(&self) -> Result<GpuQuery, FrameworkError>;
|
||||
|
||||
/// Creates a new named GPU shader. The name could be used for debugging purposes. The
|
||||
/// implementation of graphics server will generate proper resource bindings in the shader code
|
||||
/// for you.
|
||||
fn create_shader(
|
||||
&self,
|
||||
name: String,
|
||||
kind: ShaderKind,
|
||||
source: String,
|
||||
resources: &[ShaderResourceDefinition],
|
||||
line_offset: isize,
|
||||
) -> Result<GpuShader, FrameworkError>;
|
||||
|
||||
/// Creates a new named GPU program using a pair of vertex and fragment shaders. The name could
|
||||
/// be used for debugging purposes. The implementation of graphics server will generate proper
|
||||
/// resource bindings in the shader code for you.
|
||||
fn create_program(
|
||||
&self,
|
||||
name: &str,
|
||||
vertex_source: &str,
|
||||
vertex_source: String,
|
||||
vertex_source_line_offset: isize,
|
||||
fragment_source: &str,
|
||||
fragment_source: String,
|
||||
fragment_source_line_offset: isize,
|
||||
resources: &[ShaderResourceDefinition],
|
||||
) -> Result<GpuProgram, FrameworkError>;
|
||||
|
||||
+2
-2
@@ -217,9 +217,9 @@ impl RenderPassContainer {
|
||||
let program_name = format!("{}_{}", shader.definition.name, render_pass.name);
|
||||
match server.create_program(
|
||||
&program_name,
|
||||
&render_pass.vertex_shader,
|
||||
render_pass.vertex_shader.clone(),
|
||||
render_pass.vertex_shader_line,
|
||||
&render_pass.fragment_shader,
|
||||
render_pass.fragment_shader.clone(),
|
||||
render_pass.fragment_shader_line,
|
||||
&shader.definition.resources,
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user