*/
+#include "compiler/glsl/string_to_uint_map.h"
#include "main/glheader.h"
#include "main/context.h"
+#include "main/glspirv.h"
#include "main/hash.h"
#include "main/mtypes.h"
#include "main/shaderapi.h"
#include "main/uniforms.h"
#include "program/program.h"
#include "program/prog_parameter.h"
-#include "program/hash_table.h"
#include "util/ralloc.h"
+#include "util/u_atomic.h"
/**********************************************************************/
/*** Shader object functions ***/
}
if (*ptr) {
/* Unreference the old shader */
- GLboolean deleteFlag = GL_FALSE;
struct gl_shader *old = *ptr;
assert(old->RefCount > 0);
- old->RefCount--;
- deleteFlag = (old->RefCount == 0);
- if (deleteFlag) {
+ if (p_atomic_dec_zero(&old->RefCount)) {
if (old->Name != 0)
_mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
_mesa_delete_shader(ctx, old);
if (sh) {
/* reference new */
- sh->RefCount++;
+ p_atomic_inc(&sh->RefCount);
*ptr = sh;
}
}
if (shader) {
shader->Stage = stage;
shader->Name = name;
+#ifdef DEBUG
+ shader->SourceChecksum = 0xa110c; /* alloc */
+#endif
_mesa_init_shader(shader);
}
return shader;
}
-/**
- * Allocate a new gl_linked_shader object.
- * Called via ctx->Driver.NewShader()
- */
-struct gl_linked_shader *
-_mesa_new_linked_shader(gl_shader_stage stage)
-{
- struct gl_linked_shader *shader;
- shader = rzalloc(NULL, struct gl_linked_shader);
- if (shader) {
- shader->Stage = stage;
- }
- return shader;
-}
-
-
/**
* Delete a shader object.
*/
void
_mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh)
{
+ _mesa_shader_spirv_data_reference(&sh->spirv_data, NULL);
free((void *)sh->Source);
+ free((void *)sh->FallbackSource);
free(sh->Label);
ralloc_free(sh);
}
_mesa_delete_linked_shader(struct gl_context *ctx,
struct gl_linked_shader *sh)
{
+ _mesa_shader_spirv_data_reference(&sh->spirv_data, NULL);
_mesa_reference_program(ctx, &sh->Program, NULL);
ralloc_free(sh);
}
/*** Shader Program object functions ***/
/**********************************************************************/
+void
+_mesa_reference_shader_program_data(struct gl_context *ctx,
+ struct gl_shader_program_data **ptr,
+ struct gl_shader_program_data *data)
+{
+ if (*ptr == data)
+ return;
+
+ if (*ptr) {
+ struct gl_shader_program_data *oldData = *ptr;
+
+ assert(oldData->RefCount > 0);
+
+ if (p_atomic_dec_zero(&oldData->RefCount)) {
+ assert(ctx);
+ assert(oldData->NumUniformStorage == 0 ||
+ oldData->UniformStorage);
+
+ for (unsigned i = 0; i < oldData->NumUniformStorage; ++i)
+ _mesa_uniform_detach_all_driver_storage(&oldData->UniformStorage[i]);
+
+ ralloc_free(oldData);
+ }
+
+ *ptr = NULL;
+ }
+
+ if (data)
+ p_atomic_inc(&data->RefCount);
+
+ *ptr = data;
+}
/**
* Set ptr to point to shProg.
}
if (*ptr) {
/* Unreference the old shader program */
- GLboolean deleteFlag = GL_FALSE;
struct gl_shader_program *old = *ptr;
assert(old->RefCount > 0);
- old->RefCount--;
- deleteFlag = (old->RefCount == 0);
- if (deleteFlag) {
+ if (p_atomic_dec_zero(&old->RefCount)) {
if (old->Name != 0)
_mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
_mesa_delete_shader_program(ctx, old);
assert(!*ptr);
if (shProg) {
- shProg->RefCount++;
+ p_atomic_inc(&shProg->RefCount);
*ptr = shProg;
}
}
+struct gl_shader_program_data *
+_mesa_create_shader_program_data()
+{
+ struct gl_shader_program_data *data;
+ data = rzalloc(NULL, struct gl_shader_program_data);
+ if (data) {
+ data->RefCount = 1;
+ data->InfoLog = ralloc_strdup(data, "");
+ }
+
+ return data;
+}
+
static void
init_shader_program(struct gl_shader_program *prog)
{
prog->TransformFeedback.BufferMode = GL_INTERLEAVED_ATTRIBS;
exec_list_make_empty(&prog->EmptyUniformLocations);
-
- prog->InfoLog = ralloc_strdup(prog, "");
}
/**
shProg = rzalloc(NULL, struct gl_shader_program);
if (shProg) {
shProg->Name = name;
+ shProg->data = _mesa_create_shader_program_data();
+ if (!shProg->data) {
+ ralloc_free(shProg);
+ return NULL;
+ }
init_shader_program(shProg);
}
return shProg;
* Clear (free) the shader program state that gets produced by linking.
*/
void
-_mesa_clear_shader_program_data(struct gl_shader_program *shProg)
+_mesa_clear_shader_program_data(struct gl_context *ctx,
+ struct gl_shader_program *shProg)
{
- unsigned i;
-
- if (shProg->UniformStorage) {
- for (i = 0; i < shProg->NumUniformStorage; ++i)
- _mesa_uniform_detach_all_driver_storage(&shProg->UniformStorage[i]);
- ralloc_free(shProg->UniformStorage);
- shProg->NumUniformStorage = 0;
- shProg->UniformStorage = NULL;
+ for (gl_shader_stage sh = 0; sh < MESA_SHADER_STAGES; sh++) {
+ if (shProg->_LinkedShaders[sh] != NULL) {
+ _mesa_delete_linked_shader(ctx, shProg->_LinkedShaders[sh]);
+ shProg->_LinkedShaders[sh] = NULL;
+ }
}
if (shProg->UniformRemapTable) {
shProg->UniformHash = NULL;
}
- assert(shProg->InfoLog != NULL);
- ralloc_free(shProg->InfoLog);
- shProg->InfoLog = ralloc_strdup(shProg, "");
-
- ralloc_free(shProg->UniformBlocks);
- shProg->UniformBlocks = NULL;
- shProg->NumUniformBlocks = 0;
-
- ralloc_free(shProg->ShaderStorageBlocks);
- shProg->ShaderStorageBlocks = NULL;
- shProg->NumShaderStorageBlocks = 0;
-
- ralloc_free(shProg->AtomicBuffers);
- shProg->AtomicBuffers = NULL;
- shProg->NumAtomicBuffers = 0;
-
- if (shProg->ProgramResourceList) {
- ralloc_free(shProg->ProgramResourceList);
- shProg->ProgramResourceList = NULL;
- shProg->NumProgramResourceList = 0;
+ if (shProg->data && shProg->data->ProgramResourceHash) {
+ _mesa_hash_table_u64_destroy(shProg->data->ProgramResourceHash, NULL);
+ shProg->data->ProgramResourceHash = NULL;
}
+
+ _mesa_reference_shader_program_data(ctx, &shProg->data, NULL);
}
struct gl_shader_program *shProg)
{
GLuint i;
- gl_shader_stage sh;
assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
- _mesa_clear_shader_program_data(shProg);
+ _mesa_clear_shader_program_data(ctx, shProg);
if (shProg->AttributeBindings) {
string_to_uint_map_dtor(shProg->AttributeBindings);
shProg->TransformFeedback.VaryingNames = NULL;
shProg->TransformFeedback.NumVarying = 0;
-
- for (sh = 0; sh < MESA_SHADER_STAGES; sh++) {
- if (shProg->_LinkedShaders[sh] != NULL) {
- _mesa_delete_linked_shader(ctx, shProg->_LinkedShaders[sh]);
- shProg->_LinkedShaders[sh] = NULL;
- }
- }
-
free(shProg->Label);
shProg->Label = NULL;
}
struct gl_shader_program *shProg)
{
_mesa_free_shader_program_data(ctx, shProg);
-
ralloc_free(shProg);
}
void
_mesa_init_shader_object_functions(struct dd_function_table *driver)
{
- driver->NewShader = _mesa_new_linked_shader;
driver->LinkShader = _mesa_ir_link_shader;
}