Cleanup: GPU: Remove unused Transform Feedback implementation
Most of the cleanup is inside the metal backend. Pull Request: https://projects.blender.org/blender/blender/pulls/134349
This commit is contained in:
committed by
Clément Foucault
parent
1a62fdc82a
commit
86b70143d5
@@ -824,12 +824,11 @@ static void particle_batch_cache_ensure_procedural_final_points(ParticleHairCach
|
||||
GPUVertFormat format = {0};
|
||||
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
||||
|
||||
/* Transform feedback buffer only needs to be resident in device memory. */
|
||||
GPUUsageType type = GPU_transform_feedback_support() ? GPU_USAGE_DEVICE_ONLY : GPU_USAGE_STATIC;
|
||||
/* Procedural Subdiv buffer only needs to be resident in device memory. */
|
||||
cache->final[subdiv].proc_buf = GPU_vertbuf_create_with_format_ex(
|
||||
format, type | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY);
|
||||
format, GPU_USAGE_DEVICE_ONLY | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY);
|
||||
|
||||
/* Create a destination buffer for the transform feedback. Sized appropriately */
|
||||
/* Create a destination buffer for the procedural Subdiv. Sized appropriately */
|
||||
/* Those are points! not line segments. */
|
||||
uint point_len = cache->final[subdiv].strands_res * cache->strands_len;
|
||||
/* Avoid creating null sized VBO which can lead to crashes on certain platforms. */
|
||||
|
||||
@@ -69,7 +69,6 @@ void GPU_mem_stats_get(int *r_totalmem, int *r_freemem);
|
||||
bool GPU_stereo_quadbuffer_support();
|
||||
|
||||
int GPU_minimum_per_vertex_stride();
|
||||
bool GPU_transform_feedback_support();
|
||||
|
||||
/** WARNING: Should only be called at startup from creator_args. Never call it at runtime. */
|
||||
void GPU_compilation_subprocess_override_set(int count);
|
||||
|
||||
@@ -268,13 +268,6 @@ bool GPU_shader_batch_specializations_is_ready(SpecializationBatchHandle &handle
|
||||
* All of this section is deprecated and should be ported to use the API described above.
|
||||
* \{ */
|
||||
|
||||
enum eGPUShaderTFBType {
|
||||
GPU_SHADER_TFB_NONE = 0, /* Transform feedback unsupported. */
|
||||
GPU_SHADER_TFB_POINTS = 1,
|
||||
GPU_SHADER_TFB_LINES = 2,
|
||||
GPU_SHADER_TFB_TRIANGLES = 3,
|
||||
};
|
||||
|
||||
GPUShader *GPU_shader_create(std::optional<blender::StringRefNull> vertcode,
|
||||
std::optional<blender::StringRefNull> fragcode,
|
||||
std::optional<blender::StringRefNull> geomcode,
|
||||
@@ -297,17 +290,8 @@ GPUShader *GPU_shader_create_ex(std::optional<blender::StringRefNull> vertcode,
|
||||
std::optional<blender::StringRefNull> computecode,
|
||||
std::optional<blender::StringRefNull> libcode,
|
||||
std::optional<blender::StringRefNull> defines,
|
||||
eGPUShaderTFBType tf_type,
|
||||
const char **tf_names,
|
||||
int tf_count,
|
||||
blender::StringRefNull shname);
|
||||
|
||||
/**
|
||||
* Returns true if transform feedback was successfully enabled.
|
||||
*/
|
||||
bool GPU_shader_transform_feedback_enable(GPUShader *shader, blender::gpu::VertBuf *vertbuf);
|
||||
void GPU_shader_transform_feedback_disable(GPUShader *shader);
|
||||
|
||||
/**
|
||||
* Shader cache warming.
|
||||
* For each shader, rendering APIs perform a two-step compilation:
|
||||
|
||||
@@ -212,11 +212,6 @@ int GPU_minimum_per_vertex_stride()
|
||||
return GCaps.minimum_per_vertex_stride;
|
||||
}
|
||||
|
||||
bool GPU_transform_feedback_support()
|
||||
{
|
||||
return GCaps.transform_feedback_support;
|
||||
}
|
||||
|
||||
size_t GPU_max_storage_buffer_size()
|
||||
{
|
||||
return GCaps.max_storage_buffer_size;
|
||||
|
||||
@@ -47,7 +47,6 @@ struct GPUCapabilities {
|
||||
bool mem_stats_support = false;
|
||||
bool geometry_shader_support = false;
|
||||
bool shader_draw_parameters_support = false;
|
||||
bool transform_feedback_support = false;
|
||||
bool hdr_viewport_support = false;
|
||||
bool texture_view_support = true;
|
||||
bool stencil_export_support = false;
|
||||
|
||||
@@ -121,9 +121,6 @@ GPUShader *GPU_shader_create_ex(const std::optional<StringRefNull> vertcode,
|
||||
const std::optional<StringRefNull> computecode,
|
||||
const std::optional<StringRefNull> libcode,
|
||||
const std::optional<StringRefNull> defines,
|
||||
const eGPUShaderTFBType tf_type,
|
||||
const char **tf_names,
|
||||
const int tf_count,
|
||||
const StringRefNull shname)
|
||||
{
|
||||
/* At least a vertex shader and a fragment shader are required, or only a compute shader. */
|
||||
@@ -195,11 +192,6 @@ GPUShader *GPU_shader_create_ex(const std::optional<StringRefNull> vertcode,
|
||||
shader->compute_shader_from_glsl(sources);
|
||||
}
|
||||
|
||||
if (tf_names != nullptr && tf_count > 0) {
|
||||
BLI_assert(tf_type != GPU_SHADER_TFB_NONE);
|
||||
shader->transform_feedback_names_set(Span<const char *>(tf_names, tf_count), tf_type);
|
||||
}
|
||||
|
||||
if (!shader->finalize()) {
|
||||
delete shader;
|
||||
return nullptr;
|
||||
@@ -226,16 +218,8 @@ GPUShader *GPU_shader_create(const std::optional<StringRefNull> vertcode,
|
||||
const std::optional<StringRefNull> defines,
|
||||
const StringRefNull shname)
|
||||
{
|
||||
return GPU_shader_create_ex(vertcode,
|
||||
fragcode,
|
||||
geomcode,
|
||||
std::nullopt,
|
||||
libcode,
|
||||
defines,
|
||||
GPU_SHADER_TFB_NONE,
|
||||
nullptr,
|
||||
0,
|
||||
shname);
|
||||
return GPU_shader_create_ex(
|
||||
vertcode, fragcode, geomcode, std::nullopt, libcode, defines, shname);
|
||||
}
|
||||
|
||||
GPUShader *GPU_shader_create_compute(const std::optional<StringRefNull> computecode,
|
||||
@@ -243,16 +227,8 @@ GPUShader *GPU_shader_create_compute(const std::optional<StringRefNull> computec
|
||||
const std::optional<StringRefNull> defines,
|
||||
const StringRefNull shname)
|
||||
{
|
||||
return GPU_shader_create_ex(std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
computecode,
|
||||
libcode,
|
||||
defines,
|
||||
GPU_SHADER_TFB_NONE,
|
||||
nullptr,
|
||||
0,
|
||||
shname);
|
||||
return GPU_shader_create_ex(
|
||||
std::nullopt, std::nullopt, std::nullopt, computecode, libcode, defines, shname);
|
||||
}
|
||||
|
||||
const GPUShaderCreateInfo *GPU_shader_create_info_get(const char *info_name)
|
||||
@@ -378,16 +354,8 @@ GPUShader *GPU_shader_create_from_python(std::optional<StringRefNull> vertcode,
|
||||
/* Use pyGPUShader as default name for shader. */
|
||||
blender::StringRefNull shname = name.value_or("pyGPUShader");
|
||||
|
||||
GPUShader *sh = GPU_shader_create_ex(vertcode,
|
||||
fragcode,
|
||||
geomcode,
|
||||
std::nullopt,
|
||||
libcode,
|
||||
defines,
|
||||
GPU_SHADER_TFB_NONE,
|
||||
nullptr,
|
||||
0,
|
||||
shname);
|
||||
GPUShader *sh = GPU_shader_create_ex(
|
||||
vertcode, fragcode, geomcode, std::nullopt, libcode, defines, shname);
|
||||
|
||||
return sh;
|
||||
}
|
||||
@@ -515,24 +483,6 @@ void GPU_shader_warm_cache(GPUShader *shader, int limit)
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Transform feedback
|
||||
*
|
||||
* TODO(fclem): Should be replaced by compute shaders.
|
||||
* \{ */
|
||||
|
||||
bool GPU_shader_transform_feedback_enable(GPUShader *shader, blender::gpu::VertBuf *vertbuf)
|
||||
{
|
||||
return unwrap(shader)->transform_feedback_enable(vertbuf);
|
||||
}
|
||||
|
||||
void GPU_shader_transform_feedback_disable(GPUShader *shader)
|
||||
{
|
||||
unwrap(shader)->transform_feedback_disable();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Assign specialization constants.
|
||||
* \{ */
|
||||
@@ -1000,10 +950,6 @@ Shader *ShaderCompiler::compile(const shader::ShaderCreateInfo &info, bool is_ba
|
||||
shader->compute_shader_from_glsl(sources);
|
||||
}
|
||||
|
||||
if (info.tf_type_ != GPU_SHADER_TFB_NONE && info.tf_names_.size() > 0) {
|
||||
shader->transform_feedback_names_set(info.tf_names_.as_span(), info.tf_type_);
|
||||
}
|
||||
|
||||
if (!shader->finalize(&info)) {
|
||||
delete shader;
|
||||
GPU_debug_group_end();
|
||||
|
||||
@@ -250,7 +250,7 @@ std::string ShaderCreateInfo::check_error() const
|
||||
if (this->vertex_source_.is_empty()) {
|
||||
error += "Missing vertex shader in " + this->name_ + ".\n";
|
||||
}
|
||||
if (tf_type_ == GPU_SHADER_TFB_NONE && this->fragment_source_.is_empty()) {
|
||||
if (this->fragment_source_.is_empty()) {
|
||||
error += "Missing fragment shader in " + this->name_ + ".\n";
|
||||
}
|
||||
}
|
||||
@@ -563,8 +563,7 @@ bool gpu_shader_create_info_compile(const char *name_starts_with_filter)
|
||||
continue;
|
||||
}
|
||||
if ((info->metal_backend_only_ && GPU_backend_get_type() != GPU_BACKEND_METAL) ||
|
||||
(GPU_geometry_shader_support() == false && info->geometry_source_ != nullptr) ||
|
||||
(GPU_transform_feedback_support() == false && info->tf_type_ != GPU_SHADER_TFB_NONE))
|
||||
(GPU_geometry_shader_support() == false && info->geometry_source_ != nullptr))
|
||||
{
|
||||
skipped++;
|
||||
continue;
|
||||
|
||||
@@ -885,10 +885,6 @@ struct ShaderCreateInfo {
|
||||
*/
|
||||
Vector<StringRefNull> additional_infos_;
|
||||
|
||||
/* Transform feedback properties. */
|
||||
eGPUShaderTFBType tf_type_ = GPU_SHADER_TFB_NONE;
|
||||
Vector<const char *> tf_names_;
|
||||
|
||||
/* Api-specific parameters. */
|
||||
# ifdef WITH_METAL_BACKEND
|
||||
ushort mtl_max_threads_per_threadgroup_ = 0;
|
||||
@@ -1258,27 +1254,6 @@ struct ShaderCreateInfo {
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Transform feedback properties
|
||||
*
|
||||
* Transform feedback enablement and output binding assignment.
|
||||
* \{ */
|
||||
|
||||
Self &transform_feedback_mode(eGPUShaderTFBType tf_mode)
|
||||
{
|
||||
BLI_assert(tf_mode != GPU_SHADER_TFB_NONE);
|
||||
tf_type_ = tf_mode;
|
||||
return *(Self *)this;
|
||||
}
|
||||
|
||||
Self &transform_feedback_output_name(const char *name)
|
||||
{
|
||||
BLI_assert(tf_type_ != GPU_SHADER_TFB_NONE);
|
||||
tf_names_.append(name);
|
||||
return *(Self *)this;
|
||||
}
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name API-Specific Parameters
|
||||
*
|
||||
|
||||
@@ -25,7 +25,7 @@ class GPULogParser;
|
||||
class Context;
|
||||
|
||||
/* Set to 1 to log the full source of shaders that fail to compile. */
|
||||
#define DEBUG_LOG_SHADER_SRC_ON_ERROR 0
|
||||
#define DEBUG_LOG_SHADER_SRC_ON_ERROR 1
|
||||
|
||||
/**
|
||||
* Compilation is done on a list of GLSL sources. This list contains placeholders that should be
|
||||
@@ -98,11 +98,6 @@ class Shader {
|
||||
* See `GPU_shader_warm_cache(..)` in `GPU_shader.hh` for more information. */
|
||||
virtual void warm_cache(int limit) = 0;
|
||||
|
||||
virtual void transform_feedback_names_set(Span<const char *> name_list,
|
||||
eGPUShaderTFBType geom_type) = 0;
|
||||
virtual bool transform_feedback_enable(VertBuf *) = 0;
|
||||
virtual void transform_feedback_disable() = 0;
|
||||
|
||||
virtual void bind() = 0;
|
||||
virtual void unbind() = 0;
|
||||
|
||||
|
||||
@@ -522,7 +522,6 @@ void MTLBackend::capabilities_init(MTLContext *ctx)
|
||||
GCaps.max_work_group_size[1] = max_threads_per_threadgroup_per_dim;
|
||||
GCaps.max_work_group_size[2] = max_threads_per_threadgroup_per_dim;
|
||||
|
||||
GCaps.transform_feedback_support = true;
|
||||
GCaps.stencil_export_support = true;
|
||||
|
||||
/* OPENGL Related workarounds -- none needed for Metal. */
|
||||
|
||||
@@ -20,9 +20,8 @@ namespace blender::gpu {
|
||||
/* Total maximum buffers which can be bound to an encoder, for use within a shader.
|
||||
* Uniform buffers and storage buffers share the set of available bind buffers.
|
||||
* The total number of buffer bindings must be <= MTL_MAX_BUFFER_BINDINGS
|
||||
* We also require an additional 3 core buffers for:
|
||||
* We also require an additional 2 core buffers for:
|
||||
* - Argument buffer for bindless resources (e.g. samplers)
|
||||
* - Transform feedback buffer
|
||||
* - Default push constant block
|
||||
* Along with up to 6+1 buffers for vertex data, and index data. */
|
||||
#define MTL_MAX_BUFFER_BINDINGS 31
|
||||
|
||||
@@ -847,7 +847,7 @@ class MTLContext : public Context {
|
||||
* to every draw call, to ensure that all state is applied and up
|
||||
* to date. We handle:
|
||||
*
|
||||
* - Buffer bindings (Vertex buffers, Uniforms, UBOs, transform feedback)
|
||||
* - Buffer bindings (Vertex buffers, Uniforms, UBOs)
|
||||
* - Texture bindings
|
||||
* - Sampler bindings (+ argument buffer bindings)
|
||||
* - Dynamic Render pipeline state (on encoder)
|
||||
|
||||
@@ -990,32 +990,6 @@ bool MTLContext::ensure_render_pipeline_state(MTLPrimitiveType mtl_prim_type)
|
||||
this->ensure_texture_bindings(rec, shader_interface, pipeline_state_instance);
|
||||
}
|
||||
|
||||
/* Transform feedback buffer binding. */
|
||||
VertBuf *tf_vbo = this->pipeline_state.active_shader->get_transform_feedback_active_buffer();
|
||||
if (tf_vbo != nullptr && pipeline_state_instance->transform_feedback_buffer_index >= 0) {
|
||||
|
||||
/* Ensure primitive type is either GPU_LINES, GPU_TRIANGLES or GPU_POINT */
|
||||
BLI_assert(mtl_prim_type == MTLPrimitiveTypeLine ||
|
||||
mtl_prim_type == MTLPrimitiveTypeTriangle ||
|
||||
mtl_prim_type == MTLPrimitiveTypePoint);
|
||||
|
||||
/* Fetch active transform feedback buffer from vertbuf */
|
||||
MTLVertBuf *tf_vbo_mtl = static_cast<MTLVertBuf *>(reinterpret_cast<VertBuf *>(tf_vbo));
|
||||
/* Ensure TF buffer is ready. */
|
||||
tf_vbo_mtl->bind();
|
||||
id<MTLBuffer> tf_buffer_mtl = tf_vbo_mtl->get_metal_buffer();
|
||||
BLI_assert(tf_buffer_mtl != nil);
|
||||
|
||||
if (tf_buffer_mtl != nil) {
|
||||
[rec setVertexBuffer:tf_buffer_mtl
|
||||
offset:0
|
||||
atIndex:pipeline_state_instance->transform_feedback_buffer_index];
|
||||
MTL_LOG_INFO("Successfully bound VBO: %p for transform feedback (MTL Buffer: %p)",
|
||||
tf_vbo_mtl,
|
||||
tf_buffer_mtl);
|
||||
}
|
||||
}
|
||||
|
||||
/* Matrix Bindings. */
|
||||
/* This is now called upon shader bind. We may need to re-evaluate this though,
|
||||
* as was done here to ensure uniform changes between draws were tracked.
|
||||
|
||||
@@ -84,8 +84,6 @@ struct MTLRenderPipelineStateInstance {
|
||||
int base_storage_buffer_index;
|
||||
/* buffer bind slot used for null attributes (-1 if not needed). */
|
||||
int null_attribute_buffer_index;
|
||||
/* buffer bind used for transform feedback output buffer. */
|
||||
int transform_feedback_buffer_index;
|
||||
/* Topology class. */
|
||||
MTLPrimitiveTopologyClass prim_type;
|
||||
|
||||
@@ -173,16 +171,6 @@ class MTLShader : public Shader {
|
||||
/* Context Handle. */
|
||||
MTLContext *context_ = nullptr;
|
||||
|
||||
/** Transform Feedback. */
|
||||
/* Transform feedback mode. */
|
||||
eGPUShaderTFBType transform_feedback_type_ = GPU_SHADER_TFB_NONE;
|
||||
/* Transform feedback outputs written to TFB buffer. */
|
||||
blender::Vector<std::string> tf_output_name_list_;
|
||||
/* Whether transform feedback is currently active. */
|
||||
bool transform_feedback_active_ = false;
|
||||
/* Vertex buffer to write transform feedback data into. */
|
||||
VertBuf *transform_feedback_vertbuf_ = nullptr;
|
||||
|
||||
/** Shader source code. */
|
||||
MTLShaderBuilder *shd_builder_ = nullptr;
|
||||
NSString *vertex_function_name_ = @"";
|
||||
@@ -294,11 +282,6 @@ class MTLShader : public Shader {
|
||||
std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const override;
|
||||
std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const override;
|
||||
|
||||
void transform_feedback_names_set(Span<const char *> name_list,
|
||||
const eGPUShaderTFBType geom_type) override;
|
||||
bool transform_feedback_enable(VertBuf *buf) override;
|
||||
void transform_feedback_disable() override;
|
||||
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
|
||||
@@ -335,9 +318,6 @@ class MTLShader : public Shader {
|
||||
{
|
||||
return compute_pso_common_state_;
|
||||
}
|
||||
/* Transform Feedback. */
|
||||
VertBuf *get_transform_feedback_active_buffer();
|
||||
bool has_transform_feedback_varying(std::string str);
|
||||
|
||||
private:
|
||||
/* Generate MSL shader from GLSL source. */
|
||||
|
||||
@@ -318,9 +318,7 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info)
|
||||
else {
|
||||
/* Vertex/Fragment path. */
|
||||
BLI_assert([vertex_function_name_ length] > 0);
|
||||
if (transform_feedback_type_ == GPU_SHADER_TFB_NONE) {
|
||||
BLI_assert([fragment_function_name_ length] > 0);
|
||||
}
|
||||
BLI_assert([fragment_function_name_ length] > 0);
|
||||
BLI_assert([shd_builder_->msl_source_vert_ length] > 0);
|
||||
}
|
||||
|
||||
@@ -361,13 +359,6 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info)
|
||||
shd_builder_->msl_source_compute_ :
|
||||
shd_builder_->msl_source_frag_);
|
||||
|
||||
/* Transform feedback, skip compilation. */
|
||||
if (src_stage == ShaderStage::FRAGMENT && (transform_feedback_type_ != GPU_SHADER_TFB_NONE))
|
||||
{
|
||||
shader_library_frag_ = nil;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Concatenate common source. */
|
||||
NSString *str = [NSString stringWithUTF8String:datatoc_mtl_shader_common_msl];
|
||||
NSString *source_with_header_a = [str stringByAppendingString:source_to_compile];
|
||||
@@ -473,33 +464,6 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info)
|
||||
return true;
|
||||
}
|
||||
|
||||
void MTLShader::transform_feedback_names_set(Span<const char *> name_list,
|
||||
const eGPUShaderTFBType geom_type)
|
||||
{
|
||||
tf_output_name_list_.clear();
|
||||
for (int i = 0; i < name_list.size(); i++) {
|
||||
tf_output_name_list_.append(std::string(name_list[i]));
|
||||
}
|
||||
transform_feedback_type_ = geom_type;
|
||||
}
|
||||
|
||||
bool MTLShader::transform_feedback_enable(blender::gpu::VertBuf *buf)
|
||||
{
|
||||
BLI_assert(transform_feedback_type_ != GPU_SHADER_TFB_NONE);
|
||||
BLI_assert(buf);
|
||||
transform_feedback_active_ = true;
|
||||
transform_feedback_vertbuf_ = buf;
|
||||
BLI_assert(static_cast<MTLVertBuf *>(transform_feedback_vertbuf_)->get_usage_type() ==
|
||||
GPU_USAGE_DEVICE_ONLY);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MTLShader::transform_feedback_disable()
|
||||
{
|
||||
transform_feedback_active_ = false;
|
||||
transform_feedback_vertbuf_ = nullptr;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -1138,25 +1102,6 @@ MTLRenderPipelineStateInstance *MTLShader::bake_pipeline_state(
|
||||
type:MTLDataTypeInt
|
||||
withName:@"MTL_storage_buffer_base_index"];
|
||||
|
||||
/* Transform feedback constant.
|
||||
* Ensure buffer is placed after existing buffers, including default buffers. */
|
||||
int MTL_transform_feedback_buffer_index = -1;
|
||||
if (this->transform_feedback_type_ != GPU_SHADER_TFB_NONE) {
|
||||
/* If using argument buffers, insert index after argument buffer index. Otherwise, insert
|
||||
* after uniform buffer bindings. */
|
||||
MTL_transform_feedback_buffer_index =
|
||||
MTL_uniform_buffer_base_index +
|
||||
((mtl_interface->uses_argument_buffer_for_samplers()) ?
|
||||
(mtl_interface->get_argument_buffer_bind_index(ShaderStage::VERTEX) + 1) :
|
||||
(mtl_interface->get_max_buffer_index() + 2));
|
||||
}
|
||||
|
||||
if (this->transform_feedback_type_ != GPU_SHADER_TFB_NONE) {
|
||||
[values setConstantValue:&MTL_transform_feedback_buffer_index
|
||||
type:MTLDataTypeInt
|
||||
withName:@"MTL_transform_feedback_buffer_index"];
|
||||
}
|
||||
|
||||
/* Clipping planes. */
|
||||
int MTL_clip_distances_enabled = (pipeline_descriptor.clipping_plane_enable_mask > 0) ? 1 : 0;
|
||||
|
||||
@@ -1226,32 +1171,25 @@ MTLRenderPipelineStateInstance *MTLShader::bake_pipeline_state(
|
||||
}
|
||||
}
|
||||
|
||||
/* If transform feedback is used, Vertex-only stage */
|
||||
if (transform_feedback_type_ == GPU_SHADER_TFB_NONE) {
|
||||
desc.fragmentFunction = [shader_library_frag_ newFunctionWithName:fragment_function_name_
|
||||
constantValues:values
|
||||
error:&error];
|
||||
if (error) {
|
||||
bool has_error = (
|
||||
[[error localizedDescription] rangeOfString:@"Compilation succeeded"].location ==
|
||||
NSNotFound);
|
||||
desc.fragmentFunction = [shader_library_frag_ newFunctionWithName:fragment_function_name_
|
||||
constantValues:values
|
||||
error:&error];
|
||||
if (error) {
|
||||
bool has_error = (
|
||||
[[error localizedDescription] rangeOfString:@"Compilation succeeded"].location ==
|
||||
NSNotFound);
|
||||
|
||||
const char *errors_c_str = [[error localizedDescription] UTF8String];
|
||||
const StringRefNull source = shd_builder_->glsl_fragment_source_;
|
||||
const char *errors_c_str = [[error localizedDescription] UTF8String];
|
||||
const StringRefNull source = shd_builder_->glsl_fragment_source_;
|
||||
|
||||
MTLLogParser parser;
|
||||
print_log({source}, errors_c_str, "FragShader", has_error, &parser);
|
||||
MTLLogParser parser;
|
||||
print_log({source}, errors_c_str, "FragShader", has_error, &parser);
|
||||
|
||||
/* Only exit out if genuine error and not warning */
|
||||
if (has_error) {
|
||||
return nullptr;
|
||||
}
|
||||
/* Only exit out if genuine error and not warning */
|
||||
if (has_error) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
desc.fragmentFunction = nil;
|
||||
desc.rasterizationEnabled = false;
|
||||
}
|
||||
|
||||
/* Setup pixel format state */
|
||||
for (int color_attachment = 0; color_attachment < GPU_FB_MAX_COLOR_ATTACHMENT;
|
||||
@@ -1300,12 +1238,6 @@ MTLRenderPipelineStateInstance *MTLShader::bake_pipeline_state(
|
||||
MTL_MAX_BUFFER_BINDINGS,
|
||||
"UBO and SSBO bindings exceed the fragment bind table limit.");
|
||||
|
||||
/* Transform feedback buffer. */
|
||||
if (transform_feedback_type_ != GPU_SHADER_TFB_NONE) {
|
||||
BLI_assert_msg(MTL_transform_feedback_buffer_index < MTL_MAX_BUFFER_BINDINGS,
|
||||
"Transform feedback buffer binding exceeds the fragment bind table limit.");
|
||||
}
|
||||
|
||||
/* Argument buffer. */
|
||||
if (mtl_interface->uses_argument_buffer_for_samplers()) {
|
||||
BLI_assert_msg(mtl_interface->get_argument_buffer_bind_index() < MTL_MAX_BUFFER_BINDINGS,
|
||||
@@ -1344,7 +1276,6 @@ MTLRenderPipelineStateInstance *MTLShader::bake_pipeline_state(
|
||||
pso_inst->base_uniform_buffer_index = MTL_uniform_buffer_base_index;
|
||||
pso_inst->base_storage_buffer_index = MTL_storage_buffer_base_index;
|
||||
pso_inst->null_attribute_buffer_index = (using_null_buffer) ? null_buffer_index : -1;
|
||||
pso_inst->transform_feedback_buffer_index = MTL_transform_feedback_buffer_index;
|
||||
pso_inst->prim_type = prim_type;
|
||||
|
||||
pso_inst->reflection_data_available = (reflection_data != nil);
|
||||
@@ -1612,30 +1543,6 @@ MTLComputePipelineStateInstance *MTLShader::bake_compute_pipeline_state(
|
||||
}
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name SSBO-vertex-fetch-mode attribute control.
|
||||
* \{ */
|
||||
|
||||
blender::gpu::VertBuf *MTLShader::get_transform_feedback_active_buffer()
|
||||
{
|
||||
if (transform_feedback_type_ == GPU_SHADER_TFB_NONE || !transform_feedback_active_) {
|
||||
return nullptr;
|
||||
}
|
||||
return transform_feedback_vertbuf_;
|
||||
}
|
||||
|
||||
bool MTLShader::has_transform_feedback_varying(std::string str)
|
||||
{
|
||||
if (this->transform_feedback_type_ == GPU_SHADER_TFB_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (std::find(tf_output_name_list_.begin(), tf_output_name_list_.end(), str) !=
|
||||
tf_output_name_list_.end());
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* Since this is going to be compiling shaders in a multi-threaded fashion we
|
||||
* don't want to create an instance per context as we want to restrict the
|
||||
* number of simultaneous compilation threads to ensure system responsiveness.
|
||||
|
||||
@@ -121,7 +121,6 @@
|
||||
* Uniform buffers <-- MTL_uniform_buffer_base_index+1
|
||||
* Storage buffers <-- MTL_storage_buffer_base_index
|
||||
* Samplers/argument buffer table <-- last buffer + 1
|
||||
* Transform feedback buffer <-- MTL_transform_feedback_buffer_index ~last_buffer+2
|
||||
*
|
||||
* Up to a maximum of 31 bindings.
|
||||
*/
|
||||
@@ -351,8 +350,6 @@ class MSLGeneratorInterface {
|
||||
* Final shader uses the intersection between the two sets. */
|
||||
blender::Vector<MSLVertexOutputAttribute> fragment_input_varyings;
|
||||
blender::Vector<MSLFragmentOutputAttribute> fragment_outputs;
|
||||
/* Transform feedback interface. */
|
||||
blender::Vector<MSLVertexOutputAttribute> vertex_output_varyings_tf;
|
||||
/* Clip Distances. */
|
||||
blender::Vector<char> clip_distances;
|
||||
/* Max bind IDs. */
|
||||
@@ -378,7 +375,6 @@ class MSLGeneratorInterface {
|
||||
bool uses_gl_FragStencilRefARB;
|
||||
bool uses_gpu_layer;
|
||||
bool uses_gpu_viewport_index;
|
||||
bool uses_transform_feedback;
|
||||
bool uses_barycentrics;
|
||||
/* Compute shader global variables. */
|
||||
bool uses_gl_GlobalInvocationID;
|
||||
@@ -426,7 +422,6 @@ class MSLGeneratorInterface {
|
||||
std::string generate_msl_uniform_structs(ShaderStage shader_stage);
|
||||
std::string generate_msl_vertex_in_struct();
|
||||
std::string generate_msl_vertex_out_struct(ShaderStage shader_stage);
|
||||
std::string generate_msl_vertex_transform_feedback_out_struct(ShaderStage shader_stage);
|
||||
std::string generate_msl_fragment_struct(bool is_input);
|
||||
std::string generate_msl_vertex_inputs_string();
|
||||
std::string generate_msl_fragment_inputs_string();
|
||||
@@ -440,7 +435,6 @@ class MSLGeneratorInterface {
|
||||
std::string generate_msl_uniform_block_population(ShaderStage stage);
|
||||
std::string generate_msl_vertex_attribute_input_population();
|
||||
std::string generate_msl_vertex_output_population();
|
||||
std::string generate_msl_vertex_output_tf_population();
|
||||
std::string generate_msl_fragment_input_population();
|
||||
std::string generate_msl_fragment_output_population();
|
||||
std::string generate_msl_uniform_undefs(ShaderStage stage);
|
||||
|
||||
@@ -393,15 +393,7 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
|
||||
|
||||
/* Verify Source sizes are greater than zero. */
|
||||
BLI_assert(shd_builder_->glsl_vertex_source_.empty() == false);
|
||||
if (!msl_iface.uses_transform_feedback) {
|
||||
BLI_assert(shd_builder_->glsl_fragment_source_.empty() == false);
|
||||
}
|
||||
|
||||
if (transform_feedback_type_ != GPU_SHADER_TFB_NONE) {
|
||||
/* Ensure #TransformFeedback is configured correctly. */
|
||||
BLI_assert(tf_output_name_list_.is_empty() == false);
|
||||
msl_iface.uses_transform_feedback = true;
|
||||
}
|
||||
BLI_assert(shd_builder_->glsl_fragment_source_.empty() == false);
|
||||
|
||||
/* Concatenate msl_shader_defines to provide functionality mapping
|
||||
* from GLSL to MSL. Also include additional GPU defines for
|
||||
@@ -416,9 +408,7 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
|
||||
}
|
||||
|
||||
shd_builder_->glsl_vertex_source_ = msl_defines_string + shd_builder_->glsl_vertex_source_;
|
||||
if (!msl_iface.uses_transform_feedback) {
|
||||
shd_builder_->glsl_fragment_source_ = msl_defines_string + shd_builder_->glsl_fragment_source_;
|
||||
}
|
||||
shd_builder_->glsl_fragment_source_ = msl_defines_string + shd_builder_->glsl_fragment_source_;
|
||||
|
||||
/**** Extract usage of GL globals. ****/
|
||||
/* NOTE(METAL): Currently still performing fallback string scan, as info->builtins_ does
|
||||
@@ -454,7 +444,7 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
|
||||
msl_iface.uses_gpu_viewport_index = bool(info->builtins_ & BuiltinBits::VIEWPORT_INDEX);
|
||||
|
||||
/** Identify usage of fragment-shader builtins. */
|
||||
if (!msl_iface.uses_transform_feedback) {
|
||||
{
|
||||
std::smatch gl_special_cases;
|
||||
msl_iface.uses_gl_PointCoord = bool(info->builtins_ & BuiltinBits::POINT_COORD) ||
|
||||
shd_builder_->glsl_fragment_source_.find("gl_PointCoord") !=
|
||||
@@ -645,9 +635,6 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
|
||||
|
||||
/* Generate VertexOut and TransformFeedbackOutput structs. */
|
||||
ss_vertex << msl_iface.generate_msl_vertex_out_struct(ShaderStage::VERTEX);
|
||||
if (msl_iface.uses_transform_feedback) {
|
||||
ss_vertex << msl_iface.generate_msl_vertex_transform_feedback_out_struct(ShaderStage::VERTEX);
|
||||
}
|
||||
|
||||
/* Class Closing Bracket to end shader global scope. */
|
||||
ss_vertex << "};" << std::endl;
|
||||
@@ -656,7 +643,7 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
|
||||
ss_vertex << msl_iface.generate_msl_vertex_entry_stub();
|
||||
|
||||
/*** Generate FRAGMENT Stage. ***/
|
||||
if (!msl_iface.uses_transform_feedback) {
|
||||
{
|
||||
|
||||
/* Conditional defines. */
|
||||
if (msl_iface.use_argument_buffer_for_samplers()) {
|
||||
@@ -788,14 +775,12 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
|
||||
vertex_fs << ss_vertex.str();
|
||||
vertex_fs.close();
|
||||
|
||||
if (!msl_iface.uses_transform_feedback) {
|
||||
std::ofstream fragment_fs;
|
||||
fragment_fs.open(
|
||||
(std::string(path_cstr) + "/" + std::string(this->name) + "_GeneratedFragmentShader.msl")
|
||||
.c_str());
|
||||
fragment_fs << ss_fragment.str();
|
||||
fragment_fs.close();
|
||||
}
|
||||
std::ofstream fragment_fs;
|
||||
fragment_fs.open(
|
||||
(std::string(path_cstr) + "/" + std::string(this->name) + "_GeneratedFragmentShader.msl")
|
||||
.c_str());
|
||||
fragment_fs << ss_fragment.str();
|
||||
fragment_fs.close();
|
||||
|
||||
shader_debug_printf(
|
||||
"Vertex Shader Saved to: %s\n",
|
||||
@@ -804,9 +789,7 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
|
||||
|
||||
/* Set MSL source NSString's. Required by Metal API. */
|
||||
NSString *msl_final_vert = [NSString stringWithUTF8String:ss_vertex.str().c_str()];
|
||||
NSString *msl_final_frag = (msl_iface.uses_transform_feedback) ?
|
||||
(@"") :
|
||||
([NSString stringWithUTF8String:ss_fragment.str().c_str()]);
|
||||
NSString *msl_final_frag = [NSString stringWithUTF8String:ss_fragment.str().c_str()];
|
||||
|
||||
this->shader_source_from_msl(msl_final_vert, msl_final_frag);
|
||||
|
||||
@@ -1364,10 +1347,6 @@ void MSLGeneratorInterface::prepare_from_createinfo(const shader::ShaderCreateIn
|
||||
max_tex_bind_index = max_ii(max_tex_bind_index, msl_image.slot);
|
||||
}
|
||||
}
|
||||
|
||||
/* Transform feedback. */
|
||||
uses_transform_feedback = (create_info_->tf_type_ != GPU_SHADER_TFB_NONE) &&
|
||||
(create_info_->tf_names_.is_empty() == false);
|
||||
}
|
||||
|
||||
bool MSLGeneratorInterface::use_argument_buffer_for_samplers() const
|
||||
@@ -1444,12 +1423,7 @@ std::string MSLGeneratorInterface::generate_msl_vertex_entry_stub()
|
||||
|
||||
/* Generate function entry point signature w/ resource bindings and inputs. */
|
||||
out << "vertex ";
|
||||
if (this->uses_transform_feedback) {
|
||||
out << "void ";
|
||||
}
|
||||
else {
|
||||
out << get_stage_class_name(ShaderStage::VERTEX) << "::VertexOut ";
|
||||
}
|
||||
out << get_stage_class_name(ShaderStage::VERTEX) << "::VertexOut ";
|
||||
#ifndef NDEBUG
|
||||
out << "vertex_function_entry_" << parent_shader_.name_get() << "(\n\t";
|
||||
#else
|
||||
@@ -1497,14 +1471,7 @@ std::string MSLGeneratorInterface::generate_msl_vertex_entry_stub()
|
||||
out << "if(is_function_constant_defined(MTL_global_pointsize)){ output.pointsize = "
|
||||
"(MTL_global_pointsize > 0.0)?MTL_global_pointsize:output.pointsize; }"
|
||||
<< std::endl;
|
||||
|
||||
/* Populate transform feedback buffer. */
|
||||
if (this->uses_transform_feedback) {
|
||||
out << this->generate_msl_vertex_output_tf_population();
|
||||
}
|
||||
else {
|
||||
out << "\treturn output;" << std::endl;
|
||||
}
|
||||
out << "\treturn output;" << std::endl;
|
||||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
@@ -1775,14 +1742,6 @@ std::string MSLGeneratorInterface::generate_msl_vertex_inputs_string()
|
||||
|
||||
this->generate_msl_uniforms_input_string(out, ShaderStage::VERTEX, is_first_parameter);
|
||||
|
||||
/* Transform feedback buffer binding. */
|
||||
if (this->uses_transform_feedback) {
|
||||
out << parameter_delimiter(is_first_parameter) << "\n\tdevice "
|
||||
<< get_stage_class_name(ShaderStage::VERTEX)
|
||||
<< "::VertexOut_TF* "
|
||||
"transform_feedback_results[[buffer(MTL_transform_feedback_buffer_index)]]";
|
||||
}
|
||||
|
||||
/* Generate texture signatures. */
|
||||
this->generate_msl_textures_input_string(out, ShaderStage::VERTEX, is_first_parameter);
|
||||
|
||||
@@ -1994,9 +1953,7 @@ std::string MSLGeneratorInterface::generate_msl_vertex_out_struct(ShaderStage sh
|
||||
out << "typedef struct {" << std::endl;
|
||||
|
||||
/* If we use GL position, our standard output variable will be mapped to '_default_position_'.
|
||||
* Otherwise, we use the FIRST element in the output array.
|
||||
* If transform feedback is enabled, we do not need to output position, unless it
|
||||
* is explicitly specified as a tf output. */
|
||||
* Otherwise, we use the FIRST element in the output array. */
|
||||
bool first_attr_is_position = false;
|
||||
if (this->uses_gl_Position) {
|
||||
|
||||
@@ -2008,17 +1965,15 @@ std::string MSLGeneratorInterface::generate_msl_vertex_out_struct(ShaderStage sh
|
||||
out << ";" << std::endl;
|
||||
}
|
||||
else {
|
||||
if (!this->uses_transform_feedback) {
|
||||
/* Use first output element for position. */
|
||||
BLI_assert(this->vertex_output_varyings.is_empty() == false);
|
||||
BLI_assert(this->vertex_output_varyings[0].type == "vec4");
|
||||
/* Use first output element for position. */
|
||||
BLI_assert(this->vertex_output_varyings.is_empty() == false);
|
||||
BLI_assert(this->vertex_output_varyings[0].type == "vec4");
|
||||
|
||||
/* Use invariance if available. See above for detail. */
|
||||
out << "\tfloat4 " << this->vertex_output_varyings[0].name << " [[position]];";
|
||||
out << " [[invariant]]";
|
||||
out << ";" << std::endl;
|
||||
first_attr_is_position = true;
|
||||
}
|
||||
/* Use invariance if available. See above for detail. */
|
||||
out << "\tfloat4 " << this->vertex_output_varyings[0].name << " [[position]];";
|
||||
out << " [[invariant]]";
|
||||
out << ";" << std::endl;
|
||||
first_attr_is_position = true;
|
||||
}
|
||||
|
||||
/* Generate other vertex output members. */
|
||||
@@ -2112,85 +2067,6 @@ std::string MSLGeneratorInterface::generate_msl_vertex_out_struct(ShaderStage sh
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::string MSLGeneratorInterface::generate_msl_vertex_transform_feedback_out_struct(
|
||||
ShaderStage shader_stage)
|
||||
{
|
||||
BLI_assert(shader_stage == ShaderStage::VERTEX || shader_stage == ShaderStage::FRAGMENT);
|
||||
UNUSED_VARS_NDEBUG(shader_stage);
|
||||
std::stringstream out;
|
||||
vertex_output_varyings_tf.clear();
|
||||
|
||||
out << "typedef struct {" << std::endl;
|
||||
|
||||
/* If we use GL position, our standard output variable will be mapped to '_default_position_'.
|
||||
* Otherwise, we use the FIRST element in the output array -- If transform feedback is enabled,
|
||||
* we do not need to output position */
|
||||
bool first_attr_is_position = false;
|
||||
if (this->uses_gl_Position) {
|
||||
|
||||
if (parent_shader_.has_transform_feedback_varying("gl_Position")) {
|
||||
out << "\tfloat4 pos [[position]];" << std::endl;
|
||||
vertex_output_varyings_tf.append({.type = "vec4",
|
||||
.name = "gl_Position",
|
||||
.interpolation_qualifier = "",
|
||||
.is_array = false,
|
||||
.array_elems = 1});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!this->uses_transform_feedback) {
|
||||
/* Use first output element for position */
|
||||
BLI_assert(this->vertex_output_varyings.is_empty() == false);
|
||||
BLI_assert(this->vertex_output_varyings[0].type == "vec4");
|
||||
first_attr_is_position = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate other vertex outputs. */
|
||||
bool skip_first_index = first_attr_is_position;
|
||||
for (const MSLVertexOutputAttribute &v_out : this->vertex_output_varyings) {
|
||||
|
||||
/* Skip first index if used for position. */
|
||||
if (skip_first_index) {
|
||||
skip_first_index = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!parent_shader_.has_transform_feedback_varying(v_out.name)) {
|
||||
continue;
|
||||
}
|
||||
vertex_output_varyings_tf.append(v_out);
|
||||
|
||||
if (v_out.is_array) {
|
||||
/* TODO(Metal): Support array of matrix types if required. */
|
||||
for (int i = 0; i < v_out.array_elems; i++) {
|
||||
out << "\t" << v_out.type << " " << v_out.name << i
|
||||
<< v_out.get_mtl_interpolation_qualifier() << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Matrix types need to be expressed as their vector sub-components. */
|
||||
if (is_matrix_type(v_out.type)) {
|
||||
BLI_assert(v_out.get_mtl_interpolation_qualifier() == " [[flat]]" &&
|
||||
"Matrix varying types must have [[flat]] interpolation");
|
||||
std::string subtype = get_matrix_subtype(v_out.type);
|
||||
for (int elem = 0; elem < get_matrix_location_count(v_out.type); elem++) {
|
||||
out << "\t" << subtype << " __matrix_" << v_out.name << elem
|
||||
<< v_out.get_mtl_interpolation_qualifier() << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
out << "\t" << v_out.type << " " << v_out.name << v_out.get_mtl_interpolation_qualifier()
|
||||
<< ";" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out << "} VertexOut_TF;" << std::endl << std::endl;
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::string MSLGeneratorInterface::generate_msl_fragment_struct(bool is_input)
|
||||
{
|
||||
std::stringstream out;
|
||||
@@ -2499,9 +2375,8 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population()
|
||||
}
|
||||
else {
|
||||
/* If we are not using gl_Position, first vertex output is used for position.
|
||||
* Ensure it is vec4. If transform feedback is enabled, we do not need position. */
|
||||
if (!this->uses_gl_Position && output_id == 0 && !this->uses_transform_feedback) {
|
||||
|
||||
* Ensure it is vec4. */
|
||||
if (!this->uses_gl_Position && output_id == 0) {
|
||||
out << "\toutput." << v_out.instance_name << "_" << v_out.name << " = to_vec4("
|
||||
<< shader_stage_inst_name << "." << v_out.name << ");" << std::endl;
|
||||
|
||||
@@ -2510,7 +2385,6 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population()
|
||||
<< v_out.name << ".y;" << std::endl;
|
||||
}
|
||||
else {
|
||||
|
||||
/* Assign vertex output. */
|
||||
out << "\toutput." << v_out.instance_name << "_" << v_out.name << " = "
|
||||
<< shader_stage_inst_name << ".";
|
||||
@@ -2529,25 +2403,6 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population()
|
||||
return out.str();
|
||||
}
|
||||
|
||||
/* Copy desired output varyings into transform feedback structure */
|
||||
std::string MSLGeneratorInterface::generate_msl_vertex_output_tf_population()
|
||||
{
|
||||
static const char *shader_stage_inst_name = get_shader_stage_instance_name(ShaderStage::VERTEX);
|
||||
std::stringstream out;
|
||||
out << "\t/* Copy Vertex TF Outputs into transform feedback buffer */" << std::endl;
|
||||
|
||||
/* Populate output vertex variables */
|
||||
/* TODO(Metal): Currently do not need to support output matrix types etc; but may need to
|
||||
* verify for other configurations if these occur in any cases. */
|
||||
for (int v_output = 0; v_output < this->vertex_output_varyings_tf.size(); v_output++) {
|
||||
out << "transform_feedback_results[gl_VertexID]."
|
||||
<< this->vertex_output_varyings_tf[v_output].name << " = " << shader_stage_inst_name << "."
|
||||
<< this->vertex_output_varyings_tf[v_output].name << ";" << std::endl;
|
||||
}
|
||||
out << std::endl;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
/* Copy fragment stage inputs (Vertex Outputs) into local class variables. */
|
||||
std::string MSLGeneratorInterface::generate_msl_fragment_input_population()
|
||||
{
|
||||
|
||||
@@ -21,9 +21,7 @@ namespace blender::gpu {
|
||||
|
||||
class MTLVertBuf : public VertBuf {
|
||||
friend class gpu::MTLTexture; /* For buffer texture. */
|
||||
friend class MTLShader; /* For transform feedback. */
|
||||
friend class MTLBatch;
|
||||
friend class MTLContext; /* For transform feedback. */
|
||||
friend class MTLStorageBuf; /* For bind as SSBO resource access and copy sub. */
|
||||
|
||||
private:
|
||||
|
||||
@@ -590,7 +590,6 @@ void GLBackend::capabilities_init()
|
||||
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_alignment);
|
||||
GCaps.storage_buffer_alignment = size_t(ssbo_alignment);
|
||||
|
||||
GCaps.transform_feedback_support = true;
|
||||
GCaps.texture_view_support = epoxy_gl_version() >= 43 ||
|
||||
epoxy_has_gl_extension("GL_ARB_texture_view");
|
||||
GCaps.stencil_export_support = epoxy_has_gl_extension("GL_ARB_shader_stencil_export");
|
||||
|
||||
@@ -1315,59 +1315,6 @@ void GLShader::unbind()
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Transform feedback
|
||||
*
|
||||
* TODO(fclem): Should be replaced by compute shaders.
|
||||
* \{ */
|
||||
|
||||
void GLShader::transform_feedback_names_set(Span<const char *> name_list,
|
||||
const eGPUShaderTFBType geom_type)
|
||||
{
|
||||
glTransformFeedbackVaryings(
|
||||
program_get(), name_list.size(), name_list.data(), GL_INTERLEAVED_ATTRIBS);
|
||||
transform_feedback_type_ = geom_type;
|
||||
}
|
||||
|
||||
bool GLShader::transform_feedback_enable(blender::gpu::VertBuf *buf_)
|
||||
{
|
||||
if (transform_feedback_type_ == GPU_SHADER_TFB_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GLVertBuf *buf = static_cast<GLVertBuf *>(buf_);
|
||||
|
||||
if (buf->vbo_id_ == 0) {
|
||||
buf->bind();
|
||||
}
|
||||
|
||||
BLI_assert(buf->vbo_id_ != 0);
|
||||
|
||||
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf->vbo_id_);
|
||||
|
||||
switch (transform_feedback_type_) {
|
||||
case GPU_SHADER_TFB_POINTS:
|
||||
glBeginTransformFeedback(GL_POINTS);
|
||||
break;
|
||||
case GPU_SHADER_TFB_LINES:
|
||||
glBeginTransformFeedback(GL_LINES);
|
||||
break;
|
||||
case GPU_SHADER_TFB_TRIANGLES:
|
||||
glBeginTransformFeedback(GL_TRIANGLES);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLShader::transform_feedback_disable()
|
||||
{
|
||||
glEndTransformFeedback();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Uniforms setters
|
||||
* \{ */
|
||||
|
||||
@@ -149,8 +149,6 @@ class GLShader : public Shader {
|
||||
/** True if any shader failed to compile. */
|
||||
bool compilation_failed_ = false;
|
||||
|
||||
eGPUShaderTFBType transform_feedback_type_ = GPU_SHADER_TFB_NONE;
|
||||
|
||||
std::string debug_source;
|
||||
|
||||
public:
|
||||
@@ -176,12 +174,6 @@ class GLShader : public Shader {
|
||||
std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const override;
|
||||
std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const override;
|
||||
|
||||
/** Should be called before linking. */
|
||||
void transform_feedback_names_set(Span<const char *> name_list,
|
||||
eGPUShaderTFBType geom_type) override;
|
||||
bool transform_feedback_enable(VertBuf *buf) override;
|
||||
void transform_feedback_disable() override;
|
||||
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ namespace gpu {
|
||||
|
||||
class GLVertBuf : public VertBuf {
|
||||
friend class GLTexture; /* For buffer texture. */
|
||||
friend class GLShader; /* For transform feedback. */
|
||||
friend class GLStorageBuf; /* For sub copy. */
|
||||
|
||||
private:
|
||||
|
||||
@@ -20,11 +20,13 @@ uniform bool srgbTarget = false;
|
||||
|
||||
vec4 blender_srgb_to_framebuffer_space(vec4 in_color)
|
||||
{
|
||||
#ifndef USE_GPU_SHADER_CREATE_INFO
|
||||
if (srgbTarget) {
|
||||
vec3 c = max(in_color.rgb, vec3(0.0));
|
||||
vec3 c1 = c * (1.0 / 12.92);
|
||||
vec3 c2 = pow((c + 0.055) * (1.0 / 1.055), vec3(2.4));
|
||||
in_color.rgb = mix(c1, c2, step(vec3(0.04045), c));
|
||||
}
|
||||
#endif
|
||||
return in_color;
|
||||
}
|
||||
|
||||
@@ -40,10 +40,6 @@ constant int MTL_AttributeConvert13 [[function_constant(15)]];
|
||||
constant int MTL_AttributeConvert14 [[function_constant(16)]];
|
||||
constant int MTL_AttributeConvert15 [[function_constant(17)]];
|
||||
|
||||
/* Constant to flag binding index of transform feedback buffer.
|
||||
* Unused if function constant not set. */
|
||||
constant int MTL_transform_feedback_buffer_index [[function_constant(18)]];
|
||||
|
||||
/** Clip distance enablement. */
|
||||
/* General toggle to control whether any clipping distances are written at all.
|
||||
* This is an optimization to avoid having the clipping distance shader output
|
||||
|
||||
@@ -714,31 +714,6 @@ bool VKShader::finalize_descriptor_set_layouts(VKDevice &vk_device,
|
||||
return vk_descriptor_set_layout_ != VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Transform feedback
|
||||
*
|
||||
* Not supported in the vulkan backend.
|
||||
*
|
||||
* \{ */
|
||||
|
||||
void VKShader::transform_feedback_names_set(Span<const char *> /*name_list*/,
|
||||
eGPUShaderTFBType /*geom_type*/)
|
||||
{
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
|
||||
bool VKShader::transform_feedback_enable(VertBuf *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void VKShader::transform_feedback_disable()
|
||||
{
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
void VKShader::bind()
|
||||
{
|
||||
/* Intentionally empty. Binding of the pipeline are done just before drawing/dispatching.
|
||||
|
||||
@@ -76,11 +76,6 @@ class VKShader : public Shader {
|
||||
bool is_ready() const;
|
||||
void warm_cache(int limit) override;
|
||||
|
||||
void transform_feedback_names_set(Span<const char *> name_list,
|
||||
eGPUShaderTFBType geom_type) override;
|
||||
bool transform_feedback_enable(VertBuf *) override;
|
||||
void transform_feedback_disable() override;
|
||||
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user