parent
852d0aff79
commit
03e3116a75
@ -0,0 +1,26 @@ |
|||||||
|
#ifndef U_DUAL_BLEND_H |
||||||
|
#define U_DUAL_BLEND_H |
||||||
|
|
||||||
|
#include "pipe/p_state.h" |
||||||
|
|
||||||
|
static INLINE boolean util_blend_factor_is_dual_src(int factor) |
||||||
|
{ |
||||||
|
return (factor == PIPE_BLENDFACTOR_SRC1_COLOR) || |
||||||
|
(factor == PIPE_BLENDFACTOR_SRC1_ALPHA) || |
||||||
|
(factor == PIPE_BLENDFACTOR_INV_SRC1_COLOR) || |
||||||
|
(factor == PIPE_BLENDFACTOR_INV_SRC1_ALPHA); |
||||||
|
} |
||||||
|
|
||||||
|
static INLINE boolean util_blend_state_is_dual(const struct pipe_blend_state *blend,
|
||||||
|
int index) |
||||||
|
{ |
||||||
|
if (util_blend_factor_is_dual_src(blend->rt[index].rgb_src_factor) || |
||||||
|
util_blend_factor_is_dual_src(blend->rt[index].alpha_src_factor) || |
||||||
|
util_blend_factor_is_dual_src(blend->rt[index].rgb_dst_factor) || |
||||||
|
util_blend_factor_is_dual_src(blend->rt[index].alpha_dst_factor)) |
||||||
|
return true; |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,57 @@ |
|||||||
|
/**************************************************************************
|
||||||
|
* |
||||||
|
* Copyright 2009 Marek Olšák <maraeo@gmail.com> |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the |
||||||
|
* "Software"), to deal in the Software without restriction, including |
||||||
|
* without limitation the rights to use, copy, modify, merge, publish, |
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to |
||||||
|
* permit persons to whom the Software is furnished to do so, subject to |
||||||
|
* the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice (including the |
||||||
|
* next paragraph) shall be included in all copies or substantial portions |
||||||
|
* of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
||||||
|
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
* |
||||||
|
**************************************************************************/ |
||||||
|
|
||||||
|
#ifndef U_TEXTURE_H |
||||||
|
#define U_TEXTURE_H |
||||||
|
|
||||||
|
#include "pipe/p_compiler.h" |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert 2D texture coordinates of 4 vertices into cubemap coordinates |
||||||
|
* in the given face. |
||||||
|
* Coordinates must be in the range [0,1]. |
||||||
|
* |
||||||
|
* \param face Cubemap face. |
||||||
|
* \param in_st 4 pairs of 2D texture coordinates to convert. |
||||||
|
* \param in_stride Stride of in_st in floats. |
||||||
|
* \param out_str STR cubemap texture coordinates to compute. |
||||||
|
* \param out_stride Stride of out_str in floats. |
||||||
|
*/ |
||||||
|
void util_map_texcoords2d_onto_cubemap(unsigned face, |
||||||
|
const float *in_st, unsigned in_stride, |
||||||
|
float *out_str, unsigned out_stride, |
||||||
|
boolean allow_scale); |
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
@ -1,162 +0,0 @@ |
|||||||
#include <epoxy/gl.h> |
|
||||||
#include <stdio.h> |
|
||||||
#include "graw_renderer.h" |
|
||||||
#include "vrend_object.h" |
|
||||||
#include "graw_cursor.h" |
|
||||||
|
|
||||||
static const GLchar *cursor_vs_shader =
|
|
||||||
"attribute vec2 position;\n" |
|
||||||
"attribute vec2 textureCoords;\n" |
|
||||||
"varying vec2 texCoords;\n" |
|
||||||
"void main()\n" |
|
||||||
"{\n" |
|
||||||
" texCoords = textureCoords;\n" |
|
||||||
" gl_Position = vec4(position, 0.0, 1.0);\n" |
|
||||||
"}\n"; |
|
||||||
|
|
||||||
static const GLchar *cursor_fs_shader = |
|
||||||
"uniform sampler2D texSampler;\n" |
|
||||||
"varying vec2 texCoords;\n" |
|
||||||
"void main()\n" |
|
||||||
"{\n" |
|
||||||
" gl_FragColor = texture2D(texSampler, texCoords);\n" |
|
||||||
"}\n"; |
|
||||||
|
|
||||||
void graw_cursor_init(struct graw_cursor_info *cursor) |
|
||||||
{ |
|
||||||
GLuint curs_vs_id, curs_fs_id; |
|
||||||
|
|
||||||
cursor->prog_id = glCreateProgram(); |
|
||||||
curs_vs_id = glCreateShader(GL_VERTEX_SHADER); |
|
||||||
glShaderSource(curs_vs_id, 1, &cursor_vs_shader, NULL); |
|
||||||
glCompileShader(curs_vs_id); |
|
||||||
|
|
||||||
curs_fs_id = glCreateShader(GL_FRAGMENT_SHADER); |
|
||||||
glShaderSource(curs_fs_id, 1, &cursor_fs_shader, NULL); |
|
||||||
glCompileShader(curs_fs_id); |
|
||||||
|
|
||||||
glAttachShader(cursor->prog_id, curs_vs_id); |
|
||||||
glAttachShader(cursor->prog_id, curs_fs_id); |
|
||||||
glLinkProgram(cursor->prog_id); |
|
||||||
|
|
||||||
glGenBuffersARB(1, &cursor->vbo_id); |
|
||||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, cursor->vbo_id); |
|
||||||
glBufferData(GL_ARRAY_BUFFER_ARB, 4 * 4 * sizeof(GLfloat), NULL, GL_STREAM_DRAW); |
|
||||||
|
|
||||||
cursor->attrib_locs[0] = glGetAttribLocation(cursor->prog_id, "position"); |
|
||||||
cursor->attrib_locs[1] = glGetAttribLocation(cursor->prog_id, "textureCoords"); |
|
||||||
cursor->samp_loc = glGetUniformLocation(cursor->prog_id, "texSampler"); |
|
||||||
|
|
||||||
glGenVertexArrays(1, &cursor->vaoid); |
|
||||||
|
|
||||||
grend_bind_va(cursor->vaoid); |
|
||||||
|
|
||||||
glVertexAttribPointer(cursor->attrib_locs[0], 2, GL_FLOAT, GL_FALSE, 16, 0); |
|
||||||
glVertexAttribDivisorARB(cursor->attrib_locs[0], 0); |
|
||||||
glVertexAttribPointer(cursor->attrib_locs[1], 2, GL_FLOAT, GL_FALSE, 16, (GLvoid *)8); |
|
||||||
glVertexAttribDivisorARB(cursor->attrib_locs[1], 0); |
|
||||||
|
|
||||||
glEnableVertexAttribArray(cursor->attrib_locs[0]); |
|
||||||
glEnableVertexAttribArray(cursor->attrib_locs[1]); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
int graw_renderer_remove_cursor(struct graw_cursor_info *cursor, |
|
||||||
struct grend_resource *dst_res) |
|
||||||
{ |
|
||||||
struct pipe_box box; |
|
||||||
box.x = cursor->last_x; |
|
||||||
box.y = cursor->last_y; |
|
||||||
box.z = 0; |
|
||||||
box.width = 64; |
|
||||||
box.height = 64; |
|
||||||
box.depth = 1; |
|
||||||
|
|
||||||
graw_renderer_flush_buffer_res(dst_res, &box); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int graw_renderer_paint_cursor(struct graw_cursor_info *cursor, |
|
||||||
struct grend_resource *dst_res) |
|
||||||
{ |
|
||||||
GLuint fb_id; |
|
||||||
struct grend_resource *cursor_res; |
|
||||||
struct vertex { |
|
||||||
GLfloat x, y, s, t; |
|
||||||
}; |
|
||||||
struct vertex verts[4]; |
|
||||||
GLuint locs[2]; |
|
||||||
GLfloat x0, y0, x1, y1; |
|
||||||
int s_w, s_h; |
|
||||||
if (!cursor->res_handle) |
|
||||||
return 0; |
|
||||||
|
|
||||||
cursor_res = vrend_resource_lookup(cursor->res_handle, 0); |
|
||||||
if (!cursor_res) |
|
||||||
return 0; |
|
||||||
|
|
||||||
s_w = dst_res->base.width0; |
|
||||||
s_h = dst_res->base.height0; |
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); |
|
||||||
glDrawBuffer(GL_BACK); |
|
||||||
|
|
||||||
grend_use_program(cursor->prog_id); |
|
||||||
|
|
||||||
glUniform1i(cursor->samp_loc, 0); |
|
||||||
|
|
||||||
grend_blend_enable(GL_TRUE); |
|
||||||
grend_depth_test_enable(GL_FALSE); |
|
||||||
|
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
|
||||||
glBlendEquation(GL_FUNC_ADD); |
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0); |
|
||||||
glBindTexture(cursor_res->target, cursor_res->id); |
|
||||||
|
|
||||||
glTexParameteri(cursor_res->target, GL_TEXTURE_BASE_LEVEL, 0); |
|
||||||
glTexParameteri(cursor_res->target, GL_TEXTURE_MAX_LEVEL, 0); |
|
||||||
glTexParameterf(cursor_res->target, GL_TEXTURE_MIN_LOD, 0); |
|
||||||
glTexParameterf(cursor_res->target, GL_TEXTURE_MAX_LOD, 0); |
|
||||||
glTexParameterf(cursor_res->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
||||||
glTexParameterf(cursor_res->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
||||||
|
|
||||||
grend_bind_va(cursor->vaoid); |
|
||||||
|
|
||||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, cursor->vbo_id); |
|
||||||
|
|
||||||
cursor->last_x = cursor->x; |
|
||||||
cursor->last_y = cursor->y; |
|
||||||
|
|
||||||
x0 = ((float)cursor->x / (s_w / 2)) - 1.0; |
|
||||||
y0 = ((float)(s_h - cursor->y - cursor_res->base.width0) / (s_h / 2)) - 1.0; |
|
||||||
x1 = (((float)cursor->x + cursor_res->base.height0) / (s_w / 2)) - 1.0; |
|
||||||
y1 = (((float)(s_h - cursor->y)) / (s_h / 2)) - 1.0; |
|
||||||
|
|
||||||
verts[0].x = x0; |
|
||||||
verts[0].y = y0; |
|
||||||
|
|
||||||
verts[1].x = x1; |
|
||||||
verts[1].y = y0; |
|
||||||
|
|
||||||
verts[2].x = x1; |
|
||||||
verts[2].y = y1; |
|
||||||
|
|
||||||
verts[3].x = x0; |
|
||||||
verts[3].y = y1; |
|
||||||
|
|
||||||
verts[0].s = 0.0; |
|
||||||
verts[0].t = 1.0; |
|
||||||
verts[1].s = 1.0; |
|
||||||
verts[1].t = 1.0; |
|
||||||
verts[2].s = 1.0; |
|
||||||
verts[2].t = 0.0; |
|
||||||
verts[3].s = 0.0; |
|
||||||
verts[3].t = 0.0; |
|
||||||
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); |
|
||||||
|
|
||||||
glDrawArrays(GL_QUADS, 0, 4); |
|
||||||
return 0; |
|
||||||
} |
|
@ -1,24 +0,0 @@ |
|||||||
#ifndef GRAW_CURSOR_H |
|
||||||
#define GRAW_CURSOR_H |
|
||||||
|
|
||||||
/* cursor drawing state */ |
|
||||||
|
|
||||||
struct graw_cursor_info { |
|
||||||
GLuint prog_id; |
|
||||||
GLuint vaoid; |
|
||||||
GLuint vbo_id; |
|
||||||
uint32_t res_handle; |
|
||||||
int x, y; |
|
||||||
GLuint attrib_locs[2]; |
|
||||||
GLuint samp_loc; |
|
||||||
|
|
||||||
int last_x, last_y; |
|
||||||
}; |
|
||||||
|
|
||||||
void graw_cursor_init(struct graw_cursor_info *cursor); |
|
||||||
|
|
||||||
int graw_renderer_paint_cursor(struct graw_cursor_info *cursor, |
|
||||||
struct grend_resource *dst_res); |
|
||||||
int graw_renderer_remove_cursor(struct graw_cursor_info *cursor, |
|
||||||
struct grend_resource *dst_res); |
|
||||||
#endif |
|
@ -1,911 +0,0 @@ |
|||||||
#include <stdint.h> |
|
||||||
#include <string.h> |
|
||||||
#include <stdio.h> |
|
||||||
#include <epoxy/gl.h> |
|
||||||
|
|
||||||
#include "util/u_memory.h" |
|
||||||
#include "pipe/p_state.h" |
|
||||||
#include "pipe/p_shader_tokens.h" |
|
||||||
#include "graw_decode.h" |
|
||||||
#include "graw_renderer.h" |
|
||||||
#include "vrend_object.h" |
|
||||||
#include "tgsi/tgsi_text.h" |
|
||||||
|
|
||||||
/* decode side */ |
|
||||||
#define DECODE_MAX_TOKENS 8000 |
|
||||||
|
|
||||||
struct grend_decode_ctx { |
|
||||||
struct graw_decoder_state ids, *ds; |
|
||||||
struct grend_context *grctx; |
|
||||||
}; |
|
||||||
|
|
||||||
#define GRAW_MAX_CTX 16 |
|
||||||
static struct grend_decode_ctx *dec_ctx[GRAW_MAX_CTX]; |
|
||||||
|
|
||||||
static int graw_decode_create_shader(struct grend_decode_ctx *ctx, uint32_t type, |
|
||||||
uint32_t handle, |
|
||||||
uint16_t length) |
|
||||||
{ |
|
||||||
struct pipe_shader_state *state = CALLOC_STRUCT(pipe_shader_state); |
|
||||||
struct tgsi_token *tokens; |
|
||||||
int i; |
|
||||||
uint32_t shader_offset; |
|
||||||
unsigned num_tokens; |
|
||||||
if (!state) |
|
||||||
return NULL; |
|
||||||
|
|
||||||
num_tokens = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
|
|
||||||
if (num_tokens == 0) |
|
||||||
num_tokens = 300; |
|
||||||
|
|
||||||
tokens = calloc(num_tokens + 10, sizeof(struct tgsi_token)); |
|
||||||
if (!tokens) { |
|
||||||
free(state); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
state->stream_output.num_outputs = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
|
||||||
if (state->stream_output.num_outputs) { |
|
||||||
for (i = 0; i < 4; i++) |
|
||||||
state->stream_output.stride[i] = ctx->ds->buf[ctx->ds->buf_offset + 4 + i]; |
|
||||||
for (i = 0; i < state->stream_output.num_outputs; i++) { |
|
||||||
uint32_t tmp = ctx->ds->buf[ctx->ds->buf_offset + 8 + i]; |
|
||||||
|
|
||||||
state->stream_output.output[i].register_index = tmp & 0xff; |
|
||||||
state->stream_output.output[i].start_component = (tmp >> 8) & 0x3; |
|
||||||
state->stream_output.output[i].num_components = (tmp >> 10) & 0x7; |
|
||||||
state->stream_output.output[i].output_buffer = (tmp >> 13) & 0x7; |
|
||||||
state->stream_output.output[i].dst_offset = (tmp >> 16) & 0xffff;
|
|
||||||
} |
|
||||||
shader_offset = 8 + state->stream_output.num_outputs; |
|
||||||
} else |
|
||||||
shader_offset = 4; |
|
||||||
if (vrend_dump_shaders) |
|
||||||
fprintf(stderr,"shader\n%s\n", &ctx->ds->buf[ctx->ds->buf_offset + shader_offset]); |
|
||||||
if (!tgsi_text_translate(&ctx->ds->buf[ctx->ds->buf_offset + shader_offset], tokens, num_tokens + 10)) { |
|
||||||
fprintf(stderr,"failed to translate\n %s\n",&ctx->ds->buf[ctx->ds->buf_offset + shader_offset]); |
|
||||||
free(tokens); |
|
||||||
free(state); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
state->tokens = tokens; |
|
||||||
|
|
||||||
if (type == VIRGL_OBJECT_FS) |
|
||||||
grend_create_fs(ctx->grctx, handle, state); |
|
||||||
else |
|
||||||
grend_create_vs(ctx->grctx, handle, state); |
|
||||||
|
|
||||||
free(tokens); |
|
||||||
free(state); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
static int graw_decode_create_stream_output_target(struct grend_decode_ctx *ctx, uint32_t handle) |
|
||||||
{ |
|
||||||
uint32_t res_handle, buffer_size, buffer_offset; |
|
||||||
|
|
||||||
res_handle = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
buffer_offset = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
|
||||||
buffer_size = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
|
||||||
|
|
||||||
grend_create_so_target(ctx->grctx, handle, res_handle, buffer_offset, |
|
||||||
buffer_size); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_framebuffer_state(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
uint32_t nr_cbufs = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
uint32_t zsurf_handle = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
uint32_t surf_handle[8]; |
|
||||||
int i; |
|
||||||
|
|
||||||
for (i = 0; i < nr_cbufs; i++) |
|
||||||
surf_handle[i] = ctx->ds->buf[ctx->ds->buf_offset + 3 + i]; |
|
||||||
grend_set_framebuffer_state(ctx->grctx, nr_cbufs, surf_handle, zsurf_handle); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_clear(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
union pipe_color_union color; |
|
||||||
double depth; |
|
||||||
unsigned stencil, buffers; |
|
||||||
int i; |
|
||||||
int index = ctx->ds->buf_offset + 1; |
|
||||||
|
|
||||||
buffers = ctx->ds->buf[index++]; |
|
||||||
for (i = 0; i < 4; i++) |
|
||||||
color.ui[i] = ctx->ds->buf[index++]; |
|
||||||
depth = *(double *)(uint64_t *)(&ctx->ds->buf[index]); |
|
||||||
index += 2; |
|
||||||
stencil = ctx->ds->buf[index++]; |
|
||||||
|
|
||||||
grend_clear(ctx->grctx, buffers, &color, depth, stencil); |
|
||||||
} |
|
||||||
|
|
||||||
static float uif(unsigned int ui) |
|
||||||
{ |
|
||||||
union { float f; unsigned int ui; } myuif; |
|
||||||
myuif.ui = ui; |
|
||||||
return myuif.f; |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_viewport_state(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
struct pipe_viewport_state vps; |
|
||||||
int i; |
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) |
|
||||||
vps.scale[i] = uif(ctx->ds->buf[ctx->ds->buf_offset + 1 + i]); |
|
||||||
for (i = 0; i < 4; i++) |
|
||||||
vps.translate[i] = uif(ctx->ds->buf[ctx->ds->buf_offset + 5 + i]); |
|
||||||
|
|
||||||
grend_set_viewport_state(ctx->grctx, &vps); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_index_buffer(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
int offset = ctx->ds->buf_offset; |
|
||||||
grend_set_index_buffer(ctx->grctx, ctx->ds->buf[offset + 1], |
|
||||||
ctx->ds->buf[offset + 2], |
|
||||||
ctx->ds->buf[offset + 3]); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_constant_buffer(struct grend_decode_ctx *ctx, uint16_t length) |
|
||||||
{ |
|
||||||
int offset = ctx->ds->buf_offset; |
|
||||||
uint32_t shader = ctx->ds->buf[offset + 1]; |
|
||||||
uint32_t index = ctx->ds->buf[offset + 2]; |
|
||||||
int nc = (length - 2); |
|
||||||
grend_set_constants(ctx->grctx, shader, index, nc, &ctx->ds->buf[offset + 3]); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_vertex_buffers(struct grend_decode_ctx *ctx, uint16_t length) |
|
||||||
{ |
|
||||||
int num_vbo; |
|
||||||
int i; |
|
||||||
num_vbo = (length / 3); |
|
||||||
|
|
||||||
for (i = 0; i < num_vbo; i++) { |
|
||||||
int element_offset = ctx->ds->buf_offset + 1 + (i * 3); |
|
||||||
grend_set_single_vbo(ctx->grctx, i, |
|
||||||
ctx->ds->buf[element_offset], |
|
||||||
ctx->ds->buf[element_offset + 1], |
|
||||||
ctx->ds->buf[element_offset + 2]); |
|
||||||
} |
|
||||||
grend_set_num_vbo(ctx->grctx, num_vbo); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_sampler_views(struct grend_decode_ctx *ctx, uint16_t length) |
|
||||||
{ |
|
||||||
int num_samps; |
|
||||||
int i; |
|
||||||
uint32_t shader_type, start_slot; |
|
||||||
num_samps = length - 2; |
|
||||||
shader_type = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
start_slot = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
for (i = 0; i < num_samps; i++) { |
|
||||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset + 3 + i]; |
|
||||||
grend_set_single_sampler_view(ctx->grctx, shader_type, i + start_slot, handle); |
|
||||||
} |
|
||||||
grend_set_num_sampler_views(ctx->grctx, shader_type, start_slot, num_samps); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_resource_inline_write(struct grend_decode_ctx *ctx, uint16_t length) |
|
||||||
{ |
|
||||||
struct pipe_box box; |
|
||||||
uint32_t res_handle = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
uint32_t level, usage, stride, layer_stride; |
|
||||||
void *data; |
|
||||||
|
|
||||||
level = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
usage = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
|
||||||
stride = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
|
||||||
layer_stride = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
|
||||||
box.x = ctx->ds->buf[ctx->ds->buf_offset + 6]; |
|
||||||
box.y = ctx->ds->buf[ctx->ds->buf_offset + 7]; |
|
||||||
box.z = ctx->ds->buf[ctx->ds->buf_offset + 8]; |
|
||||||
box.width = ctx->ds->buf[ctx->ds->buf_offset + 9]; |
|
||||||
box.height = ctx->ds->buf[ctx->ds->buf_offset + 10]; |
|
||||||
box.depth = ctx->ds->buf[ctx->ds->buf_offset + 11]; |
|
||||||
|
|
||||||
data = &ctx->ds->buf[ctx->ds->buf_offset + 12]; |
|
||||||
grend_transfer_inline_write(ctx->grctx, res_handle, level, |
|
||||||
usage, &box, data, stride, layer_stride); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_draw_vbo(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
struct pipe_draw_info info; |
|
||||||
|
|
||||||
memset(&info, 0, sizeof(struct pipe_draw_info)); |
|
||||||
|
|
||||||
info.start = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
info.count = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
info.mode = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
|
||||||
info.indexed = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
|
||||||
info.instance_count = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
|
||||||
info.index_bias = ctx->ds->buf[ctx->ds->buf_offset + 6]; |
|
||||||
info.start_instance = ctx->ds->buf[ctx->ds->buf_offset + 7]; |
|
||||||
info.primitive_restart = ctx->ds->buf[ctx->ds->buf_offset + 8]; |
|
||||||
info.restart_index = ctx->ds->buf[ctx->ds->buf_offset + 9]; |
|
||||||
info.min_index = ctx->ds->buf[ctx->ds->buf_offset + 10]; |
|
||||||
info.max_index = ctx->ds->buf[ctx->ds->buf_offset + 11]; |
|
||||||
grend_draw_vbo(ctx->grctx, &info); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_create_blend(struct grend_decode_ctx *ctx, uint32_t handle, uint16_t length) |
|
||||||
{ |
|
||||||
struct pipe_blend_state *blend_state = CALLOC_STRUCT(pipe_blend_state); |
|
||||||
uint32_t tmp; |
|
||||||
int i; |
|
||||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
blend_state->independent_blend_enable = (tmp & 1); |
|
||||||
blend_state->logicop_enable = (tmp >> 1) & 0x1; |
|
||||||
blend_state->dither = (tmp >> 2) & 0x1; |
|
||||||
blend_state->alpha_to_coverage = (tmp >> 3) & 0x1; |
|
||||||
blend_state->alpha_to_one = (tmp >> 4) & 0x1; |
|
||||||
|
|
||||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
|
||||||
blend_state->logicop_func = tmp & 0xf; |
|
||||||
|
|
||||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { |
|
||||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 4 + i]; |
|
||||||
blend_state->rt[i].blend_enable = tmp & 0x1; |
|
||||||
blend_state->rt[i].rgb_func = (tmp >> 1) & 0x7; |
|
||||||
blend_state->rt[i].rgb_src_factor = (tmp >> 4) & 0x1f; |
|
||||||
blend_state->rt[i].rgb_dst_factor = (tmp >> 9) & 0x1f; |
|
||||||
blend_state->rt[i].alpha_func = (tmp >> 14) & 0x7; |
|
||||||
blend_state->rt[i].alpha_src_factor = (tmp >> 17) & 0x1f; |
|
||||||
blend_state->rt[i].alpha_dst_factor = (tmp >> 22) & 0x1f; |
|
||||||
blend_state->rt[i].colormask = (tmp >> 27) & 0xf; |
|
||||||
} |
|
||||||
|
|
||||||
graw_renderer_object_insert(ctx->grctx, blend_state, sizeof(struct pipe_blend_state), handle, |
|
||||||
VIRGL_OBJECT_BLEND); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_create_dsa(struct grend_decode_ctx *ctx, uint32_t handle, uint16_t length) |
|
||||||
{ |
|
||||||
int i; |
|
||||||
struct pipe_depth_stencil_alpha_state *dsa_state = CALLOC_STRUCT(pipe_depth_stencil_alpha_state); |
|
||||||
uint32_t tmp; |
|
||||||
|
|
||||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
dsa_state->depth.enabled = tmp & 0x1; |
|
||||||
dsa_state->depth.writemask = (tmp >> 1) & 0x1; |
|
||||||
dsa_state->depth.func = (tmp >> 2) & 0x7; |
|
||||||
|
|
||||||
dsa_state->alpha.enabled = (tmp >> 8) & 0x1; |
|
||||||
dsa_state->alpha.func = (tmp >> 9) & 0x7; |
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) { |
|
||||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 3 + i]; |
|
||||||
dsa_state->stencil[i].enabled = tmp & 0x1; |
|
||||||
dsa_state->stencil[i].func = (tmp >> 1) & 0x7; |
|
||||||
dsa_state->stencil[i].fail_op = (tmp >> 4) & 0x7; |
|
||||||
dsa_state->stencil[i].zpass_op = (tmp >> 7) & 0x7; |
|
||||||
dsa_state->stencil[i].zfail_op = (tmp >> 10) & 0x7; |
|
||||||
dsa_state->stencil[i].valuemask = (tmp >> 13) & 0xff; |
|
||||||
dsa_state->stencil[i].writemask = (tmp >> 21) & 0xff; |
|
||||||
} |
|
||||||
|
|
||||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
|
||||||
dsa_state->alpha.ref_value = uif(tmp); |
|
||||||
|
|
||||||
graw_renderer_object_insert(ctx->grctx, dsa_state, sizeof(struct pipe_depth_stencil_alpha_state), handle, |
|
||||||
VIRGL_OBJECT_DSA); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_create_rasterizer(struct grend_decode_ctx *ctx, uint32_t handle, uint16_t length) |
|
||||||
{ |
|
||||||
struct pipe_rasterizer_state *rs_state = CALLOC_STRUCT(pipe_rasterizer_state); |
|
||||||
uint32_t tmp; |
|
||||||
|
|
||||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
#define ebit(name, bit) rs_state->name = (tmp >> bit) & 0x1 |
|
||||||
#define emask(name, bit, mask) rs_state->name = (tmp >> bit) & mask |
|
||||||
|
|
||||||
ebit(flatshade, 0); |
|
||||||
ebit(depth_clip, 1); |
|
||||||
ebit(clip_halfz, 2); |
|
||||||
ebit(rasterizer_discard, 3); |
|
||||||
ebit(flatshade_first, 4); |
|
||||||
ebit(light_twoside, 5); |
|
||||||
ebit(sprite_coord_mode, 6); |
|
||||||
ebit(point_quad_rasterization, 7); |
|
||||||
emask(cull_face, 8, 0x3); |
|
||||||
emask(fill_front, 10, 0x3); |
|
||||||
emask(fill_back, 12, 0x3); |
|
||||||
ebit(scissor, 14); |
|
||||||
ebit(front_ccw, 15); |
|
||||||
ebit(clamp_vertex_color, 16); |
|
||||||
ebit(clamp_fragment_color, 17); |
|
||||||
ebit(offset_line, 18); |
|
||||||
ebit(offset_point, 19); |
|
||||||
ebit(offset_tri, 20); |
|
||||||
ebit(poly_smooth, 21); |
|
||||||
ebit(poly_stipple_enable, 22); |
|
||||||
ebit(point_smooth, 23); |
|
||||||
ebit(point_size_per_vertex, 24); |
|
||||||
ebit(multisample, 25); |
|
||||||
ebit(line_smooth, 26); |
|
||||||
ebit(line_stipple_enable, 27); |
|
||||||
ebit(line_last_pixel, 28); |
|
||||||
ebit(half_pixel_center, 29); |
|
||||||
ebit(bottom_edge_rule, 30); |
|
||||||
rs_state->point_size = uif(ctx->ds->buf[ctx->ds->buf_offset + 3]); |
|
||||||
rs_state->sprite_coord_enable = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
|
||||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
|
||||||
emask(line_stipple_pattern, 0, 0xffff); |
|
||||||
emask(line_stipple_factor, 16, 0xff); |
|
||||||
emask(clip_plane_enable, 24, 0xff); |
|
||||||
|
|
||||||
rs_state->line_width = uif(ctx->ds->buf[ctx->ds->buf_offset + 6]); |
|
||||||
rs_state->offset_units = uif(ctx->ds->buf[ctx->ds->buf_offset + 7]); |
|
||||||
rs_state->offset_scale = uif(ctx->ds->buf[ctx->ds->buf_offset + 8]); |
|
||||||
rs_state->offset_clamp = uif(ctx->ds->buf[ctx->ds->buf_offset + 9]); |
|
||||||
|
|
||||||
|
|
||||||
graw_renderer_object_insert(ctx->grctx, rs_state, sizeof(struct pipe_rasterizer_state), handle, |
|
||||||
VIRGL_OBJECT_RASTERIZER); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_create_surface(struct grend_decode_ctx *ctx, uint32_t handle) |
|
||||||
{ |
|
||||||
uint32_t res_handle, format, val0, val1; |
|
||||||
res_handle = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
format = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
|
||||||
val0 = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
|
||||||
val1 = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
|
||||||
grend_create_surface(ctx->grctx, handle, res_handle, format, val0, val1); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_create_sampler_view(struct grend_decode_ctx *ctx, uint32_t handle) |
|
||||||
{ |
|
||||||
uint32_t res_handle, format, val0, val1, swizzle_packed; |
|
||||||
|
|
||||||
res_handle = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
format = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
|
||||||
val0 = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
|
||||||
val1 = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
|
||||||
swizzle_packed = ctx->ds->buf[ctx->ds->buf_offset + 6]; |
|
||||||
grend_create_sampler_view(ctx->grctx, handle, res_handle, format, val0, val1,swizzle_packed); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_create_sampler_state(struct grend_decode_ctx *ctx, uint32_t handle, uint16_t length) |
|
||||||
{ |
|
||||||
struct pipe_sampler_state *state = CALLOC_STRUCT(pipe_sampler_state); |
|
||||||
int i; |
|
||||||
uint32_t tmp; |
|
||||||
|
|
||||||
tmp = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
state->wrap_s = tmp & 0x7; |
|
||||||
state->wrap_t = (tmp >> 3) & 0x7; |
|
||||||
state->wrap_r = (tmp >> 6) & 0x7; |
|
||||||
state->min_img_filter = (tmp >> 9) & 0x3; |
|
||||||
state->min_mip_filter = (tmp >> 11) & 0x3; |
|
||||||
state->mag_img_filter = (tmp >> 13) & 0x3; |
|
||||||
state->compare_mode = (tmp >> 15) & 0x1; |
|
||||||
state->compare_func = (tmp >> 16) & 0x7; |
|
||||||
|
|
||||||
state->lod_bias = uif(ctx->ds->buf[ctx->ds->buf_offset + 3]); |
|
||||||
state->min_lod = uif(ctx->ds->buf[ctx->ds->buf_offset + 4]); |
|
||||||
state->max_lod = uif(ctx->ds->buf[ctx->ds->buf_offset + 5]); |
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) |
|
||||||
state->border_color.ui[i] = ctx->ds->buf[ctx->ds->buf_offset + 6 + i]; |
|
||||||
graw_renderer_object_insert(ctx->grctx, state, sizeof(struct pipe_sampler_state), handle, |
|
||||||
VIRGL_OBJECT_SAMPLER_STATE); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_create_ve(struct grend_decode_ctx *ctx, uint32_t handle, uint16_t length) |
|
||||||
{ |
|
||||||
struct pipe_vertex_element *ve; |
|
||||||
int num_elements; |
|
||||||
int i; |
|
||||||
|
|
||||||
num_elements = (length - 1) / 4; |
|
||||||
ve = calloc(num_elements, sizeof(struct pipe_vertex_element)); |
|
||||||
if (!ve) |
|
||||||
return; |
|
||||||
|
|
||||||
for (i = 0; i < num_elements; i++) { |
|
||||||
uint32_t element_offset = ctx->ds->buf_offset + 2 + (i * 4); |
|
||||||
ve[i].src_offset = ctx->ds->buf[element_offset]; |
|
||||||
ve[i].instance_divisor = ctx->ds->buf[element_offset + 1]; |
|
||||||
ve[i].vertex_buffer_index = ctx->ds->buf[element_offset + 2]; |
|
||||||
ve[i].src_format = ctx->ds->buf[element_offset + 3]; |
|
||||||
} |
|
||||||
|
|
||||||
grend_create_vertex_elements_state(ctx->grctx, handle, num_elements, |
|
||||||
ve); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_create_query(struct grend_decode_ctx *ctx, uint32_t handle) |
|
||||||
{ |
|
||||||
uint32_t query_type; |
|
||||||
uint32_t res_handle; |
|
||||||
uint32_t offset; |
|
||||||
query_type = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
offset = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
|
||||||
res_handle = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
|
||||||
|
|
||||||
grend_create_query(ctx->grctx, handle, query_type, res_handle, offset); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_create_object(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
uint32_t header = ctx->ds->buf[ctx->ds->buf_offset]; |
|
||||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset+1]; |
|
||||||
uint16_t length; |
|
||||||
uint8_t obj_type = (header >> 8) & 0xff; |
|
||||||
|
|
||||||
length = header >> 16; |
|
||||||
|
|
||||||
switch (obj_type){ |
|
||||||
case VIRGL_OBJECT_BLEND: |
|
||||||
graw_decode_create_blend(ctx, handle, length); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_DSA: |
|
||||||
graw_decode_create_dsa(ctx, handle, length); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_RASTERIZER: |
|
||||||
graw_decode_create_rasterizer(ctx, handle, length); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_VS: |
|
||||||
case VIRGL_OBJECT_FS: |
|
||||||
graw_decode_create_shader(ctx, obj_type, handle, length); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_VERTEX_ELEMENTS: |
|
||||||
graw_decode_create_ve(ctx, handle, length); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_SURFACE: |
|
||||||
graw_decode_create_surface(ctx, handle); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_SAMPLER_VIEW: |
|
||||||
graw_decode_create_sampler_view(ctx, handle); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_SAMPLER_STATE: |
|
||||||
graw_decode_create_sampler_state(ctx, handle, length); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_QUERY: |
|
||||||
graw_decode_create_query(ctx, handle); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_STREAMOUT_TARGET: |
|
||||||
graw_decode_create_stream_output_target(ctx, handle); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_bind_object(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
uint32_t header = ctx->ds->buf[ctx->ds->buf_offset]; |
|
||||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset+1]; |
|
||||||
uint16_t length; |
|
||||||
uint8_t obj_type = (header >> 8) & 0xff; |
|
||||||
|
|
||||||
length = header >> 16; |
|
||||||
|
|
||||||
switch (obj_type) { |
|
||||||
case VIRGL_OBJECT_BLEND: |
|
||||||
grend_object_bind_blend(ctx->grctx, handle); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_DSA: |
|
||||||
grend_object_bind_dsa(ctx->grctx, handle); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_RASTERIZER: |
|
||||||
grend_object_bind_rasterizer(ctx->grctx, handle); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_VS: |
|
||||||
grend_bind_vs(ctx->grctx, handle); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_FS: |
|
||||||
grend_bind_fs(ctx->grctx, handle); |
|
||||||
break; |
|
||||||
case VIRGL_OBJECT_VERTEX_ELEMENTS: |
|
||||||
grend_bind_vertex_elements_state(ctx->grctx, handle); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_destroy_object(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset+1]; |
|
||||||
graw_renderer_object_destroy(ctx->grctx, handle); |
|
||||||
} |
|
||||||
|
|
||||||
void graw_reset_decode(void) |
|
||||||
{ |
|
||||||
// free(gdctx->grctx);
|
|
||||||
// gdctx->grctx = NULL;
|
|
||||||
//gdctx->ds = NULL;
|
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_stencil_ref(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
struct pipe_stencil_ref ref; |
|
||||||
uint32_t val = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
ref.ref_value[0] = val & 0xff; |
|
||||||
ref.ref_value[1] = (val >> 8) & 0xff; |
|
||||||
grend_set_stencil_ref(ctx->grctx, &ref); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_blend_color(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
struct pipe_blend_color color; |
|
||||||
int i; |
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) |
|
||||||
color.color[i] = uif(ctx->ds->buf[ctx->ds->buf_offset + 1 + i]); |
|
||||||
|
|
||||||
grend_set_blend_color(ctx->grctx, &color); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_scissor_state(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
struct pipe_scissor_state ss; |
|
||||||
uint32_t temp; |
|
||||||
|
|
||||||
temp = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
ss.minx = temp & 0xffff; |
|
||||||
ss.miny = (temp >> 16) & 0xffff; |
|
||||||
|
|
||||||
temp = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
ss.maxx = temp & 0xffff; |
|
||||||
ss.maxy = (temp >> 16) & 0xffff; |
|
||||||
|
|
||||||
grend_set_scissor_state(ctx->grctx, &ss); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_polygon_stipple(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
struct pipe_poly_stipple ps; |
|
||||||
int i; |
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) |
|
||||||
ps.stipple[i] = ctx->ds->buf[ctx->ds->buf_offset + 1 + i]; |
|
||||||
|
|
||||||
grend_set_polygon_stipple(ctx->grctx, &ps); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_clip_state(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
struct pipe_clip_state clip; |
|
||||||
int i, j; |
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) |
|
||||||
for (j = 0; j < 4; j++) |
|
||||||
clip.ucp[i][j] = uif(ctx->ds->buf[ctx->ds->buf_offset + 1 + (i * 4) + j]); |
|
||||||
grend_set_clip_state(ctx->grctx, &clip); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_sample_mask(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
unsigned mask; |
|
||||||
|
|
||||||
mask = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
grend_set_sample_mask(ctx->grctx, mask); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_resource_copy_region(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
struct pipe_box box; |
|
||||||
uint32_t dst_handle, src_handle; |
|
||||||
uint32_t dst_level, dstx, dsty, dstz; |
|
||||||
uint32_t src_level; |
|
||||||
|
|
||||||
dst_handle = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
dst_level = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
dstx = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
|
||||||
dsty = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
|
||||||
dstz = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
|
||||||
src_handle = ctx->ds->buf[ctx->ds->buf_offset + 6]; |
|
||||||
src_level = ctx->ds->buf[ctx->ds->buf_offset + 7]; |
|
||||||
box.x = ctx->ds->buf[ctx->ds->buf_offset + 8]; |
|
||||||
box.y = ctx->ds->buf[ctx->ds->buf_offset + 9]; |
|
||||||
box.z = ctx->ds->buf[ctx->ds->buf_offset + 10]; |
|
||||||
box.width = ctx->ds->buf[ctx->ds->buf_offset + 11]; |
|
||||||
box.height = ctx->ds->buf[ctx->ds->buf_offset + 12]; |
|
||||||
box.depth = ctx->ds->buf[ctx->ds->buf_offset + 13]; |
|
||||||
|
|
||||||
graw_renderer_resource_copy_region(ctx->grctx, dst_handle, |
|
||||||
dst_level, dstx, dsty, dstz, |
|
||||||
src_handle, src_level, |
|
||||||
&box); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
static void graw_decode_blit(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
struct pipe_blit_info info; |
|
||||||
uint32_t dst_handle, src_handle, temp; |
|
||||||
|
|
||||||
info.mask = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
info.filter = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
info.scissor_enable = ctx->ds->buf[ctx->ds->buf_offset + 3] & 1; |
|
||||||
temp = ctx->ds->buf[ctx->ds->buf_offset + 4]; |
|
||||||
info.scissor.minx = temp & 0xffff; |
|
||||||
info.scissor.miny = (temp >> 16) & 0xffff; |
|
||||||
temp = ctx->ds->buf[ctx->ds->buf_offset + 5]; |
|
||||||
info.scissor.maxx = temp & 0xffff; |
|
||||||
info.scissor.maxy = (temp >> 16) & 0xffff; |
|
||||||
dst_handle = ctx->ds->buf[ctx->ds->buf_offset + 6]; |
|
||||||
info.dst.level = ctx->ds->buf[ctx->ds->buf_offset + 7]; |
|
||||||
info.dst.format = ctx->ds->buf[ctx->ds->buf_offset + 8]; |
|
||||||
info.dst.box.x = ctx->ds->buf[ctx->ds->buf_offset + 9]; |
|
||||||
info.dst.box.y = ctx->ds->buf[ctx->ds->buf_offset + 10]; |
|
||||||
info.dst.box.z = ctx->ds->buf[ctx->ds->buf_offset + 11]; |
|
||||||
info.dst.box.width = ctx->ds->buf[ctx->ds->buf_offset + 12]; |
|
||||||
info.dst.box.height = ctx->ds->buf[ctx->ds->buf_offset + 13]; |
|
||||||
info.dst.box.depth = ctx->ds->buf[ctx->ds->buf_offset + 14]; |
|
||||||
|
|
||||||
src_handle = ctx->ds->buf[ctx->ds->buf_offset + 15]; |
|
||||||
info.src.level = ctx->ds->buf[ctx->ds->buf_offset + 16]; |
|
||||||
info.src.format = ctx->ds->buf[ctx->ds->buf_offset + 17]; |
|
||||||
info.src.box.x = ctx->ds->buf[ctx->ds->buf_offset + 18]; |
|
||||||
info.src.box.y = ctx->ds->buf[ctx->ds->buf_offset + 19]; |
|
||||||
info.src.box.z = ctx->ds->buf[ctx->ds->buf_offset + 20]; |
|
||||||
info.src.box.width = ctx->ds->buf[ctx->ds->buf_offset + 21]; |
|
||||||
info.src.box.height = ctx->ds->buf[ctx->ds->buf_offset + 22]; |
|
||||||
info.src.box.depth = ctx->ds->buf[ctx->ds->buf_offset + 23];
|
|
||||||
|
|
||||||
graw_renderer_blit(ctx->grctx, dst_handle, src_handle, &info); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_bind_sampler_states(struct grend_decode_ctx *ctx, int length) |
|
||||||
{ |
|
||||||
uint32_t shader_type = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
uint32_t start_slot = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
uint32_t num_states = length - 1; |
|
||||||
|
|
||||||
grend_bind_sampler_states(ctx->grctx, shader_type, start_slot, num_states, |
|
||||||
&ctx->ds->buf[ctx->ds->buf_offset + 3]); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_begin_query(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
|
|
||||||
grend_begin_query(ctx->grctx, handle); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_end_query(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
|
|
||||||
grend_end_query(ctx->grctx, handle); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_get_query_result(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
uint32_t wait = ctx->ds->buf[ctx->ds->buf_offset + 2]; |
|
||||||
grend_get_query_result(ctx->grctx, handle, wait); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_render_condition(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
uint32_t handle = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
boolean condition = ctx->ds->buf[ctx->ds->buf_offset + 2] & 1; |
|
||||||
uint mode = ctx->ds->buf[ctx->ds->buf_offset + 3]; |
|
||||||
grend_render_condition(ctx->grctx, handle, condition, mode); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_streamout_targets(struct grend_decode_ctx *ctx, |
|
||||||
uint16_t length) |
|
||||||
{ |
|
||||||
uint32_t handles[16]; |
|
||||||
uint32_t num_handles = length - 1; |
|
||||||
uint32_t append_bitmask; |
|
||||||
int i; |
|
||||||
|
|
||||||
append_bitmask = ctx->ds->buf[ctx->ds->buf_offset + 1]; |
|
||||||
for (i = 0; i < num_handles; i++) |
|
||||||
handles[i] = ctx->ds->buf[ctx->ds->buf_offset + 2 + i]; |
|
||||||
grend_set_streamout_targets(ctx->grctx, append_bitmask, num_handles, handles); |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_set_query_state(struct grend_decode_ctx *ctx) |
|
||||||
{ |
|
||||||
boolean enabled; |
|
||||||
|
|
||||||
enabled = ctx->ds->buf[ctx->ds->buf_offset + 1] & 0x1; |
|
||||||
grend_set_query_state(ctx->grctx, enabled); |
|
||||||
} |
|
||||||
|
|
||||||
void graw_renderer_context_create_internal(uint32_t handle, uint32_t nlen, |
|
||||||
const char *debug_name) |
|
||||||
{ |
|
||||||
struct grend_decode_ctx *dctx; |
|
||||||
|
|
||||||
if (handle > GRAW_MAX_CTX) |
|
||||||
return; |
|
||||||
|
|
||||||
dctx = malloc(sizeof(struct grend_decode_ctx)); |
|
||||||
if (!dctx) |
|
||||||
return; |
|
||||||
|
|
||||||
dctx->grctx = grend_create_context(handle, nlen, debug_name); |
|
||||||
if (!dctx->grctx) { |
|
||||||
free(dctx); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
dctx->ds = &dctx->ids; |
|
||||||
|
|
||||||
dec_ctx[handle] = dctx; |
|
||||||
} |
|
||||||
|
|
||||||
void graw_renderer_context_create(uint32_t handle, uint32_t nlen, const char *debug_name) |
|
||||||
{ |
|
||||||
if (handle > GRAW_MAX_CTX) |
|
||||||
return; |
|
||||||
/* context 0 is always available with no guarantees */ |
|
||||||
if (handle == 0) |
|
||||||
return; |
|
||||||
|
|
||||||
graw_renderer_context_create_internal(handle, nlen, debug_name); |
|
||||||
} |
|
||||||
|
|
||||||
void graw_renderer_context_destroy(uint32_t handle) |
|
||||||
{ |
|
||||||
struct grend_decode_ctx *ctx; |
|
||||||
bool ret; |
|
||||||
if (handle > GRAW_MAX_CTX) |
|
||||||
return; |
|
||||||
|
|
||||||
ctx = dec_ctx[handle]; |
|
||||||
dec_ctx[handle] = NULL; |
|
||||||
ret = grend_destroy_context(ctx->grctx); |
|
||||||
free(ctx); |
|
||||||
/* switch to ctx 0 */ |
|
||||||
if (ret) |
|
||||||
grend_hw_switch_context(dec_ctx[0]->grctx, TRUE); |
|
||||||
} |
|
||||||
|
|
||||||
struct grend_context *vrend_lookup_renderer_ctx(uint32_t ctx_id) |
|
||||||
{ |
|
||||||
if (ctx_id > GRAW_MAX_CTX) |
|
||||||
return NULL; |
|
||||||
|
|
||||||
if (dec_ctx[ctx_id] == NULL) |
|
||||||
return NULL; |
|
||||||
|
|
||||||
return dec_ctx[ctx_id]->grctx; |
|
||||||
} |
|
||||||
|
|
||||||
static void graw_decode_block(uint32_t ctx_id, uint32_t *block, int ndw) |
|
||||||
{ |
|
||||||
int i = 0; |
|
||||||
struct grend_decode_ctx *gdctx; |
|
||||||
boolean ret; |
|
||||||
if (ctx_id > GRAW_MAX_CTX) |
|
||||||
return; |
|
||||||
|
|
||||||
if (dec_ctx[ctx_id] == NULL) |
|
||||||
return; |
|
||||||
|
|
||||||
gdctx = dec_ctx[ctx_id]; |
|
||||||
|
|
||||||
ret = grend_hw_switch_context(gdctx->grctx, TRUE); |
|
||||||
if (ret == FALSE) |
|
||||||
return; |
|
||||||
|
|
||||||
gdctx->ds->buf = block; |
|
||||||
gdctx->ds->buf_total = ndw; |
|
||||||
gdctx->ds->buf_offset = 0; |
|
||||||
|
|
||||||
while (gdctx->ds->buf_offset < gdctx->ds->buf_total) { |
|
||||||
uint32_t header = gdctx->ds->buf[gdctx->ds->buf_offset]; |
|
||||||
|
|
||||||
// fprintf(stderr,"[%d] cmd is %d (obj %d) len %d\n", gdctx->ds->buf_offset, header & 0xff, (header >> 8 & 0xff), (header >> 16));
|
|
||||||
|
|
||||||
switch (header & 0xff) { |
|
||||||
case VIRGL_CCMD_CREATE_OBJECT: |
|
||||||
graw_decode_create_object(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_BIND_OBJECT: |
|
||||||
graw_decode_bind_object(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_DESTROY_OBJECT: |
|
||||||
graw_decode_destroy_object(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_CLEAR: |
|
||||||
graw_decode_clear(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_DRAW_VBO: |
|
||||||
graw_decode_draw_vbo(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_FRAMEBUFFER_STATE: |
|
||||||
graw_decode_set_framebuffer_state(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_VERTEX_BUFFERS: |
|
||||||
graw_decode_set_vertex_buffers(gdctx, header >> 16); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_RESOURCE_INLINE_WRITE: |
|
||||||
graw_decode_resource_inline_write(gdctx, header >> 16); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_VIEWPORT_STATE: |
|
||||||
graw_decode_set_viewport_state(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_SAMPLER_VIEWS: |
|
||||||
graw_decode_set_sampler_views(gdctx, header >> 16); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_INDEX_BUFFER: |
|
||||||
graw_decode_set_index_buffer(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_CONSTANT_BUFFER: |
|
||||||
graw_decode_set_constant_buffer(gdctx, header >> 16); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_STENCIL_REF: |
|
||||||
graw_decode_set_stencil_ref(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_BLEND_COLOR: |
|
||||||
graw_decode_set_blend_color(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_SCISSOR_STATE: |
|
||||||
graw_decode_set_scissor_state(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_BLIT: |
|
||||||
graw_decode_blit(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_RESOURCE_COPY_REGION: |
|
||||||
graw_decode_resource_copy_region(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_BIND_SAMPLER_STATES: |
|
||||||
graw_decode_bind_sampler_states(gdctx, header >> 16); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_BEGIN_QUERY: |
|
||||||
graw_decode_begin_query(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_END_QUERY: |
|
||||||
graw_decode_end_query(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_GET_QUERY_RESULT: |
|
||||||
graw_decode_get_query_result(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_POLYGON_STIPPLE: |
|
||||||
graw_decode_set_polygon_stipple(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_CLIP_STATE: |
|
||||||
graw_decode_set_clip_state(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_SAMPLE_MASK: |
|
||||||
graw_decode_set_sample_mask(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_STREAMOUT_TARGETS: |
|
||||||
graw_decode_set_streamout_targets(gdctx, header >> 16); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_QUERY_STATE: |
|
||||||
graw_decode_set_query_state(gdctx); |
|
||||||
break; |
|
||||||
case VIRGL_CCMD_SET_RENDER_CONDITION: |
|
||||||
graw_decode_set_render_condition(gdctx); |
|
||||||
break; |
|
||||||
} |
|
||||||
gdctx->ds->buf_offset += (header >> 16) + 1; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
void graw_decode_block_iov(struct virgl_iovec *iov, unsigned int niovs, |
|
||||||
uint32_t ctx_id, uint64_t offset, int ndw) |
|
||||||
{ |
|
||||||
uint32_t *block = (uint32_t *)(iov[0].iov_base + offset); |
|
||||||
void *data; |
|
||||||
if (niovs > 1) { |
|
||||||
data = malloc(ndw * 4); |
|
||||||
graw_iov_to_buf(iov, niovs, offset, data, ndw * 4); |
|
||||||
} |
|
||||||
else |
|
||||||
data = (uint32_t *)(iov[0].iov_base + offset); |
|
||||||
graw_decode_block(ctx_id, data, ndw); |
|
||||||
if (niovs > 1) |
|
||||||
free(data); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
@ -1,13 +0,0 @@ |
|||||||
#ifndef GRAW_DECODE_H |
|
||||||
#define GRAW_DECODE_H |
|
||||||
|
|
||||||
struct graw_decoder_state { |
|
||||||
uint32_t *buf; |
|
||||||
uint32_t buf_total; |
|
||||||
uint32_t buf_offset; |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
void graw_decode_transfer(uint32_t *data, uint32_t ndw); |
|
||||||
void graw_decode_get_transfer(uint32_t *data, uint32_t ndw); |
|
||||||
#endif |
|
@ -1,22 +0,0 @@ |
|||||||
|
|
||||||
#ifndef GRAW_IOV_H |
|
||||||
#define GRAW_IOV_H |
|
||||||
|
|
||||||
/* stolen from qemu for now until later integration */ |
|
||||||
struct virgl_iovec { |
|
||||||
void *iov_base; |
|
||||||
size_t iov_len; |
|
||||||
}; |
|
||||||
|
|
||||||
typedef void (*IOCallback)(void *cookie, unsigned int doff, void *src, int len); |
|
||||||
|
|
||||||
size_t graw_iov_size(const struct virgl_iovec *iov, const unsigned int iov_cnt); |
|
||||||
size_t graw_iov_from_buf(const struct virgl_iovec *iov, unsigned int iov_cnt, |
|
||||||
size_t offset, const void *buf, size_t bytes); |
|
||||||
size_t graw_iov_to_buf(const struct virgl_iovec *iov, const unsigned int iov_cnt, |
|
||||||
size_t offset, void *buf, size_t bytes); |
|
||||||
|
|
||||||
size_t graw_iov_to_buf_cb(const struct virgl_iovec *iov, const unsigned int iov_cnt, |
|
||||||
size_t offset, size_t bytes, IOCallback iocb, void *cookie); |
|
||||||
|
|
||||||
#endif |
|
@ -1,322 +0,0 @@ |
|||||||
#ifndef GRAW_RENDERER_H |
|
||||||
#define GRAW_RENDERER_H |
|
||||||
|
|
||||||
#include "pipe/p_state.h" |
|
||||||
#include "util/u_inlines.h" |
|
||||||
#include "virgl_protocol.h" |
|
||||||
#include "graw_iov.h" |
|
||||||
#include "virgl_hw.h" |
|
||||||
|
|
||||||
typedef void *virgl_gl_context; |
|
||||||
typedef void *virgl_gl_drawable; |
|
||||||
|
|
||||||
extern int vrend_dump_shaders; |
|
||||||
struct grend_context; |
|
||||||
|
|
||||||
struct grend_resource { |
|
||||||
struct pipe_resource base; |
|
||||||
GLuint id; |
|
||||||
GLenum target; |
|
||||||
/* fb id if we need to readback this resource */ |
|
||||||
GLuint readback_fb_id; |
|
||||||
GLuint readback_fb_level; |
|
||||||
GLuint readback_fb_z; |
|
||||||
int is_front; |
|
||||||
GLboolean renderer_flipped; |
|
||||||
void *ptr; |
|
||||||
GLuint handle; |
|
||||||
|
|
||||||
struct virgl_iovec *iov; |
|
||||||
uint32_t num_iovs; |
|
||||||
boolean y_0_top; |
|
||||||
|
|
||||||
boolean scannedout; |
|
||||||
}; |
|
||||||
|
|
||||||
/* assume every format is sampler friendly */ |
|
||||||
#define VREND_BIND_RENDER (1 << 0) |
|
||||||
#define VREND_BIND_DEPTHSTENCIL (1 << 1) |
|
||||||
|
|
||||||
struct grend_format_table { |
|
||||||
enum virgl_formats format; |
|
||||||
GLenum internalformat; |
|
||||||
GLenum glformat; |
|
||||||
GLenum gltype; |
|
||||||
uint32_t bindings; |
|
||||||
}; |
|
||||||
|
|
||||||
struct grend_if_cbs { |
|
||||||
void (*write_fence)(unsigned fence_id); |
|
||||||
/* inform the control layer about a new scanout */ |
|
||||||
void (*scanout_rect_info)(int scanout_id, GLuint tex_id, int x, int y, |
|
||||||
uint32_t width, uint32_t height); |
|
||||||
void (*scanout_resource_info)(int scanout_id, GLuint tex_id, uint32_t flags, |
|
||||||
uint32_t stride, |
|
||||||
uint32_t width, uint32_t height, uint32_t format); |
|
||||||
|
|
||||||
virgl_gl_context (*create_gl_context)(int scanout); |
|
||||||
void (*destroy_gl_context)(virgl_gl_context ctx); |
|
||||||
int (*make_current)(int scanout, virgl_gl_context ctx); |
|
||||||
|
|
||||||
void (*flush_scanout)(int scanout, int x, int y, uint32_t width, uint32_t height); |
|
||||||
void (*inval_backing)(struct virgl_iovec *iov, uint32_t iov_cnt); |
|
||||||
}; |
|
||||||
void graw_renderer_init(struct grend_if_cbs *cbs); |
|
||||||
|
|
||||||
void grend_insert_format(struct grend_format_table *entry, uint32_t bindings); |
|
||||||
void grend_create_vs(struct grend_context *ctx, |
|
||||||
uint32_t handle, |
|
||||||
const struct pipe_shader_state *vs); |
|
||||||
|
|
||||||
void grend_create_fs(struct grend_context *ctx, |
|
||||||
uint32_t handle, |
|
||||||
const struct pipe_shader_state *vs); |
|
||||||
|
|
||||||
void grend_bind_vs(struct grend_context *ctx, |
|
||||||
uint32_t handle); |
|
||||||
|
|
||||||
void grend_bind_fs(struct grend_context *ctx, |
|
||||||
uint32_t handle); |
|
||||||
|
|
||||||
void grend_bind_vs_so(struct grend_context *ctx, |
|
||||||
uint32_t handle); |
|
||||||
void grend_clear(struct grend_context *ctx, |
|
||||||
unsigned buffers, |
|
||||||
const union pipe_color_union *color, |
|
||||||
double depth, unsigned stencil); |
|
||||||
|
|
||||||
void grend_draw_vbo(struct grend_context *ctx, |
|
||||||
const struct pipe_draw_info *info); |
|
||||||
|
|
||||||
void grend_set_framebuffer_state(struct grend_context *ctx, |
|
||||||
uint32_t nr_cbufs, uint32_t surf_handle[8], |
|
||||||
uint32_t zsurf_handle); |
|
||||||
|
|
||||||
void grend_flush(struct grend_context *ctx); |
|
||||||
|
|
||||||
|
|
||||||
void grend_flush_frontbuffer(uint32_t res_handle); |
|
||||||
struct grend_context *grend_create_context(int id, uint32_t nlen, const char *debug_name); |
|
||||||
bool grend_destroy_context(struct grend_context *ctx); |
|
||||||
void graw_renderer_context_create(uint32_t handle, uint32_t nlen, const char *name); |
|
||||||
void graw_renderer_context_create_internal(uint32_t handle, uint32_t nlen, const char *name); |
|
||||||
void graw_renderer_context_destroy(uint32_t handle); |
|
||||||
|
|
||||||
struct graw_renderer_resource_create_args { |
|
||||||
uint32_t handle; |
|
||||||
enum pipe_texture_target target; |
|
||||||
uint32_t format; |
|
||||||
uint32_t bind; |
|
||||||
uint32_t width; |
|
||||||
uint32_t height; |
|
||||||
uint32_t depth; |
|
||||||
uint32_t array_size; |
|
||||||
uint32_t last_level; |
|
||||||
uint32_t nr_samples; |
|
||||||
uint32_t flags; |
|
||||||
}; |
|
||||||
|
|
||||||
void graw_renderer_resource_create(struct graw_renderer_resource_create_args *args, struct virgl_iovec *iov, uint32_t num_iovs); |
|
||||||
|
|
||||||
void graw_renderer_resource_unref(uint32_t handle); |
|
||||||
|
|
||||||
void grend_create_surface(struct grend_context *ctx, |
|
||||||
uint32_t handle, |
|
||||||
uint32_t res_handle, uint32_t format, |
|
||||||
uint32_t val0, uint32_t val1); |
|
||||||
void grend_create_sampler_view(struct grend_context *ctx, |
|
||||||
uint32_t handle, |
|
||||||
uint32_t res_handle, uint32_t format, |
|
||||||
uint32_t val0, uint32_t val1, uint32_t swizzle_packed); |
|
||||||
|
|
||||||
void grend_create_so_target(struct grend_context *ctx, |
|
||||||
uint32_t handle, |
|
||||||
uint32_t res_handle, |
|
||||||
uint32_t buffer_offset, |
|
||||||
uint32_t buffer_size); |
|
||||||
void grend_set_streamout_targets(struct grend_context *ctx, |
|
||||||
uint32_t append_bitmask, |
|
||||||
uint32_t num_targets, |
|
||||||
uint32_t *handles); |
|
||||||
|
|
||||||
void grend_create_vertex_elements_state(struct grend_context *ctx, |
|
||||||
uint32_t handle, |
|
||||||
unsigned num_elements, |
|
||||||
const struct pipe_vertex_element *elements); |
|
||||||
void grend_bind_vertex_elements_state(struct grend_context *ctx, |
|
||||||
uint32_t handle); |
|
||||||
|
|
||||||
void grend_set_single_vbo(struct grend_context *ctx, |
|
||||||
int index, |
|
||||||
uint32_t stride, |
|
||||||
uint32_t buffer_offset, |
|
||||||
uint32_t res_handle); |
|
||||||
void grend_set_num_vbo(struct grend_context *ctx, |
|
||||||
int num_vbo); |
|
||||||
|
|
||||||
void grend_transfer_inline_write(struct grend_context *ctx, |
|
||||||
uint32_t res_handle, |
|
||||||
unsigned level, |
|
||||||
unsigned usage, |
|
||||||
const struct pipe_box *box, |
|
||||||
const void *data, |
|
||||||
unsigned stride, |
|
||||||
unsigned layer_stride); |
|
||||||
|
|
||||||
void grend_set_viewport_state(struct grend_context *ctx, |
|
||||||
const struct pipe_viewport_state *state); |
|
||||||
void grend_set_num_sampler_views(struct grend_context *ctx, |
|
||||||
uint32_t shader_type, |
|
||||||
uint32_t start_slot, |
|
||||||
int num_sampler_views); |
|
||||||
void grend_set_single_sampler_view(struct grend_context *ctx, |
|
||||||
uint32_t shader_type, |
|
||||||
int index, |
|
||||||
uint32_t res_handle); |
|
||||||
|
|
||||||
void grend_object_bind_blend(struct grend_context *ctx, |
|
||||||
uint32_t handle); |
|
||||||
void grend_object_bind_dsa(struct grend_context *ctx, |
|
||||||
uint32_t handle); |
|
||||||
void grend_object_bind_rasterizer(struct grend_context *ctx, |
|
||||||
uint32_t handle); |
|
||||||
|
|
||||||
void grend_bind_sampler_states(struct grend_context *ctx, |
|
||||||
uint32_t shader_type, |
|
||||||
uint32_t start_slot, |
|
||||||
uint32_t num_states, |
|
||||||
uint32_t *handles); |
|
||||||
void grend_set_index_buffer(struct grend_context *ctx, |
|
||||||
uint32_t res_handle, |
|
||||||
uint32_t index_size, |
|
||||||
uint32_t offset); |
|
||||||
|
|
||||||
void graw_renderer_transfer_write_iov(uint32_t handle,
|
|
||||||
uint32_t ctx_id, |
|
||||||
int level, |
|
||||||
uint32_t stride, |
|
||||||
uint32_t layer_stride, |
|
||||||
struct pipe_box *box, |
|
||||||
uint64_t offset, |
|
||||||
struct virgl_iovec *iovec, |
|
||||||
unsigned int iovec_cnt); |
|
||||||
|
|
||||||
void graw_renderer_resource_copy_region(struct grend_context *ctx, |
|
||||||
uint32_t dst_handle, uint32_t dst_level, |
|
||||||
uint32_t dstx, uint32_t dsty, uint32_t dstz, |
|
||||||
uint32_t src_handle, uint32_t src_level, |
|
||||||
const struct pipe_box *src_box); |
|
||||||
|
|
||||||
void graw_renderer_blit(struct grend_context *ctx, |
|
||||||
uint32_t dst_handle, uint32_t src_handle, |
|
||||||
const struct pipe_blit_info *info); |
|
||||||
|
|
||||||
void graw_renderer_transfer_send_iov(uint32_t handle, uint32_t ctx_id, |
|
||||||
uint32_t level, uint32_t stride, |
|
||||||
uint32_t layer_stride, |
|
||||||
struct pipe_box *box, |
|
||||||
uint64_t offset, struct virgl_iovec *iov, |
|
||||||
int iovec_cnt); |
|
||||||
void grend_set_stencil_ref(struct grend_context *ctx, struct pipe_stencil_ref *ref); |
|
||||||
void grend_set_blend_color(struct grend_context *ctx, struct pipe_blend_color *color); |
|
||||||
void grend_set_scissor_state(struct grend_context *ctx, struct pipe_scissor_state *ss); |
|
||||||
|
|
||||||
void grend_set_polygon_stipple(struct grend_context *ctx, struct pipe_poly_stipple *ps); |
|
||||||
|
|
||||||
void grend_set_clip_state(struct grend_context *ctx, struct pipe_clip_state *ucp); |
|
||||||
void grend_set_sample_mask(struct grend_context *ctx, unsigned sample_mask); |
|
||||||
|
|
||||||
void grend_set_constants(struct grend_context *ctx, |
|
||||||
uint32_t shader, |
|
||||||
uint32_t index, |
|
||||||
uint32_t num_constant, |
|
||||||
float *data); |
|
||||||
|
|
||||||
void graw_transfer_write_return(void *data, uint32_t bytes, uint64_t offset, |
|
||||||
struct virgl_iovec *iov, int iovec_cnt); |
|
||||||
|
|
||||||
void graw_transfer_write_tex_return(struct pipe_resource *res, |
|
||||||
struct pipe_box *box, |
|
||||||
uint32_t level, |
|
||||||
uint32_t dst_stride, |
|
||||||
uint64_t offset, |
|
||||||
struct virgl_iovec *iov, |
|
||||||
int num_iovs, |
|
||||||
void *myptr, int size, int invert); |
|
||||||
|
|
||||||
int graw_renderer_set_scanout(uint32_t res_handle, |
|
||||||
uint32_t scanout_id, |
|
||||||
uint32_t ctx_id, |
|
||||||
struct pipe_box *box); |
|
||||||
|
|
||||||
int graw_renderer_flush_buffer(uint32_t res_handle, |
|
||||||
uint32_t ctx_id, |
|
||||||
struct pipe_box *box); |
|
||||||
|
|
||||||
void graw_renderer_fini(void); |
|
||||||
void graw_reset_decode(void); |
|
||||||
|
|
||||||
void graw_decode_block_iov(struct virgl_iovec *iov, uint32_t niovs, uint32_t ctx_id, uint64_t offset, int ndw); |
|
||||||
struct grend_context *vrend_lookup_renderer_ctx(uint32_t ctx_id); |
|
||||||
|
|
||||||
int graw_renderer_create_fence(int client_fence_id, uint32_t ctx_id); |
|
||||||
|
|
||||||
void graw_renderer_check_fences(void); |
|
||||||
void graw_renderer_check_queries(void); |
|
||||||
void grend_stop_current_queries(void); |
|
||||||
|
|
||||||
boolean grend_hw_switch_context(struct grend_context *ctx, boolean now); |
|
||||||
void graw_renderer_object_insert(struct grend_context *ctx, void *data, |
|
||||||
uint32_t size, uint32_t handle, enum virgl_object_type type); |
|
||||||
void graw_renderer_object_destroy(struct grend_context *ctx, uint32_t handle); |
|
||||||
|
|
||||||
void grend_create_query(struct grend_context *ctx, uint32_t handle, |
|
||||||
uint32_t query_type, uint32_t res_handle, |
|
||||||
uint32_t offset); |
|
||||||
|
|
||||||
void grend_begin_query(struct grend_context *ctx, uint32_t handle); |
|
||||||
void grend_end_query(struct grend_context *ctx, uint32_t handle); |
|
||||||
void grend_get_query_result(struct grend_context *ctx, uint32_t handle, |
|
||||||
uint32_t wait); |
|
||||||
void grend_set_query_state(struct grend_context *ctx, |
|
||||||
boolean enabled); |
|
||||||
void grend_render_condition(struct grend_context *ctx, |
|
||||||
uint32_t handle, |
|
||||||
boolean condtion, |
|
||||||
uint mode); |
|
||||||
void grend_set_cursor_info(uint32_t cursor_handle, int x, int y); |
|
||||||
void *graw_renderer_get_cursor_contents(uint32_t res_handle, uint32_t *width, uint32_t *height); |
|
||||||
void grend_use_program(GLuint program_id); |
|
||||||
void grend_blend_enable(GLboolean blend_enable); |
|
||||||
void grend_depth_test_enable(GLboolean depth_test_enable); |
|
||||||
void grend_bind_va(GLuint vaoid); |
|
||||||
int graw_renderer_flush_buffer_res(struct grend_resource *res, |
|
||||||
struct pipe_box *box); |
|
||||||
|
|
||||||
void graw_renderer_fill_caps(uint32_t set, uint32_t version, |
|
||||||
union virgl_caps *caps); |
|
||||||
|
|
||||||
GLint64 graw_renderer_get_timestamp(void); |
|
||||||
/* formats */ |
|
||||||
void vrend_build_format_list(void); |
|
||||||
|
|
||||||
int graw_renderer_resource_attach_iov(int res_handle, struct virgl_iovec *iov, |
|
||||||
int num_iovs); |
|
||||||
void graw_renderer_resource_invalid_iov(int res_handle); |
|
||||||
void graw_renderer_resource_destroy(struct grend_resource *res); |
|
||||||
|
|
||||||
static INLINE void |
|
||||||
grend_resource_reference(struct grend_resource **ptr, struct grend_resource *tex) |
|
||||||
{ |
|
||||||
struct grend_resource *old_tex = *ptr; |
|
||||||
|
|
||||||
if (pipe_reference(&(*ptr)->base.reference, &tex->base.reference)) |
|
||||||
graw_renderer_resource_destroy(old_tex); |
|
||||||
*ptr = tex; |
|
||||||
} |
|
||||||
|
|
||||||
void graw_renderer_force_ctx_0(void); |
|
||||||
|
|
||||||
void graw_renderer_get_rect(int idx, struct virgl_iovec *iov, unsigned int num_iovs, |
|
||||||
uint32_t offset, int x, int y, int width, int height); |
|
||||||
#endif |
|
@ -1,40 +0,0 @@ |
|||||||
#ifndef GRAW_SHADER_H |
|
||||||
#define GRAW_SHADER_H |
|
||||||
|
|
||||||
#include "pipe/p_state.h" |
|
||||||
|
|
||||||
#define SHADER_FLAG_FS_INVERT 1 |
|
||||||
|
|
||||||
/* need to store patching info for interpolation */ |
|
||||||
struct vrend_interp_info { |
|
||||||
int semantic_name; |
|
||||||
int semantic_index; |
|
||||||
int interpolate; |
|
||||||
}; |
|
||||||
|
|
||||||
struct vrend_shader_info { |
|
||||||
uint32_t samplers_used_mask; |
|
||||||
int num_consts; |
|
||||||
int num_inputs; |
|
||||||
int num_interps; |
|
||||||
int num_outputs; |
|
||||||
uint32_t shadow_samp_mask; |
|
||||||
struct pipe_stream_output_info so_info; |
|
||||||
|
|
||||||
struct vrend_interp_info *interpinfo; |
|
||||||
}; |
|
||||||
|
|
||||||
struct vrend_shader_key { |
|
||||||
uint32_t coord_replace; |
|
||||||
boolean invert_fs_origin; |
|
||||||
}; |
|
||||||
|
|
||||||
boolean vrend_patch_vertex_shader_interpolants(char *program, |
|
||||||
struct vrend_shader_info *vs_info, |
|
||||||
struct vrend_shader_info *fs_info); |
|
||||||
|
|
||||||
char *tgsi_convert(const struct tgsi_token *tokens, |
|
||||||
struct vrend_shader_key *key, |
|
||||||
struct vrend_shader_info *sinfo); |
|
||||||
|
|
||||||
#endif |
|
@ -1,426 +0,0 @@ |
|||||||
#include <stdio.h> |
|
||||||
#include <time.h> |
|
||||||
|
|
||||||
#include <epoxy/gl.h> |
|
||||||
|
|
||||||
#include <sys/mman.h> |
|
||||||
#include <sys/stat.h> |
|
||||||
#include <fcntl.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <unistd.h> |
|
||||||
#include <sys/socket.h> |
|
||||||
#include <sys/un.h> |
|
||||||
#include <sys/eventfd.h> |
|
||||||
#include "virtgpu_hw.h" |
|
||||||
#include "pipe/p_state.h" |
|
||||||
#include "util/u_format.h" |
|
||||||
#include "util/u_math.h" |
|
||||||
#include "graw_renderer.h" |
|
||||||
|
|
||||||
#include "virglrenderer.h" |
|
||||||
#include "virgl_egl.h" |
|
||||||
|
|
||||||
static struct virgl_renderer_callbacks *rcbs; |
|
||||||
|
|
||||||
static void *dev_cookie; |
|
||||||
extern int localrender; |
|
||||||
static int use_egl_context; |
|
||||||
struct virgl_egl *egl_info; |
|
||||||
static struct grend_if_cbs virgl_cbs; |
|
||||||
|
|
||||||
static int graw_process_cmd(struct virtgpu_command *cmd, struct virgl_iovec *iov, |
|
||||||
unsigned int niovs); |
|
||||||
|
|
||||||
int virgl_renderer_process_vcmd(void *cmd, struct virgl_iovec *iov, unsigned int niovs) |
|
||||||
{ |
|
||||||
struct virtgpu_command *qcmd = cmd; |
|
||||||
int ret; |
|
||||||
ret = graw_process_cmd(qcmd, iov, niovs); |
|
||||||
graw_renderer_check_fences(); |
|
||||||
return ret; |
|
||||||
} |
|
||||||
|
|
||||||
static void virgl_cmd_create_resource_2d(struct virtgpu_command *cmd) |
|
||||||
{ |
|
||||||
struct graw_renderer_resource_create_args args; |
|
||||||
|
|
||||||
args.handle = cmd->u.resource_create_2d.resource_id; |
|
||||||
args.target = 2; |
|
||||||
args.format = cmd->u.resource_create_2d.format; |
|
||||||
args.bind = (1 << 1); |
|
||||||
args.width = cmd->u.resource_create_2d.width; |
|
||||||
args.height = cmd->u.resource_create_2d.height; |
|
||||||
args.depth = 1; |
|
||||||
args.array_size = 1; |
|
||||||
args.last_level = 0; |
|
||||||
args.nr_samples = 0; |
|
||||||
args.flags = VIRGL_RESOURCE_Y_0_TOP; |
|
||||||
graw_renderer_resource_create(&args, NULL, 0); |
|
||||||
} |
|
||||||
|
|
||||||
static void virgl_cmd_create_resource_3d(struct virtgpu_command *cmd) |
|
||||||
{ |
|
||||||
struct graw_renderer_resource_create_args args; |
|
||||||
|
|
||||||
args.handle = cmd->u.resource_create_3d.resource_id; |
|
||||||
args.target = cmd->u.resource_create_3d.target; |
|
||||||
args.format = cmd->u.resource_create_3d.format; |
|
||||||
args.bind = cmd->u.resource_create_3d.bind; |
|
||||||
args.width = cmd->u.resource_create_3d.width; |
|
||||||
args.height = cmd->u.resource_create_3d.height; |
|
||||||
args.depth = cmd->u.resource_create_3d.depth; |
|
||||||
args.array_size = cmd->u.resource_create_3d.array_size; |
|
||||||
args.last_level = cmd->u.resource_create_3d.last_level; |
|
||||||
args.nr_samples = cmd->u.resource_create_3d.nr_samples; |
|
||||||
args.flags = cmd->u.resource_create_3d.flags; |
|
||||||
graw_renderer_resource_create(&args, NULL, 0); |
|
||||||
} |
|
||||||
|
|
||||||
static void virgl_resource_attach_backing(struct virtgpu_resource_attach_backing *att_rb, |
|
||||||
struct iovec *iov, |
|
||||||
unsigned int iov_cnt) |
|
||||||
{ |
|
||||||
uint32_t gsize = graw_iov_size(iov, iov_cnt); |
|
||||||
struct virgl_iovec *res_iovs; |
|
||||||
int i; |
|
||||||
void *data; |
|
||||||
int ret; |
|
||||||
|
|
||||||
res_iovs = malloc(att_rb->nr_entries * sizeof(struct virgl_iovec)); |
|
||||||
if (!res_iovs) |
|
||||||
return; |
|
||||||
|
|
||||||
if (iov_cnt > 1) { |
|
||||||
data = malloc(gsize); |
|
||||||
graw_iov_to_buf(iov, iov_cnt, 0, data, gsize); |
|
||||||
} else |
|
||||||
data = iov[0].iov_base; |
|
||||||
|
|
||||||
for (i = 0; i < att_rb->nr_entries; i++) { |
|
||||||
struct virtgpu_mem_entry *ent = ((struct virtgpu_mem_entry *)data) + i; |
|
||||||
res_iovs[i].iov_len = ent->length; |
|
||||||
ret = rcbs->map_iov(&res_iovs[i], ent->addr); |
|
||||||
if (ret) { |
|
||||||
fprintf(stderr, "failed to attach backing %d\n", att_rb->resource_id); |
|
||||||
free(res_iovs); |
|
||||||
res_iovs = NULL; |
|
||||||
goto fail_free; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
ret = graw_renderer_resource_attach_iov(att_rb->resource_id, res_iovs, |
|
||||||
att_rb->nr_entries); |
|
||||||
goto out; |
|
||||||
fail_free: |
|
||||||
free(res_iovs); |
|
||||||
out: |
|
||||||
|
|
||||||
if (iov_cnt > 1) |
|
||||||
free(data); |
|
||||||
} |
|
||||||
|
|
||||||
static void virgl_resource_inval_backing_iov(struct virgl_iovec *iov, uint32_t iov_cnt) |
|
||||||
{ |
|
||||||
int i; |
|
||||||
for (i = 0; i < iov_cnt; i++) { |
|
||||||
rcbs->unmap_iov(&iov[i]); |
|
||||||
} |
|
||||||
free(iov); |
|
||||||
} |
|
||||||
|
|
||||||
static void virgl_resource_inval_backing(int resource_id) |
|
||||||
{ |
|
||||||
graw_renderer_resource_invalid_iov(resource_id); |
|
||||||
} |
|
||||||
|
|
||||||
static int graw_process_cmd(struct virtgpu_command *cmd, struct virgl_iovec *iov, |
|
||||||
unsigned int niovs) |
|
||||||
{ |
|
||||||
static int inited; |
|
||||||
int fence_ctx_id = 0; |
|
||||||
|
|
||||||
graw_renderer_force_ctx_0(); |
|
||||||
switch (cmd->type) { |
|
||||||
case VIRTGPU_CMD_CTX_CREATE: |
|
||||||
graw_renderer_context_create(cmd->u.ctx_create.ctx_id, cmd->u.ctx_create.nlen, |
|
||||||
cmd->u.ctx_create.debug_name); |
|
||||||
break; |
|
||||||
case VIRTGPU_CMD_CTX_DESTROY: |
|
||||||
graw_renderer_context_destroy(cmd->u.ctx_destroy.ctx_id); |
|
||||||
break; |
|
||||||
case VIRTGPU_CMD_RESOURCE_CREATE_2D: |
|
||||||
virgl_cmd_create_resource_2d(cmd); |
|
||||||
break; |
|
||||||
case VIRTGPU_CMD_RESOURCE_CREATE_3D: |
|
||||||
virgl_cmd_create_resource_3d(cmd); |
|
||||||
break; |
|
||||||
case VIRTGPU_CMD_SUBMIT_3D: |
|
||||||
// fprintf(stderr,"cmd submit %lx %d\n", cmd->u.cmd_submit.data, cmd->u.cmd_submit.size);
|
|
||||||
|
|
||||||
{ |
|
||||||
graw_decode_block_iov(iov, niovs, cmd->u.cmd_submit.ctx_id, cmd->u.cmd_submit.phy_addr, cmd->u.cmd_submit.size / 4); |
|
||||||
fence_ctx_id = cmd->u.cmd_submit.ctx_id; |
|
||||||
} |
|
||||||
|
|
||||||
break; |
|
||||||
case VIRTGPU_CMD_TRANSFER_TO_HOST_2D: { |
|
||||||
struct pipe_box box; |
|
||||||
|
|
||||||
box.x = cmd->u.transfer_to_host_2d.x; |
|
||||||
box.y = cmd->u.transfer_to_host_2d.y; |
|
||||||
box.z = 0; |
|
||||||
box.width = cmd->u.transfer_to_host_2d.width; |
|
||||||
box.height = cmd->u.transfer_to_host_2d.height; |
|
||||||
box.depth = 1; |
|
||||||
|
|
||||||
// fprintf(stderr,"got transfer get %d\n", cmd->u.transfer_to_host_3d.res_handle);
|
|
||||||
graw_renderer_transfer_write_iov(cmd->u.transfer_to_host_2d.resource_id, |
|
||||||
0, |
|
||||||
0, |
|
||||||
0, |
|
||||||
0, |
|
||||||
(struct pipe_box *)&box, |
|
||||||
cmd->u.transfer_to_host_2d.offset, NULL, 0); |
|
||||||
break; |
|
||||||
} |
|
||||||
case VIRTGPU_CMD_TRANSFER_TO_HOST_3D: |
|
||||||
// fprintf(stderr,"got transfer get %d\n", cmd->u.transfer_to_host_3d.res_handle);
|
|
||||||
graw_renderer_transfer_write_iov(cmd->u.transfer_to_host_3d.resource_id, |
|
||||||
cmd->u.transfer_to_host_3d.ctx_id, |
|
||||||
cmd->u.transfer_to_host_3d.level, |
|
||||||
cmd->u.transfer_to_host_3d.stride, |
|
||||||
cmd->u.transfer_to_host_3d.layer_stride, |
|
||||||
(struct pipe_box *)&cmd->u.transfer_to_host_3d.box, |
|
||||||
cmd->u.transfer_to_host_3d.data, NULL, 0); |
|
||||||
fence_ctx_id = cmd->u.transfer_to_host_3d.ctx_id; |
|
||||||
break; |
|
||||||
case VIRTGPU_CMD_TRANSFER_FROM_HOST_3D: |
|
||||||
graw_renderer_transfer_send_iov(cmd->u.transfer_from_host_3d.resource_id, |
|
||||||
cmd->u.transfer_from_host_3d.ctx_id, |
|
||||||
cmd->u.transfer_from_host_3d.level, |
|
||||||
cmd->u.transfer_from_host_3d.stride, |
|
||||||
cmd->u.transfer_from_host_3d.layer_stride, |
|
||||||
(struct pipe_box *)&cmd->u.transfer_from_host_3d.box, |
|
||||||
cmd->u.transfer_from_host_3d.data, NULL, 0); |
|
||||||
fence_ctx_id = cmd->u.transfer_from_host_3d.ctx_id; |
|
||||||
break; |
|
||||||
|
|
||||||
case VIRTGPU_CMD_RESOURCE_ATTACH_BACKING: |
|
||||||
virgl_resource_attach_backing(&cmd->u.resource_attach_backing, iov, niovs); |
|
||||||
break; |
|
||||||
case VIRTGPU_CMD_RESOURCE_INVAL_BACKING: |
|
||||||
virgl_resource_inval_backing(cmd->u.resource_inval_backing.resource_id); |
|
||||||
break; |
|
||||||
case VIRTGPU_CMD_SET_SCANOUT: { |
|
||||||
struct pipe_box box; |
|
||||||
box.x = cmd->u.set_scanout.x; |
|
||||||
box.y = cmd->u.set_scanout.y; |
|
||||||
box.z = 0; |
|
||||||
box.width = cmd->u.set_scanout.width; |
|
||||||
box.height = cmd->u.set_scanout.height; |
|
||||||
box.depth = 1; |
|
||||||
graw_renderer_set_scanout(cmd->u.set_scanout.resource_id, cmd->u.set_scanout.scanout_id, |
|
||||||
0, &box); |
|
||||||
break; |
|
||||||
} |
|
||||||
case VIRTGPU_CMD_RESOURCE_FLUSH: |
|
||||||
{ |
|
||||||
struct pipe_box box; |
|
||||||
box.x = cmd->u.resource_flush.x; |
|
||||||
box.y = cmd->u.resource_flush.y; |
|
||||||
box.z = 0; |
|
||||||
box.width = cmd->u.resource_flush.width; |
|
||||||
box.height = cmd->u.resource_flush.height; |
|
||||||
box.depth = 1; |
|
||||||
graw_renderer_flush_buffer(cmd->u.resource_flush.resource_id, |
|
||||||
0, &box); |
|
||||||
break; |
|
||||||
}
|
|
||||||
case VIRTGPU_CMD_RESOURCE_UNREF: |
|
||||||
graw_renderer_resource_unref(cmd->u.resource_unref.resource_id); |
|
||||||
break; |
|
||||||
case VIRTGPU_CMD_CTX_ATTACH_RESOURCE: |
|
||||||
/* TODO add security */ |
|
||||||
break; |
|
||||||
case VIRTGPU_CMD_CTX_DETACH_RESOURCE: |
|
||||||
/* TODO add security */ |
|
||||||
break; |
|
||||||
case VIRTGPU_CMD_GET_CAPS: |
|
||||||
if (!niovs) |
|
||||||
return 0; |
|
||||||
|
|
||||||
{ |
|
||||||
struct virtgpu_response resp; |
|
||||||
graw_renderer_fill_caps(cmd->u.get_cap.cap_set, |
|
||||||
cmd->u.get_cap.cap_set_version, |
|
||||||
(union virgl_caps *)&resp.u.caps); |
|
||||||
resp.flags = 0; |
|
||||||
resp.type = VIRTGPU_CMD_GET_CAPS; |
|
||||||
graw_iov_from_buf(iov, niovs, 0, &resp, sizeof(struct virtgpu_response)); |
|
||||||
} |
|
||||||
|
|
||||||
break; |
|
||||||
case VIRTGPU_CMD_GET_DISPLAY_INFO: |
|
||||||
return -1; |
|
||||||
case 0xdeadbeef: |
|
||||||
if (inited) { |
|
||||||
graw_renderer_fini(); |
|
||||||
|
|
||||||
} |
|
||||||
graw_renderer_init(&virgl_cbs); |
|
||||||
inited = 1; |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
if (cmd->flags & VIRGL_COMMAND_EMIT_FENCE) |
|
||||||
graw_renderer_create_fence(cmd->fence_id, fence_ctx_id); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
void graw_transfer_write_return(void *data, uint32_t bytes, uint64_t offset, |
|
||||||
struct virgl_iovec *iov, int num_iovs) |
|
||||||
{ |
|
||||||
graw_iov_from_buf(iov, num_iovs, offset, data, bytes); |
|
||||||
} |
|
||||||
|
|
||||||
void graw_transfer_write_tex_return(struct pipe_resource *res, |
|
||||||
struct pipe_box *box, |
|
||||||
uint32_t level, |
|
||||||
uint32_t dst_stride, |
|
||||||
uint64_t offset, |
|
||||||
struct virgl_iovec *iov, |
|
||||||
int num_iovs, |
|
||||||
void *myptr, int size, int invert) |
|
||||||
{ |
|
||||||
int elsize = util_format_get_blocksize(res->format); |
|
||||||
int h; |
|
||||||
uint32_t myoffset = offset; |
|
||||||
uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, u_minify(res->width0, level)) * elsize; |
|
||||||
// uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, box->width) * elsize;
|
|
||||||
|
|
||||||
if (!invert && (stride == util_format_get_nblocksx(res->format, box->width) * elsize)) |
|
||||||
graw_iov_from_buf(iov, num_iovs, offset, myptr, size); |
|
||||||
else if (invert) { |
|
||||||
for (h = box->height - 1; h >= 0; h--) { |
|
||||||
void *sptr = myptr + (h * elsize * box->width); |
|
||||||
graw_iov_from_buf(iov, num_iovs, myoffset, sptr, box->width * elsize); |
|
||||||
myoffset += stride; |
|
||||||
} |
|
||||||
} else { |
|
||||||
for (h = 0; h < box->height; h++) { |
|
||||||
void *sptr = myptr + (h * elsize * box->width); |
|
||||||
graw_iov_from_buf(iov, num_iovs, myoffset, sptr, box->width * elsize); |
|
||||||
myoffset += stride; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void virgl_write_fence(uint32_t fence_id) |
|
||||||
{ |
|
||||||
rcbs->write_fence(dev_cookie, fence_id);
|
|
||||||
} |
|
||||||
|
|
||||||
static virgl_gl_context create_gl_context(int scanout_idx) |
|
||||||
{ |
|
||||||
if (use_egl_context) |
|
||||||
return virgl_egl_create_context(egl_info); |
|
||||||
return rcbs->create_gl_context(dev_cookie, scanout_idx); |
|
||||||
} |
|
||||||
|
|
||||||
static void destroy_gl_context(virgl_gl_context ctx) |
|
||||||
{ |
|
||||||
if (use_egl_context) |
|
||||||
return virgl_egl_destroy_context(egl_info, ctx); |
|
||||||
return rcbs->destroy_gl_context(dev_cookie, ctx); |
|
||||||
} |
|
||||||
|
|
||||||
static int make_current(int scanout_idx, virgl_gl_context ctx) |
|
||||||
{ |
|
||||||
if (use_egl_context) |
|
||||||
return virgl_egl_make_context_current(egl_info, ctx); |
|
||||||
return rcbs->make_current(dev_cookie, scanout_idx, ctx); |
|
||||||
} |
|
||||||
|
|
||||||
static void flush_scanout(int scanout_id, int x, int y, uint32_t width, uint32_t height) |
|
||||||
{ |
|
||||||
if (rcbs->rect_update) |
|
||||||
rcbs->rect_update(dev_cookie, scanout_id, x, y, width, height); |
|
||||||
} |
|
||||||
|
|
||||||
static void scanout_rect_info(int scanout_id, GLuint tex_id, |
|
||||||
int x, int y, uint32_t width, |
|
||||||
uint32_t height) |
|
||||||
{ |
|
||||||
if (rcbs->scanout_rect_info) |
|
||||||
rcbs->scanout_rect_info(dev_cookie, scanout_id, tex_id, |
|
||||||
x, y, width, height); |
|
||||||
} |
|
||||||
|
|
||||||
static void scanout_resource_info(int scanout_id, GLuint tex_id, uint32_t flags, |
|
||||||
uint32_t stride, uint32_t width, |
|
||||||
uint32_t height, uint32_t format) |
|
||||||
{ |
|
||||||
if (rcbs->scanout_resource_info) |
|
||||||
rcbs->scanout_resource_info(dev_cookie, scanout_id, tex_id, flags, |
|
||||||
stride, width, height, virgl_egl_get_gbm_format(format)); |
|
||||||
} |
|
||||||
|
|
||||||
static struct grend_if_cbs virgl_cbs = { |
|
||||||
virgl_write_fence, |
|
||||||
scanout_rect_info, |
|
||||||
scanout_resource_info, |
|
||||||
create_gl_context, |
|
||||||
destroy_gl_context, |
|
||||||
make_current, |
|
||||||
flush_scanout, |
|
||||||
virgl_resource_inval_backing_iov, |
|
||||||
}; |
|
||||||
|
|
||||||
void *virgl_get_cursor_data(uint32_t resource_id, uint32_t *width, uint32_t *height) |
|
||||||
{ |
|
||||||
return graw_renderer_get_cursor_contents(resource_id, width, height); |
|
||||||
} |
|
||||||
|
|
||||||
void virgl_renderer_set_cursor_info(uint32_t cursor_handle, int x, int y) |
|
||||||
{ |
|
||||||
grend_set_cursor_info(cursor_handle, x, y); |
|
||||||
} |
|
||||||
|
|
||||||
void virgl_renderer_poll(void) |
|
||||||
{ |
|
||||||
graw_renderer_check_queries(); |
|
||||||
graw_renderer_check_fences(); |
|
||||||
} |
|
||||||
|
|
||||||
void virgl_renderer_get_rect(int idx, struct virgl_iovec *iov, unsigned int num_iovs, |
|
||||||
uint32_t offset, int x, int y, int width, int height) |
|
||||||
{ |
|
||||||
graw_renderer_get_rect(idx, iov, num_iovs, offset, x, y, width, height); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks *cbs) |
|
||||||
{ |
|
||||||
dev_cookie = cookie; |
|
||||||
rcbs = cbs; |
|
||||||
localrender = 1; |
|
||||||
|
|
||||||
fprintf(stderr,"initied renderer %d\n", flags); |
|
||||||
if (flags & VIRGL_RENDERER_USE_EGL) { |
|
||||||
egl_info = virgl_egl_init(); |
|
||||||
if (!egl_info) |
|
||||||
return -1; |
|
||||||
use_egl_context = 1; |
|
||||||
} |
|
||||||
|
|
||||||
if (cbs->version != 1) |
|
||||||
return -1; |
|
||||||
graw_renderer_init(&virgl_cbs); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int virgl_renderer_get_fd_for_texture(uint32_t tex_id, int *fd) |
|
||||||
{ |
|
||||||
return virgl_egl_get_fd_for_texture(egl_info, tex_id, fd); |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,282 @@ |
|||||||
|
/**************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Red Hat Inc. |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the "Software"), |
||||||
|
* to deal in the Software without restriction, including without limitation |
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
* Software is furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included |
||||||
|
* in all copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||||
|
* OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
* |
||||||
|
**************************************************************************/ |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include <time.h> |
||||||
|
|
||||||
|
#include <epoxy/gl.h> |
||||||
|
|
||||||
|
#include <sys/mman.h> |
||||||
|
#include <sys/stat.h> |
||||||
|
#include <fcntl.h> |
||||||
|
#include <errno.h> |
||||||
|
#include <unistd.h> |
||||||
|
#include <sys/socket.h> |
||||||
|
#include <sys/un.h> |
||||||
|
#include <sys/eventfd.h> |
||||||
|
#include "pipe/p_state.h" |
||||||
|
#include "util/u_format.h" |
||||||
|
#include "util/u_math.h" |
||||||
|
#include "vrend_renderer.h" |
||||||
|
|
||||||
|
#include "virglrenderer.h" |
||||||
|
#include "virgl_egl.h" |
||||||
|
/* new API - just wrap internal API for now */ |
||||||
|
|
||||||
|
int virgl_renderer_resource_create(struct virgl_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs) |
||||||
|
{ |
||||||
|
return vrend_renderer_resource_create((struct vrend_renderer_resource_create_args *)args, iov, num_iovs); |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_resource_unref(uint32_t res_handle) |
||||||
|
{ |
||||||
|
vrend_renderer_resource_unref(res_handle); |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_fill_caps(uint32_t set, uint32_t version, |
||||||
|
void *caps) |
||||||
|
{ |
||||||
|
vrend_renderer_fill_caps(set, version, (union virgl_caps *)caps); |
||||||
|
} |
||||||
|
|
||||||
|
int virgl_renderer_context_create(uint32_t handle, uint32_t nlen, const char *name) |
||||||
|
{ |
||||||
|
vrend_renderer_context_create(handle, nlen, name); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_context_destroy(uint32_t handle) |
||||||
|
{ |
||||||
|
vrend_renderer_context_destroy(handle); |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_submit_cmd(void *buffer, |
||||||
|
int ctx_id, |
||||||
|
int ndw) |
||||||
|
{ |
||||||
|
vrend_decode_block(ctx_id, buffer, ndw); |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_transfer_write_iov(uint32_t handle,
|
||||||
|
uint32_t ctx_id, |
||||||
|
int level, |
||||||
|
uint32_t stride, |
||||||
|
uint32_t layer_stride, |
||||||
|
struct virgl_box *box, |
||||||
|
uint64_t offset, |
||||||
|
struct iovec *iovec, |
||||||
|
unsigned int iovec_cnt) |
||||||
|
{ |
||||||
|
vrend_renderer_transfer_write_iov(handle, ctx_id, level, |
||||||
|
stride, layer_stride, (struct pipe_box *)box, |
||||||
|
offset, iovec, iovec_cnt); |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_transfer_read_iov(uint32_t handle, uint32_t ctx_id, |
||||||
|
uint32_t level, uint32_t stride, |
||||||
|
uint32_t layer_stride, |
||||||
|
struct virgl_box *box, |
||||||
|
uint64_t offset, struct iovec *iov, |
||||||
|
int iovec_cnt) |
||||||
|
{ |
||||||
|
vrend_renderer_transfer_send_iov(handle, ctx_id, level, stride, |
||||||
|
layer_stride, (struct pipe_box *)box, |
||||||
|
offset, iov, iovec_cnt); |
||||||
|
} |
||||||
|
|
||||||
|
int virgl_renderer_resource_attach_iov(int res_handle, struct iovec *iov, |
||||||
|
int num_iovs) |
||||||
|
{ |
||||||
|
return vrend_renderer_resource_attach_iov(res_handle, iov, num_iovs); |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_resource_detach_iov(int res_handle, struct iovec **iov_p, int *num_iovs_p) |
||||||
|
{ |
||||||
|
return vrend_renderer_resource_detach_iov(res_handle, iov_p, num_iovs_p); |
||||||
|
} |
||||||
|
|
||||||
|
int virgl_renderer_create_fence(int client_fence_id, uint32_t ctx_id) |
||||||
|
{ |
||||||
|
return vrend_renderer_create_fence(client_fence_id, ctx_id); |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_force_ctx_0(void) |
||||||
|
{ |
||||||
|
vrend_renderer_force_ctx_0(); |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_ctx_attach_resource(int ctx_id, int res_handle) |
||||||
|
{ |
||||||
|
vrend_renderer_attach_res_ctx(ctx_id, res_handle); |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_ctx_detach_resource(int ctx_id, int res_handle) |
||||||
|
{ |
||||||
|
vrend_renderer_detach_res_ctx(ctx_id, res_handle); |
||||||
|
} |
||||||
|
|
||||||
|
int virgl_renderer_resource_get_info(int res_handle, |
||||||
|
struct virgl_renderer_resource_info *info) |
||||||
|
{ |
||||||
|
int ret; |
||||||
|
ret = vrend_renderer_resource_get_info(res_handle, (struct vrend_renderer_resource_info *)info); |
||||||
|
info->format = virgl_egl_get_gbm_format(info->format); |
||||||
|
return ret;
|
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_get_cap_set(uint32_t cap_set, uint32_t *max_ver, |
||||||
|
uint32_t *max_size) |
||||||
|
{ |
||||||
|
vrend_renderer_get_cap_set(cap_set, max_ver, max_size); |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_get_rect(int resource_id, struct iovec *iov, unsigned int num_iovs, |
||||||
|
uint32_t offset, int x, int y, int width, int height) |
||||||
|
{ |
||||||
|
vrend_renderer_get_rect(resource_id, iov, num_iovs, offset, x, y, width, height); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
static struct virgl_renderer_callbacks *rcbs; |
||||||
|
|
||||||
|
static void *dev_cookie; |
||||||
|
static int use_egl_context; |
||||||
|
struct virgl_egl *egl_info; |
||||||
|
static struct vrend_if_cbs virgl_cbs; |
||||||
|
|
||||||
|
void vrend_transfer_write_return(void *data, uint32_t bytes, uint64_t offset, |
||||||
|
struct iovec *iov, int num_iovs) |
||||||
|
{ |
||||||
|
vrend_write_to_iovec(iov, num_iovs, offset, data, bytes); |
||||||
|
} |
||||||
|
|
||||||
|
void vrend_transfer_write_tex_return(struct pipe_resource *res, |
||||||
|
struct pipe_box *box, |
||||||
|
uint32_t level, |
||||||
|
uint32_t dst_stride, |
||||||
|
uint64_t offset, |
||||||
|
struct iovec *iov, |
||||||
|
int num_iovs, |
||||||
|
void *myptr, int size, int invert) |
||||||
|
{ |
||||||
|
int elsize = util_format_get_blocksize(res->format); |
||||||
|
int h; |
||||||
|
uint32_t myoffset = offset; |
||||||
|
uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, u_minify(res->width0, level)) * elsize; |
||||||
|
// uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, box->width) * elsize;
|
||||||
|
|
||||||
|
if (!invert && (stride == util_format_get_nblocksx(res->format, box->width) * elsize)) |
||||||
|
vrend_write_to_iovec(iov, num_iovs, offset, myptr, size); |
||||||
|
else if (invert) { |
||||||
|
for (h = box->height - 1; h >= 0; h--) { |
||||||
|
void *sptr = myptr + (h * elsize * box->width); |
||||||
|
vrend_write_to_iovec(iov, num_iovs, myoffset, sptr, box->width * elsize); |
||||||
|
myoffset += stride; |
||||||
|
} |
||||||
|
} else { |
||||||
|
for (h = 0; h < box->height; h++) { |
||||||
|
void *sptr = myptr + (h * elsize * box->width); |
||||||
|
vrend_write_to_iovec(iov, num_iovs, myoffset, sptr, box->width * elsize); |
||||||
|
myoffset += stride; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void virgl_write_fence(uint32_t fence_id) |
||||||
|
{ |
||||||
|
rcbs->write_fence(dev_cookie, fence_id);
|
||||||
|
} |
||||||
|
|
||||||
|
static virgl_renderer_gl_context create_gl_context(int scanout_idx, struct virgl_gl_ctx_param *param) |
||||||
|
{ |
||||||
|
struct virgl_renderer_gl_ctx_param vparam; |
||||||
|
if (use_egl_context) |
||||||
|
return virgl_egl_create_context(egl_info, param); |
||||||
|
vparam.version = 1; |
||||||
|
vparam.shared = param->shared; |
||||||
|
vparam.major_ver = param->major_ver; |
||||||
|
vparam.minor_ver = param->minor_ver; |
||||||
|
return rcbs->create_gl_context(dev_cookie, scanout_idx, &vparam); |
||||||
|
} |
||||||
|
|
||||||
|
static void destroy_gl_context(virgl_renderer_gl_context ctx) |
||||||
|
{ |
||||||
|
if (use_egl_context) |
||||||
|
return virgl_egl_destroy_context(egl_info, ctx); |
||||||
|
return rcbs->destroy_gl_context(dev_cookie, ctx); |
||||||
|
} |
||||||
|
|
||||||
|
static int make_current(int scanout_idx, virgl_renderer_gl_context ctx) |
||||||
|
{ |
||||||
|
if (use_egl_context) |
||||||
|
return virgl_egl_make_context_current(egl_info, ctx); |
||||||
|
return rcbs->make_current(dev_cookie, scanout_idx, ctx); |
||||||
|
} |
||||||
|
|
||||||
|
static struct vrend_if_cbs virgl_cbs = { |
||||||
|
virgl_write_fence, |
||||||
|
create_gl_context, |
||||||
|
destroy_gl_context, |
||||||
|
make_current, |
||||||
|
}; |
||||||
|
|
||||||
|
void *virgl_renderer_get_cursor_data(uint32_t resource_id, uint32_t *width, uint32_t *height) |
||||||
|
{ |
||||||
|
return vrend_renderer_get_cursor_contents(resource_id, width, height); |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_poll(void) |
||||||
|
{ |
||||||
|
virgl_renderer_force_ctx_0(); |
||||||
|
vrend_renderer_check_queries(); |
||||||
|
vrend_renderer_check_fences(); |
||||||
|
} |
||||||
|
|
||||||
|
int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks *cbs) |
||||||
|
{ |
||||||
|
dev_cookie = cookie; |
||||||
|
rcbs = cbs; |
||||||
|
|
||||||
|
if (flags & VIRGL_RENDERER_USE_EGL) { |
||||||
|
egl_info = virgl_egl_init(); |
||||||
|
if (!egl_info) |
||||||
|
return -1; |
||||||
|
use_egl_context = 1; |
||||||
|
} |
||||||
|
|
||||||
|
if (cbs->version != 1) |
||||||
|
return -1; |
||||||
|
vrend_renderer_init(&virgl_cbs); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int virgl_renderer_get_fd_for_texture(uint32_t tex_id, int *fd) |
||||||
|
{ |
||||||
|
return virgl_egl_get_fd_for_texture(egl_info, tex_id, fd); |
||||||
|
} |
||||||
|
|
||||||
|
void virgl_renderer_reset(void) |
||||||
|
{ |
||||||
|
vrend_renderer_reset(); |
||||||
|
} |
@ -0,0 +1,563 @@ |
|||||||
|
/**************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Red Hat Inc. |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the "Software"), |
||||||
|
* to deal in the Software without restriction, including without limitation |
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
* Software is furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included |
||||||
|
* in all copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||||
|
* OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
* |
||||||
|
**************************************************************************/ |
||||||
|
|
||||||
|
/* gallium blitter implementation in GL */ |
||||||
|
/* for when we can't use glBlitFramebuffer */ |
||||||
|
#include <epoxy/gl.h> |
||||||
|
|
||||||
|
#include <stdio.h> |
||||||
|
#include "pipe/p_shader_tokens.h" |
||||||
|
|
||||||
|
#include "pipe/p_context.h" |
||||||
|
#include "pipe/p_defines.h" |
||||||
|
#include "pipe/p_screen.h" |
||||||
|
#include "pipe/p_state.h" |
||||||
|
#include "util/u_inlines.h" |
||||||
|
#include "util/u_memory.h" |
||||||
|
#include "util/u_dual_blend.h" |
||||||
|
|
||||||
|
#include "util/u_double_list.h" |
||||||
|
#include "util/u_format.h" |
||||||
|
#include "util/u_texture.h" |
||||||
|
#include "tgsi/tgsi_parse.h" |
||||||
|
|
||||||
|
#include "vrend_object.h" |
||||||
|
#include "vrend_shader.h" |
||||||
|
|
||||||
|
#include "vrend_renderer.h" |
||||||
|
|
||||||
|
#include "vrend_blitter.h" |
||||||
|
|
||||||
|
struct vrend_blitter_ctx { |
||||||
|
virgl_gl_context gl_context; |
||||||
|
bool initialised; |
||||||
|
|
||||||
|
GLuint vaoid; |
||||||
|
|
||||||
|
GLuint vs; |
||||||
|
GLuint vs_pos_only; |
||||||
|
GLuint fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES]; |
||||||
|
GLuint fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES]; |
||||||
|
GLuint fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES]; |
||||||
|
GLuint fb_id; |
||||||
|
|
||||||
|
unsigned dst_width; |
||||||
|
unsigned dst_height; |
||||||
|
|
||||||
|
GLuint vbo_id; |
||||||
|
GLfloat vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */ |
||||||
|
}; |
||||||
|
|
||||||
|
static struct vrend_blitter_ctx vrend_blit_ctx; |
||||||
|
|
||||||
|
static bool build_and_check(GLuint id, const char *buf) |
||||||
|
{ |
||||||
|
GLint param; |
||||||
|
glShaderSource(id, 1, (const char **)&buf, NULL); |
||||||
|
glCompileShader(id); |
||||||
|
|
||||||
|
glGetShaderiv(id, GL_COMPILE_STATUS, ¶m); |
||||||
|
if (param == GL_FALSE) { |
||||||
|
char infolog[65536]; |
||||||
|
int len; |
||||||
|
glGetShaderInfoLog(id, 65536, &len, infolog); |
||||||
|
fprintf(stderr,"shader failed to compile\n%s\n", infolog); |
||||||
|
fprintf(stderr,"GLSL:\n%s\n", buf); |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
static bool blit_build_vs_passthrough(struct vrend_blitter_ctx *blit_ctx) |
||||||
|
{ |
||||||
|
blit_ctx->vs = glCreateShader(GL_VERTEX_SHADER); |
||||||
|
|
||||||
|
if (!build_and_check(blit_ctx->vs, vs_passthrough)) { |
||||||
|
glDeleteShader(blit_ctx->vs); |
||||||
|
blit_ctx->vs = 0; |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
static GLuint blit_build_frag_tex_col(struct vrend_blitter_ctx *blit_ctx, int tgsi_tex_target) |
||||||
|
{ |
||||||
|
GLuint fs_id; |
||||||
|
char shader_buf[4096]; |
||||||
|
int is_shad; |
||||||
|
const char *twm; |
||||||
|
|
||||||
|
switch (tgsi_tex_target) { |
||||||
|
case TGSI_TEXTURE_1D: |
||||||
|
case TGSI_TEXTURE_BUFFER: |
||||||
|
twm = ".x"; |
||||||
|
break; |
||||||
|
case TGSI_TEXTURE_1D_ARRAY: |
||||||
|
case TGSI_TEXTURE_2D: |
||||||
|
case TGSI_TEXTURE_RECT: |
||||||
|
case TGSI_TEXTURE_2D_MSAA: |
||||||
|
default: |
||||||
|
twm = ".xy"; |
||||||
|
break; |
||||||
|
case TGSI_TEXTURE_SHADOW1D: |
||||||
|
case TGSI_TEXTURE_SHADOW2D: |
||||||
|
case TGSI_TEXTURE_SHADOW1D_ARRAY: |
||||||
|
case TGSI_TEXTURE_SHADOWRECT: |
||||||
|
case TGSI_TEXTURE_3D: |
||||||
|
case TGSI_TEXTURE_CUBE: |
||||||
|
case TGSI_TEXTURE_2D_ARRAY: |
||||||
|
case TGSI_TEXTURE_2D_ARRAY_MSAA: |
||||||
|
twm = ".xyz"; |
||||||
|
break; |
||||||
|
case TGSI_TEXTURE_SHADOWCUBE: |
||||||
|
case TGSI_TEXTURE_SHADOW2D_ARRAY: |
||||||
|
case TGSI_TEXTURE_SHADOWCUBE_ARRAY: |
||||||
|
case TGSI_TEXTURE_CUBE_ARRAY: |
||||||
|
twm = ""; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
snprintf(shader_buf, 4096, fs_texfetch_col, vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), twm, ""); |
||||||
|
|
||||||
|
fs_id = glCreateShader(GL_FRAGMENT_SHADER); |
||||||
|
|
||||||
|
if (!build_and_check(fs_id, shader_buf)) { |
||||||
|
glDeleteShader(fs_id); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
return fs_id; |
||||||
|
} |
||||||
|
|
||||||
|
static GLuint blit_build_frag_tex_writedepth(struct vrend_blitter_ctx *blit_ctx, int tgsi_tex_target) |
||||||
|
{ |
||||||
|
GLuint fs_id; |
||||||
|
char shader_buf[4096]; |
||||||
|
int is_shad; |
||||||
|
const char *twm; |
||||||
|
|
||||||
|
switch (tgsi_tex_target) { |
||||||
|
case TGSI_TEXTURE_1D: |
||||||
|
case TGSI_TEXTURE_BUFFER: |
||||||
|
twm = ".x"; |
||||||
|
break; |
||||||
|
case TGSI_TEXTURE_1D_ARRAY: |
||||||
|
case TGSI_TEXTURE_2D: |
||||||
|
case TGSI_TEXTURE_RECT: |
||||||
|
case TGSI_TEXTURE_2D_MSAA: |
||||||
|
default: |
||||||
|
twm = ".xy"; |
||||||
|
break; |
||||||
|
case TGSI_TEXTURE_SHADOW1D: |
||||||
|
case TGSI_TEXTURE_SHADOW2D: |
||||||
|
case TGSI_TEXTURE_SHADOW1D_ARRAY: |
||||||
|
case TGSI_TEXTURE_SHADOWRECT: |
||||||
|
case TGSI_TEXTURE_3D: |
||||||
|
case TGSI_TEXTURE_CUBE: |
||||||
|
case TGSI_TEXTURE_2D_ARRAY: |
||||||
|
case TGSI_TEXTURE_2D_ARRAY_MSAA: |
||||||
|
twm = ".xyz"; |
||||||
|
break; |
||||||
|
case TGSI_TEXTURE_SHADOWCUBE: |
||||||
|
case TGSI_TEXTURE_SHADOW2D_ARRAY: |
||||||
|
case TGSI_TEXTURE_SHADOWCUBE_ARRAY: |
||||||
|
case TGSI_TEXTURE_CUBE_ARRAY: |
||||||
|
twm = ""; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
snprintf(shader_buf, 4096, fs_texfetch_ds, vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), twm); |
||||||
|
|
||||||
|
fs_id = glCreateShader(GL_FRAGMENT_SHADER); |
||||||
|
|
||||||
|
if (!build_and_check(fs_id, shader_buf)) { |
||||||
|
glDeleteShader(fs_id); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
return fs_id; |
||||||
|
} |
||||||
|
|
||||||
|
static GLuint blit_build_frag_blit_msaa_depth(struct vrend_blitter_ctx *blit_ctx, int tgsi_tex_target) |
||||||
|
{ |
||||||
|
GLuint fs_id; |
||||||
|
char shader_buf[4096]; |
||||||
|
int is_shad; |
||||||
|
const char *twm; |
||||||
|
|
||||||
|
switch (tgsi_tex_target) { |
||||||
|
case TGSI_TEXTURE_2D_MSAA: |
||||||
|
twm = ".xy"; |
||||||
|
break; |
||||||
|
case TGSI_TEXTURE_2D_ARRAY_MSAA: |
||||||
|
twm = ".xyz"; |
||||||
|
break; |
||||||
|
default: |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
snprintf(shader_buf, 4096, fs_texfetch_ds_msaa, vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), twm); |
||||||
|
|
||||||
|
fs_id = glCreateShader(GL_FRAGMENT_SHADER); |
||||||
|
|
||||||
|
if (!build_and_check(fs_id, shader_buf)) { |
||||||
|
glDeleteShader(fs_id); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
return fs_id; |
||||||
|
} |
||||||
|
|
||||||
|
static GLuint blit_get_frag_tex_writedepth(struct vrend_blitter_ctx *blit_ctx, int pipe_tex_target, unsigned nr_samples) |
||||||
|
{ |
||||||
|
assert(pipe_tex_target < PIPE_MAX_TEXTURE_TYPES); |
||||||
|
|
||||||
|
if (nr_samples > 1) { |
||||||
|
GLuint *shader = &blit_ctx->fs_texfetch_depth_msaa[pipe_tex_target]; |
||||||
|
|
||||||
|
if (!*shader) { |
||||||
|
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex_target, nr_samples); |
||||||
|
|
||||||
|
*shader = blit_build_frag_blit_msaa_depth(blit_ctx, tgsi_tex); |
||||||
|
} |
||||||
|
return *shader; |
||||||
|
|
||||||
|
} else { |
||||||
|
GLuint *shader = &blit_ctx->fs_texfetch_depth[pipe_tex_target]; |
||||||
|
|
||||||
|
if (!*shader) { |
||||||
|
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex_target, 0); |
||||||
|
|
||||||
|
*shader = blit_build_frag_tex_writedepth(blit_ctx, tgsi_tex); |
||||||
|
} |
||||||
|
return *shader; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static GLuint blit_get_frag_tex_col(struct vrend_blitter_ctx *blit_ctx, int pipe_tex_target, unsigned nr_samples) |
||||||
|
{ |
||||||
|
assert(pipe_tex_target < PIPE_MAX_TEXTURE_TYPES); |
||||||
|
|
||||||
|
if (nr_samples > 1) { |
||||||
|
return 0; |
||||||
|
} else { |
||||||
|
GLuint *shader = &blit_ctx->fs_texfetch_col[pipe_tex_target]; |
||||||
|
|
||||||
|
if (!*shader) { |
||||||
|
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex_target, 0); |
||||||
|
|
||||||
|
*shader = blit_build_frag_tex_col(blit_ctx, tgsi_tex); |
||||||
|
} |
||||||
|
return *shader; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void vrend_renderer_init_blit_ctx(struct vrend_blitter_ctx *blit_ctx) |
||||||
|
{ |
||||||
|
struct virgl_gl_ctx_param ctx_params; |
||||||
|
int i; |
||||||
|
if (blit_ctx->initialised) { |
||||||
|
vrend_clicbs->make_current(0, blit_ctx->gl_context); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
ctx_params.shared = true; |
||||||
|
ctx_params.major_ver = VREND_GL_VER_MAJOR; |
||||||
|
ctx_params.minor_ver = VREND_GL_VER_MINOR; |
||||||
|
blit_ctx->gl_context = vrend_clicbs->create_gl_context(0, &ctx_params); |
||||||
|
|
||||||
|
vrend_clicbs->make_current(0, blit_ctx->gl_context); |
||||||
|
glGenVertexArrays(1, &blit_ctx->vaoid); |
||||||
|
glGenFramebuffers(1, &blit_ctx->fb_id); |
||||||
|
|
||||||
|
glGenBuffers(1, &blit_ctx->vbo_id); |
||||||
|
blit_build_vs_passthrough(blit_ctx); |
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) |
||||||
|
blit_ctx->vertices[i][0][3] = 1; /*v.w*/ |
||||||
|
glBindVertexArray(blit_ctx->vaoid); |
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, blit_ctx->vbo_id); |
||||||
|
} |
||||||
|
|
||||||
|
static inline GLenum convert_mag_filter(unsigned int filter) |
||||||
|
{ |
||||||
|
if (filter == PIPE_TEX_FILTER_NEAREST) |
||||||
|
return GL_NEAREST; |
||||||
|
return GL_LINEAR; |
||||||
|
} |
||||||
|
|
||||||
|
static void blitter_set_dst_dim(struct vrend_blitter_ctx *blit_ctx, |
||||||
|
unsigned width, unsigned height) |
||||||
|
{ |
||||||
|
blit_ctx->dst_width = width; |
||||||
|
blit_ctx->dst_height = height; |
||||||
|
} |
||||||
|
|
||||||
|
static void blitter_set_rectangle(struct vrend_blitter_ctx *blit_ctx, |
||||||
|
int x1, int y1, int x2, int y2, |
||||||
|
float depth) |
||||||
|
{ |
||||||
|
int i; |
||||||
|
|
||||||
|
/* set vertex positions */ |
||||||
|
blit_ctx->vertices[0][0][0] = (float)x1 / blit_ctx->dst_width * 2.0f - 1.0f; /*v0.x*/ |
||||||
|
blit_ctx->vertices[0][0][1] = (float)y1 / blit_ctx->dst_height * 2.0f - 1.0f; /*v0.y*/ |
||||||
|
|
||||||
|
blit_ctx->vertices[1][0][0] = (float)x2 / blit_ctx->dst_width * 2.0f - 1.0f; /*v1.x*/ |
||||||
|
blit_ctx->vertices[1][0][1] = (float)y1 / blit_ctx->dst_height * 2.0f - 1.0f; /*v1.y*/ |
||||||
|
|
||||||
|
blit_ctx->vertices[2][0][0] = (float)x2 / blit_ctx->dst_width * 2.0f - 1.0f; /*v2.x*/ |
||||||
|
blit_ctx->vertices[2][0][1] = (float)y2 / blit_ctx->dst_height * 2.0f - 1.0f; /*v2.y*/ |
||||||
|
|
||||||
|
blit_ctx->vertices[3][0][0] = (float)x1 / blit_ctx->dst_width * 2.0f - 1.0f; /*v3.x*/ |
||||||
|
blit_ctx->vertices[3][0][1] = (float)y2 / blit_ctx->dst_height * 2.0f - 1.0f; /*v3.y*/ |
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) |
||||||
|
blit_ctx->vertices[i][0][2] = depth; /*z*/ |
||||||
|
|
||||||
|
glViewport(0, 0, blit_ctx->dst_width, blit_ctx->dst_height); |
||||||
|
} |
||||||
|
|
||||||
|
static void get_texcoords(struct vrend_resource *src_res, |
||||||
|
int src_level, |
||||||
|
int x1, int y1, int x2, int y2, |
||||||
|
float out[4]) |
||||||
|
{ |
||||||
|
boolean normalized = src_res->base.target != PIPE_TEXTURE_RECT && |
||||||
|
src_res->base.nr_samples <= 1; |
||||||
|
|
||||||
|
if (normalized) { |
||||||
|
out[0] = x1 / (float)u_minify(src_res->base.width0, src_level); |
||||||
|
out[1] = y1 / (float)u_minify(src_res->base.height0, src_level); |
||||||
|
out[2] = x2 / (float)u_minify(src_res->base.width0, src_level); |
||||||
|
out[3] = y2 / (float)u_minify(src_res->base.height0, src_level); |
||||||
|
} else { |
||||||
|
out[0] = (float) x1; |
||||||
|
out[1] = (float) y1; |
||||||
|
out[2] = (float) x2; |
||||||
|
out[3] = (float) y2; |
||||||
|
} |
||||||
|
} |
||||||
|
static void set_texcoords_in_vertices(const float coord[4], |
||||||
|
float *out, unsigned stride) |
||||||
|
{ |
||||||
|
out[0] = coord[0]; /*t0.s*/ |
||||||
|
out[1] = coord[1]; /*t0.t*/ |
||||||
|
out += stride; |
||||||
|
out[0] = coord[2]; /*t1.s*/ |
||||||
|
out[1] = coord[1]; /*t1.t*/ |
||||||
|
out += stride; |
||||||
|
out[0] = coord[2]; /*t2.s*/ |
||||||
|
out[1] = coord[3]; /*t2.t*/ |
||||||
|
out += stride; |
||||||
|
out[0] = coord[0]; /*t3.s*/ |
||||||
|
out[1] = coord[3]; /*t3.t*/ |
||||||
|
} |
||||||
|
|
||||||
|
static void blitter_set_texcoords(struct vrend_blitter_ctx *blit_ctx, |
||||||
|
struct vrend_resource *src_res, |
||||||
|
int level, |
||||||
|
float layer, unsigned sample, |
||||||
|
int x1, int y1, int x2, int y2) |
||||||
|
{ |
||||||
|
float coord[4]; |
||||||
|
float face_coord[4][2]; |
||||||
|
int i; |
||||||
|
get_texcoords(src_res, level, x1, y1, x2, y2, coord); |
||||||
|
|
||||||
|
if (src_res->base.target == PIPE_TEXTURE_CUBE || |
||||||
|
src_res->base.target == PIPE_TEXTURE_CUBE_ARRAY) { |
||||||
|
set_texcoords_in_vertices(coord, &face_coord[0][0], 2); |
||||||
|
util_map_texcoords2d_onto_cubemap((unsigned)layer % 6, |
||||||
|
/* pointer, stride in floats */ |
||||||
|
&face_coord[0][0], 2, |
||||||
|
&blit_ctx->vertices[0][1][0], 8, |
||||||
|
FALSE); |
||||||
|
} else { |
||||||
|
set_texcoords_in_vertices(coord, &blit_ctx->vertices[0][1][0], 8); |
||||||
|
} |
||||||
|
|
||||||
|
switch (src_res->base.target) { |
||||||
|
case PIPE_TEXTURE_3D: |
||||||
|
{ |
||||||
|
float r = layer / (float)u_minify(src_res->base.depth0, |
||||||
|
level); |
||||||
|
for (i = 0; i < 4; i++) |
||||||
|
blit_ctx->vertices[i][1][2] = r; /*r*/ |
||||||
|
} |
||||||
|
break; |
||||||
|
|
||||||
|
case PIPE_TEXTURE_1D_ARRAY: |
||||||
|
for (i = 0; i < 4; i++) |
||||||
|
blit_ctx->vertices[i][1][1] = (float) layer; /*t*/ |
||||||
|
break; |
||||||
|
|
||||||
|
case PIPE_TEXTURE_2D_ARRAY: |
||||||
|
for (i = 0; i < 4; i++) { |
||||||
|
blit_ctx->vertices[i][1][2] = (float) layer; /*r*/ |
||||||
|
blit_ctx->vertices[i][1][3] = (float) sample; /*q*/ |
||||||
|
} |
||||||
|
break; |
||||||
|
case PIPE_TEXTURE_CUBE_ARRAY: |
||||||
|
for (i = 0; i < 4; i++) |
||||||
|
blit_ctx->vertices[i][1][3] = (float) ((unsigned)layer / 6); /*w*/ |
||||||
|
break; |
||||||
|
case PIPE_TEXTURE_2D: |
||||||
|
for (i = 0; i < 4; i++) { |
||||||
|
blit_ctx->vertices[i][1][3] = (float) sample; /*r*/ |
||||||
|
} |
||||||
|
break; |
||||||
|
default:; |
||||||
|
} |
||||||
|
} |
||||||
|
#if 0 |
||||||
|
static void set_dsa_keep_depth_stencil(void) |
||||||
|
{ |
||||||
|
glDisable(GL_STENCIL_TEST); |
||||||
|
glDisable(GL_DEPTH_TEST); |
||||||
|
glDepthMask(GL_FALSE); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
static void set_dsa_write_depth_keep_stencil(void) |
||||||
|
{ |
||||||
|
glDisable(GL_STENCIL_TEST); |
||||||
|
glEnable(GL_DEPTH_TEST); |
||||||
|
glDepthFunc(GL_ALWAYS); |
||||||
|
glDepthMask(GL_TRUE); |
||||||
|
} |
||||||
|
|
||||||
|
/* implement blitting using OpenGL. */ |
||||||
|
void vrend_renderer_blit_gl(struct vrend_context *ctx, |
||||||
|
struct vrend_resource *src_res, |
||||||
|
struct vrend_resource *dst_res, |
||||||
|
const struct pipe_blit_info *info) |
||||||
|
{ |
||||||
|
struct vrend_blitter_ctx *blit_ctx = &vrend_blit_ctx; |
||||||
|
GLuint prog_id; |
||||||
|
GLuint fs_id; |
||||||
|
GLint lret; |
||||||
|
GLenum filter; |
||||||
|
GLuint pos_loc, tc_loc; |
||||||
|
GLuint samp_loc; |
||||||
|
boolean has_depth, has_stencil; |
||||||
|
bool blit_stencil, blit_depth; |
||||||
|
int dst_z; |
||||||
|
const struct util_format_description *src_desc = |
||||||
|
util_format_description(src_res->base.format); |
||||||
|
const struct util_format_description *dst_desc = |
||||||
|
util_format_description(dst_res->base.format); |
||||||
|
|
||||||
|
has_depth = util_format_has_depth(src_desc) && |
||||||
|
util_format_has_depth(dst_desc); |
||||||
|
has_stencil = util_format_has_stencil(src_desc) && |
||||||
|
util_format_has_stencil(dst_desc); |
||||||
|
|
||||||
|
blit_depth = has_depth && (info->mask & PIPE_MASK_Z); |
||||||
|
blit_stencil = has_stencil && (info->mask & PIPE_MASK_S) & 0; |
||||||
|
|
||||||
|
filter = convert_mag_filter(info->filter); |
||||||
|
vrend_renderer_init_blit_ctx(blit_ctx); |
||||||
|
|
||||||
|
blitter_set_dst_dim(blit_ctx, |
||||||
|
u_minify(dst_res->base.width0, info->dst.level), |
||||||
|
u_minify(dst_res->base.height0, info->dst.level)); |
||||||
|
|
||||||
|
blitter_set_rectangle(blit_ctx, info->dst.box.x, info->dst.box.y, |
||||||
|
info->dst.box.x + info->dst.box.width, |
||||||
|
info->dst.box.y + info->dst.box.height, 0); |
||||||
|
|
||||||
|
|
||||||
|
prog_id = glCreateProgram(); |
||||||
|
glAttachShader(prog_id, blit_ctx->vs); |
||||||
|
|
||||||
|
if (blit_depth || blit_stencil) |
||||||
|
fs_id = blit_get_frag_tex_writedepth(blit_ctx, src_res->base.target, src_res->base.nr_samples); |
||||||
|
else |
||||||
|
fs_id = blit_get_frag_tex_col(blit_ctx, src_res->base.target, src_res->base.nr_samples); |
||||||
|
glAttachShader(prog_id, fs_id); |
||||||
|
|
||||||
|
glLinkProgram(prog_id); |
||||||
|
glGetProgramiv(prog_id, GL_LINK_STATUS, &lret); |
||||||
|
if (lret == GL_FALSE) { |
||||||
|
char infolog[65536]; |
||||||
|
int len; |
||||||
|
glGetProgramInfoLog(prog_id, 65536, &len, infolog); |
||||||
|
fprintf(stderr,"got error linking\n%s\n", infolog); |
||||||
|
/* dump shaders */ |
||||||
|
glDeleteProgram(prog_id); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
glUseProgram(prog_id); |
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER_EXT, blit_ctx->fb_id); |
||||||
|
vrend_fb_bind_texture(dst_res, 0, info->dst.level, info->dst.box.z); |
||||||
|
|
||||||
|
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); |
||||||
|
|
||||||
|
glBindTexture(src_res->target, src_res->id); |
||||||
|
|
||||||
|
glTexParameteri(src_res->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
||||||
|
glTexParameteri(src_res->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
||||||
|
glTexParameteri(src_res->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); |
||||||
|
|
||||||
|
glTexParameteri(src_res->target, GL_TEXTURE_BASE_LEVEL, info->src.level); |
||||||
|
glTexParameteri(src_res->target, GL_TEXTURE_MAX_LEVEL, info->src.level); |
||||||
|
glTexParameterf(src_res->target, GL_TEXTURE_MAG_FILTER, filter); |
||||||
|
glTexParameterf(src_res->target, GL_TEXTURE_MIN_FILTER, filter); |
||||||
|
pos_loc = glGetAttribLocation(prog_id, "arg0"); |
||||||
|
tc_loc = glGetAttribLocation(prog_id, "arg1"); |
||||||
|
samp_loc = glGetUniformLocation(prog_id, "samp"); |
||||||
|
|
||||||
|
glUniform1i(samp_loc, 0); |
||||||
|
|
||||||
|
glVertexAttribPointer(pos_loc, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(float), 0); |
||||||
|
glVertexAttribPointer(tc_loc, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(4 * sizeof(float))); |
||||||
|
|
||||||
|
glEnableVertexAttribArray(pos_loc); |
||||||
|
glEnableVertexAttribArray(tc_loc); |
||||||
|
|
||||||
|
set_dsa_write_depth_keep_stencil(); |
||||||
|
|
||||||
|
for (dst_z = 0; dst_z < info->dst.box.depth; dst_z++) { |
||||||
|
float dst2src_scale = info->src.box.depth / (float)info->dst.box.depth; |
||||||
|
float dst_offset = ((info->src.box.depth - 1) - |
||||||
|
(info->dst.box.depth - 1) * dst2src_scale) * 0.5; |
||||||
|
float src_z = (dst_z + dst_offset) * dst2src_scale; |
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER_EXT, blit_ctx->fb_id); |
||||||
|
vrend_fb_bind_texture(dst_res, 0, info->dst.level, dst_z); |
||||||
|
|
||||||
|
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); |
||||||
|
blitter_set_texcoords(blit_ctx, src_res, info->src.level, |
||||||
|
info->src.box.z + src_z, 0, |
||||||
|
info->src.box.x, info->src.box.y, |
||||||
|
info->src.box.x + info->src.box.width, |
||||||
|
info->src.box.y + info->src.box.height); |
||||||
|
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(blit_ctx->vertices), blit_ctx->vertices, GL_STATIC_DRAW); |
||||||
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
#ifndef VREND_BLITTER |
||||||
|
#define VREND_BLITTER |
||||||
|
|
||||||
|
/* shaders for blitting */ |
||||||
|
|
||||||
|
static const char *vs_passthrough = { |
||||||
|
"#version 130\n" |
||||||
|
"in vec4 arg0;\n" |
||||||
|
"in vec4 arg1;\n" |
||||||
|
"out vec4 tc;\n" |
||||||
|
"void main() {\n" |
||||||
|
" gl_Position = arg0;\n" |
||||||
|
" tc = arg1;\n" |
||||||
|
"}\n" |
||||||
|
}; |
||||||
|
|
||||||
|
static const char *fs_texfetch_col = { |
||||||
|
"#version 130\n" |
||||||
|
"uniform sampler%s samp;\n" |
||||||
|
"in vec4 tc;\n" |
||||||
|
"void main() {\n" |
||||||
|
" gl_FragColor = texture(samp, tc%s)%s;\n" |
||||||
|
"}\n" |
||||||
|
}; |
||||||
|
|
||||||
|
static const char *fs_texfetch_ds = { |
||||||
|
"#version 130\n" |
||||||
|
"uniform sampler%s samp;\n" |
||||||
|
"in vec4 tc;\n" |
||||||
|
"void main() {\n" |
||||||
|
" gl_FragDepth = float(texture(samp, tc%s).x);\n" |
||||||
|
"}\n" |
||||||
|
}; |
||||||
|
|
||||||
|
static const char *fs_texfetch_ds_msaa = { |
||||||
|
"#version 130\n" |
||||||
|
"#extension GL_ARB_texture_multisample : enable\n" |
||||||
|
"uniform sampler%s samp;\n" |
||||||
|
"in vec4 tc;\n" |
||||||
|
"void main() {\n" |
||||||
|
" gl_FragDepth = float(texelFetch(samp, tc%s, tc.z).x);\n" |
||||||
|
"}\n" |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,40 @@ |
|||||||
|
/**************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Red Hat Inc. |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the "Software"), |
||||||
|
* to deal in the Software without restriction, including without limitation |
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
* Software is furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included |
||||||
|
* in all copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||||
|
* OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
* |
||||||
|
**************************************************************************/ |
||||||
|
#ifndef VREND_IOV_H |
||||||
|
#define VREND_IOV_H |
||||||
|
|
||||||
|
#include <sys/uio.h> |
||||||
|
|
||||||
|
typedef void (*iov_cb)(void *cookie, unsigned int doff, void *src, int len); |
||||||
|
|
||||||
|
size_t vrend_get_iovec_size(const struct iovec *iov, int iovlen); |
||||||
|
size_t vrend_read_from_iovec(const struct iovec *iov, int iov_cnt, |
||||||
|
size_t offset, char *buf, size_t bytes); |
||||||
|
size_t vrend_write_to_iovec(const struct iovec *iov, int iov_cnt, |
||||||
|
size_t offset, const char *buf, size_t bytes); |
||||||
|
|
||||||
|
size_t vrend_read_from_iovec_cb(const struct iovec *iov, int iov_cnt, |
||||||
|
size_t offset, size_t bytes, iov_cb iocb, void *cookie); |
||||||
|
|
||||||
|
#endif |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,391 @@ |
|||||||
|
/**************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Red Hat Inc. |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the "Software"), |
||||||
|
* to deal in the Software without restriction, including without limitation |
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
* Software is furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included |
||||||
|
* in all copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||||
|
* OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
* |
||||||
|
**************************************************************************/ |
||||||
|
|
||||||
|
#ifndef VREND_RENDERER_H |
||||||
|
#define VREND_RENDERER_H |
||||||
|
|
||||||
|
#include "pipe/p_state.h" |
||||||
|
#include "util/u_inlines.h" |
||||||
|
#include "virgl_protocol.h" |
||||||
|
#include "vrend_iov.h" |
||||||
|
#include "virgl_hw.h" |
||||||
|
|
||||||
|
typedef void *virgl_gl_context; |
||||||
|
typedef void *virgl_gl_drawable; |
||||||
|
|
||||||
|
struct virgl_gl_ctx_param { |
||||||
|
bool shared; |
||||||
|
int major_ver; |
||||||
|
int minor_ver; |
||||||
|
}; |
||||||
|
|
||||||
|
extern int vrend_dump_shaders; |
||||||
|
struct vrend_context; |
||||||
|
|
||||||
|
struct vrend_resource { |
||||||
|
struct pipe_resource base; |
||||||
|
GLuint id; |
||||||
|
GLenum target; |
||||||
|
/* fb id if we need to readback this resource */ |
||||||
|
GLuint readback_fb_id; |
||||||
|
GLuint readback_fb_level; |
||||||
|
GLuint readback_fb_z; |
||||||
|
void *ptr; |
||||||
|
GLuint handle; |
||||||
|
|
||||||
|
struct iovec *iov; |
||||||
|
uint32_t num_iovs; |
||||||
|
boolean y_0_top; |
||||||
|
|
||||||
|
boolean scannedout; |
||||||
|
GLuint tbo_tex_id;/* tbos have two ids to track */ |
||||||
|
}; |
||||||
|
|
||||||
|
/* assume every format is sampler friendly */ |
||||||
|
#define VREND_BIND_SAMPLER (1 << 0) |
||||||
|
#define VREND_BIND_RENDER (1 << 1) |
||||||
|
#define VREND_BIND_DEPTHSTENCIL (1 << 2) |
||||||
|
|
||||||
|
#define VREND_BIND_NEED_SWIZZLE (1 << 28) |
||||||
|
|
||||||
|
struct vrend_format_table { |
||||||
|
enum virgl_formats format; |
||||||
|
GLenum internalformat; |
||||||
|
GLenum glformat; |
||||||
|
GLenum gltype; |
||||||
|
uint32_t bindings; |
||||||
|
int flags; |
||||||
|
uint8_t swizzle[4]; |
||||||
|
}; |
||||||
|
|
||||||
|
struct vrend_if_cbs { |
||||||
|
void (*write_fence)(unsigned fence_id); |
||||||
|
|
||||||
|
virgl_gl_context (*create_gl_context)(int scanout, struct virgl_gl_ctx_param *params); |
||||||
|
void (*destroy_gl_context)(virgl_gl_context ctx); |
||||||
|
int (*make_current)(int scanout, virgl_gl_context ctx); |
||||||
|
}; |
||||||
|
void vrend_renderer_init(struct vrend_if_cbs *cbs); |
||||||
|
|
||||||
|
void vrend_insert_format(struct vrend_format_table *entry, uint32_t bindings); |
||||||
|
void vrend_insert_format_swizzle(int override_format, struct vrend_format_table *entry, uint32_t bindings, uint8_t swizzle[4]); |
||||||
|
int vrend_create_shader(struct vrend_context *ctx, |
||||||
|
uint32_t handle, |
||||||
|
const struct pipe_shader_state *vs, |
||||||
|
int type); |
||||||
|
|
||||||
|
void vrend_bind_vs(struct vrend_context *ctx, |
||||||
|
uint32_t handle); |
||||||
|
|
||||||
|
void vrend_bind_gs(struct vrend_context *ctx, |
||||||
|
uint32_t handle); |
||||||
|
|
||||||
|
void vrend_bind_fs(struct vrend_context *ctx, |
||||||
|
uint32_t handle); |
||||||
|
|
||||||
|
void vrend_bind_vs_so(struct vrend_context *ctx, |
||||||
|
uint32_t handle); |
||||||
|
void vrend_clear(struct vrend_context *ctx, |
||||||
|
unsigned buffers, |
||||||
|
const union pipe_color_union *color, |
||||||
|
double depth, unsigned stencil); |
||||||
|
|
||||||
|
void vrend_draw_vbo(struct vrend_context *ctx, |
||||||
|
const struct pipe_draw_info *info); |
||||||
|
|
||||||
|
void vrend_set_framebuffer_state(struct vrend_context *ctx, |
||||||
|
uint32_t nr_cbufs, uint32_t surf_handle[8], |
||||||
|
uint32_t zsurf_handle); |
||||||
|
|
||||||
|
void vrend_flush(struct vrend_context *ctx); |
||||||
|
|
||||||
|
|
||||||
|
void vrend_flush_frontbuffer(uint32_t res_handle); |
||||||
|
struct vrend_context *vrend_create_context(int id, uint32_t nlen, const char *debug_name); |
||||||
|
bool vrend_destroy_context(struct vrend_context *ctx); |
||||||
|
void vrend_renderer_context_create(uint32_t handle, uint32_t nlen, const char *name); |
||||||
|
void vrend_renderer_context_create_internal(uint32_t handle, uint32_t nlen, const char *name); |
||||||
|
void vrend_renderer_context_destroy(uint32_t handle); |
||||||
|
|
||||||
|
struct vrend_renderer_resource_create_args { |
||||||
|
uint32_t handle; |
||||||
|
enum pipe_texture_target target; |
||||||
|
uint32_t format; |
||||||
|
uint32_t bind; |
||||||
|
uint32_t width; |
||||||
|
uint32_t height; |
||||||
|
uint32_t depth; |
||||||
|
uint32_t array_size; |
||||||
|
uint32_t last_level; |
||||||
|
uint32_t nr_samples; |
||||||
|
uint32_t flags; |
||||||
|
}; |
||||||
|
|
||||||
|
int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs); |
||||||
|
|
||||||
|
void vrend_renderer_resource_unref(uint32_t handle); |
||||||
|
|
||||||
|
int vrend_create_surface(struct vrend_context *ctx, |
||||||
|
uint32_t handle, |
||||||
|
uint32_t res_handle, uint32_t format, |
||||||
|
uint32_t val0, uint32_t val1); |
||||||
|
int vrend_create_sampler_view(struct vrend_context *ctx, |
||||||
|
uint32_t handle, |
||||||
|
uint32_t res_handle, uint32_t format, |
||||||
|
uint32_t val0, uint32_t val1, uint32_t swizzle_packed); |
||||||
|
|
||||||
|
int vrend_create_sampler_state(struct vrend_context *ctx, |
||||||
|
uint32_t handle, |
||||||
|
struct pipe_sampler_state *templ); |
||||||
|
|
||||||
|
int vrend_create_so_target(struct vrend_context *ctx, |
||||||
|
uint32_t handle, |
||||||
|
uint32_t res_handle, |
||||||
|
uint32_t buffer_offset, |
||||||
|
uint32_t buffer_size); |
||||||
|
|
||||||
|
void vrend_set_streamout_targets(struct vrend_context *ctx, |
||||||
|
uint32_t append_bitmask, |
||||||
|
uint32_t num_targets, |
||||||
|
uint32_t *handles); |
||||||
|
|
||||||
|
int vrend_create_vertex_elements_state(struct vrend_context *ctx, |
||||||
|
uint32_t handle, |
||||||
|
unsigned num_elements, |
||||||
|
const struct pipe_vertex_element *elements); |
||||||
|
void vrend_bind_vertex_elements_state(struct vrend_context *ctx, |
||||||
|
uint32_t handle); |
||||||
|
|
||||||
|
void vrend_set_single_vbo(struct vrend_context *ctx, |
||||||
|
int index, |
||||||
|
uint32_t stride, |
||||||
|
uint32_t buffer_offset, |
||||||
|
uint32_t res_handle); |
||||||
|
void vrend_set_num_vbo(struct vrend_context *ctx, |
||||||
|
int num_vbo); |
||||||
|
|
||||||
|
void vrend_transfer_inline_write(struct vrend_context *ctx, |
||||||
|
uint32_t res_handle, |
||||||
|
unsigned level, |
||||||
|
unsigned usage, |
||||||
|
const struct pipe_box *box, |
||||||
|
const void *data, |
||||||
|
unsigned stride, |
||||||
|
unsigned layer_stride); |
||||||
|
|
||||||
|
void vrend_set_viewport_state(struct vrend_context *ctx, |
||||||
|
const struct pipe_viewport_state *state); |
||||||
|
void vrend_set_num_sampler_views(struct vrend_context *ctx, |
||||||
|
uint32_t shader_type, |
||||||
|
uint32_t start_slot, |
||||||
|
int num_sampler_views); |
||||||
|
void vrend_set_single_sampler_view(struct vrend_context *ctx, |
||||||
|
uint32_t shader_type, |
||||||
|
int index, |
||||||
|
uint32_t res_handle); |
||||||
|
|
||||||
|
void vrend_object_bind_blend(struct vrend_context *ctx, |
||||||
|
uint32_t handle); |
||||||
|
void vrend_object_bind_dsa(struct vrend_context *ctx, |
||||||
|
uint32_t handle); |
||||||
|
void vrend_object_bind_rasterizer(struct vrend_context *ctx, |
||||||
|
uint32_t handle); |
||||||
|
|
||||||
|
void vrend_bind_sampler_states(struct vrend_context *ctx, |
||||||
|
uint32_t shader_type, |
||||||
|
uint32_t start_slot, |
||||||
|
uint32_t num_states, |
||||||
|
uint32_t *handles); |
||||||
|
void vrend_set_index_buffer(struct vrend_context *ctx, |
||||||
|
uint32_t res_handle, |
||||||
|
uint32_t index_size, |
||||||
|
uint32_t offset); |
||||||
|
|
||||||
|
void vrend_renderer_transfer_write_iov(uint32_t handle,
|
||||||
|
uint32_t ctx_id, |
||||||
|
int level, |
||||||
|
uint32_t stride, |
||||||
|
uint32_t layer_stride, |
||||||
|
struct pipe_box *box, |
||||||
|
uint64_t offset, |
||||||
|
struct iovec *iovec, |
||||||
|
unsigned int iovec_cnt); |
||||||
|
|
||||||
|
void vrend_renderer_resource_copy_region(struct vrend_context *ctx, |
||||||
|
uint32_t dst_handle, uint32_t dst_level, |
||||||
|
uint32_t dstx, uint32_t dsty, uint32_t dstz, |
||||||
|
uint32_t src_handle, uint32_t src_level, |
||||||
|
const struct pipe_box *src_box); |
||||||
|
|
||||||
|
void vrend_renderer_blit(struct vrend_context *ctx, |
||||||
|
uint32_t dst_handle, uint32_t src_handle, |
||||||
|
const struct pipe_blit_info *info); |
||||||
|
|
||||||
|
void vrend_renderer_transfer_send_iov(uint32_t handle, uint32_t ctx_id, |
||||||
|
uint32_t level, uint32_t stride, |
||||||
|
uint32_t layer_stride, |
||||||
|
struct pipe_box *box, |
||||||
|
uint64_t offset, struct iovec *iov, |
||||||
|
int iovec_cnt); |
||||||
|
void vrend_set_stencil_ref(struct vrend_context *ctx, struct pipe_stencil_ref *ref); |
||||||
|
void vrend_set_blend_color(struct vrend_context *ctx, struct pipe_blend_color *color); |
||||||
|
void vrend_set_scissor_state(struct vrend_context *ctx, struct pipe_scissor_state *ss); |
||||||
|
|
||||||
|
void vrend_set_polygon_stipple(struct vrend_context *ctx, struct pipe_poly_stipple *ps); |
||||||
|
|
||||||
|
void vrend_set_clip_state(struct vrend_context *ctx, struct pipe_clip_state *ucp); |
||||||
|
void vrend_set_sample_mask(struct vrend_context *ctx, unsigned sample_mask); |
||||||
|
|
||||||
|
void vrend_set_constants(struct vrend_context *ctx, |
||||||
|
uint32_t shader, |
||||||
|
uint32_t index, |
||||||
|
uint32_t num_constant, |
||||||
|
float *data); |
||||||
|
|
||||||
|
void vrend_set_uniform_buffer(struct vrend_context *ctx, uint32_t shader, |
||||||
|
uint32_t index, uint32_t offset, uint32_t length, |
||||||
|
uint32_t res_handle); |
||||||
|
|
||||||
|
void vrend_transfer_write_return(void *data, uint32_t bytes, uint64_t offset, |
||||||
|
struct iovec *iov, int iovec_cnt); |
||||||
|
|
||||||
|
void vrend_transfer_write_tex_return(struct pipe_resource *res, |
||||||
|
struct pipe_box *box, |
||||||
|
uint32_t level, |
||||||
|
uint32_t dst_stride, |
||||||
|
uint64_t offset, |
||||||
|
struct iovec *iov, |
||||||
|
int num_iovs, |
||||||
|
void *myptr, int size, int invert); |
||||||
|
|
||||||
|
void vrend_renderer_fini(void); |
||||||
|
|
||||||
|
void vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw); |
||||||
|
struct vrend_context *vrend_lookup_renderer_ctx(uint32_t ctx_id); |
||||||
|
|
||||||
|
int vrend_renderer_create_fence(int client_fence_id, uint32_t ctx_id); |
||||||
|
|
||||||
|
void vrend_renderer_check_fences(void); |
||||||
|
void vrend_renderer_check_queries(void); |
||||||
|
void vrend_stop_current_queries(void); |
||||||
|
|
||||||
|
boolean vrend_hw_switch_context(struct vrend_context *ctx, boolean now); |
||||||
|
uint32_t vrend_renderer_object_insert(struct vrend_context *ctx, void *data, |
||||||
|
uint32_t size, uint32_t handle, enum virgl_object_type type); |
||||||
|
void vrend_renderer_object_destroy(struct vrend_context *ctx, uint32_t handle); |
||||||
|
|
||||||
|
int vrend_create_query(struct vrend_context *ctx, uint32_t handle, |
||||||
|
uint32_t query_type, uint32_t res_handle, |
||||||
|
uint32_t offset); |
||||||
|
|
||||||
|
void vrend_begin_query(struct vrend_context *ctx, uint32_t handle); |
||||||
|
void vrend_end_query(struct vrend_context *ctx, uint32_t handle); |
||||||
|
void vrend_get_query_result(struct vrend_context *ctx, uint32_t handle, |
||||||
|
uint32_t wait); |
||||||
|
void vrend_render_condition(struct vrend_context *ctx, |
||||||
|
uint32_t handle, |
||||||
|
boolean condtion, |
||||||
|
uint mode); |
||||||
|
void *vrend_renderer_get_cursor_contents(uint32_t res_handle, uint32_t *width, uint32_t *height); |
||||||
|
void vrend_use_program(GLuint program_id); |
||||||
|
void vrend_blend_enable(GLboolean blend_enable); |
||||||
|
void vrend_depth_test_enable(GLboolean depth_test_enable); |
||||||
|
void vrend_bind_va(GLuint vaoid); |
||||||
|
int vrend_renderer_flush_buffer_res(struct vrend_resource *res, |
||||||
|
struct pipe_box *box); |
||||||
|
|
||||||
|
void vrend_renderer_fill_caps(uint32_t set, uint32_t version, |
||||||
|
union virgl_caps *caps); |
||||||
|
|
||||||
|
GLint64 vrend_renderer_get_timestamp(void); |
||||||
|
/* formats */ |
||||||
|
void vrend_build_format_list(void); |
||||||
|
|
||||||
|
int vrend_renderer_resource_attach_iov(int res_handle, struct iovec *iov, |
||||||
|
int num_iovs); |
||||||
|
void vrend_renderer_resource_detach_iov(int res_handle, |
||||||
|
struct iovec **iov_p, |
||||||
|
int *num_iovs_p); |
||||||
|
void vrend_renderer_resource_destroy(struct vrend_resource *res); |
||||||
|
|
||||||
|
static INLINE void |
||||||
|
vrend_resource_reference(struct vrend_resource **ptr, struct vrend_resource *tex) |
||||||
|
{ |
||||||
|
struct vrend_resource *old_tex = *ptr; |
||||||
|
|
||||||
|
if (pipe_reference(&(*ptr)->base.reference, &tex->base.reference)) |
||||||
|
vrend_renderer_resource_destroy(old_tex); |
||||||
|
*ptr = tex; |
||||||
|
} |
||||||
|
|
||||||
|
void vrend_renderer_force_ctx_0(void); |
||||||
|
|
||||||
|
void vrend_renderer_get_rect(int resource_id, struct iovec *iov, unsigned int num_iovs, |
||||||
|
uint32_t offset, int x, int y, int width, int height); |
||||||
|
void vrend_renderer_attach_res_ctx(int ctx_id, int resource_id); |
||||||
|
void vrend_renderer_detach_res_ctx(int ctx_id, int resource_id); |
||||||
|
|
||||||
|
|
||||||
|
struct vrend_renderer_resource_info { |
||||||
|
uint32_t handle; |
||||||
|
uint32_t format; |
||||||
|
uint32_t width; |
||||||
|
uint32_t height; |
||||||
|
uint32_t depth; |
||||||
|
uint32_t flags; |
||||||
|
uint32_t tex_id; |
||||||
|
uint32_t stride; |
||||||
|
}; |
||||||
|
|
||||||
|
int vrend_renderer_resource_get_info(int res_handle, |
||||||
|
struct vrend_renderer_resource_info *info); |
||||||
|
|
||||||
|
#define VREND_CAP_SET 1 |
||||||
|
|
||||||
|
void vrend_renderer_get_cap_set(uint32_t cap_set, uint32_t *max_ver, |
||||||
|
uint32_t *max_size); |
||||||
|
|
||||||
|
void vrend_renderer_create_sub_ctx(struct vrend_context *ctx, int sub_ctx_id); |
||||||
|
void vrend_renderer_destroy_sub_ctx(struct vrend_context *ctx, int sub_ctx_id); |
||||||
|
void vrend_renderer_set_sub_ctx(struct vrend_context *ctx, int sub_ctx_id); |
||||||
|
void vrend_report_buffer_error(struct vrend_context *ctx, int cmd); |
||||||
|
|
||||||
|
void vrend_fb_bind_texture(struct vrend_resource *res, |
||||||
|
int idx, |
||||||
|
uint32_t level, uint32_t layer); |
||||||
|
bool vrend_is_ds_format(enum virgl_formats format); |
||||||
|
const char *vrend_shader_samplertypeconv(int sampler_type, int *is_shad); |
||||||
|
/* blitter interface */ |
||||||
|
void vrend_renderer_blit_gl(struct vrend_context *ctx, |
||||||
|
struct vrend_resource *src_res, |
||||||
|
struct vrend_resource *dst_res, |
||||||
|
const struct pipe_blit_info *info); |
||||||
|
|
||||||
|
void vrend_renderer_reset(void); |
||||||
|
void vrend_decode_reset(void); |
||||||
|
#define VREND_GL_VER_MAJOR 3 |
||||||
|
#define VREND_GL_VER_MINOR 1 |
||||||
|
|
||||||
|
extern struct vrend_if_cbs *vrend_clicbs; |
||||||
|
#endif |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,82 @@ |
|||||||
|
/**************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Red Hat Inc. |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
* copy of this software and associated documentation files (the "Software"), |
||||||
|
* to deal in the Software without restriction, including without limitation |
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
* Software is furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included |
||||||
|
* in all copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||||
|
* OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
* |
||||||
|
**************************************************************************/ |
||||||
|
|
||||||
|
#ifndef VREND_SHADER_H |
||||||
|
#define VREND_SHADER_H |
||||||
|
|
||||||
|
#include "pipe/p_state.h" |
||||||
|
|
||||||
|
/* need to store patching info for interpolation */ |
||||||
|
struct vrend_interp_info { |
||||||
|
int semantic_name; |
||||||
|
int semantic_index; |
||||||
|
int interpolate; |
||||||
|
}; |
||||||
|
|
||||||
|
struct vrend_shader_info { |
||||||
|
uint32_t samplers_used_mask; |
||||||
|
int num_consts; |
||||||
|
int num_inputs; |
||||||
|
int num_interps; |
||||||
|
int num_outputs; |
||||||
|
int num_ubos; |
||||||
|
int num_ucp; |
||||||
|
int glsl_ver; |
||||||
|
uint32_t shadow_samp_mask; |
||||||
|
struct pipe_stream_output_info so_info; |
||||||
|
|
||||||
|
struct vrend_interp_info *interpinfo; |
||||||
|
int gs_out_prim; |
||||||
|
char **so_names; |
||||||
|
}; |
||||||
|
|
||||||
|
struct vrend_shader_key { |
||||||
|
uint32_t coord_replace; |
||||||
|
boolean invert_fs_origin; |
||||||
|
boolean pstipple_tex; |
||||||
|
boolean add_alpha_test; |
||||||
|
boolean color_two_side; |
||||||
|
uint8_t alpha_test; |
||||||
|
uint8_t clip_plane_enable; |
||||||
|
float alpha_ref_val; |
||||||
|
boolean gs_present; |
||||||
|
boolean flatshade; |
||||||
|
}; |
||||||
|
|
||||||
|
struct vrend_shader_cfg { |
||||||
|
int glsl_version; |
||||||
|
bool use_core_profile; |
||||||
|
}; |
||||||
|
|
||||||
|
boolean vrend_patch_vertex_shader_interpolants(char *program, |
||||||
|
struct vrend_shader_info *vs_info, |
||||||
|
struct vrend_shader_info *fs_info, |
||||||
|
bool is_gs, bool flatshade); |
||||||
|
|
||||||
|
char *vrend_convert_shader(struct vrend_shader_cfg *cfg, |
||||||
|
const struct tgsi_token *tokens, |
||||||
|
struct vrend_shader_key *key, |
||||||
|
struct vrend_shader_info *sinfo); |
||||||
|
const char *vrend_shader_samplertypeconv(int sampler_type, int *is_shad); |
||||||
|
#endif |
Loading…
Reference in new issue