/**********************************************************
- * Copyright 2008-2009 VMware, Inc. All rights reserved.
+ * Copyright 2008-2022 VMware, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
sizeof(svga->state.hw_draw.enabled_constbufs));
memset(svga->state.hw_draw.enabled_rawbufs, 0,
sizeof(svga->state.hw_draw.enabled_rawbufs));
+ memset(svga->state.hw_draw.enabled_raw_shaderbufs, 0,
+ sizeof(svga->state.hw_draw.enabled_raw_shaderbufs));
memset(svga->state.hw_draw.rawbufs, 0,
sizeof(svga->state.hw_draw.rawbufs));
svga->state.hw_draw.ib = NULL;
/**********************************************************
- * Copyright 2008-2009 VMware, Inc. All rights reserved.
+ * Copyright 2008-2023 VMware, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* including the zero slot for the default constant buffer.
*/
#define SVGA_MAX_CONST_BUFS 15
+#define SVGA_MAX_RAW_BUFS 64
/**
* Maximum constant buffer size that can be set in the
#define SVGA_MAX_CONST_BUF_SIZE (4096 * 4 * sizeof(int))
#define CONST0_UPLOAD_ALIGNMENT 256
+#define SVGA_MAX_UAVIEWS SVGA3D_DX11_1_MAX_UAVIEWS
#define SVGA_MAX_IMAGES SVGA3D_MAX_UAVIEWS
#define SVGA_MAX_SHADER_BUFFERS SVGA3D_MAX_UAVIEWS
#define SVGA_MAX_ATOMIC_BUFFERS SVGA3D_MAX_UAVIEWS
-#define SVGA_MAX_UAVIEWS SVGA3D_DX11_1_MAX_UAVIEWS
enum svga_surface_state
{
* svga_shader_emitter_v10.num_shader_consts.
*/
struct pipe_constant_buffer constbufs[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
- struct svga_raw_buffer rawbufs[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
+ struct svga_raw_buffer rawbufs[PIPE_SHADER_TYPES][SVGA_MAX_RAW_BUFS];
struct pipe_framebuffer_state framebuffer;
float depthscale;
/** Currently bound constant buffer, per shader stage */
struct pipe_resource *constbuf[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
struct svga_constant_buffer constbufoffsets[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
- struct svga_raw_buffer rawbufs[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
- unsigned enabled_rawbufs[PIPE_SHADER_TYPES];
+ struct svga_raw_buffer rawbufs[PIPE_SHADER_TYPES][SVGA_MAX_RAW_BUFS];
+ uint64_t enabled_rawbufs[PIPE_SHADER_TYPES];
/** Bitmask of enabled constant buffers */
unsigned enabled_constbufs[PIPE_SHADER_TYPES];
/* Shader Buffers */
unsigned num_shader_buffers[PIPE_SHADER_TYPES];
struct svga_shader_buffer shader_buffers[PIPE_SHADER_TYPES][SVGA_MAX_SHADER_BUFFERS];
+ uint64_t enabled_raw_shaderbufs[PIPE_SHADER_TYPES];
/* HW Atomic Buffers */
unsigned num_atomic_buffers;
/** bitmasks of which const buffers are changed */
unsigned dirty_constbufs[PIPE_SHADER_TYPES];
- /** bitmasks of which const buffers to be bound as raw buffers */
+ /** bitmasks of which const buffers to be bound as srv raw buffers */
unsigned raw_constbufs[PIPE_SHADER_TYPES];
+ /** bitmasks of which shader buffers to be bound as srv raw buffers */
+ uint64_t raw_shaderbufs[PIPE_SHADER_TYPES];
+
unsigned texture_timestamp;
unsigned uav_timestamp[2];
/**********************************************************
- * Copyright 2008-2009 VMware, Inc. All rights reserved.
+ * Copyright 2008-2022 VMware, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
unsigned enabled_rawbufs = svga->state.hw_draw.enabled_rawbufs[shader] & ~1u;
while (enabled_rawbufs) {
unsigned i = u_bit_scan(&enabled_rawbufs);
- buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
+ buffer = svga_buffer(svga->state.hw_draw.rawbufs[shader][i].buffer);
assert(buffer != NULL);
handle = svga_buffer_handle(svga, &buffer->b,
/**********************************************************
- * Copyright 2008-2009 VMware, Inc. All rights reserved.
+ * Copyright 2008-2022 VMware, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
}
+static inline bool
+svga_has_raw_buffer_view(struct svga_buffer *sbuf)
+{
+ return (sbuf->uav ||
+ (sbuf->key.persistent &&
+ (sbuf->key.flags & SVGA3D_SURFACE_BIND_RAW_VIEWS) != 0));
+}
+
+
struct pipe_resource *
svga_user_buffer_create(struct pipe_screen *screen,
void *ptr,
* surface cannot have other bind flags.
*/
if ((bind_flags & PIPE_BIND_CONSTANT_BUFFER) == 0) {
- sbuf->key.flags |= SVGA3D_SURFACE_BIND_RAW_VIEWS;
+ sbuf->key.flags |= SVGA3D_SURFACE_BIND_UAVIEW |
+ SVGA3D_SURFACE_BIND_RAW_VIEWS;
+ bind_flags = bind_flags | PIPE_BIND_SHADER_BUFFER;
+ //sbuf->key.flags |= SVGA3D_SURFACE_BIND_RAW_VIEWS;
}
}
}
}
if (svga_have_gl43(svga)) {
+
+ /* Save info about which constant buffers are to be viewed
+ * as srv raw buffers in the shader key.
+ */
+ if (shader->info.const_buffers_declared &
+ svga->state.raw_constbufs[shader_type]) {
+ key->raw_constbufs = svga->state.raw_constbufs[shader_type] &
+ shader->info.const_buffers_declared;
+ }
+
+ /* beginning index for srv for raw constant buffers */
+ key->srv_raw_constbuf_index = PIPE_MAX_SAMPLERS;
+
if (shader->info.uses_images || shader->info.uses_hw_atomic ||
shader->info.uses_shader_buffers) {
const struct svga_shader_buffer *cur_sbuf =
&svga->curr.shader_buffers[shader_type][0];
+ /* Save info about which shader buffers are to be viewed
+ * as srv raw buffers in the shader key.
+ */
+ if (shader->info.shader_buffers_declared &
+ svga->state.raw_shaderbufs[shader_type]) {
+ key->raw_shaderbufs = svga->state.raw_shaderbufs[shader_type] &
+ shader->info.shader_buffers_declared;
+ key->srv_raw_shaderbuf_index = key->srv_raw_constbuf_index +
+ SVGA_MAX_CONST_BUFS;
+ }
+
for (unsigned i = 0; i < ARRAY_SIZE(svga->curr.shader_buffers[shader_type]);
i++, cur_sbuf++) {
- if (cur_sbuf->resource)
+ if (cur_sbuf->resource && (!(key->raw_shaderbufs & (1 << i))))
key->shader_buf_uav_index[i] = cur_sbuf->uav_index + uav_splice_index;
else
key->shader_buf_uav_index[i] = SVGA3D_INVALID_ID;
key->image_size_used = shader->info.uses_image_size;
}
- /* Save info about which constant buffers are to be viewed
- * as raw buffers in the shader key.
- */
- if (shader->info.const_buffers_declared &
- svga->state.raw_constbufs[shader_type]) {
- key->raw_buffers = svga->state.raw_constbufs[shader_type];
-
- /* beginning index for srv for raw buffers */
- key->srv_raw_buf_index = PIPE_MAX_SAMPLERS;
- }
}
key->clamp_vertex_color = svga->curr.rast ?
/**********************************************************
- * Copyright 2008-2022 VMware, Inc. All rights reserved.
+ * Copyright 2008-2023 VMware, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
} tex[PIPE_MAX_SAMPLERS];
unsigned uav_splice_index:4; /* starting uav index */
- unsigned srv_raw_buf_index:8; /* start index for srv raw buffers */
+ unsigned srv_raw_constbuf_index:8; /* start index for srv raw buffers */
+ unsigned srv_raw_shaderbuf_index:8; /* start index for srv raw shader bufs */
unsigned image_size_used:1;
- uint16_t raw_buffers; /* bitmask of raw buffers */
+ uint16_t raw_constbufs; /* bitmask of raw constant buffers */
+ uint64_t raw_shaderbufs; /* bitmask of raw shader buffers */
struct {
enum tgsi_return_type return_type;
unsigned const_buffers_declared; /* bitmask of declared const buffers */
unsigned constbuf0_num_uniforms; /* number of uniforms in constbuf0 */
+ unsigned shader_buffers_declared; /* bitmask of declared shader buffers */
+
struct {
bool color0_writes_all_cbufs;
} fs;
buf = buffers;
if (buffers) {
int last_buffer = -1;
- for (unsigned i = start; i < start + num; i++, buf++) {
+ for (unsigned i = start, j=0; i < start + num; i++, buf++, j++) {
struct svga_shader_buffer *cbuf = &svga->curr.shader_buffers[shader][i];
if (buf && buf->buffer) {
pipe_resource_reference(&cbuf->resource, NULL);
}
cbuf->uav_index = -1;
+ cbuf->writeAccess = (writeable_bitmask & (1 << j)) != 0;
}
svga->curr.num_shader_buffers[shader] =
MAX2(svga->curr.num_shader_buffers[shader], last_buffer + 1);
return PIPE_OK;
}
+
+
+/**
+ * Returns TRUE if the shader buffer can be bound to SRV as raw buffer.
+ * It is TRUE if the shader buffer is readonly and the surface already
+ * has the RAW_BUFFER_VIEW bind flag set.
+ */
+bool
+svga_shader_buffer_can_use_srv(struct svga_context *svga,
+ enum pipe_shader_type shader,
+ unsigned index,
+ struct svga_shader_buffer *buf)
+{
+ if (buf->resource) {
+ struct svga_buffer *sbuf = svga_buffer(buf->resource);
+ if (sbuf && !buf->writeAccess && svga_has_raw_buffer_view(sbuf)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+#define SVGA_SSBO_SRV_START SVGA_MAX_CONST_BUFS
+
+/**
+ * Bind the shader buffer as SRV raw buffer.
+ */
+enum pipe_error
+svga_shader_buffer_bind_srv(struct svga_context *svga,
+ enum pipe_shader_type shader,
+ unsigned index,
+ struct svga_shader_buffer *buf)
+{
+ enum pipe_error ret;
+ unsigned slot = index + SVGA_SSBO_SRV_START;
+
+ svga->state.raw_shaderbufs[shader] |= (1 << index);
+ ret = svga_emit_rawbuf(svga, slot, shader, buf->desc.buffer_offset,
+ buf->desc.buffer_size, buf->resource);
+ if (ret == PIPE_OK)
+ svga->state.hw_draw.enabled_raw_shaderbufs[shader] |= (1 << index);
+
+ return ret;
+}
+
+
+/**
+ * Unbind the shader buffer SRV.
+ */
+enum pipe_error
+svga_shader_buffer_unbind_srv(struct svga_context *svga,
+ enum pipe_shader_type shader,
+ unsigned index,
+ struct svga_shader_buffer *buf)
+{
+ enum pipe_error ret = PIPE_OK;
+ unsigned slot = index + SVGA_SSBO_SRV_START;
+
+ if ((svga->state.hw_draw.enabled_raw_shaderbufs[shader] & (1 << index))
+ != 0) {
+ ret = svga_emit_rawbuf(svga, slot, shader, 0, 0, NULL);
+ if (ret == PIPE_OK)
+ svga->state.hw_draw.enabled_raw_shaderbufs[shader] &= ~(1 << index);
+ }
+ svga->state.raw_shaderbufs[shader] &= ~(1 << index);
+ return ret;
+}
struct pipe_resource *resource;
unsigned uav_index;
struct svga_winsys_surface *handle;
+ bool writeAccess;
};
void
void
svga_uav_cache_purge_buffers(struct svga_context *svga);
+bool
+svga_shader_buffer_can_use_srv(struct svga_context *svga,
+ enum pipe_shader_type shader,
+ unsigned index,
+ struct svga_shader_buffer *buffer);
+
+enum pipe_error
+svga_shader_buffer_bind_srv(struct svga_context *svga,
+ enum pipe_shader_type shader,
+ unsigned index,
+ struct svga_shader_buffer *buffer);
+
+enum pipe_error
+svga_shader_buffer_unbind_srv(struct svga_context *svga,
+ enum pipe_shader_type shader,
+ unsigned index,
+ struct svga_shader_buffer *buffer);
+
+enum pipe_error
+svga_emit_rawbuf(struct svga_context *svga,
+ unsigned slot,
+ enum pipe_shader_type shader,
+ unsigned buffer_offset,
+ unsigned buffer_size,
+ void *buffer);
#endif /* SVGA_SHADER_BUFFER_H */
/**********************************************************
- * Copyright 2008-2009 VMware, Inc. All rights reserved.
+ * Copyright 2008-2022 VMware, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
static const struct svga_tracked_state *hw_draw_state_gl43[] =
{
&svga_need_tgsi_transform,
- &svga_hw_uav,
&svga_need_rawbuf_srv,
+ &svga_hw_uav,
&svga_hw_fs,
&svga_hw_gs,
&svga_hw_tes,
/**
* A helper function to emit constant buffer as srv raw buffer.
*/
-static enum pipe_error
-emit_rawbuf(struct svga_context *svga,
- unsigned slot,
- enum pipe_shader_type shader,
- unsigned buffer_offset,
- unsigned buffer_size,
- void *buffer)
+enum pipe_error
+svga_emit_rawbuf(struct svga_context *svga,
+ unsigned slot,
+ enum pipe_shader_type shader,
+ unsigned buffer_offset,
+ unsigned buffer_size,
+ void *buffer)
{
enum pipe_error ret = PIPE_OK;
+
+ assert(slot < SVGA_MAX_RAW_BUFS);
+
struct svga_raw_buffer *rawbuf = &svga->state.hw_draw.rawbufs[shader][slot];
struct svga_winsys_surface *buf_handle = NULL;
unsigned srvid = SVGA3D_INVALID_ID;
* need to be bound as a shader resource raw buffer.
*/
if (svga->state.raw_constbufs[shader] & (1 << index)) {
- ret = emit_rawbuf(svga, index, shader, offset, size, buffer);
+ ret = svga_emit_rawbuf(svga, index, shader, offset, size, buffer);
if (ret != PIPE_OK) {
return ret;
}
}
else {
if (svga->state.hw_draw.enabled_rawbufs[shader] & (1 << index)) {
- ret = emit_rawbuf(svga, index, shader, offset, size, NULL);
+ ret = svga_emit_rawbuf(svga, index, shader, offset, size, NULL);
if (ret != PIPE_OK) {
return ret;
}
};
-static inline boolean
-has_raw_buffer_view(struct svga_buffer *sbuf)
-{
- return (sbuf->uav ||
- (sbuf->key.persistent &&
- (sbuf->key.flags & SVGA3D_SURFACE_BIND_RAW_VIEWS) != 0));
-}
-
/**
* A helper function to update the rawbuf for constbuf mask
*/
struct svga_buffer *sbuf =
svga_buffer(svga->curr.constbufs[shader][index].buffer);
- if (sbuf && has_raw_buffer_view(sbuf)) {
+ if (sbuf && svga_has_raw_buffer_view(sbuf)) {
svga->state.raw_constbufs[shader] |= (1 << index);
} else {
svga->state.raw_constbufs[shader] &= ~(1 << index);
for (enum pipe_shader_type shader = PIPE_SHADER_VERTEX;
shader < PIPE_SHADER_COMPUTE; shader++) {
unsigned rawbuf_mask = svga->state.raw_constbufs[shader];
+ unsigned rawbuf_sbuf_mask = svga->state.raw_shaderbufs[shader];
update_rawbuf_mask(svga, shader);
* send SVGA_NEW_XX_RAW_BUFFER to trigger a new shader
* variant that will use srv for ubo access.
*/
- if (svga->state.raw_constbufs[shader] != rawbuf_mask)
+ if ((svga->state.raw_constbufs[shader] != rawbuf_mask) ||
+ (svga->state.raw_shaderbufs[shader] != rawbuf_sbuf_mask))
svga->dirty |= rawbuf_dirtybit[shader];
}
&svga->curr.shader_buffers[shader][i];
struct pipe_resource *res = cur_sbuf->resource;
SVGA3dUAViewId uaViewId;
+ enum pipe_error ret;
+
+ /* Use srv rawbuffer to access readonly shader buffer */
+ if (svga_shader_buffer_can_use_srv(svga, shader, i, cur_sbuf)) {
+ ret = svga_shader_buffer_bind_srv(svga, shader, i, cur_sbuf);
+ if (ret != PIPE_OK)
+ return ret;
+ continue;
+ } else {
+ ret = svga_shader_buffer_unbind_srv(svga, shader, i, cur_sbuf);
+ if (ret != PIPE_OK)
+ return ret;
+ }
if (res) {
/* Get the buffer handle that can be bound as uav. */
info->uses_image_size = tgsi_info->opcode_count[TGSI_OPCODE_RESQ] ? 1 : 0;
info->uses_shader_buffers = tgsi_info->shader_buffers_declared != 0;
info->const_buffers_declared = tgsi_info->const_buffers_declared;
+ info->shader_buffers_declared = tgsi_info->shader_buffers_declared;
info->generic_inputs_mask = svga_get_generic_inputs_mask(tgsi_info);
info->generic_outputs_mask = svga_get_generic_outputs_mask(tgsi_info);
/* Shader buffers */
unsigned num_shader_bufs;
+ unsigned raw_shaderbuf_srv_start_index; /* starting srv index for raw shaderbuf */
+ uint64_t raw_shaderbufs; /* raw shader buffers bitmask */
/* HW atomic buffers */
unsigned num_atomic_bufs;
* immediates that are allocated after the block is declared. Those
* immediates are used as constant indices to constant buffers.
*/
-static boolean
+static bool
reemit_immediates_block(struct svga_shader_emitter_v10 *emit)
{
unsigned num_tokens = emit_get_num_tokens(emit);
/* Reserve room for the new immediates */
if (!reserve(emit, 4 * num_new_immediates))
- return FALSE;
+ return false;
/* Move the tokens after the immediates block to make room for the
* new immediates.
emit->ptr = (char *) (tokens + num_tokens + 4 * num_new_immediates);
- return TRUE;
+ return true;
}
{
unsigned i;
unsigned size = emit->key.tcs.vertices_per_patch;
- UNUSED unsigned indicesMask = 0;
bool addSignature = true;
if (!emit->tcs.control_point_phase)
SVGA3dDXSignatureSemanticName sgn_name =
map_tgsi_semantic_to_sgn_name(semantic_name);
- /* indices that are declared */
- indicesMask |= 1 << index;
-
if (semantic_name == TGSI_SEMANTIC_POSITION ||
index == emit->linkage.position_index) {
/* save the input control point index for later use */
static bool
+emit_rawbuf_declaration(struct svga_shader_emitter_v10 *emit,
+ unsigned index)
+{
+ VGPU10OpcodeToken0 opcode1;
+ VGPU10OperandToken0 operand1;
+
+ opcode1.value = 0;
+ opcode1.opcodeType = VGPU10_OPCODE_DCL_RESOURCE_RAW;
+ opcode1.resourceDimension = VGPU10_RESOURCE_DIMENSION_UNKNOWN;
+
+ operand1.value = 0;
+ operand1.numComponents = VGPU10_OPERAND_0_COMPONENT;
+ operand1.operandType = VGPU10_OPERAND_TYPE_RESOURCE;
+ operand1.indexDimension = VGPU10_OPERAND_INDEX_1D;
+ operand1.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
+
+ begin_emit_instruction(emit);
+ emit_dword(emit, opcode1.value);
+ emit_dword(emit, operand1.value);
+ emit_dword(emit, index);
+ end_emit_instruction(emit);
+
+ return true;
+}
+
+
+static bool
emit_constant_declaration(struct svga_shader_emitter_v10 *emit)
{
VGPU10OpcodeToken0 opcode0;
if (emit->num_shader_consts[i] > 0) {
if (emit->raw_bufs & (1 << i)) {
/* UBO declared as srv raw buffer */
-
- VGPU10OpcodeToken0 opcode1;
- VGPU10OperandToken0 operand1;
-
- opcode1.value = 0;
- opcode1.opcodeType = VGPU10_OPCODE_DCL_RESOURCE_RAW;
- opcode1.resourceDimension = VGPU10_RESOURCE_DIMENSION_UNKNOWN;
-
- operand1.value = 0;
- operand1.numComponents = VGPU10_OPERAND_0_COMPONENT;
- operand1.operandType = VGPU10_OPERAND_TYPE_RESOURCE;
- operand1.indexDimension = VGPU10_OPERAND_INDEX_1D;
- operand1.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
-
- begin_emit_instruction(emit);
- emit_dword(emit, opcode1.value);
- emit_dword(emit, operand1.value);
- emit_dword(emit, i + emit->raw_buf_srv_start_index);
- end_emit_instruction(emit);
+ emit_rawbuf_declaration(emit, i + emit->raw_buf_srv_start_index);
}
else {
VGPU10OpcodeToken0 opcode0;
VGPU10OperandToken0 operand0;
+ if (emit->raw_shaderbufs & (1 << i)) {
+ emit_rawbuf_declaration(emit, i + emit->raw_shaderbuf_srv_start_index);
+ continue;
+ }
+
/* If the corresponding uav for the shader buf is already declared,
* skip this shader buffer declaration.
*/
} else if (resourceType == TGSI_FILE_HW_ATOMIC) {
emit_uav_register(emit, inst->Src[0].Dimension.Index,
UAV_LOAD, inst->Src[0].Register.File, 0);
+ } else if (resourceType == TGSI_FILE_BUFFER) {
+ if (emit->raw_shaderbufs & (1 << resourceIndex))
+ emit_resource_register(emit, resourceIndex +
+ emit->raw_shaderbuf_srv_start_index);
+ else
+ emit_uav_register(emit, resourceIndex,
+ UAV_LOAD, inst->Src[0].Register.File, 0);
} else {
emit_uav_register(emit, resourceIndex,
UAV_LOAD, inst->Src[0].Register.File, 0);
imm.Int = element_index;
int immpos = find_immediate(emit, imm, 0);
if (immpos < 0) {
- unsigned element_index_imm = add_immediate_int(emit, element_index);
+ UNUSED unsigned element_index_imm =
+ add_immediate_int(emit, element_index);
}
element_src = make_immediate_reg_int(emit, element_index);
}
}
/* Determine if constbuf to rawbuf translation is needed */
- if (emit->info.const_buffers_declared) {
- emit->raw_bufs = emit->key.raw_buffers;
- emit->raw_buf_srv_start_index = emit->key.srv_raw_buf_index;
- }
+ emit->raw_buf_srv_start_index = emit->key.srv_raw_constbuf_index;
+ if (emit->info.const_buffers_declared)
+ emit->raw_bufs = emit->key.raw_constbufs;
+
+ emit->raw_shaderbuf_srv_start_index = emit->key.srv_raw_shaderbuf_index;
+ if (emit->info.shader_buffers_declared)
+ emit->raw_shaderbufs = emit->key.raw_shaderbufs;
/*
* Do actual shader translation.